📄 ruledlt.c
字号:
/**********************************************************************/
/* DetachJoins: Removes a join node and all of its parent nodes from */
/* the join network. Nodes are only removed if they are no required */
/* by other rules (the same join can be shared by multiple rules). */
/* Any partial matches associated with the join are also removed. */
/* A rule's joins are typically removed by removing the bottom most */
/* join used by the rule and then removing any parent joins which */
/* are not shared by other rules. */
/**********************************************************************/
static void DetachJoins(
void *theEnv,
struct defrule *theRule,
intBool destroy)
{
struct joinNode *join;
struct joinNode *prevJoin;
struct joinNode *joinPtr, *lastJoin, *rightJoin;
/*==================================*/
/* Find the last join for the rule. */
/*==================================*/
join = theRule->lastJoin;
theRule->lastJoin = NULL;
if (join == NULL) return;
/*===================================================*/
/* Remove the activation link from the last join. If */
/* there are joins below this join, then all of the */
/* joins for this rule were shared with another rule */
/* and thus no joins can be deleted. */
/*===================================================*/
join->ruleToActivate = NULL;
if (join->nextLevel != NULL) return;
/*===========================*/
/* Begin removing the joins. */
/*===========================*/
while (join != NULL)
{
/*==========================================================*/
/* Remember the join "above" this join (the one that enters */
/* from the left). If the join is entered from the right by */
/* another join, remember the right entering join as well. */
/*==========================================================*/
prevJoin = join->lastLevel;
if (join->joinFromTheRight)
{ rightJoin = (struct joinNode *) join->rightSideEntryStructure; }
else
{ rightJoin = NULL; }
/*=================================================*/
/* If the join was attached to a pattern, remove */
/* any structures associated with the pattern that */
/* are no longer needed. */
/*=================================================*/
#if (! RUN_TIME) && (! BLOAD_ONLY)
if (! destroy)
{
if ((join->rightSideEntryStructure != NULL) && (join->joinFromTheRight == FALSE))
{ RemoveIntranetworkLink(theEnv,join); }
}
#endif
/*======================================*/
/* Remove any partial matches contained */
/* in the beta memory of the join. */
/*======================================*/
if (destroy)
{ DestroyAlphaBetaMemory(theEnv,join->beta); }
else
{ FlushAlphaBetaMemory(theEnv,join->beta); }
join->beta = NULL;
/*===================================*/
/* Remove the expressions associated */
/* with the join. */
/*===================================*/
#if (! RUN_TIME) && (! BLOAD_ONLY)
if (! destroy)
{ RemoveHashedExpression(theEnv,join->networkTest); }
#endif
/*==================================================*/
/* Remove the link to the join from the join above. */
/*==================================================*/
if (prevJoin == NULL)
{
#if (! RUN_TIME) && (! BLOAD_ONLY)
rtn_struct(theEnv,joinNode,join);
#endif
return;
}
lastJoin = NULL;
joinPtr = prevJoin->nextLevel;
while (joinPtr != NULL)
{
if (joinPtr == join)
{
if (lastJoin == NULL)
{ prevJoin->nextLevel = joinPtr->rightDriveNode; }
else
{ lastJoin->rightDriveNode = joinPtr->rightDriveNode; }
joinPtr = NULL;
}
else
{
lastJoin = joinPtr;
joinPtr = joinPtr->rightDriveNode;
}
}
/*==================*/
/* Delete the join. */
/*==================*/
#if (! RUN_TIME) && (! BLOAD_ONLY)
rtn_struct(theEnv,joinNode,join);
#endif
/*==========================================*/
/* Remove the right join link if it exists. */
/*==========================================*/
if (rightJoin != NULL)
{
rightJoin->nextLevel = NULL;
prevJoin = rightJoin;
}
/*===========================================================*/
/* Move on to the next join to be removed. All the joins of */
/* a rule can be deleted by following the right joins links */
/* (when these links exist) and then following the left join */
/* links. This works because if join A enters join B from */
/* the right, the right/left links of join A eventually lead */
/* to the join which enters join B from the left. */
/*===========================================================*/
if (prevJoin->ruleToActivate != NULL)
{ join = NULL; }
else if (prevJoin->nextLevel == NULL)
{ join = prevJoin; }
else
{ join = NULL; }
}
}
#if (! RUN_TIME) && (! BLOAD_ONLY)
/***********************************************************************/
/* RemoveIntranetworkLink: Removes the link between a join node in the */
/* join network and its corresponding pattern node in the pattern */
/* network. If the pattern node is then no longer associated with */
/* any other joins, it is removed using the function DetachPattern. */
/***********************************************************************/
static void RemoveIntranetworkLink(
void *theEnv,
struct joinNode *join)
{
struct patternNodeHeader *patternPtr;
struct joinNode *joinPtr, *lastJoin;
/*================================================*/
/* Determine the pattern that enters this join. */
/* Determine the list of joins which this pattern */
/* enters from the right. */
/*================================================*/
patternPtr = (struct patternNodeHeader *) join->rightSideEntryStructure;
joinPtr = patternPtr->entryJoin;
lastJoin = NULL;
/*=================================================*/
/* Loop through the list of joins that the pattern */
/* enters until the join being removed is found. */
/* Remove this join from the list. */
/*=================================================*/
while (joinPtr != NULL)
{
if (joinPtr == join)
{
if (lastJoin == NULL)
{ patternPtr->entryJoin = joinPtr->rightMatchNode; }
else
{ lastJoin->rightMatchNode = joinPtr->rightMatchNode; }
joinPtr = NULL;
}
else
{
lastJoin = joinPtr;
joinPtr = joinPtr->rightMatchNode;
}
}
/*===================================================*/
/* If the terminal node of the pattern doesn't point */
/* to any joins, then start removing the pattern. */
/*===================================================*/
if (patternPtr->entryJoin == NULL)
{ DetachPattern(theEnv,(int) join->rhsType,patternPtr); }
}
#endif /* (! RUN_TIME) && (! BLOAD_ONLY) */
#endif /* DEFRULE_CONSTRUCT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -