📄 reteutil.c
字号:
/***************************************************************/
/* NewPseudoFactPartialMatch: Creates a partial structure that */
/* indicates the "pseudo" fact to which a not pattern CE has */
/* been bound. Since a non-existant fact has no fact index, */
/* the partial match structure is given a pseudo fact index */
/* (a unique negative integer). Note that a "pseudo" fact */
/* can also be used as a "pseudo" instance. */
/***************************************************************/
globle struct partialMatch *NewPseudoFactPartialMatch(
void *theEnv)
{
struct partialMatch *linker;
struct alphaMatch *tempAlpha;
linker = get_struct(theEnv,partialMatch);
linker->next = NULL;
linker->betaMemory = TRUE;
linker->busy = FALSE;
linker->activationf = FALSE;
linker->dependentsf = FALSE;
linker->notOriginf = TRUE;
linker->counterf = FALSE;
linker->bcount = 0;
tempAlpha = get_struct(theEnv,alphaMatch);
tempAlpha->next = NULL;
tempAlpha->matchingItem = NULL;
tempAlpha->markers = NULL;
linker->binds[0].gm.theMatch = tempAlpha;
return(linker);
}
/******************************************************************/
/* FlushAlphaBetaMemory: Returns all partial matches in a list of */
/* partial matches either directly to the pool of free memory */
/* or to the list of GarbagePartialMatches. Partial matches */
/* stored in alpha memories and partial matches which store the */
/* information for pseudo facts (for not CEs) may be referred */
/* to by other data structures and thus must be placed on the */
/* list of GarbagePartialMatches. */
/******************************************************************/
globle void FlushAlphaBetaMemory(
void *theEnv,
struct partialMatch *pfl)
{
struct partialMatch *pfltemp;
while (pfl != NULL)
{
pfltemp = pfl->next;
if (((pfl->notOriginf) && (pfl->counterf == FALSE)) ||
(pfl->betaMemory == FALSE))
{
pfl->next = EngineData(theEnv)->GarbagePartialMatches;
EngineData(theEnv)->GarbagePartialMatches = pfl;
}
else
{ ReturnPartialMatch(theEnv,pfl); }
pfl = pfltemp;
}
}
/*****************************************************************/
/* DestroyAlphaBetaMemory: Returns all partial matches in a list */
/* of partial matches directly to the pool of free memory. */
/*****************************************************************/
globle void DestroyAlphaBetaMemory(
void *theEnv,
struct partialMatch *pfl)
{
struct partialMatch *pfltemp;
while (pfl != NULL)
{
pfltemp = pfl->next;
DestroyPartialMatch(theEnv,pfl);
pfl = pfltemp;
}
}
/******************************************************/
/* FindEntityInPartialMatch: Searches for a specified */
/* data entity in a partial match. */
/******************************************************/
globle int FindEntityInPartialMatch(
struct patternEntity *theEntity,
struct partialMatch *thePartialMatch)
{
short int i;
for (i = 0 ; i < (int) thePartialMatch->bcount; i++)
{
if (thePartialMatch->binds[i].gm.theMatch->matchingItem == theEntity)
{ return(TRUE); }
}
return(FALSE);
}
/***********************************************************************/
/* GetPatternNumberFromJoin: Given a pointer to a join associated with */
/* a pattern CE, returns an integer representing the position of the */
/* pattern CE in the rule (e.g. first, second, third). */
/***********************************************************************/
globle int GetPatternNumberFromJoin(
struct joinNode *joinPtr)
{
int whichOne = 0;
while (joinPtr != NULL)
{
if (joinPtr->joinFromTheRight)
{ joinPtr = (struct joinNode *) joinPtr->rightSideEntryStructure; }
else
{
whichOne++;
joinPtr = joinPtr->lastLevel;
}
}
return(whichOne);
}
/************************************************************************/
/* TraceErrorToRule: Prints an error message when a error occurs as the */
/* result of evaluating an expression in the pattern network. Used to */
/* indicate which rule caused the problem. */
/************************************************************************/
globle void TraceErrorToRule(
void *theEnv,
struct joinNode *joinPtr,
char *indentSpaces)
{
MarkRuleNetwork(theEnv,0);
TraceErrorToRuleDriver(theEnv,joinPtr,indentSpaces);
}
/**************************************************************/
/* TraceErrorToRuleDriver: Driver code for printing out which */
/* rule caused a pattern or join network error. */
/**************************************************************/
static void TraceErrorToRuleDriver(
void *theEnv,
struct joinNode *joinPtr,
char *indentSpaces)
{
char *name;
while (joinPtr != NULL)
{
if (joinPtr->marked)
{ /* Do Nothing */ }
else if (joinPtr->ruleToActivate != NULL)
{
joinPtr->marked = 1;
name = EnvGetDefruleName(theEnv,joinPtr->ruleToActivate);
EnvPrintRouter(theEnv,WERROR,indentSpaces);
EnvPrintRouter(theEnv,WERROR,name);
EnvPrintRouter(theEnv,WERROR,"\n");
}
else
{
joinPtr->marked = 1;
TraceErrorToRuleDriver(theEnv,joinPtr->nextLevel,indentSpaces);
}
joinPtr = joinPtr->rightDriveNode;
}
}
/********************************************************/
/* MarkRuleNetwork: Sets the marked flag in each of the */
/* joins in the join network to the specified value. */
/********************************************************/
globle void MarkRuleNetwork(
void *theEnv,
int value)
{
struct defrule *rulePtr;
struct joinNode *joinPtr;
struct defmodule *modulePtr;
/*===========================*/
/* Loop through each module. */
/*===========================*/
SaveCurrentModule(theEnv);
for (modulePtr = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
modulePtr != NULL;
modulePtr = (struct defmodule *) EnvGetNextDefmodule(theEnv,modulePtr))
{
EnvSetCurrentModule(theEnv,(void *) modulePtr);
/*=========================*/
/* Loop through each rule. */
/*=========================*/
rulePtr = (struct defrule *) EnvGetNextDefrule(theEnv,NULL);
while (rulePtr != NULL)
{
/*=============================*/
/* Mark each join for the rule */
/* with the specified value. */
/*=============================*/
joinPtr = rulePtr->lastJoin;
while (joinPtr != NULL)
{
joinPtr->marked = value;
joinPtr = GetPreviousJoin(joinPtr);
}
/*=================================*/
/* Move on to the next rule or the */
/* next disjunct for this rule. */
/*=================================*/
if (rulePtr->disjunct != NULL) rulePtr = rulePtr->disjunct;
else rulePtr = (struct defrule *) EnvGetNextDefrule(theEnv,rulePtr);
}
}
RestoreCurrentModule(theEnv);
}
#if (CONSTRUCT_COMPILER || BLOAD_AND_BSAVE) && (! RUN_TIME)
/*************************************************************/
/* TagRuleNetwork: Assigns each join in the join network and */
/* each defrule data structure with a unique integer ID. */
/* Also counts the number of defrule and joinNode data */
/* structures currently in use. */
/*************************************************************/
globle void TagRuleNetwork(
void *theEnv,
long int *moduleCount,
long int *ruleCount,
long int *joinCount)
{
struct defmodule *modulePtr;
struct defrule *rulePtr;
struct joinNode *joinPtr;
*moduleCount = 0;
*ruleCount = 0;
*joinCount = 0;
MarkRuleNetwork(theEnv,0);
/*===========================*/
/* Loop through each module. */
/*===========================*/
for (modulePtr = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
modulePtr != NULL;
modulePtr = (struct defmodule *) EnvGetNextDefmodule(theEnv,modulePtr))
{
(*moduleCount)++;
EnvSetCurrentModule(theEnv,(void *) modulePtr);
/*=========================*/
/* Loop through each rule. */
/*=========================*/
rulePtr = (struct defrule *) EnvGetNextDefrule(theEnv,NULL);
while (rulePtr != NULL)
{
rulePtr->header.bsaveID = *ruleCount;
(*ruleCount)++;
/*=========================*/
/* Loop through each join. */
/*=========================*/
for (joinPtr = rulePtr->lastJoin;
joinPtr != NULL;
joinPtr = GetPreviousJoin(joinPtr))
{
if (joinPtr->marked == 0)
{
joinPtr->marked = 1;
joinPtr->bsaveID = *joinCount;
(*joinCount)++;
}
}
if (rulePtr->disjunct != NULL) rulePtr = rulePtr->disjunct;
else rulePtr = (struct defrule *) EnvGetNextDefrule(theEnv,rulePtr);
}
}
}
#endif /* (CONSTRUCT_COMPILER || BLOAD_AND_BSAVE) && (! RUN_TIME) */
#endif /* DEFRULE_CONSTRUCT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -