📄 rulebld.c
字号:
/*******************************************************/ /* "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 + -