globle CLIPS_BOOLEAN AddLogicalDependencies( void *theEnv, struct patternEntity *theEntity, int existingEntity) { struct partialMatch *theBinds; struct dependency *newDependency; /*==============================================*/ /* If the rule has no logical patterns, then no */ /* dependencies have to be established. */ /*==============================================*/ if (EngineData(theEnv)->TheLogicalJoin == NULL) { if (existingEntity) RemoveEntityDependencies(theEnv,theEntity); return(TRUE); } else if (existingEntity && (theEntity->dependents == NULL)) { return(TRUE); } /*============================================================*/ /* Find the partial match in the logical join associated with */ /* activation partial match. If the partial match cannot be */ /* found, then the partial match must have been deleted by a */ /* previous RHS action and the dependency link should not be */ /* added. */ /*============================================================*/ theBinds = FindLogicalBind(EngineData(theEnv)->TheLogicalJoin,EngineData(theEnv)->GlobalLHSBinds); if (theBinds == NULL) return(FALSE); /*==============================================================*/ /* Add a dependency link between the partial match and the data */ /* entity. The dependency links are stored in the partial match */ /* behind the data entities stored in the partial match and the */ /* activation link, if any. */ /*==============================================================*/ newDependency = get_struct(theEnv,dependency); newDependency->dPtr = (void *) theEntity; newDependency->next = (struct dependency *) theBinds->binds[theBinds->bcount + theBinds->activationf].gm.theValue; theBinds->binds[theBinds->bcount + theBinds->activationf].gm.theValue = (void *) newDependency; /*================================================================*/ /* Add a dependency link between the entity and the partialMatch. */ /*================================================================*/ newDependency = get_struct(theEnv,dependency); newDependency->dPtr = (void *) theBinds; newDependency->next = (struct dependency *) theEntity->dependents; theEntity->dependents = (void *) newDependency; /*==================================================================*/ /* Return TRUE to indicate that the data entity should be asserted. */ /*==================================================================*/ return(TRUE); }
bool AddLogicalDependencies( Environment *theEnv, struct patternEntity *theEntity, bool existingEntity) { struct partialMatch *theBinds; struct dependency *newDependency; /*==============================================*/ /* If the rule has no logical patterns, then no */ /* dependencies have to be established. */ /*==============================================*/ if (EngineData(theEnv)->TheLogicalJoin == NULL) { if (existingEntity) RemoveEntityDependencies(theEnv,theEntity); return true; } else if (existingEntity && (theEntity->dependents == NULL)) { return true; } /*===========================================================*/ /* Retrieve the partial match in the logical join associated */ /* with activation partial match (retrieved when the run */ /* command was initiated). If the partial match's parent */ /* links have been removed, then the partial match must have */ /* been deleted by a previous RHS action and the dependency */ /* link should not be added. */ /*===========================================================*/ theBinds = EngineData(theEnv)->TheLogicalBind; if (theBinds == NULL) return false; if ((theBinds->leftParent == NULL) && (theBinds->rightParent == NULL)) { return false; } /*==============================================================*/ /* Add a dependency link between the partial match and the data */ /* entity. The dependency links are stored in the partial match */ /* behind the data entities stored in the partial match and the */ /* activation link, if any. */ /*==============================================================*/ newDependency = get_struct(theEnv,dependency); newDependency->dPtr = theEntity; newDependency->next = (struct dependency *) theBinds->dependents; theBinds->dependents = newDependency; /*================================================================*/ /* Add a dependency link between the entity and the partialMatch. */ /*================================================================*/ newDependency = get_struct(theEnv,dependency); newDependency->dPtr = theBinds; newDependency->next = (struct dependency *) theEntity->dependents; theEntity->dependents = newDependency; /*==================================================================*/ /* Return true to indicate that the data entity should be asserted. */ /*==================================================================*/ return true; }
globle BOOLEAN Retract( void *vTheFact) { struct fact *theFact = (struct fact *) vTheFact; /*===========================================*/ /* A fact can not be retracted while another */ /* fact is being asserted or retracted. */ /*===========================================*/ if (JoinOperationInProgress) { PrintErrorID("FACTMNGR",1,TRUE); PrintRouter(WERROR,"Facts may not be retracted during pattern-matching\n"); return(FALSE); } /*====================================*/ /* A NULL fact pointer indicates that */ /* all facts should be retracted. */ /*====================================*/ if (theFact == NULL) { RemoveAllFacts(); return(TRUE); } /*======================================================*/ /* Check to see if the fact has already been retracted. */ /*======================================================*/ if (theFact->garbage) return(FALSE); /*============================*/ /* Print retraction output if */ /* facts are being watched. */ /*============================*/ #if DEBUGGING_FUNCTIONS if (theFact->whichDeftemplate->watch) { PrintRouter(WTRACE,"<== "); PrintFactWithIdentifier(WTRACE,theFact); PrintRouter(WTRACE,"\n"); } #endif /*==================================*/ /* Set the change flag to indicate */ /* the fact-list has been modified. */ /*==================================*/ ChangeToFactList = TRUE; /*===============================================*/ /* Remove any links between the fact and partial */ /* matches in the join network. These links are */ /* used to keep track of logical dependencies. */ /*===============================================*/ #if LOGICAL_DEPENDENCIES RemoveEntityDependencies((struct patternEntity *) theFact); #endif /*===========================================*/ /* Remove the fact from the fact hash table. */ /*===========================================*/ RemoveHashedFact(theFact); /*=====================================*/ /* Remove the fact from the fact list. */ /*=====================================*/ if (theFact == LastFact) { LastFact = theFact->previousFact; } if (theFact->previousFact == NULL) { FactList = FactList->nextFact; if (FactList != NULL) { FactList->previousFact = NULL; } } else { theFact->previousFact->nextFact = theFact->nextFact; if (theFact->nextFact != NULL) { theFact->nextFact->previousFact = theFact->previousFact; } } /*==================================*/ /* Update busy counts and ephemeral */ /* garbage information. */ /*==================================*/ FactDeinstall(theFact); EphemeralItemCount++; EphemeralItemSize += sizeof(struct fact) + (sizeof(struct field) * theFact->theProposition.multifieldLength); /*========================================*/ /* Add the fact to the fact garbage list. */ /*========================================*/ theFact->nextFact = GarbageFacts; GarbageFacts = theFact; theFact->garbage = TRUE; /*===================================================*/ /* Reset the evaluation error flag since expressions */ /* will be evaluated as part of the retract. */ /*===================================================*/ SetEvaluationError(FALSE); /*===========================================*/ /* Loop through the list of all the patterns */ /* that matched the fact and process the */ /* retract operation for each one. */ /*===========================================*/ JoinOperationInProgress = TRUE; NetworkRetract((struct patternMatch *) theFact->list); JoinOperationInProgress = FALSE; /*=========================================*/ /* Free partial matches that were released */ /* by the retraction of the fact. */ /*=========================================*/ if (ExecutingRule == NULL) { FlushGarbagePartialMatches(); } /*=========================================*/ /* Retract other facts that were logically */ /* dependent on the fact just retracted. */ /*=========================================*/ #if LOGICAL_DEPENDENCIES ForceLogicalRetractions(); #endif /*===========================================*/ /* Force periodic cleanup if the retract was */ /* executed from an embedded application. */ /*===========================================*/ if ((CurrentEvaluationDepth == 0) && (! EvaluatingTopLevelCommand) && (CurrentExpression == NULL)) { PeriodicCleanup(TRUE,FALSE); } /*==================================*/ /* Return TRUE to indicate the fact */ /* was successfully retracted. */ /*==================================*/ return(TRUE); }