⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rulebld.c

📁 NASA 开发使用的一个专家系统
💻 C
📖 第 1 页 / 共 2 页
字号:
   /*******************************************************/   /*      "C" Language Integrated Production System      */   /*                                                     */   /*             CLIPS Version 6.05  04/09/97            */   /*                                                     */   /*                  RULE BUILD MODULE                  */   /*******************************************************//*************************************************************//* Purpose: Provides routines to ntegrates a set of pattern  *//*   and join tests associated with a rule into the pattern  *//*   and join networks. The joins are integrated into the    *//*   join network by routines in this module. The pattern    *//*   is integrated by calling the external routine           *//*   associated with the pattern parser that originally      *//*   parsed the pattern.                                     *//*                                                           *//* Principal Programmer(s):                                  *//*      Gary D. Riley                                        *//*                                                           *//* Contributing Programmer(s):                               *//*                                                           *//* Revision History:                                         *//*                                                           *//*************************************************************/#define _RULEBLD_SOURCE_#include "setup.h"#if DEFRULE_CONSTRUCT && (! RUN_TIME) && (! BLOAD_ONLY)#include <stdio.h>#define _CLIPS_STDIO_#include "constant.h"#include "clipsmem.h"#include "router.h"#include "watch.h"#include "constrct.h"#include "drive.h"#include "pattern.h"#include "reteutil.h"#include "incrrset.h"#include "rulebld.h"/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/#if ANSI_COMPILER   static struct joinNode        *FindShareableJoin(struct joinNode *,VOID *,int,int,int,                                                    struct expr *,                                                    int,int,int,struct joinNode **);   static int                     TestJoinForReuse(struct joinNode *,int,int,int,                                                   struct expr *,                                                   int,int,int,struct joinNode **);   static struct joinNode        *CreateNewJoin(struct expr *,                                                struct joinNode *,VOID *,int,int);   static VOID                    AttachTestCEsToPatternCEs(struct lhsParseNode *);                                           #else   static struct joinNode        *FindShareableJoin();   static int                     TestJoinForReuse();   static struct joinNode        *CreateNewJoin();   static VOID                    AttachTestCEsToPatternCEs(); #endif  /****************************************************************//* ConstructJoins: Integrates a set of pattern and join tests   *//*   associated with a rule into the pattern and join networks. *//****************************************************************/globle struct joinNode *ConstructJoins(logicalJoin,theLHS)  int logicalJoin;  struct lhsParseNode *theLHS;  {   struct joinNode *lastJoin = NULL;   struct patternNodeHeader *lastPattern;   int firstJoin = CLIPS_TRUE;   int tryToReuse = CLIPS_TRUE;   struct joinNode *listOfJoins;   struct joinNode *oldJoin;   int joinNumber = 1;   int isLogical;   struct joinNode *nandReconnect[32];   int currentDepth = 1;   int lastIteration = CLIPS_FALSE;   int rhsType;   int endDepth;      /*===================================================*/   /* Remove any test CEs from the LHS and attach their */   /* expression to the closest preceeding non-negated  */   /* join at the same not/and depth.                   */   /*===================================================*/      AttachTestCEsToPatternCEs(theLHS);        /*=====================================================*/   /* Process each pattern CE in the rule. At this point, */   /* there should be no and/or/not/test CEs in the LHS.  */   /*=====================================================*/      while (theLHS != NULL)     {      if (theLHS->bottom == NULL) lastIteration = CLIPS_TRUE;            /*==================================================*/      /* If the pattern is the start of a new not/and CE, */      /* then remember the join to reconnect to after the */      /* join from the right is completed.                */      /*==================================================*/            while (theLHS->beginNandDepth > currentDepth)        {         nandReconnect[currentDepth-1] = lastJoin;         currentDepth++;        }            /*============================================================*/      /* Add the next pattern for this rule to the pattern network. */      /*============================================================*/              rhsType = theLHS->patternType->positionInArray;      lastPattern = (*theLHS->patternType->addPatternFunction)(theLHS);            /*======================================================*/      /* Determine if the join being added is a logical join. */      /*======================================================*/            if (joinNumber == logicalJoin) isLogical = CLIPS_TRUE;      else isLogical = CLIPS_FALSE;            /*===============================================*/        /* Get the list of joins which could potentially */      /* be reused in place of the join being added.   */      /*===============================================*/              if (firstJoin == CLIPS_TRUE)        { listOfJoins = lastPattern->entryJoin; }      else        { listOfJoins = lastJoin->nextLevel; }              /*=======================================================*/      /* Determine if the next join to be added can be shared. */      /*=======================================================*/      endDepth = theLHS->endNandDepth;      if ((tryToReuse == CLIPS_TRUE) &&          ((oldJoin = FindShareableJoin(listOfJoins,(VOID *) lastPattern,firstJoin,                                        (int) theLHS->negated,isLogical,                                        theLHS->networkTest,                                        endDepth,currentDepth,                                        lastIteration,nandReconnect)) != NULL) )        {#if DEBUGGING_FUNCTIONS         if ((GetWatchItem("compilations") == CLIPS_TRUE) && GetPrintWhileLoading())           { PrintCLIPS(WDIALOG,"=j"); }#endif         lastJoin = oldJoin;        }      else        {         tryToReuse = CLIPS_FALSE;         lastJoin = CreateNewJoin(theLHS->networkTest,                                  lastJoin,lastPattern,                                  CLIPS_FALSE,(int) theLHS->negated);         lastJoin->rhsType = rhsType;        }      /*==========================================================*/      /* Create any joins from the right needed to handle not/and */      /* CE combinations and connect them to the join network.    */      /*==========================================================*/            while (endDepth < currentDepth)        {         currentDepth--;                    if (lastJoin->nextLevel == NULL) tryToReuse = CLIPS_FALSE;              if (tryToReuse)           { #if DEBUGGING_FUNCTIONS            if ((GetWatchItem("compilations") == CLIPS_TRUE) && GetPrintWhileLoading())              { PrintCLIPS(WDIALOG,"=j"); }#endif            lastJoin = lastJoin->nextLevel;           }         else           {            lastJoin = CreateNewJoin(NULL,nandReconnect[currentDepth-1],                                     lastJoin,CLIPS_TRUE,CLIPS_FALSE);           }        }              /*=======================================*/      /* Move on to the next join to be added. */      /*=======================================*/      theLHS = theLHS->bottom;      joinNumber++;      firstJoin = CLIPS_FALSE;     }   /*===================================================*/   /* If compilations are being watched, put a carriage */   /* return after all of the =j's and +j's             */   /*===================================================*/   #if DEBUGGING_FUNCTIONS   if ((GetWatchItem("compilations") == CLIPS_TRUE) && GetPrintWhileLoading())     { PrintCLIPS(WDIALOG,"\n"); }#endif   /*=============================*/   /* Return the last join added. */   /*=============================*/      return(lastJoin);  }  /****************************************************************//* AttachTestCEsToPatternCEs: Attaches the expressions found in *//*   test CEs to the closest preceeding pattern CE that is not  *//*   negated and is at the same not/and depth.                  *//****************************************************************/static VOID AttachTestCEsToPatternCEs(theLHS)  struct lhsParseNode *theLHS;  {   struct lhsParseNode *lastNode, *trackNode, *tempNode;      /*===============================================*/   /* Look at each pattern on the rule's LHS to see */   /* if any test CEs should be attached to it.     */   /*===============================================*/      while (theLHS != NULL)     {      /*==============================================*/      /* If the pattern is negated, then don't bother */      /* looking for any test CEs to attach to it.    */      /*==============================================*/            if (theLHS->negated)        { trackNode = NULL; }      else        {         lastNode = theLHS;         trackNode = theLHS->bottom;        }              /*=================================================*/      /* Check all of the patterns following the current */      /* pattern to check for test CEs which can be      */      /* attached to the current pattern.                */      /*=================================================*/            while (trackNode != NULL)        {         /*=======================================================*/         /* Skip over any CEs that have a higher not/and depth or */         /* are negated since any test CEs found within these CEs */         /* would be attached to another pattern with the same    */         /* depth, rather than the current pattern.               */         /*=======================================================*/                  if ((trackNode->beginNandDepth != theLHS->beginNandDepth) ||             (trackNode->negated))           {            lastNode = trackNode;            trackNode = trackNode->bottom;           }                    /*======================================================*/         /* Once a non-negated pattern has been encounted at the */         /* same not/and depth as the current pattern, then stop */         /* because any test CEs following this pattern would be */         /* attached to it rather than the current pattern.      */         /*======================================================*/                  else if (trackNode->type == PATTERN_CE)           { trackNode = NULL; }                    /*==================================================*/         /* A test CE encountered at the same not/and depth  */         /* can be added to the network test expressions for */          /* the currentpattern.                              */         /*==================================================*/                  else if (trackNode->type == TEST_CE)           {            theLHS->networkTest = CombineExpressions(theLHS->networkTest,                                                     trackNode->networkTest);            trackNode->networkTest = NULL;            tempNode = trackNode->bottom;            trackNode->bottom = NULL;            lastNode->bottom = tempNode;            lastNode->endNandDepth = trackNode->endNandDepth;            ReturnLHSParseNodes(trackNode);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -