📄 factbld.c
字号:
/*=====================================================*/ /* If there is an upper level above the new node, then */ /* place the new node as the first child in the upper */ /* level's nextLevel (child) link. */ /*=====================================================*/ if (upperLevel != NULL) { newNode->rightNode = upperLevel->nextLevel; if (upperLevel->nextLevel != NULL) { upperLevel->nextLevel->leftNode = newNode; } upperLevel->nextLevel = newNode; return(newNode); } /*=====================================================*/ /* Since there is no upper level above the new node, */ /* (i.e. the new node is being added to the highest */ /* level in the pattern network), the new node becomes */ /* the first node visited in the pattern network. */ /*=====================================================*/ newNode->rightNode = CurrentDeftemplate->patternNetwork; if (CurrentDeftemplate->patternNetwork != NULL) { CurrentDeftemplate->patternNetwork->leftNode = newNode; } CurrentDeftemplate->patternNetwork = newNode; return(newNode); }/*************************************************************//* DetachFactPattern: Removes a pattern node and all of its *//* parent nodes from the pattern network. Nodes are only *//* removed if they are no longer shared (i.e. a pattern *//* node that has more than one child node is shared). A *//* pattern from a rule is typically removed by removing *//* the bottom most pattern node used by the pattern and *//* then removing any parent nodes which are not shared by *//* other patterns. *//* *//* Example: *//* Patterns (a b c d) and (a b e f) would be represented *//* by the pattern net shown on the left. If (a b c d) *//* was detached, the resultant pattern net would be the *//* one shown on the right. *//* *//* a a *//* | | *//* b b *//* | | *//* c--e e *//* | | | *//* d f f *//* *//*************************************************************/static VOID DetachFactPattern(thePattern) struct patternNodeHeader *thePattern; { struct factPatternNode *patternPtr; struct factPatternNode *upperLevel; /*=====================================================*/ /* Get rid of any matches stored in the alpha memory. */ /*=====================================================*/ patternPtr = (struct factPatternNode *) thePattern; ClearPatternMatches(patternPtr); /*=====================================================*/ /* If there are no joins entered from this pattern, then */ /* the pattern node is no longer a stop node. Also if */ /* the pattern has a next level pointer, then it can */ /* not be removed since other patterns make use of it. */ /*=====================================================*/ if (patternPtr->header.entryJoin == NULL) patternPtr->header.stopNode = CLIPS_FALSE; if (patternPtr->nextLevel != NULL) return; /*==============================================================*/ /* Loop until all appropriate pattern nodes have been detached. */ /*==============================================================*/ upperLevel = patternPtr; while (upperLevel != NULL) { if ((upperLevel->leftNode == NULL) && (upperLevel->rightNode == NULL)) { /*===============================================*/ /* Pattern node is the only node on this level. */ /* Remove it and continue detaching other nodes */ /* above this one, because no other patterns are */ /* dependent upon this node. */ /*===============================================*/ patternPtr = upperLevel; upperLevel = patternPtr->lastLevel; if (upperLevel == NULL) { FindAndSetDeftemplatePatternNetwork(patternPtr,NULL); } else { upperLevel->nextLevel = NULL; if (upperLevel->header.stopNode) upperLevel = NULL; } RemoveHashedExpression(patternPtr->networkTest); rtn_struct(factPatternNode,patternPtr); } else if (upperLevel->leftNode != NULL) { /*====================================================*/ /* Pattern node has another pattern node which must */ /* be checked preceding it. Remove the pattern node, */ /* but do not detach any nodes above this one. */ /*====================================================*/ patternPtr = upperLevel; upperLevel->leftNode->rightNode = upperLevel->rightNode; if (upperLevel->rightNode != NULL) { upperLevel->rightNode->leftNode = upperLevel->leftNode; } RemoveHashedExpression(patternPtr->networkTest); rtn_struct(factPatternNode,patternPtr); upperLevel = NULL; } else { /*====================================================*/ /* Pattern node has no pattern node preceding it, but */ /* does have one succeeding it. Remove the pattern */ /* node, but do not detach any nodes above this one. */ /*====================================================*/ patternPtr = upperLevel; upperLevel = upperLevel->lastLevel; if (upperLevel == NULL) { FindAndSetDeftemplatePatternNetwork(patternPtr,patternPtr->rightNode); } else { upperLevel->nextLevel = patternPtr->rightNode; } patternPtr->rightNode->leftNode = NULL; RemoveHashedExpression(patternPtr->networkTest); rtn_struct(factPatternNode,patternPtr); upperLevel = NULL; } } } /***********************************************************//* FindAndSetDeftemplatePatternNetwork: When a deftemplate *//* pattern is detached from the fact pattern network, it *//* is not possible to directly detach the link from the *//* deftemplate to the pattern network (it is a one way *//* link). Therefore if the top most pointer to a *//* deftemplates pattern network must be changed, it is *//* necessary to search the list of deftemplates to find *//* the appropriate one to modify. *//***********************************************************/static VOID FindAndSetDeftemplatePatternNetwork(rootNode,newRootNode) struct factPatternNode *rootNode; struct factPatternNode *newRootNode; { struct deftemplate *theDeftemplate; struct defmodule *theModule; /*=======================================================*/ /* Save the current module since we will be changing it. */ /*=======================================================*/ SaveCurrentModule(); /*=======================================================*/ /* Loop through every module looking for the deftemplate */ /* associated with the specified root node. */ /*=======================================================*/ for (theModule = (struct defmodule *) GetNextDefmodule(NULL); theModule != NULL; theModule = (struct defmodule *) GetNextDefmodule(theModule)) { /*======================================================*/ /* Set the current module to the module being examined. */ /*======================================================*/ SetCurrentModule((VOID *) theModule); /*======================================================*/ /* Loop through every deftemplate in the current module */ /* searching for the deftemplate associated with the */ /* specified root node. */ /*======================================================*/ for (theDeftemplate = (struct deftemplate *) GetNextDeftemplate(NULL); theDeftemplate != NULL; theDeftemplate = (struct deftemplate *) GetNextDeftemplate(theDeftemplate)) { /*===========================================================*/ /* When the associated deftemplate is found, change its root */ /* node from the current value to the new value. Restore the */ /* current module before leaving this routine. */ /*===========================================================*/ if (theDeftemplate->patternNetwork == rootNode) { RestoreCurrentModule(); theDeftemplate->patternNetwork = newRootNode; return; } } } /*========================================================*/ /* If the deftemplate wasn't found, then we're presumably */ /* we're in the the middle of a clear and the deftemplate */ /* has already been deleted so there's no need to update */ /* the links to the fact pattern network. */ /*========================================================*/ RestoreCurrentModule(); } /***************************************************************//* ClearPatternMatches: Clears the fact list of all pointers *//* which point to a specific pattern. The pointers are used *//* to remember which patterns were matched by a fact to *//* make retraction easier. When a rule is excised, the *//* pointers need to be removed. *//***************************************************************/static VOID ClearPatternMatches(patternPtr) struct factPatternNode *patternPtr; { struct fact *theFact; struct patternMatch *lastMatch, *theMatch; /*===========================================*/ /* Loop through every fact in the fact list. */ /*===========================================*/ for (theFact = (struct fact *) GetNextFact(NULL); theFact != NULL; theFact = (struct fact *) GetNextFact(theFact)) { /*========================================*/ /* Loop through every match for the fact. */ /*========================================*/ lastMatch = NULL; theMatch = (struct patternMatch *) theFact->list; while (theMatch != NULL) { /*================================================*/ /* If the match is for the pattern being deleted, */ /* then remove the match. */ /*================================================*/ if (theMatch->matchingPattern == (struct patternNodeHeader *) patternPtr) { if (lastMatch == NULL) { /*=====================================*/ /* Remove the first match of the fact. */ /*=====================================*/ theFact->list = (VOID *) theMatch->next; rtn_struct(patternMatch,theMatch); theMatch = (struct patternMatch *) theFact->list; } else { /*===================================*/ /* Remove a match for the fact which */ /* follows the first match. */ /*===================================*/ lastMatch->next = theMatch->next; rtn_struct(patternMatch,theMatch); theMatch = lastMatch->next; } } /*====================================================*/ /* If the match is not for the pattern being deleted, */ /* then move on to the next match for the fact. */ /*====================================================*/ else { lastMatch = theMatch; theMatch = theMatch->next; } } } } #endif /* (! RUN_TIME) && (! BLOAD_ONLY) */ #endif /* DEFTEMPLATE_CONSTRUCT && DEFRULE_CONSTRUCT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -