📄 factbld.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.24 05/17/06 */
/* */
/* 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: */
/* */
/* 6.24: Removed INCREMENTAL_RESET compilation flag. */
/* */
/*************************************************************/
#define _FACTBLD_SOURCE_
#include "setup.h"
#if DEFTEMPLATE_CONSTRUCT && DEFRULE_CONSTRUCT
#include <stdio.h>
#define _STDIO_INCLUDED_
#include "memalloc.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 "envrnmnt.h"
#include "factbld.h"
/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/
#if (! RUN_TIME) && (! BLOAD_ONLY)
static struct factPatternNode *FindPatternNode(struct factPatternNode *,struct lhsParseNode *,
struct factPatternNode **,unsigned);
static struct factPatternNode *CreateNewPatternNode(void *,struct lhsParseNode *,struct factPatternNode *,
struct factPatternNode *,unsigned);
static void ClearPatternMatches(void *,struct factPatternNode *);
static void DetachFactPattern(void *,struct patternNodeHeader *);
static struct patternNodeHeader *PlaceFactPattern(void *,struct lhsParseNode *);
static struct lhsParseNode *RemoveUnneededSlots(void *,struct lhsParseNode *);
static void FindAndSetDeftemplatePatternNetwork(void *,struct factPatternNode *,struct factPatternNode *);
#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(
void *theEnv)
{
#if DEFRULE_CONSTRUCT
struct patternParser *newPtr;
InitializeFactReteFunctions(theEnv);
newPtr = get_struct(theEnv,patternParser);
newPtr->name = "facts";
newPtr->priority = 0;
newPtr->entityType = &FactData(theEnv)->FactInfo;
#if (! RUN_TIME) && (! BLOAD_ONLY)
newPtr->recognizeFunction = FactPatternParserFind;
newPtr->parseFunction = FactPatternParse;
newPtr->postAnalysisFunction = NULL;
newPtr->addPatternFunction = PlaceFactPattern;
newPtr->removePatternFunction = DetachFactPattern;
newPtr->genJNConstantFunction = NULL;
newPtr->replaceGetJNValueFunction = FactReplaceGetvar;
newPtr->genGetJNValueFunction = FactGenGetvar;
newPtr->genCompareJNValuesFunction = FactJNVariableComparison;
newPtr->genPNConstantFunction = FactGenPNConstant;
newPtr->replaceGetPNValueFunction = FactReplaceGetfield;
newPtr->genGetPNValueFunction = FactGenGetfield;
newPtr->genComparePNValuesFunction = FactPNVariableComparison;
newPtr->returnUserDataFunction = NULL;
newPtr->copyUserDataFunction = NULL;
#else
newPtr->recognizeFunction = NULL;
newPtr->parseFunction = NULL;
newPtr->postAnalysisFunction = NULL;
newPtr->addPatternFunction = NULL;
newPtr->removePatternFunction = NULL;
newPtr->genJNConstantFunction = NULL;
newPtr->replaceGetJNValueFunction = NULL;
newPtr->genGetJNValueFunction = NULL;
newPtr->genCompareJNValuesFunction = NULL;
newPtr->genPNConstantFunction = NULL;
newPtr->replaceGetPNValueFunction = NULL;
newPtr->genGetPNValueFunction = NULL;
newPtr->genComparePNValuesFunction = NULL;
newPtr->returnUserDataFunction = NULL;
newPtr->copyUserDataFunction = NULL;
#endif
newPtr->markIRPatternFunction = MarkFactPatternForIncrementalReset;
newPtr->incrementalResetFunction = FactsIncrementalReset;
#if (! RUN_TIME) && (! BLOAD_ONLY)
newPtr->initialPatternFunction = CreateInitialFactPattern;
#if CONSTRUCT_COMPILER
newPtr->codeReferenceFunction = FactPatternNodeReference;
#else
newPtr->codeReferenceFunction = NULL;
#endif
#else
newPtr->initialPatternFunction = NULL;
newPtr->codeReferenceFunction = NULL;
#endif
AddPatternParser(theEnv,newPtr);
#endif
}
#if (! RUN_TIME) && (! BLOAD_ONLY)
/******************************************************************************/
/* PlaceFactPattern: Integrates a fact pattern into the fact pattern network. */
/******************************************************************************/
static struct patternNodeHeader *PlaceFactPattern(
void *theEnv,
struct lhsParseNode *thePattern)
{
struct lhsParseNode *tempPattern = NULL;
struct factPatternNode *currentLevel, *lastLevel;
struct factPatternNode *nodeBeforeMatch, *newNode = NULL;
unsigned endSlot;
int 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(theEnv,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(theEnv,thePattern->right->networkTest);
thePattern->right->networkTest = NULL;
}
else
{
tempPattern = thePattern->right;
thePattern->right = thePattern->right->right;
tempPattern->right = NULL;
ReturnLHSParseNodes(theEnv,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). */
/*============================================================*/
FactData(theEnv)->CurrentDeftemplate = (struct deftemplate *)
FindImportedConstruct(theEnv,"deftemplate",NULL,
deftemplateName,&count,
TRUE,NULL);
/*================================================*/
/* Initialize some pointers to indicate where the */
/* pattern is being added to the pattern network. */
/*================================================*/
currentLevel = FactData(theEnv)->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 = TRUE; }
else
{ endSlot = 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(theEnv,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 = 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);
}
/*************************************************************/
/* FindPatternNode: Looks for a pattern node at a specified */
/* level in the pattern network that can be reused (shared) */
/* with a pattern field being added to the pattern network. */
/*************************************************************/
static struct factPatternNode *FindPatternNode(
struct factPatternNode *listOfNodes,
struct lhsParseNode *thePattern,
struct factPatternNode **nodeBeforeMatch,
unsigned endSlot)
{
*nodeBeforeMatch = NULL;
/*==========================================================*/
/* Loop through the nodes at the given level in the pattern */
/* network looking for a node that can be reused (shared)? */
/*==========================================================*/
while (listOfNodes != NULL)
{
/*==========================================================*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -