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

📄 rulebld.c

📁 clips源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
   /*******************************************************/   /*      "C" Language Integrated Production System      */   /*                                                     */   /*             CLIPS Version 6.30  10/19/06            */   /*                                                     */   /*                  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:                                         *//*                                                           *//*      6.24: Removed INCREMENTAL_RESET compilation flag.    *//*                                                           *//*            Corrected code to remove compiler warnings.    *//*                                                           *//*      6.30: Added support for hashed alpha memories.       *//*                                                           *//*************************************************************/#define _RULEBLD_SOURCE_#include "setup.h"#if DEFRULE_CONSTRUCT && (! RUN_TIME) && (! BLOAD_ONLY)#include <stdio.h>#define _STDIO_INCLUDED_#include <stdlib.h>#include "constant.h"#include "envrnmnt.h"#include "constrct.h"#include "drive.h"#include "incrrset.h"#include "memalloc.h"#include "pattern.h"#include "reteutil.h"#include "router.h"#include "rulebld.h"#include "watch.h"/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/   static struct joinNode        *FindShareableJoin(struct joinLink *,struct joinNode *,intBool,void *,unsigned,unsigned,                                                    unsigned,unsigned,struct expr *,struct expr *,                                                    struct expr *,struct expr *);   static int                     TestJoinForReuse(struct joinNode *,unsigned,unsigned,                                                   unsigned,unsigned,struct expr *,struct expr *,                                                   struct expr *,struct expr *);   static struct joinNode        *CreateNewJoin(void *,struct expr *,struct expr *,struct joinNode *,void *,                                                int,int,int,struct expr *,struct expr *);   static void                    AttachTestCEsToPatternCEs(void *,struct lhsParseNode *);/****************************************************************//* ConstructJoins: Integrates a set of pattern and join tests   *//*   associated with a rule into the pattern and join networks. *//****************************************************************/globle struct joinNode *ConstructJoins(  void *theEnv,  int logicalJoin,  struct lhsParseNode *theLHS,  int startDepth)  {   struct joinNode *lastJoin = NULL;   struct patternNodeHeader *lastPattern;   unsigned firstJoin = TRUE;   int tryToReuse = TRUE;   struct joinNode *listOfJoins = NULL;   struct joinNode *oldJoin;   int joinNumber = 1;   int isLogical, isExists;   struct joinNode *lastRightJoin;   int lastIteration = FALSE;   int rhsType;   struct expr *leftHash, *rightHash;   void *rhsStruct;   struct lhsParseNode *nextLHS;   struct expr *networkTest, *secondaryNetworkTest, *secondaryExternalTest;   int joinFromTheRight;   struct joinLink *theLinks;   intBool useLinks;   /*===================================================*/   /* Remove any test CEs from the LHS and attach their */   /* expression to the closest preceeding non-negated  */   /* join at the same not/and depth.                   */   /*===================================================*/   if (startDepth == 1)     { AttachTestCEsToPatternCEs(theEnv,theLHS); }   if (theLHS == NULL)     {      lastJoin = FindShareableJoin(DefruleData(theEnv)->RightPrimeJoins,NULL,TRUE,NULL,TRUE,                                   FALSE,FALSE,FALSE,NULL,NULL,NULL,NULL);                                              if (lastJoin == NULL)        { lastJoin = CreateNewJoin(theEnv,NULL,NULL,NULL,NULL,FALSE,FALSE,FALSE,NULL,NULL); }     }   /*=====================================================*/   /* 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)     {      /*======================================================*/      /* Find the beginning of the next group of patterns. If */      /* the current pattern is not the beginning of a "join  */      /* from the right" group of patterns, then the next     */      /* pattern is the next pattern. Otherwise skip over all */      /* the patterns that belong to the group of subjoins.   */      /*======================================================*/                   nextLHS = theLHS->bottom;      secondaryExternalTest = NULL;      if (theLHS->endNandDepth > startDepth)        {         while ((nextLHS != NULL) &&                (nextLHS->endNandDepth > startDepth))           { nextLHS = nextLHS->bottom; }                  /*====================================================*/         /* Variable nextLHS is now pointing to the end of the */         /* not/and group beginning with variable theLHS. If   */          /* the end depth of the group is less than the depth  */         /* of the current enclosing not/and group, then this  */         /* is the last iteration for the enclosing group.     */         /*====================================================*/                    if (nextLHS != NULL)           {            if (nextLHS->endNandDepth < startDepth)              { lastIteration = TRUE; }           }                    if (nextLHS != NULL)           { nextLHS = nextLHS->bottom; }                    if ((nextLHS != NULL) && (nextLHS->type == TEST_CE))           {             secondaryExternalTest = nextLHS->networkTest;            nextLHS = nextLHS->bottom;            }        }             /*=======================================*/      /* Is this the last pattern to be added? */      /*=======================================*/            if (nextLHS == NULL)        { lastIteration = TRUE; }      else if (theLHS->endNandDepth < startDepth)        { lastIteration = TRUE; }       else if ((nextLHS->type == TEST_CE) &&               (theLHS->beginNandDepth > startDepth) &&               (nextLHS->endNandDepth < startDepth))        { lastIteration = TRUE; }       /*===============================================*/      /* If the pattern is a join from the right, then */      /* construct the subgroup of patterns and use    */      /* that as the RHS of the join to be added.      */      /*===============================================*/                                               if (theLHS->beginNandDepth > startDepth)        {         joinFromTheRight = TRUE;         isExists = theLHS->existsNand;         lastRightJoin = ConstructJoins(theEnv,logicalJoin,theLHS,startDepth+1);                    rhsStruct = lastRightJoin;         rhsType = 0;         lastPattern = NULL;         networkTest = theLHS->externalNetworkTest; /* TBD */         secondaryNetworkTest = secondaryExternalTest;         leftHash = theLHS->externalLeftHash;         rightHash = theLHS->externalRightHash;        }               /*=======================================================*/      /* Otherwise, add the pattern to the appropriate pattern */      /* network and use the pattern node containing the alpha */      /* memory as the RHS of the join to be added.            */      /*=======================================================*/            else if (theLHS->right == NULL)        {         joinFromTheRight = FALSE;         rhsType = 0;         lastPattern = NULL;         rhsStruct = NULL;         lastRightJoin = NULL;         isExists = theLHS->exists;         networkTest = theLHS->networkTest;         secondaryNetworkTest = theLHS->secondaryNetworkTest;         leftHash = NULL;         rightHash = NULL;        }      else        {         joinFromTheRight = FALSE;         rhsType = theLHS->patternType->positionInArray;         lastPattern = (*theLHS->patternType->addPatternFunction)(theEnv,theLHS);         rhsStruct = lastPattern;         lastRightJoin = NULL;         isExists = theLHS->exists;         networkTest = theLHS->networkTest;         secondaryNetworkTest = theLHS->secondaryNetworkTest;         leftHash = theLHS->leftHash;         rightHash = theLHS->rightHash;        }            /*======================================================*/      /* Determine if the join being added is a logical join. */      /*======================================================*/      if ((startDepth == 1) && (joinNumber == logicalJoin)) isLogical = TRUE;      else isLogical = FALSE;      /*===============================================*/      /* Get the list of joins which could potentially */      /* be reused in place of the join being added.   */      /*===============================================*/      useLinks = TRUE;      if (firstJoin == TRUE)        {          if (theLHS->right == NULL)           { theLinks = DefruleData(theEnv)->RightPrimeJoins; }         else if (lastPattern != NULL)           {             listOfJoins = lastPattern->entryJoin;            theLinks = NULL;            useLinks = FALSE;           }         else           { theLinks = lastRightJoin->nextLinks; }        }      else        { theLinks = lastJoin->nextLinks; }      /*=======================================================*/      /* Determine if the next join to be added can be shared. */      /*=======================================================*/      if ((tryToReuse == TRUE) &&          ((oldJoin = FindShareableJoin(theLinks,listOfJoins,useLinks,rhsStruct,firstJoin,

⌨️ 快捷键说明

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