📄 rulepsr.c
字号:
/*========================*/ /* Return the rule's RHS. */ /*========================*/ return(actions); } /************************************************************//* RuleComplexity: Returns the complexity of a rule for use *//* by the LEX and MEA conflict resolution strategies. *//************************************************************/static int RuleComplexity(theLHS) struct lhsParseNode *theLHS; { struct lhsParseNode *thePattern, *tempPattern; int complexity = 0; while (theLHS != NULL) { complexity += 1; /* Add 1 for each pattern. */ complexity += ExpressionComplexity(theLHS->networkTest); thePattern = theLHS->right; while (thePattern != NULL) { if (thePattern->multifieldSlot) { tempPattern = thePattern->bottom; while (tempPattern != NULL) { complexity += ExpressionComplexity(tempPattern->networkTest); tempPattern = tempPattern->right; } } else { complexity += ExpressionComplexity(thePattern->networkTest); } thePattern = thePattern->right; } theLHS = theLHS->bottom; } return(complexity); } /********************************************************************//* ExpressionComplexity: Determines the complexity of a expression. *//********************************************************************/static int ExpressionComplexity(exprPtr) struct expr *exprPtr; { int complexity = 0; while (exprPtr != NULL) { if (exprPtr->type == FCALL) { /*=========================================*/ /* Logical combinations do not add to the */ /* complexity, but their arguments do. */ /*=========================================*/ if ((exprPtr->value == PTR_AND) || (exprPtr->value == PTR_NOT) || (exprPtr->value == PTR_OR)) { complexity += ExpressionComplexity(exprPtr->argList); } /*=========================================*/ /* else other function calls increase the */ /* complexity, but their arguments do not. */ /*=========================================*/ else { complexity++; } } else if ((PrimitivesArray[exprPtr->type] != NULL) ? PrimitivesArray[exprPtr->type]->addsToRuleComplexity : CLIPS_FALSE) { complexity++; } exprPtr = exprPtr->nextArg; } return(complexity); } #if LOGICAL_DEPENDENCIES/********************************************//* LogicalAnalysis: Analyzes the use of the *//* logical CE within the LHS of a rule. *//********************************************/static int LogicalAnalysis(patternList) struct lhsParseNode *patternList; { int firstLogical, logicalsFound = CLIPS_FALSE, logicalJoin = 0; int gap = CLIPS_FALSE; firstLogical = patternList->logical; /*===================================================*/ /* Loop through each pattern in the LHS of the rule. */ /*===================================================*/ for (; patternList != NULL; patternList = patternList->bottom) { /*=======================================*/ /* Skip anything that isn't a pattern CE */ /* or is embedded within a not/and CE. */ /*=======================================*/ if ((patternList->type != PATTERN_CE) || (patternList->endNandDepth != 1)) { continue; } /*=====================================================*/ /* If the pattern CE is not contained within a logical */ /* CE, then set the gap flag to TRUE indicating that */ /* any subsequent pattern CE found within a logical CE */ /* represents a gap between logical CEs which is an */ /* error. */ /*=====================================================*/ if (patternList->logical == CLIPS_FALSE) { gap = CLIPS_TRUE; continue; } /*=================================================*/ /* If a logical CE is encountered and the first CE */ /* of the rule isn't a logical CE, then indicate */ /* that the first CE must be a logical CE. */ /*=================================================*/ if (! firstLogical) { PrintErrorID("RULEPSR",1,CLIPS_TRUE); PrintCLIPS(WERROR,"Logical CEs must be placed first in a rule\n"); return(-1); } /*===================================================*/ /* If a break within the logical CEs was found and a */ /* new logical CE is encountered, then indicate that */ /* there can't be any gaps between logical CEs. */ /*===================================================*/ if (gap) { PrintErrorID("RULEPSR",2,CLIPS_TRUE); PrintCLIPS(WERROR,"Gaps may not exist between logical CEs\n"); return(-1); } /*===========================================*/ /* Increment the count of logical CEs found. */ /*===========================================*/ logicalJoin++; logicalsFound = CLIPS_TRUE; } /*============================================*/ /* If logical CEs were found, then return the */ /* join number where the logical information */ /* will be stored in the join network. */ /*============================================*/ if (logicalsFound) return(logicalJoin); /*=============================*/ /* Return zero indicating that */ /* no logical CE was found. */ /*=============================*/ return(0); }#endif /* LOGICAL_DEPENDENCIES *//*****************************************************************//* FindVariable: Searches for the last occurence of a variable *//* in the LHS of a rule that is visible from the RHS of a rule. *//* The last occurence of the variable on the LHS side of the *//* rule will have the strictest constraints (because it will *//* have been intersected with all of the other constraints for *//* the variable on the LHS of the rule). The strictest *//* constraints are useful for performing type checking on the *//* RHS of the rule. *//*****************************************************************/globle struct lhsParseNode *FindVariable(name,theLHS) SYMBOL_HN *name; struct lhsParseNode *theLHS; { struct lhsParseNode *theFields, *tmpFields = NULL; struct lhsParseNode *theReturnValue = NULL; /*==============================================*/ /* Loop through each CE in the LHS of the rule. */ /*==============================================*/ for (; theLHS != NULL; theLHS = theLHS->bottom) { /*==========================================*/ /* Don't bother searching for the variable */ /* in anything other than a pattern CE that */ /* is not contained within a not CE. */ /*==========================================*/ if ((theLHS->type != PATTERN_CE) || (theLHS->negated == CLIPS_TRUE) || (theLHS->beginNandDepth > 1)) { continue; } /*=====================================*/ /* Check the pattern address variable. */ /*=====================================*/ if (theLHS->value == (VOID *) name) { theReturnValue = theLHS; } /*============================================*/ /* Check for the variable inside the pattern. */ /*============================================*/ theFields = theLHS->right; while (theFields != NULL) { /*=================================================*/ /* Go one level deeper to check a multifield slot. */ /*=================================================*/ if (theFields->multifieldSlot) { tmpFields = theFields; theFields = theFields->bottom; } /*=================================*/ /* See if the field being examined */ /* is the variable being sought. */ /*=================================*/ if (theFields == NULL) { /* Do Nothing */ } else if (((theFields->type == SF_VARIABLE) || (theFields->type == MF_VARIABLE)) && (theFields->value == (VOID *) name)) { theReturnValue = theFields; } /*============================*/ /* Move on to the next field. */ /*============================*/ if (theFields == NULL) { theFields = tmpFields; tmpFields = NULL; } else if ((theFields->right == NULL) && (tmpFields != NULL)) { theFields = tmpFields; tmpFields = NULL; } theFields = theFields->right; } } /*=========================================================*/ /* Return a pointer to the LHS location where the variable */ /* was found (or a NULL pointer if it wasn't). */ /*=========================================================*/ return(theReturnValue); } /**********************************************************//* AddToDefruleList: Adds a defrule to the list of rules. *//**********************************************************/static VOID AddToDefruleList(rulePtr) struct defrule *rulePtr; { struct defrule *tempRule; struct defruleModule *theModuleItem; theModuleItem = (struct defruleModule *) rulePtr->header.whichModule; if (theModuleItem->header.lastItem == NULL) { theModuleItem->header.firstItem = (struct constructHeader *) rulePtr; } else { tempRule = (struct defrule *) theModuleItem->header.lastItem; while (tempRule != NULL) { tempRule->header.next = (struct constructHeader *) rulePtr; tempRule = tempRule->disjunct; } } theModuleItem->header.lastItem = (struct constructHeader *) rulePtr; } #endif /* (! RUN_TIME) && (! BLOAD_ONLY) */#endif /* DEFRULE_CONSTRUCT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -