static void DetachJoinsDriver( void *theEnv, struct defrule *theRule, intBool destroy) { struct joinNode *join; /*==================================*/ /* 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->nextLinks != NULL) return; DetachJoins(theEnv,join,destroy); }
globle void DestroyDefrule( void *theEnv, void *vTheDefrule) { struct defrule *theDefrule = (struct defrule *) vTheDefrule; struct defrule *nextDisjunct; int first = TRUE; if (theDefrule == NULL) return; while (theDefrule != NULL) { DetachJoins(theEnv,theDefrule,TRUE); if (first) { #if (! BLOAD_ONLY) && (! RUN_TIME) #if DYNAMIC_SALIENCE if (theDefrule->dynamicSalience != NULL) { ReturnPackedExpression(theEnv,theDefrule->dynamicSalience); } #endif if (theDefrule->header.ppForm != NULL) { rm(theEnv,theDefrule->header.ppForm,strlen(theDefrule->header.ppForm) + 1); } #endif first = FALSE; } if (theDefrule->header.usrData != NULL) { ClearUserDataList(theEnv,theDefrule->header.usrData); } #if (! BLOAD_ONLY) && (! RUN_TIME) if (theDefrule->actions != NULL) { ReturnPackedExpression(theEnv,theDefrule->actions); } #endif nextDisjunct = theDefrule->disjunct; #if (! BLOAD_ONLY) && (! RUN_TIME) rtn_struct(theEnv,defrule,theDefrule); #endif theDefrule = nextDisjunct; } }
static void DetachJoins( void *theEnv, struct joinNode *join, intBool destroy) { struct joinNode *prevJoin, *rightJoin; struct joinLink *lastLink, *theLink; int lastMark; /*===========================*/ /* Begin removing the joins. */ /*===========================*/ while (join != NULL) { if (join->marked) return; /*==========================================================*/ /* 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) { DestroyBetaMemory(theEnv,join,LHS); DestroyBetaMemory(theEnv,join,RHS); } else { FlushBetaMemory(theEnv,join,LHS); FlushBetaMemory(theEnv,join,RHS); } ReturnLeftMemory(theEnv,join); ReturnRightMemory(theEnv,join); /*===================================*/ /* Remove the expressions associated */ /* with the join. */ /*===================================*/ #if (! RUN_TIME) && (! BLOAD_ONLY) if (! destroy) { RemoveHashedExpression(theEnv,join->networkTest); RemoveHashedExpression(theEnv,join->secondaryNetworkTest); RemoveHashedExpression(theEnv,join->leftHash); RemoveHashedExpression(theEnv,join->rightHash); } #endif /*============================*/ /* Fix the right prime links. */ /*============================*/ if (join->firstJoin && (join->rightSideEntryStructure == NULL)) { lastLink = NULL; theLink = DefruleData(theEnv)->RightPrimeJoins; while (theLink != NULL) { if (theLink->join == join) { if (lastLink == NULL) { DefruleData(theEnv)->RightPrimeJoins = theLink->next; } else { lastLink->next = theLink->next; } #if (! RUN_TIME) && (! BLOAD_ONLY) rtn_struct(theEnv,joinLink,theLink); #endif theLink = NULL; } else { lastLink = theLink; theLink = lastLink->next; } } } /*===========================*/ /* Fix the left prime links. */ /*===========================*/ if (join->firstJoin && (join->patternIsNegated || join->joinFromTheRight) && (! join->patternIsExists)) { lastLink = NULL; theLink = DefruleData(theEnv)->LeftPrimeJoins; while (theLink != NULL) { if (theLink->join == join) { if (lastLink == NULL) { DefruleData(theEnv)->LeftPrimeJoins = theLink->next; } else { lastLink->next = theLink->next; } #if (! RUN_TIME) && (! BLOAD_ONLY) rtn_struct(theEnv,joinLink,theLink); #endif theLink = NULL; } else { lastLink = theLink; theLink = theLink->next; } } } /*==================================================*/ /* Remove the link to the join from the join above. */ /*==================================================*/ if (prevJoin != NULL) { lastLink = NULL; theLink = prevJoin->nextLinks; while (theLink != NULL) { if (theLink->join == join) { if (lastLink == NULL) { prevJoin->nextLinks = theLink->next; } else { lastLink->next = theLink->next; } #if (! RUN_TIME) && (! BLOAD_ONLY) rtn_struct(theEnv,joinLink,theLink); #endif theLink = NULL; } else { lastLink = theLink; theLink = theLink->next; } } } /*==========================================*/ /* Remove the right join link if it exists. */ /*==========================================*/ if (rightJoin != NULL) { lastLink = NULL; theLink = rightJoin->nextLinks; while (theLink != NULL) { if (theLink->join == join) { if (lastLink == NULL) { rightJoin->nextLinks = theLink->next; } else { lastLink->next = theLink->next; } #if (! RUN_TIME) && (! BLOAD_ONLY) rtn_struct(theEnv,joinLink,theLink); #endif theLink = NULL; } else { lastLink = theLink; theLink = theLink->next; } } if ((rightJoin->nextLinks == NULL) && (rightJoin->ruleToActivate == NULL)) { if (prevJoin != NULL) { lastMark = prevJoin->marked; prevJoin->marked = TRUE; DetachJoins(theEnv,rightJoin,destroy); prevJoin->marked = lastMark; } else { DetachJoins(theEnv,rightJoin,destroy); } } } /*==================*/ /* Delete the join. */ /*==================*/ #if (! RUN_TIME) && (! BLOAD_ONLY) rtn_struct(theEnv,joinNode,join); #endif /*===========================================================*/ /* 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 == NULL) { return; } else if (prevJoin->ruleToActivate != NULL) { return; } else if (prevJoin->nextLinks == NULL) { join = prevJoin; } else { return; } } }
globle void ReturnDefrule( void *vWaste) { #if (MAC_MPW || MAC_MCW) && (RUN_TIME || BLOAD_ONLY) #pragma unused(vWaste) #endif #if (! RUN_TIME) && (! BLOAD_ONLY) struct defrule *waste = (struct defrule *) vWaste; int first = TRUE; struct defrule *nextPtr; if (waste == NULL) return; /*======================================*/ /* If a rule is redefined, then we want */ /* to save its breakpoint status. */ /*======================================*/ #if DEBUGGING_FUNCTIONS DeletedRuleDebugFlags = 0; if (waste->afterBreakpoint) BitwiseSet(DeletedRuleDebugFlags,0); if (waste->watchActivation) BitwiseSet(DeletedRuleDebugFlags,1); if (waste->watchFiring) BitwiseSet(DeletedRuleDebugFlags,2); #endif /*================================*/ /* Clear the agenda of all the */ /* activations added by the rule. */ /*================================*/ ClearRuleFromAgenda(waste); /*======================*/ /* Get rid of the rule. */ /*======================*/ while (waste != NULL) { /*================================================*/ /* Remove the rule's joins from the join network. */ /*================================================*/ DetachJoins(waste); /*=============================================*/ /* If this is the first disjunct, get rid of */ /* the dynamic salience and pretty print form. */ /*=============================================*/ if (first) { #if DYNAMIC_SALIENCE if (waste->dynamicSalience != NULL) { ExpressionDeinstall(waste->dynamicSalience); ReturnPackedExpression(waste->dynamicSalience); waste->dynamicSalience = NULL; } #endif #if CERTAINTY_FACTORS /* changed 03-12-96 */ if (waste->dynamicCF != NULL) { ExpressionDeinstall(waste->dynamicCF); ReturnPackedExpression(waste->dynamicCF); waste->dynamicCF = NULL; } #endif if (waste->header.ppForm != NULL) { rm(waste->header.ppForm,(int) strlen(waste->header.ppForm) + 1); waste->header.ppForm = NULL; } first = FALSE; } /*===========================*/ /* Get rid of any user data. */ /*===========================*/ if (waste->header.usrData != NULL) { ClearUserDataList(waste->header.usrData); } /*===========================================*/ /* Decrement the count for the defrule name. */ /*===========================================*/ DecrementSymbolCount(waste->header.name); /*========================================*/ /* Get rid of the the rule's RHS actions. */ /*========================================*/ if (waste->actions != NULL) { ExpressionDeinstall(waste->actions); ReturnPackedExpression(waste->actions); } /*===============================*/ /* Move on to the next disjunct. */ /*===============================*/ nextPtr = waste->disjunct; #if FUZZY_DEFTEMPLATES if (waste != ExecutingRule) { if (waste->numberOfFuzzySlots > 0) rm(waste->pattern_fv_arrayPtr, sizeof(struct fzSlotLocator) * waste->numberOfFuzzySlots); } #endif rtn_struct(defrule,waste); waste = nextPtr; } /*==========================*/ /* Free up partial matches. */ /*==========================*/ if (ExecutingRule == NULL) FlushGarbagePartialMatches(); #endif }
globle void ReturnDefrule( void *theEnv, void *vWaste) { #if (MAC_MCW || IBM_MCW) && (RUN_TIME || BLOAD_ONLY) #pragma unused(theEnv,vWaste) #endif #if (! RUN_TIME) && (! BLOAD_ONLY) struct defrule *waste = (struct defrule *) vWaste; int first = TRUE; struct defrule *nextPtr; if (waste == NULL) return; /*======================================*/ /* If a rule is redefined, then we want */ /* to save its breakpoint status. */ /*======================================*/ #if DEBUGGING_FUNCTIONS DefruleData(theEnv)->DeletedRuleDebugFlags = 0; if (waste->afterBreakpoint) BitwiseSet(DefruleData(theEnv)->DeletedRuleDebugFlags,0); if (waste->watchActivation) BitwiseSet(DefruleData(theEnv)->DeletedRuleDebugFlags,1); if (waste->watchFiring) BitwiseSet(DefruleData(theEnv)->DeletedRuleDebugFlags,2); #endif /*================================*/ /* Clear the agenda of all the */ /* activations added by the rule. */ /*================================*/ ClearRuleFromAgenda(theEnv,waste); /*======================*/ /* Get rid of the rule. */ /*======================*/ while (waste != NULL) { /*================================================*/ /* Remove the rule's joins from the join network. */ /*================================================*/ DetachJoins(theEnv,waste,FALSE); /*=============================================*/ /* If this is the first disjunct, get rid of */ /* the dynamic salience and pretty print form. */ /*=============================================*/ if (first) { #if DYNAMIC_SALIENCE if (waste->dynamicSalience != NULL) { ExpressionDeinstall(theEnv,waste->dynamicSalience); ReturnPackedExpression(theEnv,waste->dynamicSalience); waste->dynamicSalience = NULL; } #endif if (waste->header.ppForm != NULL) { rm(theEnv,waste->header.ppForm,strlen(waste->header.ppForm) + 1); waste->header.ppForm = NULL; } first = FALSE; } /*===========================*/ /* Get rid of any user data. */ /*===========================*/ if (waste->header.usrData != NULL) { ClearUserDataList(theEnv,waste->header.usrData); } /*===========================================*/ /* Decrement the count for the defrule name. */ /*===========================================*/ DecrementSymbolCount(theEnv,waste->header.name); /*========================================*/ /* Get rid of the the rule's RHS actions. */ /*========================================*/ if (waste->actions != NULL) { ExpressionDeinstall(theEnv,waste->actions); ReturnPackedExpression(theEnv,waste->actions); } /*===============================*/ /* Move on to the next disjunct. */ /*===============================*/ nextPtr = waste->disjunct; rtn_struct(theEnv,defrule,waste); waste = nextPtr; } /*==========================*/ /* Free up partial matches. */ /*==========================*/ if (EngineData(theEnv)->ExecutingRule == NULL) FlushGarbagePartialMatches(theEnv); #endif }