?? rulecstr.c
字號:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.24 06/05/06 */ /* */ /* RULE CONSTRAINTS MODULE */ /*******************************************************//*************************************************************//* Purpose: Provides routines for detecting constraint *//* conflicts in the LHS and RHS of rules. *//* *//* Principal Programmer(s): *//* Gary D. Riley *//* *//* Contributing Programmer(s): *//* *//* Revision History: *//* *//* 6.24: Renamed BOOLEAN macro type to intBool. *//* *//*************************************************************/#define _RULECSTR_SOURCE_#include "setup.h"#if (! RUN_TIME) && (! BLOAD_ONLY) && DEFRULE_CONSTRUCT#include <stdio.h>#define _STDIO_INCLUDED_#include "analysis.h"#include "cstrnchk.h"#include "cstrnops.h"#include "cstrnutl.h"#include "envrnmnt.h"#include "extnfunc.h"#include "prcdrpsr.h"#include "reorder.h"#include "router.h"#include "rulepsr.h"#include "rulecstr.h"/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/ static intBool CheckForUnmatchableConstraints(void *,struct lhsParseNode *,int); static intBool MultifieldCardinalityViolation(void *,struct lhsParseNode *); static struct lhsParseNode *UnionVariableConstraints(void *,struct lhsParseNode *, struct lhsParseNode *); static struct lhsParseNode *AddToVariableConstraints(void *,struct lhsParseNode *, struct lhsParseNode *); static void ConstraintConflictMessage(void *,struct symbolHashNode *, int,int,struct symbolHashNode *); static intBool CheckArgumentForConstraintError(void *,struct expr *,struct expr*, int,struct FunctionDefinition *, struct lhsParseNode *);/***********************************************************//* CheckForUnmatchableConstraints: Determines if a LHS CE *//* node contains unmatchable constraints. Return TRUE if *//* there are unmatchable constraints, otherwise FALSE. *//***********************************************************/static intBool CheckForUnmatchableConstraints( void *theEnv, struct lhsParseNode *theNode, int whichCE) { if (EnvGetStaticConstraintChecking(theEnv) == FALSE) return(FALSE); if (UnmatchableConstraint(theNode->constraints)) { ConstraintConflictMessage(theEnv,(SYMBOL_HN *) theNode->value,whichCE, theNode->index,theNode->slot); return(TRUE); } return(FALSE); }/******************************************************//* ConstraintConflictMessage: Error message used when *//* a constraint restriction for a slot prevents any *//* value from matching the pattern constraint. *//******************************************************/static void ConstraintConflictMessage( void *theEnv, struct symbolHashNode *variableName, int thePattern, int theField, struct symbolHashNode *theSlot) { /*=========================*/ /* Print the error header. */ /*=========================*/ PrintErrorID(theEnv,"RULECSTR",1,TRUE); /*======================================================*/ /* Print the variable name (if available) and CE number */ /* for which the constraint violation occurred. */ /*======================================================*/ if (variableName != NULL) { EnvPrintRouter(theEnv,WERROR,"Variable ?"); EnvPrintRouter(theEnv,WERROR,ValueToString(variableName)); EnvPrintRouter(theEnv,WERROR," in CE #"); PrintLongInteger(theEnv,WERROR,(long int) thePattern); } else { EnvPrintRouter(theEnv,WERROR,"Pattern #"); PrintLongInteger(theEnv,WERROR,(long int) thePattern); } /*=======================================*/ /* Print the slot name or field position */ /* in which the violation occurred. */ /*=======================================*/ if (theSlot == NULL) { EnvPrintRouter(theEnv,WERROR," field #"); PrintLongInteger(theEnv,WERROR,(long int) theField); } else { EnvPrintRouter(theEnv,WERROR," slot "); EnvPrintRouter(theEnv,WERROR,ValueToString(theSlot)); } /*======================================*/ /* Print the rest of the error message. */ /*======================================*/ EnvPrintRouter(theEnv,WERROR,"\nhas constraint conflicts which make the pattern unmatchable.\n"); }/***************************************************************//* MultifieldCardinalityViolation: Determines if a cardinality *//* violation has occurred for a LHS CE node. *//***************************************************************/static intBool MultifieldCardinalityViolation( void *theEnv, struct lhsParseNode *theNode) { struct lhsParseNode *tmpNode; struct expr *tmpMax; long minFields = 0; long maxFields = 0; int posInfinity = FALSE; CONSTRAINT_RECORD *newConstraint, *tempConstraint; /*================================*/ /* A single field slot can't have */ /* a cardinality violation. */ /*================================*/ if (theNode->multifieldSlot == FALSE) return(FALSE); /*=============================================*/ /* Determine the minimum and maximum number of */ /* fields the slot could contain based on the */ /* slot constraints found in the pattern. */ /*=============================================*/ for (tmpNode = theNode->bottom; tmpNode != NULL; tmpNode = tmpNode->right) { /*====================================================*/ /* A single field variable increases both the minimum */ /* and maximum number of fields by one. */ /*====================================================*/ if ((tmpNode->type == SF_VARIABLE) || (tmpNode->type == SF_WILDCARD)) { minFields++; maxFields++; } /*=================================================*/ /* Otherwise a multifield wildcard or variable has */ /* been encountered. If it is constrained then use */ /* minimum and maximum number of fields constraint */ /* associated with this LHS node. */ /*=================================================*/ else if (tmpNode->constraints != NULL) { /*=======================================*/ /* The lowest minimum of all the min/max */ /* pairs will be the first in the list. */ /*=======================================*/ if (tmpNode->constraints->minFields->value != SymbolData(theEnv)->NegativeInfinity) { minFields += (long) ValueToLong(tmpNode->constraints->minFields->value); } /*=========================================*/ /* The greatest maximum of all the min/max */ /* pairs will be the last in the list. */ /*=========================================*/ tmpMax = tmpNode->constraints->maxFields; while (tmpMax->nextArg != NULL) tmpMax = tmpMax->nextArg; if (tmpMax->value == SymbolData(theEnv)->PositiveInfinity) { posInfinity = TRUE; } else { maxFields += (long) ValueToLong(tmpMax->value); } } /*================================================*/ /* Otherwise an unconstrained multifield wildcard */ /* or variable increases the maximum number of */ /* fields to positive infinity. */ /*================================================*/ else { posInfinity = TRUE; } } /*==================================================================*/ /* Create a constraint record for the cardinality of the sum of the */ /* cardinalities of the restrictions inside the multifield slot. */ /*==================================================================*/ if (theNode->constraints == NULL) tempConstraint = GetConstraintRecord(theEnv); else tempConstraint = CopyConstraintRecord(theEnv,theNode->constraints); ReturnExpression(theEnv,tempConstraint->minFields); ReturnExpression(theEnv,tempConstraint->maxFields); tempConstraint->minFields = GenConstant(theEnv,INTEGER,EnvAddLong(theEnv,(long long) minFields)); if (posInfinity) tempConstraint->maxFields = GenConstant(theEnv,SYMBOL,SymbolData(theEnv)->PositiveInfinity); else tempConstraint->maxFields = GenConstant(theEnv,INTEGER,EnvAddLong(theEnv,(long long) maxFields)); /*================================================================*/ /* Determine the final cardinality for the multifield slot by */ /* intersecting the cardinality sum of the restrictions within */ /* the multifield slot with the original cardinality of the slot. */ /*================================================================*/ newConstraint = IntersectConstraints(theEnv,theNode->constraints,tempConstraint); if (theNode->derivedConstraints) RemoveConstraint(theEnv,theNode->constraints); RemoveConstraint(theEnv,tempConstraint); theNode->constraints = newConstraint; theNode->derivedConstraints = TRUE; /*===================================================================*/ /* Determine if the final cardinality for the slot can be satisfied. */ /*===================================================================*/ if (EnvGetStaticConstraintChecking(theEnv) == FALSE) return(FALSE); if (UnmatchableConstraint(newConstraint)) return(TRUE); return(FALSE); }/***************************************************//* ProcessConnectedConstraints: Examines a single *//* connected constraint searching for constraint *//* violations. *//***************************************************/globle intBool ProcessConnectedConstraints( void *theEnv, struct lhsParseNode *theNode, struct lhsParseNode *multifieldHeader, struct lhsParseNode *patternHead) { struct constraintRecord *orConstraints = NULL, *andConstraints; struct constraintRecord *tmpConstraints, *rvConstraints; struct lhsParseNode *orNode, *andNode; struct expr *tmpExpr; /*============================================*/ /* Loop through all of the or (|) constraints */ /* found in the connected constraint. */ /*============================================*/ for (orNode = theNode->bottom; orNode != NULL; orNode = orNode->bottom) { /*=================================================*/ /* Intersect all of the &'ed constraints together. */ /*=================================================*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -