📄 factgen.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.20 01/31/02 */
/* */
/* FACT RETE FUNCTION GENERATION MODULE */
/*******************************************************/
/*************************************************************/
/* Purpose: Creates expressions used by the fact pattern */
/* matcher and the join network. The expressions created */
/* are used to extract and compare values from facts as */
/* needed by the Rete pattern matching algorithm. These */
/* expressions are also used to extract values from facts */
/* needed by expressions on the RHS of a rule. */
/* */
/* Principal Programmer(s): */
/* Gary D. Riley */
/* */
/* Contributing Programmer(s): */
/* */
/* Revision History: */
/* */
/*************************************************************/
#define _FACTGEN_SOURCE_
#include "setup.h"
#if DEFTEMPLATE_CONSTRUCT && DEFRULE_CONSTRUCT
#include <stdio.h>
#define _STDIO_INCLUDED_
#include "constant.h"
#include "memalloc.h"
#include "router.h"
#include "scanner.h"
#include "exprnpsr.h"
#include "constrct.h"
#include "network.h"
#include "reteutil.h"
#include "factmch.h"
#include "factrete.h"
#include "factmngr.h"
#include "pattern.h"
#include "factprt.h"
#include "envrnmnt.h"
#include "tmpltdef.h"
#include "tmpltlhs.h"
#include "factgen.h"
#define FACTGEN_DATA 2
struct factgenData
{
globle struct entityRecord FactJNGV1Info;
globle struct entityRecord FactJNGV2Info;
globle struct entityRecord FactJNGV3Info;
globle struct entityRecord FactPNGV1Info;
globle struct entityRecord FactPNGV2Info;
globle struct entityRecord FactPNGV3Info;
globle struct entityRecord FactJNCV1Info;
globle struct entityRecord FactJNCV2Info;
globle struct entityRecord FactPNCV1Info;
globle struct entityRecord FactStoreMFInfo;
globle struct entityRecord FactSlotLengthInfo;
globle struct entityRecord FactPNConstant1Info;
globle struct entityRecord FactPNConstant2Info;
};
#define FactgenData(theEnv) ((struct factgenData *) GetEnvironmentData(theEnv,FACTGEN_DATA))
/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/
#if (! RUN_TIME) && (! BLOAD_ONLY)
static void *FactGetVarJN1(void *,struct lhsParseNode *);
static void *FactGetVarJN2(void *,struct lhsParseNode *);
static void *FactGetVarJN3(void *,struct lhsParseNode *);
static void *FactGetVarPN1(void *,struct lhsParseNode *);
static void *FactGetVarPN2(void *,struct lhsParseNode *);
static void *FactGetVarPN3(void *,struct lhsParseNode *);
#endif
/*******************************************************************/
/* InitializeFactReteFunctions: Installs the fact pattern matching */
/* and value access routines as primitive operations. */
/*******************************************************************/
globle void InitializeFactReteFunctions(
void *theEnv)
{
#if DEFRULE_CONSTRUCT
struct entityRecord factJNGV1Info = { "FACT_JN_VAR1", FACT_JN_VAR1,0,1,0,
PrintFactJNGetVar1,
PrintFactJNGetVar1,NULL,
FactJNGetVar1,
NULL,NULL,NULL,NULL,NULL,NULL };
struct entityRecord factJNGV2Info = { "FACT_JN_VAR2", FACT_JN_VAR2,0,1,0,
PrintFactJNGetVar2,
PrintFactJNGetVar2,NULL,
FactJNGetVar2,
NULL,NULL,NULL,NULL,NULL,NULL };
struct entityRecord factJNGV3Info = { "FACT_JN_VAR3", FACT_JN_VAR3,0,1,0,
PrintFactJNGetVar3,
PrintFactJNGetVar3,NULL,
FactJNGetVar3,
NULL,NULL,NULL,NULL,NULL,NULL };
struct entityRecord factPNGV1Info = { "FACT_PN_VAR1", FACT_PN_VAR1,0,1,0,
PrintFactPNGetVar1,
PrintFactPNGetVar1,NULL,
FactPNGetVar1,
NULL,NULL,NULL,NULL,NULL,NULL };
struct entityRecord factPNGV2Info = { "FACT_PN_VAR2", FACT_PN_VAR2,0,1,0,
PrintFactPNGetVar2,
PrintFactPNGetVar2,NULL,
FactPNGetVar2,
NULL,NULL,NULL,NULL,NULL,NULL };
struct entityRecord factPNGV3Info = { "FACT_PN_VAR3", FACT_PN_VAR3,0,1,0,
PrintFactPNGetVar3,
PrintFactPNGetVar3,NULL,
FactPNGetVar3,
NULL,NULL,NULL,NULL,NULL,NULL };
struct entityRecord factJNCV1Info = { "FACT_JN_CMP1", FACT_JN_CMP1,0,1,1,
PrintFactJNCompVars1,
PrintFactJNCompVars1,NULL,
FactJNCompVars1,
NULL,NULL,NULL,NULL,NULL,NULL };
struct entityRecord factJNCV2Info = { "FACT_JN_CMP2", FACT_JN_CMP2,0,1,1,
PrintFactJNCompVars2,
PrintFactJNCompVars2,NULL,
FactJNCompVars2,
NULL,NULL,NULL,NULL,NULL,NULL };
struct entityRecord factPNCV1Info = { "FACT_PN_CMP1", FACT_PN_CMP1,0,1,1,
PrintFactPNCompVars1,
PrintFactPNCompVars1,NULL,
FactPNCompVars1,
NULL,NULL,NULL,NULL,NULL,NULL };
struct entityRecord factStoreMFInfo = { "FACT_STORE_MULTIFIELD",
FACT_STORE_MULTIFIELD,0,1,0,
NULL,NULL,NULL,
FactStoreMultifield,
NULL,NULL,NULL,NULL,NULL,NULL };
struct entityRecord factSlotLengthInfo = { "FACT_SLOT_LENGTH",
FACT_SLOT_LENGTH,0,1,0,
PrintFactSlotLength,
PrintFactSlotLength,NULL,
FactSlotLength,
NULL,NULL,NULL,NULL,NULL,NULL };
struct entityRecord factPNConstant1Info = { "FACT_PN_CONSTANT1",
FACT_PN_CONSTANT1,0,1,1,
PrintFactPNConstant1,
PrintFactPNConstant1,NULL,
FactPNConstant1,
NULL,NULL,NULL,NULL,NULL,NULL };
struct entityRecord factPNConstant2Info = { "FACT_PN_CONSTANT2",
FACT_PN_CONSTANT2,0,1,1,
PrintFactPNConstant2,
PrintFactPNConstant2,NULL,
FactPNConstant2,
NULL,NULL,NULL,NULL,NULL,NULL };
AllocateEnvironmentData(theEnv,FACTGEN_DATA,sizeof(struct factgenData),NULL);
memcpy(&FactgenData(theEnv)->FactJNGV1Info,&factJNGV1Info,sizeof(struct entityRecord));
memcpy(&FactgenData(theEnv)->FactJNGV2Info,&factJNGV2Info,sizeof(struct entityRecord));
memcpy(&FactgenData(theEnv)->FactJNGV3Info,&factJNGV3Info,sizeof(struct entityRecord));
memcpy(&FactgenData(theEnv)->FactPNGV1Info,&factPNGV1Info,sizeof(struct entityRecord));
memcpy(&FactgenData(theEnv)->FactPNGV2Info,&factPNGV2Info,sizeof(struct entityRecord));
memcpy(&FactgenData(theEnv)->FactPNGV3Info,&factPNGV3Info,sizeof(struct entityRecord));
memcpy(&FactgenData(theEnv)->FactJNCV1Info,&factJNCV1Info,sizeof(struct entityRecord));
memcpy(&FactgenData(theEnv)->FactJNCV2Info,&factJNCV2Info,sizeof(struct entityRecord));
memcpy(&FactgenData(theEnv)->FactPNCV1Info,&factPNCV1Info,sizeof(struct entityRecord));
memcpy(&FactgenData(theEnv)->FactStoreMFInfo,&factStoreMFInfo,sizeof(struct entityRecord));
memcpy(&FactgenData(theEnv)->FactSlotLengthInfo,&factSlotLengthInfo,sizeof(struct entityRecord));
memcpy(&FactgenData(theEnv)->FactPNConstant1Info,&factPNConstant1Info,sizeof(struct entityRecord));
memcpy(&FactgenData(theEnv)->FactPNConstant2Info,&factPNConstant2Info,sizeof(struct entityRecord));
InstallPrimitive(theEnv,(ENTITY_RECORD_PTR) &FactData(theEnv)->FactInfo,FACT_ADDRESS);
InstallPrimitive(theEnv,&FactgenData(theEnv)->FactJNGV1Info,FACT_JN_VAR1);
InstallPrimitive(theEnv,&FactgenData(theEnv)->FactJNGV2Info,FACT_JN_VAR2);
InstallPrimitive(theEnv,&FactgenData(theEnv)->FactJNGV3Info,FACT_JN_VAR3);
InstallPrimitive(theEnv,&FactgenData(theEnv)->FactPNGV1Info,FACT_PN_VAR1);
InstallPrimitive(theEnv,&FactgenData(theEnv)->FactPNGV2Info,FACT_PN_VAR2);
InstallPrimitive(theEnv,&FactgenData(theEnv)->FactPNGV3Info,FACT_PN_VAR3);
InstallPrimitive(theEnv,&FactgenData(theEnv)->FactJNCV1Info,FACT_JN_CMP1);
InstallPrimitive(theEnv,&FactgenData(theEnv)->FactJNCV2Info,FACT_JN_CMP2);
InstallPrimitive(theEnv,&FactgenData(theEnv)->FactPNCV1Info,FACT_PN_CMP1);
InstallPrimitive(theEnv,&FactgenData(theEnv)->FactStoreMFInfo,FACT_STORE_MULTIFIELD);
InstallPrimitive(theEnv,&FactgenData(theEnv)->FactSlotLengthInfo,FACT_SLOT_LENGTH);
InstallPrimitive(theEnv,&FactgenData(theEnv)->FactPNConstant1Info,FACT_PN_CONSTANT1);
InstallPrimitive(theEnv,&FactgenData(theEnv)->FactPNConstant2Info,FACT_PN_CONSTANT2);
#endif
}
#if (! RUN_TIME) && (! BLOAD_ONLY)
/******************************************************************/
/* FactGenPNConstant: Generates an expression for use in the fact */
/* pattern network that compares a field from a single field or */
/* multifield slot against a constant. */
/******************************************************************/
globle struct expr *FactGenPNConstant(
void *theEnv,
struct lhsParseNode *theField)
{
struct expr *top;
unsigned short tempValue;
struct factConstantPN1Call hack1;
struct factConstantPN2Call hack2;
/*=================================================================*/
/* If the value of a single field slot (or relation name) is being */
/* compared against a constant, then use specialized routines for */
/* doing the comparison. */
/*=================================================================*/
if (theField->withinMultifieldSlot == FALSE)
{
ClearBitString(&hack1,sizeof(struct factConstantPN1Call));
if (theField->negated) hack1.testForEquality = FALSE;
else hack1.testForEquality = TRUE;
hack1.whichSlot = theField->slotNumber - 1;
top = GenConstant(theEnv,FACT_PN_CONSTANT1,AddBitMap(theEnv,&hack1,sizeof(struct factConstantPN1Call)));
top->argList = GenConstant(theEnv,theField->type,theField->value);
return(top);
}
/*=================================================================*/
/* If a constant comparison is being done within a multifield slot */
/* and the constant's position has no multifields to the left, */
/* then use the same routine used for the single field slot case, */
/* but include the offset from the beginning of the slot. */
/*=================================================================*/
else if ((theField->multiFieldsBefore == 0) ||
((theField->multiFieldsBefore == 1) && (theField->multiFieldsAfter == 0)))
{
ClearBitString(&hack2,sizeof(struct factConstantPN2Call));
if (theField->negated) hack2.testForEquality = FALSE;
else hack2.testForEquality = TRUE;
hack2.whichSlot = theField->slotNumber - 1;
if (theField->multiFieldsBefore == 0)
{
hack2.fromBeginning = TRUE;
hack2.offset = theField->singleFieldsBefore;
}
else
{
hack2.fromBeginning = FALSE;
hack2.offset = theField->singleFieldsAfter;
}
top = GenConstant(theEnv,FACT_PN_CONSTANT2,AddBitMap(theEnv,&hack2,sizeof(struct factConstantPN2Call)));
top->argList = GenConstant(theEnv,theField->type,theField->value);
return(top);
}
/*===============================================================*/
/* Otherwise, use the equality or inequality function to compare */
/* the constant against the value returned by the appropriate */
/* pattern network variable retrieval function call. */
/*===============================================================*/
else
{
if (theField->negated)
{ top = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_NEQ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -