ruledlt.c
来自「clips源代码」· C语言 代码 · 共 576 行 · 第 1/2 页
C
576 行
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.30 10/19/06 */ /* */ /* RULE DELETION MODULE */ /*******************************************************//*************************************************************//* Purpose: Provides routines for deleting a rule including *//* freeing the defrule data structures and removing the *//* appropriate joins from the join network. *//* *//* Principal Programmer(s): *//* Gary D. Riley *//* *//* Contributing Programmer(s): *//* *//* Revision History: *//* *//* 6.24: Removed DYNAMIC_SALIENCE compilation flag. *//* *//* Renamed BOOLEAN macro type to intBool. *//* *//* 6.30: Added support for hashed alpha memories. *//* *//*************************************************************/#define _RULEDLT_SOURCE_#include "setup.h"#if DEFRULE_CONSTRUCT#include <stdio.h>#define _STDIO_INCLUDED_#include <string.h>#include "memalloc.h"#include "engine.h"#include "envrnmnt.h"#include "reteutil.h"#include "pattern.h"#include "agenda.h"#include "drive.h"#include "retract.h"#include "constrct.h"#if BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE#include "bload.h"#endif#include "ruledlt.h"/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/#if (! RUN_TIME) && (! BLOAD_ONLY) static void RemoveIntranetworkLink(void *,struct joinNode *);#endif static void DetachJoins(void *,struct joinNode *,intBool); static void DetachJoinsDriver(void *,struct defrule *,intBool);/**********************************************************************//* ReturnDefrule: Returns a defrule data structure and its associated *//* data structures to the memory manager. Note that the first *//* disjunct of a rule is the only disjunct which allocates storage *//* for the rule's dynamic salience and pretty print form (so these *//* are only deallocated for the first disjunct). *//**********************************************************************/globle void ReturnDefrule( void *theEnv, void *vWaste) {#if (MAC_MCW || IBM_MCW) && (RUN_TIME || BLOAD_ONLY)#pragma unused(theEnv,vWaste)#endif#if (! RUN_TIME) && (! BLOAD_ONLY) struct defrule *waste = (struct defrule *) vWaste; int first = TRUE; struct defrule *nextPtr; if (waste == NULL) return; /*======================================*/ /* If a rule is redefined, then we want */ /* to save its breakpoint status. */ /*======================================*/#if DEBUGGING_FUNCTIONS DefruleData(theEnv)->DeletedRuleDebugFlags = 0; if (waste->afterBreakpoint) BitwiseSet(DefruleData(theEnv)->DeletedRuleDebugFlags,0); if (waste->watchActivation) BitwiseSet(DefruleData(theEnv)->DeletedRuleDebugFlags,1); if (waste->watchFiring) BitwiseSet(DefruleData(theEnv)->DeletedRuleDebugFlags,2);#endif /*================================*/ /* Clear the agenda of all the */ /* activations added by the rule. */ /*================================*/ ClearRuleFromAgenda(theEnv,waste); /*======================*/ /* Get rid of the rule. */ /*======================*/ while (waste != NULL) { /*================================================*/ /* Remove the rule's joins from the join network. */ /*================================================*/ DetachJoinsDriver(theEnv,waste,FALSE); /*=============================================*/ /* If this is the first disjunct, get rid of */ /* the dynamic salience and pretty print form. */ /*=============================================*/ if (first) { if (waste->dynamicSalience != NULL) { ExpressionDeinstall(theEnv,waste->dynamicSalience); ReturnPackedExpression(theEnv,waste->dynamicSalience); waste->dynamicSalience = NULL; } if (waste->header.ppForm != NULL) { rm(theEnv,waste->header.ppForm,strlen(waste->header.ppForm) + 1); waste->header.ppForm = NULL; } first = FALSE; } /*===========================*/ /* Get rid of any user data. */ /*===========================*/ if (waste->header.usrData != NULL) { ClearUserDataList(theEnv,waste->header.usrData); } /*===========================================*/ /* Decrement the count for the defrule name. */ /*===========================================*/ DecrementSymbolCount(theEnv,waste->header.name); /*========================================*/ /* Get rid of the the rule's RHS actions. */ /*========================================*/ if (waste->actions != NULL) { ExpressionDeinstall(theEnv,waste->actions); ReturnPackedExpression(theEnv,waste->actions); } /*===============================*/ /* Move on to the next disjunct. */ /*===============================*/ nextPtr = waste->disjunct; rtn_struct(theEnv,defrule,waste); waste = nextPtr; } /*==========================*/ /* Free up partial matches. */ /*==========================*/ if (EngineData(theEnv)->ExecutingRule == NULL) FlushGarbagePartialMatches(theEnv);#endif }/********************************************************//* DestroyDefrule: Action used to remove defrules *//* as a result of DestroyEnvironment. *//********************************************************/globle void DestroyDefrule( void *theEnv, void *vTheDefrule) { struct defrule *theDefrule = (struct defrule *) vTheDefrule; struct defrule *nextDisjunct; int first = TRUE; if (theDefrule == NULL) return; while (theDefrule != NULL) { DetachJoinsDriver(theEnv,theDefrule,TRUE); if (first) {#if (! BLOAD_ONLY) && (! RUN_TIME) if (theDefrule->dynamicSalience != NULL) { ReturnPackedExpression(theEnv,theDefrule->dynamicSalience); } if (theDefrule->header.ppForm != NULL) { rm(theEnv,theDefrule->header.ppForm,strlen(theDefrule->header.ppForm) + 1); }#endif first = FALSE; } if (theDefrule->header.usrData != NULL) { ClearUserDataList(theEnv,theDefrule->header.usrData); } #if (! BLOAD_ONLY) && (! RUN_TIME) if (theDefrule->actions != NULL) { ReturnPackedExpression(theEnv,theDefrule->actions); }#endif nextDisjunct = theDefrule->disjunct; #if (! BLOAD_ONLY) && (! RUN_TIME) rtn_struct(theEnv,defrule,theDefrule);#endif theDefrule = nextDisjunct; } }/**********************************************************************//* DetachJoinsDriver: *//**********************************************************************/static void DetachJoinsDriver( void *theEnv, struct defrule *theRule, intBool destroy) { struct joinNode *join; /*==================================*/ /* Find the last join for the rule. */ /*==================================*/ join = theRule->lastJoin; theRule->lastJoin = NULL; if (join == NULL) return; /*===================================================*/ /* Remove the activation link from the last join. If */ /* there are joins below this join, then all of the */ /* joins for this rule were shared with another rule */ /* and thus no joins can be deleted. */ /*===================================================*/ join->ruleToActivate = NULL; if (join->nextLinks != NULL) return; DetachJoins(theEnv,join,destroy); } /**********************************************************************//* DetachJoins: Removes a join node and all of its parent nodes from *//* the join network. Nodes are only removed if they are no required *//* by other rules (the same join can be shared by multiple rules). *//* Any partial matches associated with the join are also removed. *//* A rule's joins are typically removed by removing the bottom most *//* join used by the rule and then removing any parent joins which *//* are not shared by other rules. *//**********************************************************************/static void DetachJoins( void *theEnv, struct joinNode *join, intBool destroy) { struct joinNode *prevJoin, *rightJoin; struct joinLink *lastLink, *theLink; int lastMark; /*===========================*/ /* Begin removing the joins. */ /*===========================*/ while (join != NULL) { if (join->marked) return; /*==========================================================*/ /* Remember the join "above" this join (the one that enters */ /* from the left). If the join is entered from the right by */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?