📄 factmch.c
字号:
case FACT_PN_CONSTANT2: oldArgument = CurrentExpression; CurrentExpression = theTest; rv = FactPNConstant2(theTest->value,&theResult); CurrentExpression = oldArgument; return(rv); /*================================================*/ /* This primitive determines if a multifield slot */ /* contains at least a certain number of fields. */ /*================================================*/ case FACT_SLOT_LENGTH: oldArgument = CurrentExpression; CurrentExpression = theTest; rv = FactSlotLength(theTest->value,&theResult); CurrentExpression = oldArgument; return(rv); } /*==============================================*/ /* Evaluate "or" expressions by evaluating each */ /* argument and return TRUE if any of them */ /* evaluated to TRUE, otherwise return FALSE. */ /*==============================================*/ if (theTest->value == PTR_OR) { for (theTest = theTest->argList; theTest != NULL; theTest = theTest->nextArg) { if (EvaluatePatternExpression(patternPtr,theTest,thePosition) == CLIPS_TRUE) { if (EvaluationError) return(CLIPS_FALSE); return(CLIPS_TRUE); } if (EvaluationError) return(CLIPS_FALSE); } return(CLIPS_FALSE); } /*===============================================*/ /* Evaluate "and" expressions by evaluating each */ /* argument and return FALSE if any of them */ /* evaluated to FALSE, otherwise return TRUE. */ /*===============================================*/ else if (theTest->value == PTR_AND) { for (theTest = theTest->argList; theTest != NULL; theTest = theTest->nextArg) { if (EvaluatePatternExpression(patternPtr,theTest,thePosition) == CLIPS_FALSE) { return(CLIPS_FALSE); } if (EvaluationError) return(CLIPS_FALSE); } return(CLIPS_TRUE); } /*==========================================================*/ /* Evaluate all other expressions using EvaluateExpression. */ /*==========================================================*/ if (EvaluateExpression(theTest,&theResult)) { PatternNetErrorMessage(patternPtr); return(CLIPS_FALSE); } if ((theResult.value == CLIPSFalseSymbol) && (theResult.type == SYMBOL)) { return(CLIPS_FALSE); } return(CLIPS_TRUE); }/************************************************************************//* PatternNetErrorMessage: Prints the informational header to the error *//* message that occurs when a error occurs as the result of *//* evaluating an expression in the fact pattern network. Prints the *//* fact currently being pattern matched and the field number or slot *//* name in the pattern from which the error originated. The error is *//* then trace to the point where the pattern enters the join network *//* so that the names of the rule which utilize the pattern can also *//* be printed. *//************************************************************************/static VOID PatternNetErrorMessage(patternPtr) struct factPatternNode *patternPtr; { char buffer[60]; struct templateSlot *theSlots; int i; /*=======================================*/ /* Print the fact being pattern matched. */ /*=======================================*/ PrintErrorID("FACTMCH",1,CLIPS_TRUE); PrintCLIPS(WERROR,"This error occurred in the fact pattern network\n"); PrintCLIPS(WERROR," Currently active fact: "); PrintFact(WERROR,CurrentPatternFact); PrintCLIPS(WERROR,"\n"); /*==============================================*/ /* Print the field position or slot name of the */ /* pattern from which the error originated. */ /*==============================================*/ if (CurrentPatternFact->whichDeftemplate->implied) { sprintf(buffer," Problem resides in field #%d\n",patternPtr->whichField); } else { theSlots = CurrentPatternFact->whichDeftemplate->slotList; for (i = 0; i < (int) patternPtr->whichSlot; i++) theSlots = theSlots->next; sprintf(buffer," Problem resides in slot %s\n",ValueToString(theSlots->slotName)); } PrintCLIPS(WERROR,buffer); /*==========================================================*/ /* Trace the pattern to its entry point to the join network */ /* (which then traces to the defrule data structure so that */ /* the name(s) of the rule(s) utilizing the patterns can be */ /* printed). */ /*==========================================================*/ TraceErrorToJoin(patternPtr,CLIPS_FALSE); PrintCLIPS(WERROR,"\n"); }/***************************************************************************//* TraceErrorToJoin: Traces the cause of an evaluation error which occured *//* in the fact pattern network to the entry join in the join network for *//* the pattern from which the error originated. Once the entry join is *//* reached, the error is then traced to the defrule data structures so *//* that the name of the rule(s) containing the pattern can be printed. *//***************************************************************************/static VOID TraceErrorToJoin(patternPtr,traceRight) struct factPatternNode *patternPtr; int traceRight; { struct joinNode *joinPtr; char buffer[60]; while (patternPtr != NULL) { if (patternPtr->header.stopNode) { for (joinPtr = patternPtr->header.entryJoin; joinPtr != NULL; joinPtr = joinPtr->rightMatchNode) { sprintf(buffer," Of pattern #%d in rule(s):\n",GetPatternNumberFromJoin(joinPtr)); PrintCLIPS(WERROR,buffer); TraceErrorToRule(joinPtr," "); } } else { TraceErrorToJoin(patternPtr->nextLevel,CLIPS_TRUE); } if (traceRight) patternPtr = patternPtr->rightNode; else patternPtr = NULL; } } /***********************************************************************//* SkipFactPatternNode: During an incremental reset, only fact pattern *//* nodes associated with new patterns are traversed. Given a pattern *//* node, this routine will return TRUE if the pattern node should be *//* traversed during incremental reset pattern matching or FALSE if *//* the node should be skipped. *//***********************************************************************/static int SkipFactPatternNode(thePattern) struct factPatternNode *thePattern; {#if (MAC_MPW || MAC_MCW) && (RUN_TIME || BLOAD_ONLY || (! INCREMENTAL_RESET))#pragma unused(thePattern)#endif#if INCREMENTAL_RESET && (! RUN_TIME) && (! BLOAD_ONLY) if (IncrementalResetInProgress && (thePattern->header.initialize == CLIPS_FALSE)) { return(CLIPS_TRUE); } #endif return(CLIPS_FALSE); }#if INCREMENTAL_RESET/***************************************************************//* MarkFactPatternForIncrementalReset: Sets the initialization *//* field of a fact pattern for use with incremental reset. *//* This is called before an incremental reset for newly added *//* patterns to indicate that the pattern nodes should be *//* traversed and then after an incremental reset to indicate *//* that the nodes were traversed ("initialized") by the *//* incremental reset. *//***************************************************************/globle VOID MarkFactPatternForIncrementalReset(thePattern,value) struct patternNodeHeader *thePattern; int value; { struct factPatternNode *patternPtr = (struct factPatternNode *) thePattern; /*=====================================*/ /* We should be passed a valid pointer */ /* to a fact pattern network node. */ /*=====================================*/ Bogus(patternPtr == NULL); /*============================================*/ /* If the pattern was previously initialized, */ /* then don't bother with it. */ /*============================================*/ if (patternPtr->header.initialize == CLIPS_FALSE) return; /*======================================================*/ /* Set the initialization field of this pattern network */ /* node and all pattern network nodes which preceed it. */ /*======================================================*/ while (patternPtr != NULL) { patternPtr->header.initialize = value; patternPtr = patternPtr->lastLevel; } } /**************************************************************//* FactsIncrementalReset: Incremental reset function for the *//* fact pattern network. Asserts all facts in the fact-list *//* so that they repeat the pattern matching process. During *//* an incremental reset, newly added patterns should be the *//* only active patterns in the fact pattern network. *//**************************************************************/globle VOID FactsIncrementalReset() { struct fact *factPtr; for (factPtr = (struct fact *) GetNextFact(NULL); factPtr != NULL; factPtr = (struct fact *) GetNextFact(factPtr)) { FactPatternMatch(factPtr, factPtr->whichDeftemplate->patternNetwork, 0,NULL,NULL); } } #endif /* INCREMENTAL_RESET */#endif /* DEFTEMPLATE_CONSTRUCT && DEFRULE_CONSTRUCT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -