📄 drive.c
字号:
struct partialMatch *linker;
struct joinNode *listOfJoins;
/*==================================================*/
/* Merge the alpha and beta memory partial matches. */
/*==================================================*/
linker = MergePartialMatches(theEnv,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(theEnv,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(theEnv,linker,listOfJoins,RHS); }
else while (listOfJoins != NULL)
{
NetworkAssert(theEnv,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(
void *theEnv,
struct joinNode *join,
struct partialMatch *lhsBinds,
struct partialMatch *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 == 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 = TRUE;
/*===================================================================*/
/* If the partial match caused an activation, remove the activation. */
/*===================================================================*/
if ((lhsBinds->activationf) ?
(lhsBinds->binds[lhsBinds->bcount].gm.theValue != NULL) : FALSE)
{ RemoveActivation(theEnv,(struct activation *) lhsBinds->binds[lhsBinds->bcount].gm.theValue,TRUE,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. */
/*===========================================================*/
if (join->joinFromTheRight) /* GDR 111599 #834 Begin */
{
RetractCheckDriveRetractions(theEnv,lhsBinds->binds[lhsBinds->bcount - 1].gm.theMatch,
(int) join->depth-1);
} /* GDR 111599 #834 End */
listOfJoins = join->nextLevel;
if (listOfJoins != NULL)
{
if (((struct joinNode *) (listOfJoins->rightSideEntryStructure)) == join)
{ NegEntryRetract(theEnv,listOfJoins,lhsBinds,NULL); }
else while (listOfJoins != NULL)
{
PosEntryRetract(theEnv,listOfJoins,
lhsBinds->binds[lhsBinds->bcount - 1].gm.theMatch,
lhsBinds,(int) join->depth-1,NULL);
listOfJoins = listOfJoins->rightDriveNode;
}
}
/*=========================================================================*/
/* Remove any logical dependency links associated with this partial match. */
/*=========================================================================*/
if (lhsBinds->dependentsf) RemoveLogicalSupport(theEnv,lhsBinds);
/*========================================*/
/* Put the pseudo-fact on a garbage list. */
/*========================================*/
lhsBinds->binds[lhsBinds->bcount - 1].gm.theMatch->next = EngineData(theEnv)->GarbageAlphaMatches;
EngineData(theEnv)->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(
void *theEnv,
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(theEnv,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 = FALSE;
binds->binds[binds->bcount - 1].gm.theMatch = tempAlpha;
/*====================================================*/
/* Activate the rule satisfied by this partial match. */
/*====================================================*/
if (join->ruleToActivate != NULL) AddActivation(theEnv,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(theEnv,binds,listOfJoins,RHS); }
else while (listOfJoins != NULL)
{
NetworkAssert(theEnv,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(
void *theEnv,
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(theEnv,join->networkTest,NULL,rhsBinds,join);
EvaluationData(theEnv)->EvaluationError = FALSE;
if (joinExpr == FALSE) return;
}
/*===========================================================*/
/* The first join of a rule cannot be connected to a NOT CE. */
/*===========================================================*/
if (join->patternIsNegated == TRUE)
{
SystemError(theEnv,"DRIVE",2);
EnvExitRouter(theEnv,EXIT_FAILURE);
}
/*=========================================================*/
/* 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(theEnv,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(theEnv,join->ruleToActivate,linker);
/*============================================*/
/* Send the partial match to all child joins. */
/*============================================*/
listOfJoins = join->nextLevel;
while (listOfJoins != NULL)
{
NetworkAssert(theEnv,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(
void *theEnv,
struct joinNode *joinPtr)
{
char buffer[60];
PrintErrorID(theEnv,"DRIVE",1,TRUE);
EnvPrintRouter(theEnv,WERROR,"This error occurred in the join network\n");
sprintf(buffer," Problem resides in join #%d in rule(s):\n",joinPtr->depth);
EnvPrintRouter(theEnv,WERROR,buffer);
TraceErrorToRule(theEnv,joinPtr," ");
EnvPrintRouter(theEnv,WERROR,"\n");
}
#endif /* DEFRULE_CONSTRUCT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -