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 + -
显示快捷键?