📄 retract.c
字号:
/*=============================================*/ /* 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. */ /*==============================================*/ else { lastPM = listOfPMs; listOfPMs = listOfPMs->next; } } /*===============================================*/ /* Return the last partial match in the new list */ /* of partial matches via one of the function's */ /* parameters. */ /*===============================================*/ *returnLast = lastPM; /*=====================================================*/ /* Return the head of the new list of partial matches. */ /*=====================================================*/ return(head); } /***************************************************//* DeletePartialMatches: Returns a list of partial *//* matches to the pool of free memory. *//***************************************************/static VOID DeletePartialMatches(listOfPMs,betaDelete) struct partialMatch *listOfPMs; int betaDelete; { struct partialMatch *nextPM; while (listOfPMs != NULL) { /*============================================*/ /* Remember the next partial match to delete. */ /*============================================*/ nextPM = listOfPMs->next; /*================================================*/ /* Remove the links between the partial match and */ /* any data entities that it is attached to as a */ /* result of a logical CE. */ /*================================================*/ #if LOGICAL_DEPENDENCIES if (listOfPMs->dependentsf) RemoveLogicalSupport(listOfPMs);#endif /*==========================================================*/ /* If the partial match is being deleted from a beta memory */ /* and the partial match isn't associated with a satisfied */ /* not CE, then it can be immediately returned to the pool */ /* of free memory. Otherwise, it's could be in use (either */ /* to retrieve variables from the LHS or by the activation */ /* of the rule). Since a not CE creates a "pseudo" data */ /* entity, the beta partial match which stores this pseudo */ /* data entity can not be deleted immediately (for the same */ /* reason an alpha memory partial match can't be deleted */ /* immediately). */ /*==========================================================*/ if (betaDelete && ((listOfPMs->notOriginf == CLIPS_FALSE) || (listOfPMs->counterf))) { ReturnPartialMatch(listOfPMs); } else { listOfPMs->next = GarbagePartialMatches; GarbagePartialMatches = listOfPMs; } /*====================================*/ /* Move on to the next partial match. */ /*====================================*/ listOfPMs = nextPM; } }/**************************************************************//* ReturnPartialMatch: Returns the data structures associated *//* with a partial match to the pool of free memory. *//**************************************************************/globle VOID ReturnPartialMatch(waste) struct partialMatch *waste; { /*==============================================*/ /* If the partial match is in use, then put it */ /* on a garbage list to be processed later when */ /* the partial match is not in use. */ /*==============================================*/ if (waste->busy) { waste->next = GarbagePartialMatches; GarbagePartialMatches = waste; return; } /*======================================================*/ /* If we're dealing with an alpha memory partial match, */ /* then return the multifield markers associated with */ /* the partial match (if any) along with the alphaMatch */ /* data structure. */ /*======================================================*/ if (waste->betaMemory == CLIPS_FALSE) { if (waste->binds[0].gm.theMatch->markers != NULL) { ReturnMarkers(waste->binds[0].gm.theMatch->markers); } rm(waste->binds[0].gm.theMatch,(int) sizeof(struct alphaMatch)); } /*=================================================*/ /* Remove any links between the partial match and */ /* a data entity that were created with the use of */ /* the logical CE. */ /*=================================================*/ #if LOGICAL_DEPENDENCIES if (waste->dependentsf) RemovePMDependencies(waste);#endif /*======================================================*/ /* Return the partial match to the pool of free memory. */ /*======================================================*/ rtn_var_struct(partialMatch,(int) sizeof(struct genericMatch *) * (waste->bcount + waste->activationf + waste->dependentsf - 1), waste); }/******************************************************//* ReturnMarkers: Returns a linked list of multifield *//* markers associated with a data entity matching a *//* pattern to the pool of free memory. *//******************************************************/static VOID ReturnMarkers(waste) struct multifieldMarker *waste; { struct multifieldMarker *temp; while (waste != NULL) { temp = waste->next; rtn_struct(multifieldMarker,waste); waste = temp; } }/*************************************************//* DriveRetractions: Filters the list of partial *//* matches created as a result of removing a *//* data entity through the join network. *//*************************************************/static VOID DriveRetractions() { struct rdriveinfo *tempDR; struct joinNode *joinPtr; while (DriveRetractionList != NULL) { for (joinPtr = DriveRetractionList->jlist; joinPtr != NULL; joinPtr = joinPtr->rightDriveNode) { NetworkAssert(DriveRetractionList->link,joinPtr,LHS); } tempDR = DriveRetractionList->next; rtn_struct(rdriveinfo,DriveRetractionList); DriveRetractionList = tempDR; } } /*************************************************************//* FlushGarbagePartialMatches: Returns partial matches and *//* associated structures that were removed as part of a *//* retraction. It is necessary to postpone returning these *//* structures to memory because RHS actions retrieve their *//* variable bindings directly from the fact and instance *//* data structures through the alpha memory bindings. *//*************************************************************/globle VOID FlushGarbagePartialMatches() { struct partialMatch *pmPtr; struct alphaMatch *amPtr; /*===================================================*/ /* Return the garbage partial matches collected from */ /* the alpha memories of the pattern networks. */ /*===================================================*/ while (GarbageAlphaMatches != NULL) { amPtr = GarbageAlphaMatches->next; rtn_struct(alphaMatch,GarbageAlphaMatches); GarbageAlphaMatches = amPtr; } /*==============================================*/ /* Return the garbage partial matches collected */ /* from the beta memories of the join networks. */ /*==============================================*/ while (GarbagePartialMatches != NULL) { /*=====================================================*/ /* Remember the next garbage partial match to process. */ /*=====================================================*/ pmPtr = GarbagePartialMatches->next; /*=======================================================*/ /* If a "pseudo" data entity was created for the partial */ /* match (i.e. a not CE was satisfied), then dispose of */ /* the pseudo data entity. */ /*=======================================================*/ if ((GarbagePartialMatches->notOriginf) && (GarbagePartialMatches->counterf == CLIPS_FALSE)) { if (GarbagePartialMatches->binds[GarbagePartialMatches->bcount - 1].gm.theMatch != NULL) { rtn_struct(alphaMatch, GarbagePartialMatches->binds[GarbagePartialMatches->bcount - 1].gm.theMatch); } } /*============================================*/ /* Dispose of the garbage partial match being */ /* examined and move on to the next one. */ /*============================================*/ GarbagePartialMatches->busy = CLIPS_FALSE; ReturnPartialMatch(GarbagePartialMatches); GarbagePartialMatches = pmPtr; } }#endif /* DEFRULE_CONSTRUCT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -