📄 objrtmch.c
字号:
if (upper->matchTimeTag == CurrentObjectMatchTimeTag) break; else upper->matchTimeTag = CurrentObjectMatchTimeTag; } } } } alphaPtr = alphaPtr->nxtTerminal; } }/*************************************************** NAME : CompareSlotBitMaps DESCRIPTION : Compares two slot bitmaps by bitwising and'ing byte per byte up to the length of the smaller map. INPUTS : The two slot bitmaps RETURNS : CLIPS_TRUE if any common bits are set in both maps, CLIPS_FALSE otherwise SIDE EFFECTS : None NOTES : None ***************************************************/static BOOLEAN CompareSlotBitMaps(smap1,smap2) SLOT_BITMAP *smap1,*smap2; { unsigned short i,maxByte; maxByte = (unsigned short) (((smap1->maxid < smap2->maxid) ? smap1->maxid : smap2->maxid) / BITS_PER_BYTE); for (i = 0 ; i <= maxByte ; i++) if (smap1->map[i] & smap2->map[i]) return(CLIPS_TRUE); return(CLIPS_FALSE); } /********************************************************************************** NAME : ObjectPatternMatch DESCRIPTION : Iterates through all the pattern nodes on one level in the pattern network. A node is only processed if it can lead to a terminating class bitmap node which applies to the object being matched. This allows for a significant reduction in the number of patterns considered. INPUTS : 1) The offset of the slot position from the pattern index 2) The pattern node being examined 3) The end of the list of multifield markers for the pattern RETURNS : Nothing useful SIDE EFFECTS : The pattern tests are evaluated and the child nodes may be processed (which may cause a whole series of Rete network updates). NOTES : Several globals are used to keep track of the current slot being examined: CurrentPatternMarks - the series of multifield markers CurrentPatternObject - the object being pattern-matched CurrentPatternObjectSlot - the current slot being examined CurrentObjectSlotLength - the cardinality of the slot value An optimization is performed when evaluating constant tests on a slot value field. All pattern nodes on a level which restrict the same slot are grouped together. Those which are constant tests are placed at the far right. Thus, as soon as one of these constant tests succeeds, the remaining nodes for that slot on this level can be skipped **********************************************************************************/static VOID ObjectPatternMatch(offset,patternTop,endMark) int offset; OBJECT_PATTERN_NODE *patternTop; struct multifieldMarker *endMark; { register int saveSlotLength; register INSTANCE_SLOT *saveSlot; OBJECT_PATTERN_NODE *blockedNode; while (patternTop != NULL) { /* =========================================================== MarkObjectPatternNetwork() has already marked pattern nodes which need processing according to the class bitmaps, slot updates and incremental reset status =========================================================== */ if (patternTop->matchTimeTag == CurrentObjectMatchTimeTag) { /* ======================================== Make sure we are examining the correct slot of the object for this pattern node ======================================== */ if ((patternTop->slotNameID == ISA_ID) || (patternTop->slotNameID == NAME_ID)) { CurrentPatternObjectSlot = NULL; CurrentObjectSlotLength = 1; offset = 0; } else if ((CurrentPatternObjectSlot == NULL) ? CLIPS_TRUE : (CurrentPatternObjectSlot->desc->slotName->id != patternTop->slotNameID)) { /* ==================================================== Need to reset the indices for the multifield markers now that we have moved onto a different slot ==================================================== */ CurrentPatternObjectSlot = CurrentPatternObject->slotAddresses[CurrentPatternObject->cls->slotNameMap [patternTop->slotNameID] - 1]; offset = 0; if (CurrentPatternObjectSlot->desc->multiple) CurrentObjectSlotLength = GetInstanceSlotLength(CurrentPatternObjectSlot); else CurrentObjectSlotLength = 1; } /* ======================================================== Process the pattern node. If it is satisfied by the the instance, ProcessPatternNode() will recursively pass all of its children nodes through ObjectPatternMatch() ======================================================== */ saveSlotLength = CurrentObjectSlotLength; saveSlot = CurrentPatternObjectSlot; ProcessPatternNode(offset,patternTop,endMark); CurrentObjectSlotLength = saveSlotLength; CurrentPatternObjectSlot = saveSlot; } /* ============================================================== Move on to the siblings of this node - if the current node was a constant test that succeeded, skip further sibling nodes (which test on the same field in the pattern) which match on the same slot since they are all constant tests as well and will, of course fail. ============================================================== */ if (patternTop->blocked == CLIPS_TRUE) { patternTop->blocked = CLIPS_FALSE; blockedNode = patternTop; patternTop = patternTop->rightNode; while (patternTop != NULL) { if ((patternTop->slotNameID != blockedNode->slotNameID) || (patternTop->whichField != blockedNode->whichField)) break; patternTop = patternTop->rightNode; } } else patternTop = patternTop->rightNode; } }/********************************************************************************** NAME : ProcessPatternNode DESCRIPTION : Determines if a pattern node satsifies the corresponding slot value field(s) in an object. If it does, ObjectPatternMatch() is recursively called to process the child nodes of this node. In this mutual recursion between ObjectPatternMatch() and ProcessPatternNode(), the nodes of all applicable patterns are processed to completion. ObjectPatternMatch() enters an object into a pattern's aplha memory when the traversal reaches a terminal class bitmap node. INPUTS : 1) The offset of the slot index from the pattern index 2) The pattern node being examined 3) The end of the list of multifield markers for the pattern RETURNS : Nothing useful SIDE EFFECTS : The pattern tests are evaluated and the child nodes may be processed (which may cause a whole series of Rete network updates). NOTES : Several globals are used to keep track of the current slot being examined: CurrentPatternMarks - the series of multifield markers CurrentPatternObject - the object being pattern-matched CurrentPatternObjectSlot - the current slot being examined CurrentObjectSlotLength - the cardinality of the slot value **********************************************************************************/static VOID ProcessPatternNode(offset,patternNode,endMark) int offset; OBJECT_PATTERN_NODE *patternNode; struct multifieldMarker *endMark; { int patternSlotField,objectSlotField, objectSlotLength, repeatCount; INSTANCE_SLOT *objectSlot; struct multifieldMarker *newMark; patternSlotField = patternNode->whichField; objectSlotField = patternSlotField + offset; /* ========================================== If this is a test on the class or the name of the object, process it separately. ========================================== */ if (CurrentPatternObjectSlot == NULL) { if ((patternNode->networkTest == NULL) ? CLIPS_TRUE : (EvaluateObjectPatternTest(objectSlotField,NULL, (EXPRESSION *) patternNode->networkTest,patternNode))) { if (patternNode->alphaNode != NULL) CreateObjectAlphaMatch(patternNode->alphaNode); ObjectPatternMatch(offset,patternNode->nextLevel,endMark); } return; } /* ================================ Check a single-field restriction ================================ */ if (patternNode->multifieldNode == 0) { if ((patternNode->networkTest == NULL) ? CLIPS_TRUE : EvaluateObjectPatternTest(objectSlotField,NULL, (EXPRESSION *) patternNode->networkTest,patternNode)) { if (patternNode->alphaNode != NULL) CreateObjectAlphaMatch(patternNode->alphaNode); ObjectPatternMatch(offset,patternNode->nextLevel,endMark); } return; } /* ================================================================== Check a multifield restriction. Add a marker for this field which has indices indicating to which values in the object slot the multifield pattern node is bound ================================================================== */ newMark = get_struct(multifieldMarker); newMark->whichField = patternSlotField; newMark->where.whichSlot = (VOID *) CurrentPatternObjectSlot->desc->slotName->name; newMark->startPosition = objectSlotField; newMark->next = NULL; if (CurrentPatternObjectMarks == NULL) CurrentPatternObjectMarks = newMark; else endMark->next = newMark; /* ========================================================== If there are further pattern restrictions on this slot, try pattern-matching for all possible bound values of the multifield pattern node: from no values to all values from the starting position of the multifield to the end of the object slot. Otherwise, bind the multifield to all the remaining fields in the slot value and continue with pattern-matching ========================================================== */ if (patternNode->endSlot == CLIPS_FALSE) { objectSlotLength = CurrentObjectSlotLength; objectSlot = CurrentPatternObjectSlot; newMark->endPosition = newMark->startPosition - 1; repeatCount = objectSlotLength - newMark->startPosition - patternNode->leaveFields + 2; while (repeatCount > 0) { if ((patternNode->networkTest == NULL) ? CLIPS_TRUE : EvaluateObjectPatternTest(objectSlotField,newMark, (EXPRESSION *) patternNode->networkTest,patternNode)) { if (patternNode->alphaNode != NULL) CreateObjectAlphaMatch(patternNode->alphaNode); ObjectPatternMatch((int) (offset + (newMark->endPosition - objectSlotField)), patternNode->nextLevel,newMark); CurrentObjectSlotLength = objectSlotLength; CurrentPatternObjectSlot = objectSlot; } newMark->endPosition++; repeatCount--; } } else { newMark->endPosition = CurrentObjectSlotLength; if ((patternNode->networkTest == NULL) ? CLIPS_TRUE : EvaluateObjectPatternTest(objectSlotField,newMark, (EXPRESSION *) patternNode->networkTest,patternNode)) { if (patternNode->alphaNode != NULL) CreateObjectAlphaMatch(patternNode->alphaNode); ObjectPatternMatch(0,patternNode->nextLevel,newMark); } } /* ====================================== Delete the temporary multifield marker ====================================== */ if (CurrentPatternObjectMarks == newMark) CurrentPatternObjectMarks = NULL; else endMark->next = NULL; rtn_struct(multifieldMarker,newMark); }/*************************************************** NAME : CreateObjectAlphaMatch DESCRIPTION : Places an instance in the alpha memory of a pattern and drives the partial match through the join network INPUTS : The alpha memory node RETURNS : Nothing useful SIDE EFFECTS : Join network updated NOTES : None ***************************************************/static VOID CreateObjectAlphaMatch(alphaPtr) OBJECT_ALPHA_NODE *alphaPtr; { struct joinNode *listOfJoins; struct partialMatch *theMatch; struct patternMatch *newMatch; while (alphaPtr != NULL) { if (alphaPtr->matchTimeTag == CurrentObjectMatchTimeTag) { /* =================================================== If we have reached the class bitmap of the pattern, place the object in the alpha memory of each of the terminal nodes underneath and drive the partial matches through the join network. Insert the instance into the alpha memory of this pattern and mark it as busy =================================================== */ CurrentPatternObject->busy++; theMatch = CreateAlphaMatch((VOID *) CurrentPatternObject, CurrentPatternObjectMarks, (struct patternNodeHeader *) alphaPtr); /* ====================================== Attach the partial match to the object to ease later retraction ====================================== */ newMatch = get_struct(patternMatch); newMatch->next = (struct patternMatch *) CurrentPatternObject->partialMatchList; newMatch->matchingPattern = (struct patternNodeHeader *) alphaPtr; newMatch->theMatch = theMatch; CurrentPatternObject->partialMatchList = (VOID *) newMatch; /* ================================================ Drive the partial match through the join network ================================================ */ listOfJoins = alphaPtr->header.entryJoin; while (listOfJoins != NULL) { NetworkAssert(theMatch,listOfJoins,RHS);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -