📄 retract.c
字号:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.05 04/09/97 */ /* */ /* RETRACT MODULE */ /*******************************************************//*************************************************************//* Purpose: Handles join network activity associated with *//* with the removal of a data entity such as a fact or *//* instance. *//* *//* Principal Programmer(s): *//* Gary D. Riley *//* *//* Contributing Programmer(s): *//* *//* Revision History: *//* *//*************************************************************/#define _RETRACT_SOURCE_#include <stdio.h>#define _CLIPS_STDIO_#include "setup.h"#if DEFRULE_CONSTRUCT#include "constant.h"#include "clipsmem.h"#include "symbol.h"#include "argacces.h"#include "router.h" #include "network.h" #include "agenda.h" #include "match.h"#include "drive.h" #if LOGICAL_DEPENDENCIES#include "lgcldpnd.h" #endif#include "retract.h"#if ANSI_COMPILER static struct partialMatch *RemovePartialMatches(struct alphaMatch *, struct partialMatch *, struct partialMatch **,int, struct partialMatch **); static VOID DeletePartialMatches(struct partialMatch *,int); static VOID ReturnMarkers(struct multifieldMarker *); static VOID DriveRetractions(void); static BOOLEAN FindNextConflictingAlphaMatch(struct partialMatch *, struct partialMatch *, struct joinNode *); static BOOLEAN PartialMatchDefunct(struct partialMatch *);#else static struct partialMatch *RemovePartialMatches(); static VOID DeletePartialMatches(); static VOID ReturnMarkers(); static VOID DriveRetractions(); static BOOLEAN FindNextConflictingAlphaMatch(); static BOOLEAN PartialMatchDefunct();#endif/**************//* STRUCTURES *//**************/struct rdriveinfo { struct partialMatch *link; struct joinNode *jlist; struct rdriveinfo *next; };/***************************************//* LOCAL INTERNAL VARIABLE DEFINITIONS *//***************************************/ static struct rdriveinfo *DriveRetractionList = NULL;/****************************************//* GLOBAL INTERNAL VARIABLE DEFINITIONS *//****************************************/ globle struct partialMatch *GarbagePartialMatches = NULL; globle struct alphaMatch *GarbageAlphaMatches = NULL;/************************************************************//* NetworkRetract: Retracts a data entity (such as a fact *//* or instance) from the pattern and join networks given *//* a pointer to the list of patterns which the data *//* entity matched. The data entity is first removed from *//* the join network through patterns not directly *//* enclosed within a not CE and then through patterns *//* enclosed by a not CE. Any new partial matches created *//* by the removal are then filtered through the join *//* network. This ordering prevents partial matches from *//* being generated that contain the data entity which was *//* removed. *//************************************************************/globle VOID NetworkRetract(listOfMatchedPatterns) struct patternMatch *listOfMatchedPatterns; { struct patternMatch *tempMatch; struct partialMatch *deletedMatches, *theLast; struct joinNode *joinPtr; /*===============================*/ /* Remember the beginning of the */ /* list of matched patterns. */ /*===============================*/ tempMatch = listOfMatchedPatterns; /*============================================*/ /* Remove the data entity from all joins that */ /* aren't directly enclosed by a not CE. */ /*============================================*/ for (; listOfMatchedPatterns != NULL; listOfMatchedPatterns = listOfMatchedPatterns->next) { /*====================================*/ /* Loop through the list of all joins */ /* attached to this pattern. */ /*====================================*/ for (joinPtr = listOfMatchedPatterns->matchingPattern->entryJoin; joinPtr != NULL; joinPtr = joinPtr->rightMatchNode) { if (joinPtr->patternIsNegated == CLIPS_FALSE) { PosEntryRetract(joinPtr, listOfMatchedPatterns->theMatch->binds[0].gm.theMatch, listOfMatchedPatterns->theMatch, (int) joinPtr->depth - 1,CLIPS_TRUE); } } } /*============================================*/ /* Remove the data entity from all joins that */ /* are directly enclosed by a not CE. */ /*============================================*/ listOfMatchedPatterns = tempMatch; while (listOfMatchedPatterns != NULL) { /*====================================*/ /* Loop through the list of all joins */ /* attached to this pattern. */ /*====================================*/ for (joinPtr = listOfMatchedPatterns->matchingPattern->entryJoin; joinPtr != NULL; joinPtr = joinPtr->rightMatchNode) { if (joinPtr->patternIsNegated == CLIPS_TRUE) { if (joinPtr->firstJoin == CLIPS_TRUE) { CLIPSSystemError("RETRACT",3); ExitCLIPS(5); } else { NegEntryRetract(joinPtr,listOfMatchedPatterns->theMatch,CLIPS_TRUE); } } } /*===================================================*/ /* Remove from the alpha memory of the pattern node. */ /*===================================================*/ theLast = NULL; listOfMatchedPatterns->matchingPattern->alphaMemory = RemovePartialMatches(listOfMatchedPatterns->theMatch->binds[0].gm.theMatch, listOfMatchedPatterns->matchingPattern->alphaMemory, &deletedMatches,0,&theLast); listOfMatchedPatterns->matchingPattern->endOfQueue = theLast; DeletePartialMatches(deletedMatches,0); tempMatch = listOfMatchedPatterns->next; rtn_struct(patternMatch,listOfMatchedPatterns); listOfMatchedPatterns = tempMatch; } /*=========================================*/ /* Filter new partial matches generated by */ /* retraction through the join network. */ /*=========================================*/ DriveRetractions(); } /***************************************************************//* PosEntryRetract: Handles retract for a join of a rule with *//* a positive pattern when the retraction is starting from *//* the RHS of that join (empty or positive LHS entry, *//* positive RHS entry), or the LHS of that join (positive *//* LHS entry, negative or positive RHS entry). *//***************************************************************/globle VOID PosEntryRetract(join,theAlphaNode,theMatch,position,duringRetract) struct joinNode *join; struct alphaMatch *theAlphaNode; struct partialMatch *theMatch; int position; int duringRetract; { struct partialMatch *deletedMatches; struct joinNode *joinPtr; struct partialMatch *theLast; while (join != NULL) { /*=========================================*/ /* Remove the bindings from this join that */ /* contain the fact to be retracted. */ /*=========================================*/ if (join->beta == NULL) return; /* optimize */ join->beta = RemovePartialMatches(theAlphaNode,join->beta,&deletedMatches, position,&theLast); /*===================================================*/ /* If no facts were deleted at this join, then there */ /* is no need to check joins at a lower level. */ /*===================================================*/ if (deletedMatches == NULL) return; /*==================================================*/ /* If there is more than one join below this join, */ /* then recursively remove fact bindings from all */ /* but one of the lower joins. Remove the bindings */ /* from the other join through this loop. */ /*==================================================*/ joinPtr = join->nextLevel; if (joinPtr == NULL) { DeletePartialMatches(deletedMatches,1); return; } if (((struct joinNode *) (joinPtr->rightSideEntryStructure)) == join) { theMatch = deletedMatches; while (theMatch != NULL) { NegEntryRetract(joinPtr,theMatch,duringRetract); theMatch = theMatch->next; } DeletePartialMatches(deletedMatches,1); return; } DeletePartialMatches(deletedMatches,1); while (joinPtr->rightDriveNode != NULL) { PosEntryRetract(joinPtr,theAlphaNode,theMatch,position,duringRetract); joinPtr = joinPtr->rightDriveNode; } join = joinPtr; } }/*****************************************************************//* NegEntryRetract: Handles retract for a join of a rule with a *//* not CE when the retraction is process from the RHS of that *//* join. *//*****************************************************************/VOID NegEntryRetract(theJoin,theMatch,duringRetract) struct joinNode *theJoin; struct partialMatch *theMatch; int duringRetract; { struct partialMatch *theLHS; int result; struct rdriveinfo *tempDR; struct alphaMatch *tempAlpha; struct joinNode *listOfJoins; /*===============================================*/ /* Loop through all LHS partial matches checking */ /* for sets that satisfied the join expression. */ /*===============================================*/ for (theLHS = theJoin->beta; theLHS != NULL; theLHS = theLHS->next) { /*===========================================================*/ /* Don't bother checking partial matches that are satisfied. */ /* We're looking for joins from which the removal of a */ /* partial match would satisfy the join. */ /*===========================================================*/ if (theLHS->counterf == CLIPS_FALSE) continue;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -