📄 rulepsr.c
字号:
/* Perform entity dependent post analysis. */
/*=========================================*/
if (PostPatternAnalysis(theEnv,tempNode))
{
*error = TRUE;
ReturnDefrule(theEnv,topDisjunct);
return(NULL);
}
/*========================================================*/
/* Print out developer information if it's being watched. */
/*========================================================*/
#if DEVELOPER && DEBUGGING_FUNCTIONS
/*
if (EnvGetWatchItem(theEnv,"rule-analysis"))
{
struct lhsParseNode *traceNode;
char buffer[20];
EnvPrintRouter(theEnv,WDISPLAY,"\n");
for (traceNode = tempNode; traceNode != NULL; traceNode = traceNode->bottom)
{
if (traceNode->userCE)
{
sprintf(buffer,"CE %2d: ",traceNode->whichCE);
EnvPrintRouter(theEnv,WDISPLAY,buffer);
PrintExpression(theEnv,WDISPLAY,traceNode->networkTest);
EnvPrintRouter(theEnv,WDISPLAY,"\n");
}
}
}
*/
#endif
/*========================================*/
/* Check to see that logical CEs are used */
/* appropriately in the LHS of the rule. */
/*========================================*/
if ((logicalJoin = LogicalAnalysis(theEnv,tempNode)) < 0)
{
*error = TRUE;
ReturnDefrule(theEnv,topDisjunct);
return(NULL);
}
/*======================================================*/
/* Check to see if there are any RHS constraint errors. */
/*======================================================*/
if (CheckRHSForConstraintErrors(theEnv,actions,tempNode))
{
*error = TRUE;
ReturnDefrule(theEnv,topDisjunct);
return(NULL);
}
/*=================================================*/
/* Replace variable references in the RHS with the */
/* appropriate variable retrieval functions. */
/*=================================================*/
newActions = CopyExpression(theEnv,actions);
if (ReplaceProcVars(theEnv,"RHS of defrule",newActions,NULL,NULL,
ReplaceRHSVariable,(void *) tempNode))
{
*error = TRUE;
ReturnDefrule(theEnv,topDisjunct);
ReturnExpression(theEnv,newActions);
return(NULL);
}
/*==================================*/
/* We're finished for this disjunct */
/* if we're only checking syntax. */
/*==================================*/
if (ConstructData(theEnv)->CheckSyntaxMode)
{
ReturnExpression(theEnv,newActions);
continue;
}
/*=================================*/
/* Install the disjunct's actions. */
/*=================================*/
ExpressionInstall(theEnv,newActions);
packPtr = PackExpression(theEnv,newActions);
ReturnExpression(theEnv,newActions);
/*===============================================================*/
/* Create the pattern and join data structures for the new rule. */
/*===============================================================*/
lastJoin = ConstructJoins(theEnv,logicalJoin,tempNode);
/*===================================================================*/
/* Determine the rule's complexity for use with conflict resolution. */
/*===================================================================*/
complexity = RuleComplexity(theEnv,tempNode);
/*=====================================================*/
/* Create the defrule data structure for this disjunct */
/* and put it in the list of disjuncts for this rule. */
/*=====================================================*/
currentDisjunct = CreateNewDisjunct(theEnv,ruleName,localVarCnt,packPtr,complexity,
(unsigned) logicalJoin,lastJoin);
/*============================================================*/
/* Place the disjunct in the list of disjuncts for this rule. */
/* If the disjunct is the first disjunct, then increment the */
/* reference counts for the dynamic salience (the expression */
/* for the dynamic salience is only stored with the first */
/* disjuncts and the other disjuncts refer back to the first */
/* disjunct for their dynamic salience value. */
/*============================================================*/
if (topDisjunct == NULL)
{
topDisjunct = currentDisjunct;
ExpressionInstall(theEnv,topDisjunct->dynamicSalience);
}
else lastDisjunct->disjunct = currentDisjunct;
/*===========================================*/
/* Move on to the next disjunct of the rule. */
/*===========================================*/
lastDisjunct = currentDisjunct;
}
return(topDisjunct);
}
/************************************************************************/
/* CreateNewDisjunct: Creates and initializes a defrule data structure. */
/************************************************************************/
static struct defrule *CreateNewDisjunct(
void *theEnv,
SYMBOL_HN *ruleName,
int localVarCnt,
struct expr *theActions,
int complexity,
unsigned logicalJoin,
struct joinNode *lastJoin)
{
struct joinNode *tempJoin;
struct defrule *newDisjunct;
/*===================================================*/
/* Create and initialize the defrule data structure. */
/*===================================================*/
newDisjunct = get_struct(theEnv,defrule);
newDisjunct->header.ppForm = NULL;
newDisjunct->header.next = NULL;
newDisjunct->header.usrData = NULL;
newDisjunct->logicalJoin = NULL;
newDisjunct->disjunct = NULL;
newDisjunct->header.name = ruleName;
IncrementSymbolCount(newDisjunct->header.name);
newDisjunct->actions = theActions;
newDisjunct->salience = PatternData(theEnv)->GlobalSalience;
newDisjunct->afterBreakpoint = 0;
newDisjunct->watchActivation = 0;
newDisjunct->watchFiring = 0;
newDisjunct->executing = 0;
newDisjunct->complexity = complexity;
newDisjunct->autoFocus = PatternData(theEnv)->GlobalAutoFocus;
newDisjunct->dynamicSalience = PatternData(theEnv)->SalienceExpression;
newDisjunct->localVarCnt = localVarCnt;
/*=====================================*/
/* Add a pointer to the rule's module. */
/*=====================================*/
newDisjunct->header.whichModule =
(struct defmoduleItemHeader *)
GetModuleItem(theEnv,NULL,FindModuleItem(theEnv,"defrule")->moduleIndex);
/*============================================================*/
/* Attach the rule's last join to the defrule data structure. */
/*============================================================*/
lastJoin->ruleToActivate = newDisjunct;
newDisjunct->lastJoin = lastJoin;
/*=================================================*/
/* Determine the rule's logical join if it exists. */
/*=================================================*/
tempJoin = lastJoin;
while (tempJoin != NULL)
{
if (tempJoin->depth == logicalJoin)
{
newDisjunct->logicalJoin = tempJoin;
tempJoin->logicalJoin = TRUE;
}
tempJoin = tempJoin->lastLevel;
}
/*==================================================*/
/* Return the newly created defrule data structure. */
/*==================================================*/
return(newDisjunct);
}
/****************************************************************/
/* ReplaceExpressionVariables: Replaces all symbolic references */
/* to variables (local and global) found in an expression on */
/* the RHS of a rule with expressions containing function */
/* calls to retrieve the variable's value. Makes the final */
/* modifications necessary for handling the modify and */
/* duplicate commands. */
/****************************************************************/
static int ReplaceRHSVariable(
void *theEnv,
struct expr *list,
void *VtheLHS)
{
struct lhsParseNode *theVariable;
/*=======================================*/
/* Handle modify and duplicate commands. */
/*=======================================*/
#if DEFTEMPLATE_CONSTRUCT
if (list->type == FCALL)
{
if (list->value == (void *) FindFunction(theEnv,"modify"))
{
if (UpdateModifyDuplicate(theEnv,list,"modify",VtheLHS) == FALSE)
return(-1);
}
else if (list->value == (void *) FindFunction(theEnv,"duplicate"))
{
if (UpdateModifyDuplicate(theEnv,list,"duplicate",VtheLHS) == FALSE)
return(-1);
}
return(0);
}
#endif
if ((list->type != SF_VARIABLE) && (list->type != MF_VARIABLE))
{ return(FALSE); }
/*===============================================================*/
/* Check to see if the variable is bound on the LHS of the rule. */
/*===============================================================*/
theVariable = FindVariable((SYMBOL_HN *) list->value,(struct lhsParseNode *) VtheLHS);
if (theVariable == NULL) return(FALSE);
/*================================================*/
/* Replace the variable reference with a function */
/* call to retrieve the variable. */
/*================================================*/
if (theVariable->patternType != NULL)
{ (*theVariable->patternType->replaceGetJNValueFunction)(theEnv,list,theVariable); }
else
{ return(FALSE); }
/*=================================================================*/
/* Return TRUE to indicate the variable was successfully replaced. */
/*=================================================================*/
return(TRUE);
}
/*******************************************************/
/* ParseRuleRHS: Coordinates all the actions necessary */
/* for parsing the RHS of a rule. */
/*******************************************************/
static struct expr *ParseRuleRHS(
void *theEnv,
char *readSource)
{
struct expr *actions;
struct token theToken;
/*=========================================================*/
/* Process the actions on the right hand side of the rule. */
/*=========================================================*/
SavePPBuffer(theEnv,"\n ");
SetIndentDepth(theEnv,3);
actions = GroupActions(theEnv,readSource,&theToken,TRUE,NULL,FALSE);
if (actions == NULL) return(NULL);
/*=============================*/
/* Reformat the closing token. */
/*=============================*/
PPBackup(theEnv);
PPBackup(theEnv);
SavePPBuffer(theEnv,theToken.printForm);
/*======================================================*/
/* Check for the closing right parenthesis of the rule. */
/*======================================================*/
if (theToken.type != RPAREN)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -