📄 drive.c
字号:
{ PPDrive(lhsBinds,rhsBinds,join); } /*=====================================================*/ /* Use the PNRDrive routine when the new partial match */ /* enters from the RHS of the join and the join either */ /* is associated with a not CE or has a join from the */ /* right. */ /*=====================================================*/ else if (enterDirection == RHS) { PNRDrive(join,comparePMs,rhsBinds); } /*===========================================================*/ /* If the new partial match entered from the LHS of the join */ /* and the join is either associated with a not CE or the */ /* join has a join from the right, then mark the LHS partial */ /* match indicating that there is a RHS partial match */ /* preventing this join from being satisfied. Once this has */ /* happened, the other RHS partial matches don't have to be */ /* tested since it only takes one partial match to prevent */ /* the LHS from being satisfied. */ /*===========================================================*/ else if (enterDirection == LHS) { binds->binds[binds->bcount - 1].gm.theValue = (VOID *) rhsBinds; comparePMs = NULL; continue; } } /*====================================*/ /* Move on to the next partial match. */ /*====================================*/ comparePMs = comparePMs->next; } /*==================================================================*/ /* If a join with an associated not CE or join from the right was */ /* entered from the LHS side of the join, and the join expression */ /* failed for all sets of matches for the new bindings on the LHS */ /* side (there was no RHS partial match preventing the LHS partial */ /* match from being satisfied), then the LHS partial match appended */ /* with an pseudo-fact that represents the instance of the not */ /* pattern or join from the right that was satisfied should be sent */ /* to the joins below this join. */ /*==================================================================*/ if ((join->patternIsNegated || join->joinFromTheRight) && (enterDirection == LHS) && (binds->binds[binds->bcount - 1].gm.theValue == NULL)) { PNLDrive(join,binds); } return; }/*******************************************************//* EvaluateJoinExpression: Evaluates join expressions. *//* Performs a faster evaluation for join expressions *//* than if EvaluateExpression was used directly. *//*******************************************************/globle BOOLEAN EvaluateJoinExpression(joinExpr,lbinds,rbinds,joinPtr) struct expr *joinExpr; struct partialMatch *lbinds, *rbinds; struct joinNode *joinPtr; { DATA_OBJECT theResult; int andLogic, result = CLIPS_TRUE; struct partialMatch *oldLHSBinds; struct partialMatch *oldRHSBinds; struct joinNode *oldJoin; /*======================================*/ /* A NULL expression evaluates to TRUE. */ /*======================================*/ if (joinExpr == NULL) return(CLIPS_TRUE); /*=========================================*/ /* Initialize some of the global variables */ /* used when evaluating expressions. */ /*=========================================*/ oldLHSBinds = GlobalLHSBinds; oldRHSBinds = GlobalRHSBinds; oldJoin = GlobalJoin; GlobalLHSBinds = lbinds; GlobalRHSBinds = rbinds; GlobalJoin = joinPtr; /*=====================================================*/ /* Partial matches stored in joins that are associated */ /* with a not CE contain an additional slot shouldn't */ /* be considered when evaluating expressions. Since */ /* joins that have joins from the right don't have any */ /* expression, we don't have to do this for partial */ /* matches contained in these joins. */ /*=====================================================*/ if (joinPtr->patternIsNegated) lbinds->bcount--; /*====================================================*/ /* Initialize some variables which allow this routine */ /* to avoid calling the "and" and "or" functions if */ /* they are the first part of the expression to be */ /* evaluated. Most of the join expressions do not use */ /* deeply nested and/or functions so this technique */ /* speeds up evaluation. */ /*====================================================*/ if (joinExpr->value == PTR_AND) { andLogic = CLIPS_TRUE; joinExpr = joinExpr->argList; } else if (joinExpr->value == PTR_OR) { andLogic = CLIPS_FALSE; joinExpr = joinExpr->argList; } else { andLogic = CLIPS_TRUE; } /*=========================================*/ /* Evaluate each of the expressions linked */ /* together in the join expression. */ /*=========================================*/ while (joinExpr != NULL) { /*================================*/ /* Evaluate a primitive function. */ /*================================*/ if ((PrimitivesArray[joinExpr->type] == NULL) ? CLIPS_FALSE : PrimitivesArray[joinExpr->type]->evaluateFunction != NULL) { struct expr *oldArgument; oldArgument = CurrentExpression; CurrentExpression = joinExpr; result = (*PrimitivesArray[joinExpr->type]->evaluateFunction)(joinExpr->value,&theResult); CurrentExpression = oldArgument; } /*=============================*/ /* Evaluate the "or" function. */ /*=============================*/ else if (joinExpr->value == PTR_OR) { result = CLIPS_FALSE; if (EvaluateJoinExpression(joinExpr,lbinds,rbinds,joinPtr) == CLIPS_TRUE) { if (EvaluationError) { if (joinPtr->patternIsNegated) lbinds->bcount++; GlobalLHSBinds = oldLHSBinds; GlobalRHSBinds = oldRHSBinds; GlobalJoin = oldJoin; return(CLIPS_FALSE); } result = CLIPS_TRUE; } else if (EvaluationError) { if (joinPtr->patternIsNegated) lbinds->bcount++; GlobalLHSBinds = oldLHSBinds; GlobalRHSBinds = oldRHSBinds; GlobalJoin = oldJoin; return(CLIPS_FALSE); } } /*==============================*/ /* Evaluate the "and" function. */ /*==============================*/ else if (joinExpr->value == PTR_AND) { result = CLIPS_TRUE; if (EvaluateJoinExpression(joinExpr,lbinds,rbinds,joinPtr) == CLIPS_FALSE) { if (EvaluationError) { if (joinPtr->patternIsNegated) lbinds->bcount++; GlobalLHSBinds = oldLHSBinds; GlobalRHSBinds = oldRHSBinds; GlobalJoin = oldJoin; return(CLIPS_FALSE); } result = CLIPS_FALSE; } else if (EvaluationError) { if (joinPtr->patternIsNegated) lbinds->bcount++; GlobalLHSBinds = oldLHSBinds; GlobalRHSBinds = oldRHSBinds; GlobalJoin = oldJoin; return(CLIPS_FALSE); } } /*==========================================================*/ /* Evaluate all other expressions using EvaluateExpression. */ /*==========================================================*/ else { EvaluateExpression(joinExpr,&theResult); if (EvaluationError) { JoinNetErrorMessage(joinPtr); if (joinPtr->patternIsNegated) lbinds->bcount++; GlobalLHSBinds = oldLHSBinds; GlobalRHSBinds = oldRHSBinds; GlobalJoin = oldJoin; return(CLIPS_FALSE); } if ((theResult.value == CLIPSFalseSymbol) && (theResult.type == SYMBOL)) { result = CLIPS_FALSE; } else { result = CLIPS_TRUE; } } /*====================================*/ /* Handle the short cut evaluation of */ /* the "and" and "or" functions. */ /*====================================*/ if ((andLogic == CLIPS_TRUE) && (result == CLIPS_FALSE)) { if (joinPtr->patternIsNegated) lbinds->bcount++; GlobalLHSBinds = oldLHSBinds; GlobalRHSBinds = oldRHSBinds; GlobalJoin = oldJoin; return(CLIPS_FALSE); } else if ((andLogic == CLIPS_FALSE) && (result == CLIPS_TRUE)) { if (joinPtr->patternIsNegated) lbinds->bcount++; GlobalLHSBinds = oldLHSBinds; GlobalRHSBinds = oldRHSBinds; GlobalJoin = oldJoin; return(CLIPS_TRUE); } /*==============================================*/ /* Move to the next expression to be evaluated. */ /*==============================================*/ joinExpr = joinExpr->nextArg; } /*=======================================*/ /* Restore some of the global variables. */ /*=======================================*/ GlobalLHSBinds = oldLHSBinds; GlobalRHSBinds = oldRHSBinds; GlobalJoin = oldJoin; /*=====================================*/ /* Restore the count value for the LHS */ /* binds if it had to be modified. */ /*=====================================*/ if (joinPtr->patternIsNegated) lbinds->bcount++; /*=================================================*/ /* Return the result of evaluating the expression. */ /*=================================================*/ return(result); }/*******************************************************************//* PPDrive: Handles the merging of an alpha memory partial match *//* with a beta memory partial match for a join that has positive *//* LHS entry and positive RHS entry. The partial matches being *//* merged have previously been checked to determine that they *//* satisify the constraints for the join. Once merged, the new *//* partial match is sent to each child join of the join from */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -