📄 generate.c
字号:
/* value returned by the function call. Otherwise, use eq to */ /* compare the two values. */ /*============================================================*/ if (theField->negated) { top = GenConstant(FCALL,PTR_NEQ); } else { top = GenConstant(FCALL,PTR_EQ); } top->argList = (*theField->patternType->genGetPNValueFunction)(theField); top->argList->nextArg = conversion; return(top); }/******************************************************************//* GetvarReplace: Replaces occurences of variables in expressions *//* with function calls that will extract the variable's value *//* from a partial match (i.e. from information stored in the *//* join network or the activation of the rule). *//******************************************************************/globle struct expr *GetvarReplace(nodeList) struct lhsParseNode *nodeList; { struct expr *newList; /*====================================*/ /* Return NULL for a NULL pointer */ /* (i.e. nothing has to be replaced). */ /*====================================*/ if (nodeList == NULL) return(NULL); /*=====================================================*/ /* Create an expression data structure and recursively */ /* replace variables in its argument list and next */ /* argument links. */ /*=====================================================*/ newList = get_struct(expr); newList->type = (short) nodeList->type; newList->value = nodeList->value; newList->nextArg = GetvarReplace(nodeList->right); newList->argList = GetvarReplace(nodeList->bottom); /*=========================================================*/ /* If the present node being examined is either a local or */ /* global variable, then replace it with a function call */ /* that will return the variable's value. */ /*=========================================================*/ if ((nodeList->type == SF_VARIABLE) || (nodeList->type == MF_VARIABLE)) { (*nodeList->referringNode->patternType->replaceGetJNValueFunction) (newList,nodeList->referringNode); }#if DEFGLOBAL_CONSTRUCT else if (newList->type == GBL_VARIABLE) { ReplaceGlobalVariable(newList); }#endif /*====================================================*/ /* Return the expression with its variables replaced. */ /*====================================================*/ return(newList); }/**********************************************************************//* GetfieldReplace: Replaces occurences of variables in expressions *//* with function calls that will extract the variable's value *//* given a pointer to the data entity that contains the value (i.e. *//* from information stored in the pattern network). *//**********************************************************************/static struct expr *GetfieldReplace(nodeList) struct lhsParseNode *nodeList; { struct expr *newList; /*====================================*/ /* Return NULL for a NULL pointer */ /* (i.e. nothing has to be replaced). */ /*====================================*/ if (nodeList == NULL) return(NULL); /*=====================================================*/ /* Create an expression data structure and recursively */ /* replace variables in its argument list and next */ /* argument links. */ /*=====================================================*/ newList = get_struct(expr); newList->type = (short) nodeList->type; newList->value = nodeList->value; newList->nextArg = GetfieldReplace(nodeList->right); newList->argList = GetfieldReplace(nodeList->bottom); /*=========================================================*/ /* If the present node being examined is either a local or */ /* global variable, then replace it with a function call */ /* that will return the variable's value. */ /*=========================================================*/ if ((nodeList->type == SF_VARIABLE) || (nodeList->type == MF_VARIABLE)) { (*nodeList->referringNode->patternType->replaceGetPNValueFunction) (newList,nodeList->referringNode); }#if DEFGLOBAL_CONSTRUCT else if (newList->type == GBL_VARIABLE) { ReplaceGlobalVariable(newList); }#endif /*====================================================*/ /* Return the expression with its variables replaced. */ /*====================================================*/ return(newList); }/**************************************************************//* GenJNVariableComparison: Generates a join network test for *//* comparing two variables found in different patterns. *//**************************************************************/static struct expr *GenJNVariableComparison(selfNode,referringNode) struct lhsParseNode *selfNode, *referringNode; { struct expr *top; /*========================================================*/ /* If either pattern is missing a function for generating */ /* the appropriate test, then no test is generated. */ /*========================================================*/ if ((selfNode->patternType->genCompareJNValuesFunction == NULL) || (referringNode->patternType->genCompareJNValuesFunction == NULL)) { return(NULL); } /*=====================================================*/ /* If both patterns are of the same type, then use the */ /* special function for generating the join test. */ /*=====================================================*/ if (selfNode->patternType->genCompareJNValuesFunction == referringNode->patternType->genCompareJNValuesFunction) { return (*selfNode->patternType->genCompareJNValuesFunction)(selfNode, referringNode); } /*===========================================================*/ /* If the patterns are of different types, then generate a */ /* join test by using the eq/neq function with its arguments */ /* being function calls to retrieve the appropriate values */ /* from the patterns. */ /*===========================================================*/ if (selfNode->negated) top = GenConstant(FCALL,PTR_NEQ); else top = GenConstant(FCALL,PTR_EQ); top->argList = (*selfNode->patternType->genGetJNValueFunction)(selfNode); top->argList->nextArg = (*referringNode->patternType->genGetJNValueFunction)(referringNode); return(top); }/*************************************************************//* GenPNVariableComparison: Generates a pattern network test *//* for comparing two variables found in the same pattern. *//*************************************************************/static struct expr *GenPNVariableComparison(selfNode,referringNode) struct lhsParseNode *selfNode, *referringNode; { if (selfNode->patternType->genComparePNValuesFunction != NULL) { return (*selfNode->patternType->genComparePNValuesFunction)(selfNode,referringNode); } return(NULL); }/************************************************************//* AllVariablesInPattern: Determines if all of the variable *//* references in a field constraint can be referenced *//* within thepattern in which the field is contained. *//************************************************************/static int AllVariablesInPattern(orField,pattern) struct lhsParseNode *orField; int pattern; { struct lhsParseNode *andField; /*=========================================*/ /* Loop through each of the | constraints. */ /*=========================================*/ for (; orField != NULL; orField = orField->bottom) { /*=========================================*/ /* Loop through each of the & constraints. */ /*=========================================*/ for (andField = orField; andField != NULL; andField = andField->right) { /*========================================================*/ /* If a variable is found, make sure the pattern in which */ /* the variable was previously bound is the same as the */ /* pattern being checked. */ /*========================================================*/ if ((andField->type == SF_VARIABLE) || (andField->type == MF_VARIABLE)) { if (andField->referringNode->pattern != pattern) return(CLIPS_FALSE); } /*========================================================*/ /* Check predicate and return value constraints to see */ /* that all variables can be referenced from the pattern. */ /*========================================================*/ else if ((andField->type == PREDICATE_CONSTRAINT) || (andField->type == RETURN_VALUE_CONSTRAINT)) { if (AllVariablesInExpression(andField->expression,pattern) == CLIPS_FALSE) { return(CLIPS_FALSE); } } } } /*=====================================*/ /* All variables in the field can be */ /* referenced from within the pattern. */ /*=====================================*/ return(CLIPS_TRUE); }/**************************************************************************//* AllVariablesInExpression: Determines if all of the variable references *//* in an expression can be referenced within the pattern in which the *//* expression is contained. *//**************************************************************************/static int AllVariablesInExpression(theExpression,pattern) struct lhsParseNode *theExpression; int pattern; { /*==========================================*/ /* Check all expressions in the right link. */ /*==========================================*/ for (; theExpression != NULL; theExpression = theExpression->right) { /*========================================================*/ /* If a variable is found, make sure the pattern in which */ /* the variable is bound is the same as the pattern being */ /* checked. */ /*========================================================*/ if ((theExpression->type == SF_VARIABLE) || (theExpression->type == MF_VARIABLE)) { if (theExpression->referringNode->pattern != pattern) return(CLIPS_FALSE); } /*=======================================================*/ /* Recursively check all expressions in the bottom link. */ /*=======================================================*/ if (AllVariablesInExpression(theExpression->bottom,pattern) == CLIPS_FALSE) { return(CLIPS_FALSE); } } /*========================================*/ /* All variables in the expression can be */ /* referenced from within the pattern. */ /*========================================*/ return(CLIPS_TRUE); }#endif /* (! RUN_TIME) && (! BLOAD_ONLY) && DEFRULE_CONSTRUCT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -