📄 objrtmch.c
字号:
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 =================================================== */ ObjectReteData(theEnv)->CurrentPatternObject->busy++; theMatch = CreateAlphaMatch(theEnv,(void *) ObjectReteData(theEnv)->CurrentPatternObject, ObjectReteData(theEnv)->CurrentPatternObjectMarks, (struct patternNodeHeader *) alphaPtr,hashValue); theMatch->owner = alphaPtr; /* ====================================== Attach the partial match to the object to ease later retraction ====================================== */ newMatch = get_struct(theEnv,patternMatch); newMatch->next = (struct patternMatch *) ObjectReteData(theEnv)->CurrentPatternObject->partialMatchList; newMatch->matchingPattern = (struct patternNodeHeader *) alphaPtr; newMatch->theMatch = theMatch; ObjectReteData(theEnv)->CurrentPatternObject->partialMatchList = (void *) newMatch; /* ================================================ Drive the partial match through the join network ================================================ */ listOfJoins = alphaPtr->header.entryJoin; while (listOfJoins != NULL) { NetworkAssert(theEnv,theMatch,listOfJoins); listOfJoins = listOfJoins->rightMatchNode; } } alphaPtr = alphaPtr->nxtInGroup; } }/****************************************************** NAME : EvaluateObjectPatternTest DESCRIPTION : Evaluates the pattern network test expression for a node INPUTS : 1) The actual index of the slot value field currently being examined 2) The multifield marker (if any) for the pattern node being exmained 3) The pattern network test expression 4) The pattern node being examined RETURNS : TRUE if the node passes the test, FALSE otherwise SIDE EFFECTS : Evaluation of the test EvaluationError and HaltExecution are always set to FALSE NOTES : Assumes networkTest != NULL ******************************************************/static intBool EvaluateObjectPatternTest( void *theEnv, int objectSlotField, struct multifieldMarker *selfSlotMarker, EXPRESSION *networkTest, OBJECT_PATTERN_NODE *patternNode) { DATA_OBJECT vresult; int rv; if (networkTest == NULL) return(TRUE); if (networkTest->type == OBJ_PN_CONSTANT) { struct expr *oldArgument; oldArgument = EvaluationData(theEnv)->CurrentExpression; EvaluationData(theEnv)->CurrentExpression = networkTest; rv = ObjectCmpConstantFunction(theEnv,networkTest->value,&vresult); EvaluationData(theEnv)->CurrentExpression = oldArgument; if (rv) { if (((struct ObjectCmpPNConstant *) ValueToBitMap(networkTest->value))->pass) patternNode->blocked = TRUE; return(TRUE); } return(FALSE); } /* ========================================================= Evaluate or expressions expressed in the format: (or <expression 1> <expression 2> ... <expression n>) Returns TRUE (1.0) if any of the expression are TRUE, otherwise returns false (0.0). ========================================================= */ if (networkTest->value == ExpressionData(theEnv)->PTR_OR) { networkTest = networkTest->argList; while (networkTest != NULL) { if (EvaluateObjectPatternTest(theEnv,objectSlotField,selfSlotMarker,networkTest,patternNode)) { /* ============================================ A node can be blocked ONLY if there were one positive constant test on that node ============================================ */ patternNode->blocked = FALSE; return(TRUE); } patternNode->blocked = FALSE; networkTest = networkTest->nextArg; } return(FALSE); } /* ========================================================== Evaluate and expressions expressed in the format: (and <expression 1> <expression 2> ... <expression n>) Returns false (0.0) if any of the expression are false, otherwise returns TRUE (1.0). ========================================================== */ else if (networkTest->value == ExpressionData(theEnv)->PTR_AND) { networkTest = networkTest->argList; while (networkTest != NULL) { if (EvaluateObjectPatternTest(theEnv,objectSlotField,selfSlotMarker,networkTest,patternNode) == FALSE) { patternNode->blocked = FALSE; return(FALSE); } patternNode->blocked = FALSE; networkTest = networkTest->nextArg; } return(TRUE); } /* ======================================================= Evaluate all other expressions using EvaluateExpression ======================================================= */ else { EvaluationData(theEnv)->HaltExecution = FALSE; if (EvaluateExpression(theEnv,networkTest,&vresult)) { ObjectPatternNetErrorMessage(theEnv,patternNode); EvaluationData(theEnv)->EvaluationError = FALSE; EvaluationData(theEnv)->HaltExecution = FALSE; return(FALSE); } if ((vresult.value != EnvFalseSymbol(theEnv)) || (vresult.type != SYMBOL)) return(TRUE); } return(FALSE); }/*************************************************** NAME : ObjectAssertAction DESCRIPTION : Filters an instance through the object pattern network INPUTS : The instance RETURNS : Nothing useful SIDE EFFECTS : Instance matched NOTES : None ***************************************************/static void ObjectAssertAction( void *theEnv, INSTANCE_TYPE *ins) { ins->header.timeTag = ObjectReteData(theEnv)->UseEntityTimeTag; ObjectReteData(theEnv)->CurrentPatternObject = ins; ObjectReteData(theEnv)->CurrentPatternObjectSlot = NULL; MarkObjectPatternNetwork(theEnv,NULL); ObjectPatternMatch(theEnv,0,ObjectNetworkPointer(theEnv),NULL); ins->reteSynchronized = TRUE; }/********************************************************************** NAME : ObjectModifyAction DESCRIPTION : Removes an instance from patterns (and attached joins) applicable to specified slot(s), and then filters same instance through object pattern network (only against patterns which explicitly match on named slot(s)) INPUTS : 1) The instance 2) The bitmap of slot ids RETURNS : Nothing useful SIDE EFFECTS : Instance retracted/asserted NOTES : None **********************************************************************/static void ObjectModifyAction( void *theEnv, INSTANCE_TYPE *ins, SLOT_BITMAP *slotNameIDs) { ins->header.timeTag = ObjectReteData(theEnv)->UseEntityTimeTag; ObjectRetractAction(theEnv,ins,slotNameIDs); ObjectReteData(theEnv)->CurrentPatternObject = ins; ObjectReteData(theEnv)->CurrentPatternObjectSlot = NULL; MarkObjectPatternNetwork(theEnv,slotNameIDs); ObjectPatternMatch(theEnv,0,ObjectNetworkPointer(theEnv),NULL); ins->reteSynchronized = TRUE; }/**************************************************** NAME : ObjectRetractAction DESCRIPTION : Retracts the instance from the applicable patterns for the object (if the slotNameID != -1, then the instance is only retracted from the alpha memories of the patterns which actually match on that slot) INPUTS : 1) The instance 2) The slot bitmap for a modify (NULL if the instance is actually being removed) RETURNS : Nothing useful SIDE EFFECTS : Retractions performed NOTES : None ****************************************************/static void ObjectRetractAction( void *theEnv, INSTANCE_TYPE *ins, SLOT_BITMAP *slotNameIDs) { struct patternMatch *prvMatch,*tmpMatch, *deleteMatch,*lastDeleteMatch; OBJECT_ALPHA_NODE *alphaPtr; void *saveDependents; if (slotNameIDs == NULL) { if (ins->partialMatchList != NULL) { tmpMatch = (struct patternMatch *) ins->partialMatchList; while (tmpMatch != NULL) { ins->busy--; tmpMatch = tmpMatch->next; } NetworkRetract(theEnv,(struct patternMatch *) ins->partialMatchList); ins->partialMatchList = NULL; } } else { deleteMatch = NULL; lastDeleteMatch = NULL; prvMatch = NULL; tmpMatch = (struct patternMatch *) ins->partialMatchList; while (tmpMatch != NULL) { alphaPtr = (OBJECT_ALPHA_NODE *) tmpMatch->matchingPattern; if (alphaPtr->slotbmp != NULL) { if (CompareSlotBitMaps(slotNameIDs, (SLOT_BITMAP *) ValueToBitMap(alphaPtr->slotbmp))) { ins->busy--; if (prvMatch == NULL) ins->partialMatchList = (void *) tmpMatch->next; else prvMatch->next = tmpMatch->next; if (!deleteMatch) deleteMatch = tmpMatch; else lastDeleteMatch->next = tmpMatch; lastDeleteMatch = tmpMatch; tmpMatch = tmpMatch->next; lastDeleteMatch->next = NULL; } else { prvMatch = tmpMatch; tmpMatch = tmpMatch->next; } } else { prvMatch = tmpMatch; tmpMatch = tmpMatch->next; } } /* ============================================= We need to preserve any logical dependencies of this object and reattach them after doing the retract. Otherwise, the Rete network will believe the object is gone and remove the links from the partial matches upon which this object is logically dependent. ============================================= */ if (deleteMatch != NULL) { saveDependents = ins->header.dependents; ins->header.dependents = NULL; NetworkRetract(theEnv,deleteMatch); ins->header.dependents = saveDependents; } } ins->reteSynchronized = TRUE; }/***************************************************** NAME : ObjectPatternNetErrorMessage DESCRIPTION : Prints out a locational error message when an evaluation error occurs during object pattern-matching INPUTS : The pattern node RETURNS : Nothing useful SIDE EFFECTS : Error message displayed NOTES : None *****************************************************/static void ObjectPatternNetErrorMessage( void *theEnv, OBJECT_PATTERN_NODE *patternPtr) { PrintErrorID(theEnv,"OBJRTMCH",1,TRUE); EnvPrintRouter(theEnv,WERROR,"This error occurred in the object pattern network\n"); EnvPrintRouter(theEnv,WERROR," Currently active instance: ["); EnvPrintRouter(theEnv,WERROR,ValueToString(ObjectReteData(theEnv)->CurrentPatternObject->name)); EnvPrintRouter(theEnv,WERROR,"]\n"); EnvPrintRouter(theEnv,WERROR," Problem resides in slot "); EnvPrintRouter(theEnv,WERROR,ValueToString(FindIDSlotName(theEnv,patternPtr->slotNameID))); EnvPrintRouter(theEnv,WERROR," field #"); PrintLongInteger(theEnv,WERROR,(long long) patternPtr->whichField); EnvPrintRouter(theEnv,WERROR,"\n"); TraceErrorToObjectPattern(theEnv,TRUE,patternPtr); EnvPrintRouter(theEnv,WERROR,"\n"); }/********************************************************* NAME : TraceErrorToObjectPattern DESCRIPTION : Used by ObjectPatternNetErrorMessage() to print the rule(s) which contain an object pattern. INPUTS : 1) A flag indicating if this is the node in which the error actually occurred or not 2) The pattern node RETURNS : Nothing useful SIDE EFFECTS : Error message displayed NOTES : None *********************************************************/static void TraceErrorToObjectPattern( void *theEnv, int errorNode, OBJECT_PATTERN_NODE *patternPtr) { struct joinNode *joinPtr; while (patternPtr != NULL) { if (patternPtr->alphaNode != NULL) { joinPtr = patternPtr->alphaNode->header.entryJoin; while (joinPtr != NULL) { TraceErrorToRule(theEnv,joinPtr," "); joinPtr = joinPtr->rightMatchNode; } } TraceErrorToObjectPattern(theEnv,FALSE,patternPtr->nextLevel); if (errorNode) break; patternPtr = patternPtr->rightNode; } }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -