📄 factmch.c
字号:
switch(theTest->type) { /*==============================================*/ /* This primitive compares the value stored in */ /* a single field slot to a constant for either */ /* equality or inequality. */ /*==============================================*/ case FACT_PN_CONSTANT1: oldArgument = EvaluationData(theEnv)->CurrentExpression; EvaluationData(theEnv)->CurrentExpression = theTest; rv = FactPNConstant1(theEnv,theTest->value,&theResult); EvaluationData(theEnv)->CurrentExpression = oldArgument; return(rv); /*=============================================*/ /* This primitive compares the value stored in */ /* a multifield slot to a constant for either */ /* equality or inequality. */ /*=============================================*/ case FACT_PN_CONSTANT2: oldArgument = EvaluationData(theEnv)->CurrentExpression; EvaluationData(theEnv)->CurrentExpression = theTest; rv = FactPNConstant2(theEnv,theTest->value,&theResult); EvaluationData(theEnv)->CurrentExpression = oldArgument; return(rv); /*================================================*/ /* This primitive determines if a multifield slot */ /* contains at least a certain number of fields. */ /*================================================*/ case FACT_SLOT_LENGTH: oldArgument = EvaluationData(theEnv)->CurrentExpression; EvaluationData(theEnv)->CurrentExpression = theTest; rv = FactSlotLength(theEnv,theTest->value,&theResult); EvaluationData(theEnv)->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 == ExpressionData(theEnv)->PTR_OR) { for (theTest = theTest->argList; theTest != NULL; theTest = theTest->nextArg) { if (EvaluatePatternExpression(theEnv,patternPtr,theTest) == TRUE) { if (EvaluationData(theEnv)->EvaluationError) return(FALSE); return(TRUE); } if (EvaluationData(theEnv)->EvaluationError) return(FALSE); } return(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 == ExpressionData(theEnv)->PTR_AND) { for (theTest = theTest->argList; theTest != NULL; theTest = theTest->nextArg) { if (EvaluatePatternExpression(theEnv,patternPtr,theTest) == FALSE) { return(FALSE); } if (EvaluationData(theEnv)->EvaluationError) return(FALSE); } return(TRUE); } /*==========================================================*/ /* Evaluate all other expressions using EvaluateExpression. */ /*==========================================================*/ if (EvaluateExpression(theEnv,theTest,&theResult)) { PatternNetErrorMessage(theEnv,patternPtr); return(FALSE); } if ((theResult.value == EnvFalseSymbol(theEnv)) && (theResult.type == SYMBOL)) { return(FALSE); } return(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( void *theEnv, struct factPatternNode *patternPtr) { char buffer[60]; struct templateSlot *theSlots; int i; /*=======================================*/ /* Print the fact being pattern matched. */ /*=======================================*/ PrintErrorID(theEnv,"FACTMCH",1,TRUE); EnvPrintRouter(theEnv,WERROR,"This error occurred in the fact pattern network\n"); EnvPrintRouter(theEnv,WERROR," Currently active fact: "); PrintFact(theEnv,WERROR,FactData(theEnv)->CurrentPatternFact,FALSE,FALSE); EnvPrintRouter(theEnv,WERROR,"\n"); /*==============================================*/ /* Print the field position or slot name of the */ /* pattern from which the error originated. */ /*==============================================*/ if (FactData(theEnv)->CurrentPatternFact->whichDeftemplate->implied) { gensprintf(buffer," Problem resides in field #%d\n",patternPtr->whichField); } else { theSlots = FactData(theEnv)->CurrentPatternFact->whichDeftemplate->slotList; for (i = 0; i < (int) patternPtr->whichSlot; i++) theSlots = theSlots->next; gensprintf(buffer," Problem resides in slot %s\n",ValueToString(theSlots->slotName)); } EnvPrintRouter(theEnv,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(theEnv,patternPtr,FALSE); EnvPrintRouter(theEnv,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( void *theEnv, struct factPatternNode *patternPtr, int traceRight) { struct joinNode *joinPtr; while (patternPtr != NULL) { if (patternPtr->header.stopNode) { for (joinPtr = patternPtr->header.entryJoin; joinPtr != NULL; joinPtr = joinPtr->rightMatchNode) { TraceErrorToRule(theEnv,joinPtr," "); } } else { TraceErrorToJoin(theEnv,patternPtr->nextLevel,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( void *theEnv, struct factPatternNode *thePattern) {#if (MAC_MCW || IBM_MCW) && (RUN_TIME || BLOAD_ONLY)#pragma unused(theEnv,thePattern)#endif#if (! RUN_TIME) && (! BLOAD_ONLY) if (EngineData(theEnv)->IncrementalResetInProgress && (thePattern->header.initialize == FALSE)) { return(TRUE); }#endif return(FALSE); }/***************************************************************//* 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. *//***************************************************************/#if IBM_TBC#pragma argsused#endifgloble void MarkFactPatternForIncrementalReset( void *theEnv, struct patternNodeHeader *thePattern, int value) { struct factPatternNode *patternPtr = (struct factPatternNode *) thePattern;#if MAC_MCW || IBM_MCW || MAC_XCD#pragma unused(theEnv)#endif /*=====================================*/ /* 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 == 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( void *theEnv) { struct fact *factPtr; for (factPtr = (struct fact *) EnvGetNextFact(theEnv,NULL); factPtr != NULL; factPtr = (struct fact *) EnvGetNextFact(theEnv,factPtr)) { EngineData(theEnv)->JoinOperationInProgress = TRUE; FactPatternMatch(theEnv,factPtr, factPtr->whichDeftemplate->patternNetwork, 0,NULL,NULL); EngineData(theEnv)->JoinOperationInProgress = FALSE; } }#endif /* DEFTEMPLATE_CONSTRUCT && DEFRULE_CONSTRUCT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -