📄 generate.c
字号:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.05 04/09/97 */ /* */ /* GENERATE MODULE */ /*******************************************************//*************************************************************//* Purpose: Provides routines for converting field *//* constraints to expressions which can be used *//* in the pattern and join networks. *//* *//* Principal Programmer(s): *//* Gary D. Riley *//* *//* Contributing Programmer(s): *//* *//* Revision History: *//* *//*************************************************************/#define _GENERATE_SOURCE_#include <stdio.h>#define _CLIPS_STDIO_#include "setup.h"#if (! RUN_TIME) && (! BLOAD_ONLY) && DEFRULE_CONSTRUCT#include "constant.h"#include "clipsmem.h"#include "symbol.h"#include "exprnpsr.h"#include "argacces.h"#include "extnfunc.h"#include "router.h"#include "ruledef.h"#include "pattern.h"#include "generate.h"#if DEFGLOBAL_CONSTRUCT#include "globlpsr.h"#endif/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/#if ANSI_COMPILER static VOID ExtractAnds(struct lhsParseNode *,int, struct expr **,struct expr **); static VOID ExtractFieldTest(struct lhsParseNode *,int, struct expr **,struct expr **); static struct expr *GetfieldReplace(struct lhsParseNode *); static struct expr *GenPNConstant(struct lhsParseNode *); static struct expr *GenJNConstant(struct lhsParseNode *); static struct expr *GenJNColon(struct lhsParseNode *); static struct expr *GenPNColon(struct lhsParseNode *); static struct expr *GenJNEq(struct lhsParseNode *); static struct expr *GenPNEq(struct lhsParseNode *); static struct expr *GenJNVariableComparison(struct lhsParseNode *, struct lhsParseNode *); static struct expr *GenPNVariableComparison(struct lhsParseNode *, struct lhsParseNode *); static int AllVariablesInPattern(struct lhsParseNode *, int); static int AllVariablesInExpression(struct lhsParseNode *, int);#else static VOID ExtractAnds(); static VOID ExtractFieldTest(); static struct expr *GetfieldReplace(); static struct expr *GenPNConstant(); static struct expr *GenJNConstant(); static struct expr *GenJNColon(); static struct expr *GenPNColon(); static struct expr *GenJNEq(); static struct expr *GenPNEq(); static struct expr *GenJNVariableComparison(); static struct expr *GenPNVariableComparison(); static int AllVariablesInPattern(); static int AllVariablesInExpression();#endif/*******************************************************//* FieldConversion: Generates join and pattern network *//* expressions for a field constraint. *//*******************************************************/globle VOID FieldConversion(theField,thePattern) struct lhsParseNode *theField; struct lhsParseNode *thePattern; { int testInPatternNetwork = CLIPS_TRUE; struct lhsParseNode *patternPtr; struct expr *headOfPNExpression, *headOfJNExpression; struct expr *lastPNExpression, *lastJNExpression; struct expr *tempExpression; struct expr *patternNetTest = NULL; struct expr *joinNetTest = NULL; /*==================================================*/ /* Consider a NULL pointer to be an internal error. */ /*==================================================*/ if (theField == NULL) { CLIPSSystemError("ANALYSIS",3); ExitCLIPS(4); } /*========================================================*/ /* Determine if constant testing must be performed in the */ /* join network. Only possible when a field contains an */ /* or ('|') and references are made to variables outside */ /* the pattern. */ /*========================================================*/ if (theField->bottom != NULL) { if (theField->bottom->bottom != NULL) { testInPatternNetwork = AllVariablesInPattern(theField->bottom,theField->pattern); } } /*=============================================================*/ /* Extract pattern and join network expressions. Loop through */ /* the or'ed constraints of the field, extracting pattern and */ /* join network expressions and adding them to a running list. */ /*=============================================================*/ headOfPNExpression = lastPNExpression = NULL; headOfJNExpression = lastJNExpression = NULL; for (patternPtr = theField->bottom; patternPtr != NULL; patternPtr = patternPtr->bottom) { /*=============================================*/ /* Extract pattern and join network tests from */ /* the or'ed constraint being examined. */ /*=============================================*/ ExtractAnds(patternPtr,testInPatternNetwork,&patternNetTest,&joinNetTest); /*=====================================================*/ /* Add the new pattern network expressions to the list */ /* of pattern network expressions being constructed. */ /*=====================================================*/ if (patternNetTest != NULL) { if (lastPNExpression == NULL) { headOfPNExpression = patternNetTest; } else { lastPNExpression->nextArg = patternNetTest; } lastPNExpression = patternNetTest; } /*==================================================*/ /* Add the new join network expressions to the list */ /* of join network expressions being constructed. */ /*==================================================*/ if (joinNetTest != NULL) { if (lastJNExpression == NULL) { headOfJNExpression = joinNetTest; } else { lastJNExpression->nextArg = joinNetTest; } lastJNExpression = joinNetTest; } } /*==========================================================*/ /* If there was more than one expression generated from the */ /* or'ed field constraints for the pattern network, then */ /* enclose the expressions within an "or" function call. */ /*==========================================================*/ if ((headOfPNExpression != NULL) ? (headOfPNExpression->nextArg != NULL) : CLIPS_FALSE) { tempExpression = GenConstant(FCALL,PTR_OR); tempExpression->argList = headOfPNExpression; headOfPNExpression = tempExpression; } /*==========================================================*/ /* If there was more than one expression generated from the */ /* or'ed field constraints for the join network, then */ /* enclose the expressions within an "or" function call. */ /*==========================================================*/ if ((headOfJNExpression != NULL) ? (headOfJNExpression->nextArg != NULL) : CLIPS_FALSE) { tempExpression = GenConstant(FCALL,PTR_OR); tempExpression->argList = headOfJNExpression; headOfJNExpression = tempExpression; } /*===============================================================*/ /* If the field constraint binds a variable that was previously */ /* bound somewhere in the LHS of the rule, then generate an */ /* expression to compare this binding occurrence of the variable */ /* to the previous binding occurrence. */ /*===============================================================*/ if (((theField->type == MF_VARIABLE) || (theField->type == SF_VARIABLE)) && (theField->referringNode != NULL)) { /*================================================================*/ /* If the previous variable reference is within the same pattern, */ /* then the variable comparison can occur in the pattern network. */ /*================================================================*/ if (theField->referringNode->pattern == theField->pattern) { tempExpression = GenPNVariableComparison(theField,theField->referringNode); headOfPNExpression = CombineExpressions(tempExpression,headOfPNExpression); } /*====================================*/ /* Otherwise, the variable comparison */ /* must occur in the join network. */ /*====================================*/ else if (theField->referringNode->pattern > 0) { tempExpression = GenJNVariableComparison(theField,theField->referringNode); headOfJNExpression = CombineExpressions(tempExpression,headOfJNExpression); } } /*======================================================*/ /* Attach the pattern network expressions to the field. */ /*======================================================*/ theField->networkTest = headOfPNExpression; /*=====================================================*/ /* Attach the join network expressions to the pattern. */ /*=====================================================*/ thePattern->networkTest = CombineExpressions(thePattern->networkTest,headOfJNExpression); }/****************************************************************************//* ExtractAnds: Loops through a single set of subfields bound together by *//* an & connective constraint in a field and generates expressions needed *//* for testing conditions in the pattern and join network. *//****************************************************************************/static VOID ExtractAnds(andField,testInPatternNetwork,patternNetTest,joinNetTest) struct lhsParseNode *andField; int testInPatternNetwork; struct expr **patternNetTest; struct expr **joinNetTest; { struct expr *newPNTest, *newJNTest; /*=================================================*/ /* Before starting, the subfield has no pattern or */ /* join network expressions associated with it. */ /*=================================================*/ *patternNetTest = NULL; *joinNetTest = NULL; /*=========================================*/ /* Loop through each of the subfields tied */ /* together by the & constraint. */ /*=========================================*/ for (; andField != NULL; andField = andField->right) { /*======================================*/ /* Extract the pattern and join network */ /* expressions from the subfield. */ /*======================================*/ ExtractFieldTest(andField,testInPatternNetwork,&newPNTest,&newJNTest); /*=================================================*/ /* Add the new expressions to the list of pattern */ /* and join network expressions being constructed. */ /*=================================================*/ *patternNetTest = CombineExpressions(*patternNetTest,newPNTest);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -