📄 objrtmch.c
字号:
JoinOperationInProgress = CLIPS_FALSE; #if LOGICAL_DEPENDENCIES ForceLogicalRetractions();#endif } /* ========================================= ***************************************** INTERNALLY VISIBLE FUNCTIONS ========================================= ***************************************** */ /*************************************************** NAME : ResetObjectMatchTimeTags DESCRIPTION : If CurrentObjectMatchTimeTag + 1 would cause an overflow, CurrentObjectMatchTimeTag is reset to 0L and all time tags in object pattern nodes are reset. INPUTS : None RETURNS : Nothing useful SIDE EFFECTS : CurrentObjectMatchTimeTag reset to 0, and all match time tags reset These tags are used to recognize valid pattern nodes on a match NOTES : None ***************************************************/static VOID ResetObjectMatchTimeTags() { OBJECT_ALPHA_NODE *alphaPtr; OBJECT_PATTERN_NODE *lastLevel; /* ============================================ If the current tag incremented by one would not cause an overflow, then we can leave things alone. ============================================ */ if ((CurrentObjectMatchTimeTag + 1L) > CurrentObjectMatchTimeTag) return; CurrentObjectMatchTimeTag = 0L; alphaPtr = ObjectNetworkTerminalPointer(); while (alphaPtr != NULL) { alphaPtr->matchTimeTag = 0L; lastLevel = alphaPtr->patternNode; while (lastLevel != NULL) { if (lastLevel->matchTimeTag == 0L) break; lastLevel->matchTimeTag = 0L; lastLevel = lastLevel->lastLevel; } alphaPtr = alphaPtr->nxtTerminal; } }/*************************************************** NAME : QueueObjectMatchAction DESCRIPTION : Posts a Rete network match event for later processing INPUTS : 1) The match action type OBJECT_ASSERT (1) OBJECT_RETRACT (2) OBJECT_MODIFY (3) 2) The instance to be matched 3) The name id of the slot being updated (can be -1) RETURNS : Nothing useful SIDE EFFECTS : Queue updated NOTES : None ***************************************************/static VOID QueueObjectMatchAction(type,ins,slotNameID) int type; INSTANCE_TYPE *ins; int slotNameID; { OBJECT_MATCH_ACTION *prv,*cur,*new; prv = NULL; cur = ObjectMatchActionQueue; while (cur != NULL) { /* =========================================================== Here are the possibilities for the first Rete event already on the queue as compared with the new event for an object: Assert/Retract --> Delete assert event Ignore retract event Assert/Modify --> Ignore modify event Modify/Modify --> Merge new modify event Modify/Retract --> Delete modify event Queue the retract event =========================================================== */ if (cur->ins == ins) { /* =================================================== An action for initially asserting the newly created object to all applicable patterns =================================================== */ if (cur->type == OBJECT_ASSERT) { if (type == OBJECT_RETRACT) { /* =================================================== If we are retracting the entire object, then we can remove the assert action (and all modifies as well) and ignore the retract action (basically the object came and went before the Rete network had a chance to see it) =================================================== */ if (prv == NULL) ObjectMatchActionQueue = cur->nxt; else prv->nxt = cur->nxt; cur->ins->busy--; ReturnObjectMatchAction(cur); } /* ================================================= If this is a modify action, then we can ignore it since the assert action will encompass it ================================================= */ } /* =================================================== If the object is being deleted after a slot modify, drop the modify event and replace with the retract =================================================== */ else if (type == OBJECT_RETRACT) { cur->type = OBJECT_RETRACT; if (cur->slotNameIDs != NULL) { rm((VOID *) cur->slotNameIDs,SlotBitMapSize(cur->slotNameIDs)); cur->slotNameIDs = NULL; } } /* ==================================================== If a modify event for this slot is already on the queue, ignore this one. Otherwise, merge the slot id ==================================================== */ else cur->slotNameIDs = QueueModifySlotMap(cur->slotNameIDs,slotNameID); return; } prv = cur; cur = cur->nxt; } /* ================================================ If there are no actions for the instance already on the queue, the new action is simply appended. ================================================ */ new = get_struct(objectMatchAction); new->type = type; new->nxt = cur; new->slotNameIDs = (type != OBJECT_MODIFY) ? NULL : QueueModifySlotMap(NULL,slotNameID); new->ins = ins; new->ins->busy++; if (prv == NULL) ObjectMatchActionQueue = new; else prv->nxt = new; }/**************************************************** NAME : QueueModifySlotMap DESCRIPTION : Sets the bitmap for a queued object modify Rete network action INPUTS : 1) The old bitmap (can be NULL) 2) The canonical slot id to set RETURNS : The (new) bitmap SIDE EFFECTS : Bitmap allocated/reallocated if necessary, and slot id bit set NOTES : If the bitmap must be (re)allocated, this routine allocates twice the room necessary for the current id to allow for growth. ****************************************************/static SLOT_BITMAP *QueueModifySlotMap(oldMap,slotNameID) SLOT_BITMAP *oldMap; int slotNameID; { SLOT_BITMAP *newMap; unsigned short newmaxid; int oldsz,newsz; if ((oldMap == NULL) ? CLIPS_TRUE : (slotNameID > oldMap->maxid)) { newmaxid = (unsigned short) (slotNameID * 2); newsz = (int) (sizeof(SLOT_BITMAP) + (sizeof(char) * (newmaxid / BITS_PER_BYTE))); newMap = (SLOT_BITMAP *) gm2(newsz); ClearBitString((VOID *) newMap,newsz); if (oldMap != NULL) { oldsz = SlotBitMapSize(oldMap); CopyMemory(char,oldsz,newMap,oldMap); rm((VOID *) oldMap,oldsz); } newMap->maxid = newmaxid; } else newMap = oldMap; SetBitMap(newMap->map,slotNameID); return(newMap); }/*************************************************** NAME : ReturnObjectMatchAction DESCRIPTION : Deallocates and object match action structure and associated slot bitmap (if any) INPUTS : The queued match action item RETURNS : Nothing useful SIDE EFFECTS : Object match action item deleted NOTES : None ***************************************************/static VOID ReturnObjectMatchAction(omaPtr) OBJECT_MATCH_ACTION *omaPtr; { if (omaPtr->slotNameIDs != NULL) rm((VOID *) omaPtr->slotNameIDs,SlotBitMapSize(omaPtr->slotNameIDs)); rtn_struct(objectMatchAction,omaPtr); } /*************************************************** NAME : ProcessObjectMatchQueue DESCRIPTION : Processes all outstanding object Rete network update events INPUTS : None RETURNS : Nothing useful SIDE EFFECTS : Pattern-matching on objects NOTES : None ***************************************************/static VOID ProcessObjectMatchQueue() { OBJECT_MATCH_ACTION *cur; while ((ObjectMatchActionQueue != NULL) && (DelayObjectPatternMatching == CLIPS_FALSE)) { cur = ObjectMatchActionQueue; ObjectMatchActionQueue = cur->nxt; switch(cur->type) { case OBJECT_ASSERT : ObjectAssertAction(cur->ins); break; case OBJECT_RETRACT : ObjectRetractAction(cur->ins,cur->slotNameIDs); break; default : ObjectModifyAction(cur->ins,cur->slotNameIDs); } cur->ins->busy--; ReturnObjectMatchAction(cur); } }/****************************************************** NAME : MarkObjectPatternNetwork DESCRIPTION : Iterates through all terminal pattern nodes checking class and slot bitmaps. If a pattern is applicable to the object/slot change, then all the nodes belonging to the pattern are marked as needing to be examined by the pattern matcher. INPUTS : The bitmap of ids of the slots being changed (NULL if this is an assert for the for the entire object) RETURNS : Nothing useful SIDE EFFECTS : Applicable pattern nodes marked NOTES : Incremental reset status is also checked here ******************************************************/static VOID MarkObjectPatternNetwork(slotNameIDs) SLOT_BITMAP *slotNameIDs; { OBJECT_ALPHA_NODE *alphaPtr; OBJECT_PATTERN_NODE *upper; CLASS_BITMAP *clsset; unsigned id; ResetObjectMatchTimeTags(); CurrentObjectMatchTimeTag++; alphaPtr = ObjectNetworkTerminalPointer(); id = CurrentPatternObject->cls->id; while (alphaPtr != NULL) { /* ============================================================= If an incremental reset is in progress, make sure that the pattern has been marked for initialization before proceeding. ============================================================= */#if INCREMENTAL_RESET && (! RUN_TIME) && (! BLOAD_ONLY) if (IncrementalResetInProgress && (alphaPtr->header.initialize == CLIPS_FALSE)) { alphaPtr = alphaPtr->nxtTerminal; continue; }#endif /* ============================================ Check the class bitmap to see if the pattern pattern is applicable to the object at all ============================================ */ clsset = (CLASS_BITMAP *) ValueToBitMap(alphaPtr->classbmp); if ((id > (unsigned) clsset->maxid) ? CLIPS_FALSE : TestBitMap(clsset->map,id)) { /* =================================================== If we are doing an assert, then we need to check all patterns which satsify the class bitmap (The retraction has already been done in this case) =================================================== */ if (slotNameIDs == NULL) { alphaPtr->matchTimeTag = CurrentObjectMatchTimeTag; for (upper = alphaPtr->patternNode ; upper != NULL ; upper = upper->lastLevel) { if (upper->matchTimeTag == CurrentObjectMatchTimeTag) break; else upper->matchTimeTag = CurrentObjectMatchTimeTag; } } /* =================================================== If we are doing a slot modify, then we need to check only the subset of patterns which satisfy the class bitmap AND actually match on the slot in question. =================================================== */ else if (alphaPtr->slotbmp != NULL) { if (CompareSlotBitMaps(slotNameIDs, (SLOT_BITMAP *) ValueToBitMap(alphaPtr->slotbmp))) { alphaPtr->matchTimeTag = CurrentObjectMatchTimeTag; for (upper = alphaPtr->patternNode ; upper != NULL ; upper = upper->lastLevel) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -