📄 drive.c
字号:
else if (enterDirection == RHS)
{ PNRDrive(theEnv,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(theEnv,join,binds); }
return;
}
/*******************************************************/
/* EvaluateJoinExpression: Evaluates join expressions. */
/* Performs a faster evaluation for join expressions */
/* than if EvaluateExpression was used directly. */
/*******************************************************/
globle intBool EvaluateJoinExpression(
void *theEnv,
struct expr *joinExpr,
struct partialMatch *lbinds,
struct partialMatch *rbinds,
struct joinNode *joinPtr)
{
DATA_OBJECT theResult;
int andLogic, result = TRUE;
struct partialMatch *oldLHSBinds;
struct partialMatch *oldRHSBinds;
struct joinNode *oldJoin;
/*======================================*/
/* A NULL expression evaluates to TRUE. */
/*======================================*/
if (joinExpr == NULL) return(TRUE);
/*=========================================*/
/* Initialize some of the global variables */
/* used when evaluating expressions. */
/*=========================================*/
oldLHSBinds = EngineData(theEnv)->GlobalLHSBinds;
oldRHSBinds = EngineData(theEnv)->GlobalRHSBinds;
oldJoin = EngineData(theEnv)->GlobalJoin;
EngineData(theEnv)->GlobalLHSBinds = lbinds;
EngineData(theEnv)->GlobalRHSBinds = rbinds;
EngineData(theEnv)->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 == ExpressionData(theEnv)->PTR_AND)
{
andLogic = TRUE;
joinExpr = joinExpr->argList;
}
else if (joinExpr->value == ExpressionData(theEnv)->PTR_OR)
{
andLogic = FALSE;
joinExpr = joinExpr->argList;
}
else
{ andLogic = TRUE; }
/*=========================================*/
/* Evaluate each of the expressions linked */
/* together in the join expression. */
/*=========================================*/
while (joinExpr != NULL)
{
/*================================*/
/* Evaluate a primitive function. */
/*================================*/
if ((EvaluationData(theEnv)->PrimitivesArray[joinExpr->type] == NULL) ?
FALSE :
EvaluationData(theEnv)->PrimitivesArray[joinExpr->type]->evaluateFunction != NULL)
{
struct expr *oldArgument;
oldArgument = EvaluationData(theEnv)->CurrentExpression;
EvaluationData(theEnv)->CurrentExpression = joinExpr;
result = (*EvaluationData(theEnv)->PrimitivesArray[joinExpr->type]->evaluateFunction)(theEnv,joinExpr->value,&theResult);
EvaluationData(theEnv)->CurrentExpression = oldArgument;
}
/*=============================*/
/* Evaluate the "or" function. */
/*=============================*/
else if (joinExpr->value == ExpressionData(theEnv)->PTR_OR)
{
result = FALSE;
if (EvaluateJoinExpression(theEnv,joinExpr,lbinds,rbinds,joinPtr) == TRUE)
{
if (EvaluationData(theEnv)->EvaluationError)
{
if (joinPtr->patternIsNegated) lbinds->bcount++;
EngineData(theEnv)->GlobalLHSBinds = oldLHSBinds;
EngineData(theEnv)->GlobalRHSBinds = oldRHSBinds;
EngineData(theEnv)->GlobalJoin = oldJoin;
return(FALSE);
}
result = TRUE;
}
else if (EvaluationData(theEnv)->EvaluationError)
{
if (joinPtr->patternIsNegated) lbinds->bcount++;
EngineData(theEnv)->GlobalLHSBinds = oldLHSBinds;
EngineData(theEnv)->GlobalRHSBinds = oldRHSBinds;
EngineData(theEnv)->GlobalJoin = oldJoin;
return(FALSE);
}
}
/*==============================*/
/* Evaluate the "and" function. */
/*==============================*/
else if (joinExpr->value == ExpressionData(theEnv)->PTR_AND)
{
result = TRUE;
if (EvaluateJoinExpression(theEnv,joinExpr,lbinds,rbinds,joinPtr) == FALSE)
{
if (EvaluationData(theEnv)->EvaluationError)
{
if (joinPtr->patternIsNegated) lbinds->bcount++;
EngineData(theEnv)->GlobalLHSBinds = oldLHSBinds;
EngineData(theEnv)->GlobalRHSBinds = oldRHSBinds;
EngineData(theEnv)->GlobalJoin = oldJoin;
return(FALSE);
}
result = FALSE;
}
else if (EvaluationData(theEnv)->EvaluationError)
{
if (joinPtr->patternIsNegated) lbinds->bcount++;
EngineData(theEnv)->GlobalLHSBinds = oldLHSBinds;
EngineData(theEnv)->GlobalRHSBinds = oldRHSBinds;
EngineData(theEnv)->GlobalJoin = oldJoin;
return(FALSE);
}
}
/*==========================================================*/
/* Evaluate all other expressions using EvaluateExpression. */
/*==========================================================*/
else
{
EvaluateExpression(theEnv,joinExpr,&theResult);
if (EvaluationData(theEnv)->EvaluationError)
{
JoinNetErrorMessage(theEnv,joinPtr);
if (joinPtr->patternIsNegated) lbinds->bcount++;
EngineData(theEnv)->GlobalLHSBinds = oldLHSBinds;
EngineData(theEnv)->GlobalRHSBinds = oldRHSBinds;
EngineData(theEnv)->GlobalJoin = oldJoin;
return(FALSE);
}
if ((theResult.value == EnvFalseSymbol(theEnv)) && (theResult.type == SYMBOL))
{ result = FALSE; }
else
{ result = TRUE; }
}
/*====================================*/
/* Handle the short cut evaluation of */
/* the "and" and "or" functions. */
/*====================================*/
if ((andLogic == TRUE) && (result == FALSE))
{
if (joinPtr->patternIsNegated) lbinds->bcount++;
EngineData(theEnv)->GlobalLHSBinds = oldLHSBinds;
EngineData(theEnv)->GlobalRHSBinds = oldRHSBinds;
EngineData(theEnv)->GlobalJoin = oldJoin;
return(FALSE);
}
else if ((andLogic == FALSE) && (result == TRUE))
{
if (joinPtr->patternIsNegated) lbinds->bcount++;
EngineData(theEnv)->GlobalLHSBinds = oldLHSBinds;
EngineData(theEnv)->GlobalRHSBinds = oldRHSBinds;
EngineData(theEnv)->GlobalJoin = oldJoin;
return(TRUE);
}
/*==============================================*/
/* Move to the next expression to be evaluated. */
/*==============================================*/
joinExpr = joinExpr->nextArg;
}
/*=======================================*/
/* Restore some of the global variables. */
/*=======================================*/
EngineData(theEnv)->GlobalLHSBinds = oldLHSBinds;
EngineData(theEnv)->GlobalRHSBinds = oldRHSBinds;
EngineData(theEnv)->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 */
/* which the merge took place. */
/*******************************************************************/
static void PPDrive(
void *theEnv,
struct partialMatch *lhsBinds,
struct partialMatch *rhsBinds,
struct joinNode *join)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -