📄 factbld.c
字号:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.05 04/09/97 */ /* */ /* FACT BUILD MODULE */ /*******************************************************//*************************************************************//* Purpose: Given a new fact pattern, adds the pattern to *//* the pattern network of the associated deftemplate. Also *//* contains routines for deleting a pattern from the fact *//* pattern network. *//* *//* Principal Programmer(s): *//* Gary D. Riley *//* *//* Contributing Programmer(s): *//* *//* Revision History: *//* *//*************************************************************/#define _FACTBLD_SOURCE_#include "setup.h"#if DEFTEMPLATE_CONSTRUCT && DEFRULE_CONSTRUCT#include <stdio.h>#define _CLIPS_STDIO_#include "clipsmem.h"#include "reteutil.h"#include "router.h"#include "reorder.h"#include "factcmp.h"#include "factmch.h"#include "factgen.h"#include "factmngr.h"#include "factlhs.h"#include "argacces.h"#include "modulutl.h"#include "tmpltdef.h"#include "factbld.h"/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/#if ANSI_COMPILER#if (! RUN_TIME) && (! BLOAD_ONLY) static struct factPatternNode *FindPatternNode(struct factPatternNode *,struct lhsParseNode *, struct factPatternNode **,int); static struct factPatternNode *CreateNewPatternNode(struct lhsParseNode *,struct factPatternNode *, struct factPatternNode *,int); static VOID ClearPatternMatches(struct factPatternNode *); static VOID DetachFactPattern(struct patternNodeHeader *); static struct patternNodeHeader *PlaceFactPattern(struct lhsParseNode *); static struct lhsParseNode *RemoveUnneededSlots(struct lhsParseNode *); static VOID FindAndSetDeftemplatePatternNetwork(struct factPatternNode *,struct factPatternNode *);#endif#else#if (! RUN_TIME) && (! BLOAD_ONLY) static struct factPatternNode *FindPatternNode(); static struct factPatternNode *CreateNewPatternNode(); static VOID ClearPatternMatches(); static VOID DetachFactPattern(); static struct patternNodeHeader *PlaceFactPattern(); static struct lhsParseNode *RemoveUnneededSlots(); static VOID FindAndSetDeftemplatePatternNetwork();#endif#endif/****************************************//* GLOBAL INTERNAL VARIABLE DEFINITIONS *//****************************************/ globle struct patternEntityRecord FactInfo = { { FACT_ADDRESS,1,0,0, PrintFactIdentifier, PrintFactIdentifierInLongForm, Retract, NULL, GetNextFact, IncrementFactCount, DecrementFactCount,NULL,NULL,NULL,NULL }, DecrementFactBasisCount, IncrementFactBasisCount, MatchFactFunction, NULL };/***************************************//* LOCAL INTERNAL VARIABLE DEFINITIONS *//***************************************/#if (! RUN_TIME) && (! BLOAD_ONLY) static struct deftemplate *CurrentDeftemplate;#endif/*********************************************************//* InitializeFactPatterns: Adds fact patterns to the set *//* of patterns recognized by the rule pattern parsing *//* and pattern/join network integration routines. *//*********************************************************/globle VOID InitializeFactPatterns() {#if DEFRULE_CONSTRUCT InitializeFactReteFunctions(); #if (! RUN_TIME) && (! BLOAD_ONLY) AddPatternParser("facts",0,&FactInfo, FactPatternParserFind, FactPatternParse, NULL,PlaceFactPattern, DetachFactPattern, NULL,FactReplaceGetvar, FactGenGetvar,FactJNVariableComparison, FactGenPNConstant,FactReplaceGetfield, FactGenGetfield,FactPNVariableComparison, NULL,NULL,#if INCREMENTAL_RESET MarkFactPatternForIncrementalReset, FactsIncrementalReset,#else NULL,NULL,#endif CreateInitialFactPattern,#if CONSTRUCT_COMPILER FactPatternNodeReference);#else NULL);#endif#else AddPatternParser("facts",0,&FactInfo, NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,#if INCREMENTAL_RESET MarkFactPatternForIncrementalReset, FactsIncrementalReset,#else NULL,NULL,#endif NULL,NULL); #endif #endif }#if (! RUN_TIME) && (! BLOAD_ONLY) /******************************************************************************//* PlaceFactPattern: Integrates a fact pattern into the fact pattern network. *//******************************************************************************/static struct patternNodeHeader *PlaceFactPattern(thePattern) struct lhsParseNode *thePattern; { struct lhsParseNode *tempPattern = NULL; struct factPatternNode *currentLevel, *lastLevel; struct factPatternNode *nodeBeforeMatch, *newNode; int endSlot, count; char *deftemplateName; /*======================================================================*/ /* Get the name of the deftemplate associated with the pattern being */ /* added (recall that the first field of any pattern must be a symbol). */ /*======================================================================*/ deftemplateName = ValueToString(thePattern->right->bottom->value); /*=====================================================*/ /* Remove any slot tests that test only for existance. */ /*=====================================================*/ thePattern->right = RemoveUnneededSlots(thePattern->right); /*========================================================*/ /* If the constant test for the relation name is the only */ /* pattern network test and there are no other network */ /* tests, then remove the test, but keep the node since */ /* there must be a link from the fact pattern network to */ /* the join network. Otherwise, remove the test for the */ /* relation name since this test has already been done */ /* before entering the pattern network (since each */ /* deftemplate has its own pattern network). */ /*========================================================*/ if (thePattern->right->right == NULL) { ReturnExpression(thePattern->right->networkTest); thePattern->right->networkTest = NULL; } else { tempPattern = thePattern->right; thePattern->right = thePattern->right->right; tempPattern->right = NULL; ReturnLHSParseNodes(tempPattern); tempPattern = NULL; } /*============================================================*/ /* Get a pointer to the deftemplate data structure associated */ /* with the pattern (use the deftemplate name extracted from */ /* the first field of the pattern. */ /*============================================================*/ CurrentDeftemplate = (struct deftemplate *) FindImportedConstruct("deftemplate",NULL, deftemplateName,&count, CLIPS_TRUE,NULL); /*================================================*/ /* Initialize some pointers to indicate where the */ /* pattern is being added to the pattern network. */ /*================================================*/ currentLevel = CurrentDeftemplate->patternNetwork; lastLevel = NULL; thePattern = thePattern->right; /*===========================================*/ /* Loop until all fields in the pattern have */ /* been added to the pattern network. */ /*===========================================*/ while (thePattern != NULL) { /*===========================================================*/ /* If a multifield slot is being processed, then process the */ /* pattern nodes attached to the multifield pattern node. */ /*===========================================================*/ if (thePattern->multifieldSlot) { tempPattern = thePattern; thePattern = thePattern->bottom; } /*============================================*/ /* Determine if the last pattern field within */ /* a multifield slot is being processed. */ /*============================================*/ if ((thePattern->right == NULL) && (tempPattern != NULL)) { endSlot = CLIPS_TRUE; } else { endSlot = CLIPS_FALSE; } /*========================================*/ /* Is there a node in the pattern network */ /* that can be reused (shared)? */ /*========================================*/ newNode = FindPatternNode(currentLevel,thePattern,&nodeBeforeMatch,endSlot); /*================================================*/ /* If the pattern node cannot be shared, then add */ /* a new pattern node to the pattern network. */ /*================================================*/ if (newNode == NULL) { newNode = CreateNewPatternNode(thePattern,nodeBeforeMatch,lastLevel,endSlot); } /*===========================================================*/ /* Move on to the next field in the new pattern to be added. */ /*===========================================================*/ if ((thePattern->right == NULL) && (tempPattern != NULL)) { thePattern = tempPattern; tempPattern = NULL; } thePattern = thePattern->right; /*==========================================================*/ /* If there are no more pattern nodes to be added to the */ /* pattern network, then mark the last pattern node added */ /* as a stop node (i.e. if you get to this node and the */ /* network test succeeds, then a pattern has been matched). */ /*==========================================================*/ if (thePattern == NULL) newNode->header.stopNode = CLIPS_TRUE; /*================================================*/ /* Update the pointers which indicate where we're */ /* trying to add the new pattern to the currently */ /* existing pattern network. */ /*================================================*/ lastLevel = newNode; currentLevel = newNode->nextLevel; } /*==================================================*/ /* Return the leaf node of the newly added pattern. */ /*==================================================*/ return((struct patternNodeHeader *) newNode); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -