📄 factmngr.c
字号:
return(CLIPS_FALSE); } /*====================================*/ /* A NULL fact pointer indicates that */ /* all facts should be retracted. */ /*====================================*/ if (theFact == NULL) { RemoveAllFacts(); return(CLIPS_TRUE); } /*======================================================*/ /* Check to see if the fact has already been retracted. */ /*======================================================*/ if (theFact->garbage) return(CLIPS_FALSE); /*============================*/ /* Print retraction output if */ /* facts are being watched. */ /*============================*/#if DEBUGGING_FUNCTIONS if (theFact->whichDeftemplate->watch) { PrintCLIPS(WTRACE,"<== "); PrintFactWithIdentifier(WTRACE,theFact); PrintCLIPS(WTRACE,"\n"); }#endif /*==================================*/ /* Set the change flag to indicate */ /* the fact-list has been modified. */ /*==================================*/ ChangeToFactList = CLIPS_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 = CLIPS_TRUE; /*===================================================*/ /* Reset the evaluation error flag since expressions */ /* will be evaluated as part of the retract. */ /*===================================================*/ SetEvaluationError(CLIPS_FALSE); /*===========================================*/ /* Loop through the list of all the patterns */ /* that matched the fact and process the */ /* retract operation for each one. */ /*===========================================*/ JoinOperationInProgress = CLIPS_TRUE; NetworkRetract((struct patternMatch *) theFact->list); JoinOperationInProgress = CLIPS_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(CLIPS_TRUE,CLIPS_FALSE); } /*==================================*/ /* Return TRUE to indicate the fact */ /* was successfully retracted. */ /*==================================*/ return(CLIPS_TRUE); }/*******************************************************************//* RemoveGarbageFacts: Returns facts that have been retracted to *//* the pool of available memory. It is necessary to postpone *//* returning the facts to memory because RHS actions retrieve *//* their variable bindings directly from the fact data structure *//* and the facts may be in use in other data structures. *//*******************************************************************/static VOID RemoveGarbageFacts() { struct fact *factPtr, *nextPtr, *lastPtr = NULL; factPtr = GarbageFacts; while (factPtr != NULL) { nextPtr = factPtr->nextFact; if ((factPtr->factHeader.busyCount == 0) && (((int) factPtr->depth) > CurrentEvaluationDepth)) { EphemeralItemCount--; EphemeralItemSize -= sizeof(struct fact) + (sizeof(struct field) * factPtr->theProposition.multifieldLength); ReturnFact(factPtr); if (lastPtr == NULL) GarbageFacts = nextPtr; else lastPtr->nextFact = nextPtr; } else { lastPtr = factPtr; } factPtr = nextPtr; } }/*****************************************************//* Assert: C access routine for the assert function. *//*****************************************************/globle VOID *Assert(vTheFact) VOID *vTheFact; { int hashValue; int length, i; struct field *theField; struct fact *theFact = (struct fact *) vTheFact; /*==========================================*/ /* A fact can not be asserted while another */ /* fact is being asserted or retracted. */ /*==========================================*/ if (JoinOperationInProgress) { ReturnFact(theFact); PrintErrorID("FACTMNGR",2,CLIPS_TRUE); PrintCLIPS(WERROR,"Facts may not be asserted during pattern-matching\n"); return(NULL); } /*=============================================================*/ /* Replace invalid data types in the fact with the symbol nil. */ /*=============================================================*/ length = theFact->theProposition.multifieldLength; theField = theFact->theProposition.theFields; for (i = 0; i < length; i++) { if (theField[i].type == RVOID) { theField[i].type = SYMBOL; theField[i].value = (VOID *) AddSymbol("nil"); } } /*========================================================*/ /* If fact assertions are being checked for duplications, */ /* then search the fact list for a duplicate fact. */ /*========================================================*/ hashValue = HandleFactDuplication(theFact); if (hashValue < 0) return(NULL); /*==========================================================*/ /* If necessary, add logical dependency links between the */ /* fact and the partial match which is its logical support. */ /*==========================================================*/ #if LOGICAL_DEPENDENCIES if (AddLogicalDependencies((struct patternEntity *) theFact,CLIPS_FALSE) == CLIPS_FALSE) { ReturnFact(theFact); return(NULL); }#endif /*======================================*/ /* Add the fact to the fact hash table. */ /*======================================*/ AddHashedFact(theFact,hashValue); /*================================*/ /* Add the fact to the fact list. */ /*================================*/ theFact->nextFact = NULL; theFact->list = NULL; theFact->previousFact = LastFact; if (LastFact == NULL) { FactList = theFact; } else { LastFact->nextFact = theFact; } LastFact = theFact; /*==================================*/ /* Set the fact index and time tag. */ /*==================================*/ theFact->factIndex = NextFactIndex++; theFact->factHeader.timeTag = CurrentEntityTimeTag++; /*=====================*/ /* Update busy counts. */ /*=====================*/ FactInstall(theFact); /*==========================*/ /* Print assert output if */ /* facts are being watched. */ /*==========================*/#if DEBUGGING_FUNCTIONS if (theFact->whichDeftemplate->watch) { PrintCLIPS(WTRACE,"==> "); PrintFactWithIdentifier(WTRACE,theFact); PrintCLIPS(WTRACE,"\n"); }#endif /*==================================*/ /* Set the change flag to indicate */ /* the fact-list has been modified. */ /*==================================*/ ChangeToFactList = CLIPS_TRUE; /*==========================================*/ /* Check for constraint errors in the fact. */ /*==========================================*/ CheckTemplateFact(theFact); /*===================================================*/ /* Reset the evaluation error flag since expressions */ /* will be evaluated as part of the assert . */ /*===================================================*/ SetEvaluationError(CLIPS_FALSE); /*=============================================*/ /* Pattern match the fact using the associated */ /* deftemplate's pattern network. */ /*=============================================*/ JoinOperationInProgress = CLIPS_TRUE; FactPatternMatch(theFact,theFact->whichDeftemplate->patternNetwork,0,NULL,NULL); JoinOperationInProgress = CLIPS_FALSE; /*===================================================*/ /* Retract other facts that were logically dependent */ /* on the non-existence of the fact just asserted. */ /*===================================================*/#if LOGICAL_DEPENDENCIES ForceLogicalRetractions();#endif /*=========================================*/ /* Free partial matches that were released */ /* by the assertion of the fact. */ /*=========================================*/ if (ExecutingRule == NULL) FlushGarbagePartialMatches(); /*==========================================*/ /* Force periodic cleanup if the assert was */ /* executed from an embedded application. */ /*==========================================*/ if ((CurrentEvaluationDepth == 0) && (! EvaluatingTopLevelCommand) && (CurrentExpression == NULL)) { PeriodicCleanup(CLIPS_TRUE,CLIPS_FALSE); } /*===============================*/ /* Return a pointer to the fact. */ /*===============================*/ return((VOID *) theFact); }/**************************************//* RemoveAllFacts: Loops through the *//* fact-list and removes each fact. *//**************************************/globle VOID RemoveAllFacts() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -