📄 drive.c
字号:
/* which the merge took place. *//*******************************************************************/static VOID PPDrive(lhsBinds,rhsBinds,join) struct partialMatch *lhsBinds, *rhsBinds; struct joinNode *join; { struct partialMatch *linker; struct joinNode *listOfJoins; /*==================================================*/ /* Merge the alpha and beta memory partial matches. */ /*==================================================*/ linker = MergePartialMatches(lhsBinds,rhsBinds, (join->ruleToActivate == NULL) ? 0 : 1, (int) join->logicalJoin); /*=======================================================*/ /* Add the partial match to the beta memory of the join. */ /*=======================================================*/ linker->next = join->beta; join->beta = linker; /*====================================================*/ /* Activate the rule satisfied by this partial match. */ /*====================================================*/ if (join->ruleToActivate != NULL) AddActivation(join->ruleToActivate,linker); /*================================================*/ /* Send the new partial match to all child joins. */ /*================================================*/ listOfJoins = join->nextLevel; if (listOfJoins != NULL) { if (((struct joinNode *) (listOfJoins->rightSideEntryStructure)) == join) { NetworkAssert(linker,listOfJoins,RHS); } else while (listOfJoins != NULL) { NetworkAssert(linker,listOfJoins,LHS); listOfJoins = listOfJoins->rightDriveNode; } } return; }/**********************************************************************//* PNRDrive: Handles the entry of a partial match from the RHS of a *//* join that has positive LHS entry and negative RHS entry (meaning *//* the conditional element associated with this join is a not *//* conditional element). Entry of the alpha memory partial match *//* will cause the counterf value of the associated beta memory *//* partial match to be set. This in turn may cause partial matches *//* associated with the beta memory partial match to be removed from *//* the network. *//**********************************************************************/static VOID PNRDrive(join,lhsBinds,rhsBinds) struct joinNode *join; struct partialMatch *lhsBinds, *rhsBinds; { struct joinNode *listOfJoins; /*==================================================*/ /* If the partial match already has a partial match */ /* in the alpha memory which prevents it from being */ /* satisfied, then don't do anything. */ /*==================================================*/ if (lhsBinds->counterf == CLIPS_TRUE) return; /*=================================================*/ /* Set the counterf flag to indicate that an alpha */ /* memory partial match is preventing the beta */ /* memory partial match from being satisfied. */ /*=================================================*/ lhsBinds->counterf = CLIPS_TRUE; /*===================================================================*/ /* If the partial match caused an activation, remove the activation. */ /*===================================================================*/ if ((lhsBinds->activationf) ? (lhsBinds->binds[lhsBinds->bcount].gm.theValue != NULL) : FALSE) { RemoveActivation((struct activation *) lhsBinds->binds[lhsBinds->bcount].gm.theValue,CLIPS_TRUE,CLIPS_TRUE); } /*===========================================================*/ /* The counterf flag was FALSE. This means that a pointer to */ /* the pseudo-fact matching the not CE is stored directly in */ /* the partial match. Determine the ID of this pseudo-fact */ /* and remove all partial matches from descendent joins that */ /* contain the ID. */ /*===========================================================*/ listOfJoins = join->nextLevel; if (listOfJoins != NULL) { if (((struct joinNode *) (listOfJoins->rightSideEntryStructure)) == join) { NegEntryRetract(listOfJoins,lhsBinds,CLIPS_FALSE); } else while (listOfJoins != NULL) { PosEntryRetract(listOfJoins, lhsBinds->binds[lhsBinds->bcount - 1].gm.theMatch, lhsBinds,(int) join->depth-1,CLIPS_FALSE); listOfJoins = listOfJoins->rightDriveNode; } } /*=========================================================================*/ /* Remove any logical dependency links associated with this partial match. */ /*=========================================================================*/#if LOGICAL_DEPENDENCIES if (lhsBinds->dependentsf) RemoveLogicalSupport(lhsBinds);#endif /*========================================*/ /* Put the pseudo-fact on a garbage list. */ /*========================================*/ lhsBinds->binds[lhsBinds->bcount - 1].gm.theMatch->next = GarbageAlphaMatches; GarbageAlphaMatches = lhsBinds->binds[lhsBinds->bcount - 1].gm.theMatch; /*========================================================*/ /* Store the partial match from the alpha memory that is */ /* preventing the LHS partial match from being satisfied. */ /*========================================================*/ lhsBinds->binds[lhsBinds->bcount - 1].gm.theValue = (VOID *) rhsBinds; }/********************************************************************//* PNLDrive: Handles the entry of a partial match from the LHS of a *//* join that has positive LHS entry and negative RHS entry *//* (meaning the conditional element associated with this join is *//* a not conditional element). An new partial match is created by *//* combining the match from the beta memory with a "pseudo" *//* partial match corresponding to the facts which didn't match *//* the not CE. Once merged, the new partial match is sent to each *//* child join of the join from which the merge took place. *//********************************************************************/globle VOID PNLDrive(join,binds) struct joinNode *join; struct partialMatch *binds; { struct joinNode *listOfJoins; struct alphaMatch *tempAlpha; /*=======================================================*/ /* Create a pseudo-fact representing the facts which did */ /* not match the not CE associated with this join. */ /*=======================================================*/ tempAlpha = get_struct(alphaMatch); tempAlpha->next = NULL; tempAlpha->matchingItem = NULL; tempAlpha->markers = NULL; /*===============================================*/ /* Store the pointer to the pseudo-fact directly */ /* in the beta memory partial match. */ /*===============================================*/ binds->counterf = CLIPS_FALSE; binds->binds[binds->bcount - 1].gm.theMatch = tempAlpha; /*====================================================*/ /* Activate the rule satisfied by this partial match. */ /*====================================================*/ if (join->ruleToActivate != NULL) AddActivation(join->ruleToActivate,binds); /*========================================================*/ /* Send the merged partial match to all descendent joins. */ /*========================================================*/ listOfJoins = join->nextLevel; if (listOfJoins != NULL) { if (((struct joinNode *) (listOfJoins->rightSideEntryStructure)) == join) { NetworkAssert(binds,listOfJoins,RHS); } else while (listOfJoins != NULL) { NetworkAssert(binds,listOfJoins,LHS); listOfJoins = listOfJoins->rightDriveNode; } } }/***************************************************************//* EmptyDrive: Handles the entry of a alpha memory partial *//* match from the RHS of a join that is the first join of *//* a rule (i.e. a join that cannot be entered from the LHS). *//***************************************************************/static VOID EmptyDrive(join,rhsBinds) struct joinNode *join; struct partialMatch *rhsBinds; { struct partialMatch *linker; struct joinNode *listOfJoins; int joinExpr; /*======================================================*/ /* Determine if the alpha memory partial match satifies */ /* the join expression. If it doesn't then no further */ /* action is taken. */ /*======================================================*/ if (join->networkTest != NULL) { joinExpr = EvaluateJoinExpression(join->networkTest,NULL,rhsBinds,join); EvaluationError = CLIPS_FALSE; if (joinExpr == CLIPS_FALSE) return; } /*===========================================================*/ /* The first join of a rule cannot be connected to a NOT CE. */ /*===========================================================*/ if (join->patternIsNegated == CLIPS_TRUE) { CLIPSSystemError("DRIVE",2); ExitCLIPS(5); } /*=========================================================*/ /* If the join's RHS entry is associated with a pattern CE */ /* (positive entry), then copy the alpha memory partial */ /* match and send it to all child joins. */ /*=========================================================*/ linker = CopyPartialMatch(rhsBinds, (join->ruleToActivate == NULL) ? 0 : 1, (int) join->logicalJoin); /*=======================================================*/ /* Add the partial match to the beta memory of the join. */ /*=======================================================*/ linker->next = join->beta; join->beta = linker; /*====================================================*/ /* Activate the rule satisfied by this partial match. */ /*====================================================*/ if (join->ruleToActivate != NULL) AddActivation(join->ruleToActivate,linker); /*============================================*/ /* Send the partial match to all child joins. */ /*============================================*/ listOfJoins = join->nextLevel; while (listOfJoins != NULL) { NetworkAssert(linker,listOfJoins,LHS); listOfJoins = listOfJoins->rightDriveNode; } }/********************************************************************//* JoinNetErrorMessage: Prints an informational message indicating *//* which join of a rule generated an error when a join expression *//* was being evaluated. *//********************************************************************/static VOID JoinNetErrorMessage(joinPtr) struct joinNode *joinPtr; { char buffer[60]; PrintErrorID("DRIVE",1,CLIPS_TRUE); PrintCLIPS(WERROR,"This error occurred in the join network\n"); sprintf(buffer," Problem resides in join #%d in rule(s):\n",joinPtr->depth); PrintCLIPS(WERROR,buffer); TraceErrorToRule(joinPtr," "); PrintCLIPS(WERROR,"\n"); }#endif /* DEFRULE_CONSTRUCT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -