📄 factbld.c
字号:
/* 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 = FactData(theEnv)->CurrentDeftemplate->patternNetwork; if (FactData(theEnv)->CurrentDeftemplate->patternNetwork != NULL) { FactData(theEnv)->CurrentDeftemplate->patternNetwork->leftNode = newNode; } FactData(theEnv)->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( void *theEnv, struct patternNodeHeader *thePattern) { struct factPatternNode *patternPtr; struct factPatternNode *upperLevel; /*=====================================================*/ /* Get rid of any matches stored in the alpha memory. */ /*=====================================================*/ patternPtr = (struct factPatternNode *) thePattern; ClearPatternMatches(theEnv,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 = 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(theEnv,patternPtr,NULL); } else { if (upperLevel->header.selector) { RemoveHashedPatternNode(theEnv,upperLevel,patternPtr,patternPtr->networkTest->type,patternPtr->networkTest->value); } upperLevel->nextLevel = NULL; if (upperLevel->header.stopNode) upperLevel = NULL; } RemoveHashedExpression(theEnv,patternPtr->networkTest); RemoveHashedExpression(theEnv,patternPtr->header.rightHash); rtn_struct(theEnv,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; if ((patternPtr->lastLevel != NULL) && (patternPtr->lastLevel->header.selector)) { RemoveHashedPatternNode(theEnv,patternPtr->lastLevel,patternPtr,patternPtr->networkTest->type,patternPtr->networkTest->value); } upperLevel->leftNode->rightNode = upperLevel->rightNode; if (upperLevel->rightNode != NULL) { upperLevel->rightNode->leftNode = upperLevel->leftNode; } RemoveHashedExpression(theEnv,patternPtr->networkTest); RemoveHashedExpression(theEnv,patternPtr->header.rightHash); rtn_struct(theEnv,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(theEnv,patternPtr,patternPtr->rightNode); } else { if (upperLevel->header.selector) { RemoveHashedPatternNode(theEnv,upperLevel,patternPtr,patternPtr->networkTest->type,patternPtr->networkTest->value); } upperLevel->nextLevel = patternPtr->rightNode; } patternPtr->rightNode->leftNode = NULL; RemoveHashedExpression(theEnv,patternPtr->networkTest); RemoveHashedExpression(theEnv,patternPtr->header.rightHash); rtn_struct(theEnv,factPatternNode,patternPtr); upperLevel = NULL; } } }#endif/**************************************************************//* DestroyFactPatternNetwork: Deallocates the data structures *//* associated with a fact pattern network. *//**************************************************************/globle void DestroyFactPatternNetwork( void *theEnv, struct factPatternNode *thePattern) { struct factPatternNode *patternPtr; if (thePattern == NULL) return; while (thePattern != NULL) { patternPtr = thePattern->rightNode; DestroyFactPatternNetwork(theEnv,thePattern->nextLevel); DestroyAlphaMemory(theEnv,&thePattern->header,FALSE); if ((thePattern->lastLevel != NULL) && (thePattern->lastLevel->header.selector)) { RemoveHashedPatternNode(theEnv,thePattern->lastLevel,thePattern,thePattern->networkTest->type,thePattern->networkTest->value); }#if (! BLOAD_ONLY) && (! RUN_TIME) rtn_struct(theEnv,factPatternNode,thePattern);#endif thePattern = patternPtr; } } #if (! RUN_TIME) && (! BLOAD_ONLY) /***********************************************************//* 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( void *theEnv, struct factPatternNode *rootNode, struct factPatternNode *newRootNode) { struct deftemplate *theDeftemplate; struct defmodule *theModule; /*=======================================================*/ /* Save the current module since we will be changing it. */ /*=======================================================*/ SaveCurrentModule(theEnv); /*=======================================================*/ /* Loop through every module looking for the deftemplate */ /* associated with the specified root node. */ /*=======================================================*/ for (theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL); theModule != NULL; theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,theModule)) { /*======================================================*/ /* Set the current module to the module being examined. */ /*======================================================*/ EnvSetCurrentModule(theEnv,(void *) theModule); /*======================================================*/ /* Loop through every deftemplate in the current module */ /* searching for the deftemplate associated with the */ /* specified root node. */ /*======================================================*/ for (theDeftemplate = (struct deftemplate *) EnvGetNextDeftemplate(theEnv,NULL); theDeftemplate != NULL; theDeftemplate = (struct deftemplate *) EnvGetNextDeftemplate(theEnv,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(theEnv); 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(theEnv); }/***************************************************************//* 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( void *theEnv, struct factPatternNode *patternPtr) { struct fact *theFact; struct patternMatch *lastMatch, *theMatch; /*===========================================*/ /* Loop through every fact in the fact list. */ /*===========================================*/ for (theFact = (struct fact *) EnvGetNextFact(theEnv,NULL); theFact != NULL; theFact = (struct fact *) EnvGetNextFact(theEnv,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(theEnv,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(theEnv,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 + -