📄 lgcldpnd.c
字号:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.05 04/09/97 */ /* */ /* LOGICAL DEPENDENCIES MODULE */ /*******************************************************//*************************************************************//* Purpose: Provide support routines for managing truth *//* maintenance using the logical conditional element. *//* *//* Principal Programmer(s): *//* Gary D. Riley *//* *//* Contributing Programmer(s): *//* *//* Revision History: *//* *//*************************************************************/#define _LGCLDPND_SOURCE_#include <stdio.h>#define _CLIPS_STDIO_#include "setup.h"#if DEFRULE_CONSTRUCT && LOGICAL_DEPENDENCIES#include "clipsmem.h"#include "router.h"#include "evaluatn.h"#include "engine.h"#include "reteutil.h"#include "pattern.h"#include "argacces.h"#include "factmngr.h"#if OBJECT_SYSTEM#include "insfun.h"#endif#include "lgcldpnd.h"/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/#if ANSI_COMPILER static struct partialMatch *FindLogicalBind(struct joinNode *,struct partialMatch *); static int FindEntityInPartialMatch(struct patternEntity *,struct partialMatch *); static struct dependency *DetachAssociatedDependencies(struct dependency *,VOID *);#if DEBUGGING_FUNCTIONS static VOID *GetFactOrInstanceArgument(DATA_OBJECT *,char *);#endif#else static struct partialMatch *FindLogicalBind(); static int FindEntityInPartialMatch(); static struct dependency *DetachAssociatedDependencies();#if DEBUGGING_FUNCTIONS static VOID *GetFactOrInstanceArgument();#endif#endif/***************************************//* LOCAL INTERNAL VARIABLE DEFINITIONS *//***************************************/ static struct dependency *UnsupportedDataEntities = NULL;/***********************************************************************//* AddLogicalDependencies: Adds the logical dependency links between a *//* data entity (such as a fact or instance) and the partial match *//* which logically supports that data entity. If a data entity is *//* unconditionally asserted (i.e. the global variable TheLogicalJoin *//* is NULL), then existing logical support for the data entity is no *//* longer needed and it is removed. If a data entity is already *//* unconditionally supported and that data entity is conditionally *//* asserted (i.e. the global variable TheLogicalJoin is not NULL), *//* then the logical support is ignored. Otherwise, the partial match *//* is linked to the data entity and the data entity is linked to the *//* partial match. Note that the word assert is used to refer to *//* creating a fact with the assert command and creating an instance *//* with the make-instance command. *//***********************************************************************/globle BOOLEAN AddLogicalDependencies(theEntity,existingEntity) struct patternEntity *theEntity; int existingEntity; { struct partialMatch *theBinds; struct dependency *newDependency; /*==============================================*/ /* If the rule has no logical patterns, then no */ /* dependencies have to be established. */ /*==============================================*/ if (TheLogicalJoin == NULL) { if (existingEntity) RemoveEntityDependencies(theEntity); return(CLIPS_TRUE); } else if (existingEntity && (theEntity->dependents == NULL)) { return(CLIPS_TRUE); } /*============================================================*/ /* Find the partial match in the logical join associated with */ /* activation partial match. If the partial match cannot be */ /* found, then the partial match must have been deleted by a */ /* previous RHS action and the dependency link should not be */ /* added. */ /*============================================================*/ theBinds = FindLogicalBind(TheLogicalJoin,GlobalLHSBinds); if (theBinds == NULL) return(CLIPS_FALSE); /*==============================================================*/ /* Add a dependency link between the partial match and the data */ /* entity. The dependency links are stored in the partial match */ /* behind the data entities stored in the partial match and the */ /* activation link, if any. */ /*==============================================================*/ newDependency = get_struct(dependency); newDependency->dPtr = (VOID *) theEntity; newDependency->next = (struct dependency *) theBinds->binds[theBinds->bcount + theBinds->activationf].gm.theValue; theBinds->binds[theBinds->bcount + theBinds->activationf].gm.theValue = (VOID *) newDependency; /*================================================================*/ /* Add a dependency link between the entity and the partialMatch. */ /*================================================================*/ newDependency = get_struct(dependency); newDependency->dPtr = (VOID *) theBinds; newDependency->next = (struct dependency *) theEntity->dependents; theEntity->dependents = (VOID *) newDependency; /*==================================================================*/ /* Return true to indicate that the data entity should be asserted. */ /*==================================================================*/ return(TRUE); }/************************************************************************//* FindLogicalBind: Finds the partial match associated with the logical *//* CE which will provide logical support for a data entity asserted *//* from the currently executing rule. The function is called when *//* creating logical support links between the data entity and *//* supporting partial matches. It compares each partial match found *//* at a specified join to the partial match associated with a rule *//* activation until it finds the partial match that generated the *//* rule activation. *//************************************************************************/static struct partialMatch *FindLogicalBind(theJoin,theBinds) struct joinNode *theJoin; struct partialMatch *theBinds; { struct partialMatch *compPtr; unsigned int i; int found; /*==================================*/ /* Loop through each of the partial */ /* matches in the beta memory. */ /*==================================*/ for (compPtr = theJoin->beta; compPtr != NULL; compPtr = compPtr->next) { /*==================================================*/ /* Compare each of the data entities in the partial */ /* match being examined and the partial match used */ /* in the dependency link. */ /*==================================================*/ found = CLIPS_TRUE; for (i = 0; i < compPtr->bcount; i++) { if (compPtr->binds[i].gm.theMatch != theBinds->binds[i].gm.theMatch) { found = CLIPS_FALSE; break; } } /*========================================================*/ /* If all of the data entities in the partial match are */ /* identical to the partial match in the dependency link, */ /* then this is the partial match we're looking for. */ /*========================================================*/ if (found) return(compPtr); } /*========================================*/ /* The partial match corresponding to the */ /* logical dependency couldn't be found. */ /*========================================*/ return(NULL); }/*********************************************************************//* RemoveEntityDependencies: Removes all logical support links from *//* a pattern entity that point to partial matches or other pattern *//* entities. Also removes the associated links from the partial *//* matches or pattern entities which point back to the pattern *//* entities. *//*********************************************************************/globle VOID RemoveEntityDependencies(theEntity) struct patternEntity *theEntity; { struct dependency *fdPtr, *nextPtr, *theList; struct partialMatch *theBinds; /*===============================*/ /* Get the list of dependencies. */ /*===============================*/ fdPtr = (struct dependency *) theEntity->dependents; /*========================================*/ /* Loop through each of the dependencies. */ /*========================================*/ while (fdPtr != NULL) { /*===============================*/ /* Remember the next dependency. */ /*===============================*/ nextPtr = fdPtr->next; /*================================================================*/ /* Remove the link between the data entity and the partial match. */ /*================================================================*/ theBinds = (struct partialMatch *) fdPtr->dPtr; theList = (struct dependency *) theBinds->binds[theBinds->bcount + theBinds->activationf].gm.theValue; theList = DetachAssociatedDependencies(theList,(VOID *) theEntity); theBinds->binds[theBinds->bcount + theBinds->activationf].gm.theValue = (VOID *) theList; /*========================*/ /* Return the dependency. */ /*========================*/ rtn_struct(dependency,fdPtr); /*=================================*/ /* Move on to the next dependency. */ /*=================================*/ fdPtr = nextPtr; } /*=====================================================*/ /* Set the dependency list of the data entity to NULL. */ /*=====================================================*/ theEntity->dependents = NULL; }/*******************************************************************//* DetachAssociatedDependencies: Removes all logical support links *//* which pointer to a pattern entity from a list of dependencies *//* (which may be associated with either a partial match or *//* another pattern entity). Does not remove links which point in *//* the other direction. *//*******************************************************************/static struct dependency *DetachAssociatedDependencies(theList,theEntity) struct dependency *theList; VOID *theEntity; { struct dependency *fdPtr, *nextPtr, *lastPtr = NULL; fdPtr = theList; while (fdPtr != NULL) { if (fdPtr->dPtr == theEntity) { nextPtr = fdPtr->next; if (lastPtr == NULL) theList = nextPtr; else lastPtr->next = nextPtr; rtn_struct(dependency,fdPtr); fdPtr = nextPtr; } else { lastPtr = fdPtr; fdPtr = fdPtr->next; } } return(theList); } /**************************************************************************//* RemovePMDependencies: Removes all logical support links from a partial *//* match that point to any data entities. Also removes the associated *//* links from the data entities which point back to the partial match. *//**************************************************************************/globle VOID RemovePMDependencies(theBinds) struct partialMatch *theBinds; { struct dependency *fdPtr, *nextPtr, *theList; struct patternEntity *theEntity; fdPtr = (struct dependency *) theBinds->binds[theBinds->bcount + theBinds->activationf].gm.theValue; while (fdPtr != NULL) { nextPtr = fdPtr->next; theEntity = (struct patternEntity *) fdPtr->dPtr; theList = (struct dependency *) theEntity->dependents; theList = DetachAssociatedDependencies(theList,(VOID *) theBinds); theEntity->dependents = (VOID *) theList; rtn_struct(dependency,fdPtr); fdPtr = nextPtr; } theBinds->binds[theBinds->bcount + theBinds->activationf].gm.theValue = NULL; }/************************************************************************//* RemoveLogicalSupport: Removes the dependency links between a partial *//* match and the data entities it logically supports. Also removes *//* the associated links from the data entities which point back to *//* the partial match by calling DetachAssociatedEntityDependencies. *//* If an entity has all of its logical support removed as a result of *//* this procedure, the dependency link from the partial match is *//* added to the list of unsupported data entities so that the entity *//* will be deleted as a result of losing its logical support. *//************************************************************************/globle VOID RemoveLogicalSupport(theBinds) struct partialMatch *theBinds; { struct dependency *dlPtr, *tempPtr, *theList; struct patternEntity *theEntity; /*========================================*/ /* If the partial match has no associated */ /* dependencies, then return. */ /*========================================*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -