📄 retract.c
字号:
/*==============================================*/
if (theJoin->ruleToActivate != NULL)
{ AddActivation(theEnv,theJoin->ruleToActivate,theLHS); }
/*=======================================================*/
/* Send the partial match to the list of joins following */
/* this join. If we're in the middle of a retract, add */
/* the partial match to the list of join activities that */
/* need to be processed later. If we're doing an assert, */
/* then the join activity can be processed immediately. */
/*=======================================================*/
listOfJoins = theJoin->nextLevel;
if (listOfJoins != NULL)
{
if (((struct joinNode *) (listOfJoins->rightSideEntryStructure)) == theJoin)
{ NetworkAssert(theEnv,theLHS,listOfJoins,RHS); }
else
{
if (duringRetract != NULL)
{
if (FindEntityInPartialMatch((struct patternEntity *) duringRetract,theLHS) == FALSE)
{
tempDR = get_struct(theEnv,rdriveinfo);
tempDR->link = theLHS;
tempDR->jlist = theJoin->nextLevel;
tempDR->next = EngineData(theEnv)->DriveRetractionList;
EngineData(theEnv)->DriveRetractionList = tempDR;
}
}
else while (listOfJoins != NULL)
{
NetworkAssert(theEnv,theLHS,listOfJoins,LHS);
listOfJoins = listOfJoins->rightDriveNode;
}
}
}
}
}
}
/**************************************************************/
/* FindNextConflictingAlphaMatch: Finds the next conflicting */
/* partial match in the alpha memory of a join (or the beta */
/* memory of a join from the right) that prevents a partial */
/* match in the beta memory of the join from being */
/* satisfied. */
/**************************************************************/
static intBool FindNextConflictingAlphaMatch(
void *theEnv,
struct partialMatch *theBind,
struct partialMatch *possibleConflicts,
struct joinNode *theJoin)
{
int i, result;
/*=====================================================*/
/* If we're dealing with a join from the right, then */
/* we need to check the entire beta memory of the join */
/* from the right (a join doesn't have an end of queue */
/* pointer like a pattern data structure has). */
/*=====================================================*/
if (theJoin->joinFromTheRight)
{ possibleConflicts = ((struct joinNode *) theJoin->rightSideEntryStructure)->beta; }
/*====================================*/
/* Check each of the possible partial */
/* matches which could conflict. */
/*====================================*/
for (;
possibleConflicts != NULL;
possibleConflicts = possibleConflicts->next)
{
/*=====================================*/
/* Initially indicate that the partial */
/* match doesn't conflict. */
/*=====================================*/
result = FALSE;
/*====================================================*/
/* A partial match with the counterf flag set is not */
/* yet a "real" partial match, so ignore it. When the */
/* counterf flag is set that means that the partial */
/* match is associated with a not CE that has a data */
/* entity preventing it from being satsified. */
/*====================================================*/
if (possibleConflicts->counterf)
{ /* Do Nothing */ }
/*======================================================*/
/* 6.05 Bug Fix. It is possible that a pattern entity */
/* (e.g., instance) in a partial match is 'out of date' */
/* with respect to the lazy evaluation scheme use by */
/* negated patterns. In other words, the object may */
/* have changed since it was last pushed through the */
/* network, and thus the partial match may be invalid. */
/* If so, the partial match must be ignored here. */
/*======================================================*/
else if (PartialMatchDefunct(theEnv,possibleConflicts))
{ /* Do Nothing */ }
/*==================================================*/
/* If the join doesn't have a network expression to */
/* be evaluated, then partial match conflicts. If */
/* the partial match is retrieved from a join from */
/* the right, the RHS partial match must correspond */
/* to the partial match in the beta memory of the */
/* join being examined (in a join associated with a */
/* not CE, each partial match in the beta memory of */
/* the join corresponds uniquely to a partial match */
/* in either the alpha memory from the RHS or in */
/* the beta memory of a join from the right). */
/*==================================================*/
else if (theJoin->networkTest == NULL)
{
result = TRUE;
if (theJoin->joinFromTheRight)
{
for (i = 0; i < (int) (theBind->bcount - 1); i++)
{
if (possibleConflicts->binds[i].gm.theMatch != theBind->binds[i].gm.theMatch)
{
result = FALSE;
break;
}
}
}
}
/*=================================================*/
/* Otherwise, if the join has a network expression */
/* to evaluate, then evaluate it. */
/*=================================================*/
else
{
result = EvaluateJoinExpression(theEnv,theJoin->networkTest,theBind,
possibleConflicts,theJoin);
if (EvaluationData(theEnv)->EvaluationError)
{
result = TRUE;
EvaluationData(theEnv)->EvaluationError = FALSE;
}
}
/*==============================================*/
/* If the network expression evaluated to TRUE, */
/* then partial match being examined conflicts. */
/* Point the beta memory partial match to the */
/* conflicting partial match and return TRUE to */
/* indicate a conflict was found. */
/*==============================================*/
if (result != FALSE)
{
theBind->binds[theBind->bcount - 1].gm.theValue = (void *) possibleConflicts;
return(TRUE);
}
}
/*========================*/
/* No conflict was found. */
/*========================*/
return(FALSE);
}
/***********************************************************/
/* PartialMatchDefunct: Determines if any pattern entities */
/* contained within the partial match have changed since */
/* this partial match was generated. Assumes counterf is */
/* FALSE. */
/***********************************************************/
static intBool PartialMatchDefunct(
void *theEnv,
struct partialMatch *thePM)
{
register unsigned i;
register struct patternEntity * thePE;
for (i = 0 ; i < thePM->bcount ; i++)
{
thePE = thePM->binds[i].gm.theMatch->matchingItem;
if (thePE && thePE->theInfo->synchronized &&
!(*thePE->theInfo->synchronized)(theEnv,thePE))
return(TRUE);
}
return(FALSE);
}
/*************************************************************/
/* RemovePartialMatches: Searches through a list of partial */
/* matches and removes any partial match that contains the */
/* specified data entity. */
/*************************************************************/
static struct partialMatch *RemovePartialMatches(
void *theEnv,
struct alphaMatch *theAlphaNode,
struct partialMatch *listOfPMs,
struct partialMatch **deleteHead,
int position,
struct partialMatch **returnLast)
{
struct partialMatch *head, *lastPM, *nextPM;
struct partialMatch *lastDelete = NULL;
/*====================================================*/
/* Initialize pointers used for creating the new list */
/* of partial matches and the list of partial matches */
/* to be deleted. */
/*====================================================*/
head = listOfPMs;
lastPM = listOfPMs;
*deleteHead = NULL;
/*==========================================*/
/* Loop through each of the partial matches */
/* and determine if it needs to be deleted. */
/*==========================================*/
while (listOfPMs != NULL)
{
if ((listOfPMs->counterf == TRUE) && (position == ((int) (listOfPMs->bcount - 1))))
{
lastPM = listOfPMs;
listOfPMs = listOfPMs->next;
}
/*=====================================================*/
/* Otherwise, if the specified position in the partial */
/* match contains the specified data entity, then */
/* remove the partial match from the list and add it */
/* to a deletion list. */
/*=====================================================*/
else if (listOfPMs->binds[position].gm.theMatch == theAlphaNode)
{
/*===================================================*/
/* If the partial match has an activation associated */
/* with it, then return the activation. */
/*===================================================*/
if ((listOfPMs->activationf) ?
(listOfPMs->binds[listOfPMs->bcount].gm.theValue != NULL) : FALSE)
{ RemoveActivation(theEnv,(struct activation *) listOfPMs->binds[listOfPMs->bcount].gm.theValue,TRUE,TRUE); }
/*==================================================*/
/* If the partial match is at the head of the list */
/* of matches, then use the following deletion code */
/* for the head of the list. */
/*==================================================*/
if (listOfPMs == head)
{
/*===================================*/
/* Remember the new beginning of the */
/* new list of partial matches. */
/*===================================*/
nextPM = listOfPMs->next;
/*=============================================*/
/* Add the partial match to the deletion list. */
/*=============================================*/
if (*deleteHead == NULL)
{ *deleteHead = listOfPMs; }
else
{ lastDelete->next = listOfPMs; }
listOfPMs->next = NULL;
lastDelete = listOfPMs;
/*================================================*/
/* Update the head and tail pointers for the new */
/* list of partial matches as well as the pointer */
/* to the next partial match to be examined. */
/*================================================*/
listOfPMs = nextPM;
head = listOfPMs;
lastPM = head;
}
/*======================================*/
/* Otherwise, use the following code to */
/* delete the partial match. */
/*======================================*/
else
{
/*========================================*/
/* Detach the partial match being deleted */
/* from the new list of partial matches. */
/*========================================*/
lastPM->next = listOfPMs->next;
/*=============================================*/
/* Add the partial match to the deletion list. */
/*=============================================*/
if (*deleteHead == NULL)
{ *deleteHead = listOfPMs; }
else
{ lastDelete->next = listOfPMs; }
listOfPMs->next = NULL;
lastDelete = listOfPMs;
/*=============================*/
/* Move on to the next partial */
/* match to be examined. */
/*=============================*/
listOfPMs = lastPM->next;
}
}
/*==============================================*/
/* Otherwise, the partial match should be added */
/* to the new list of partial matches. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -