⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rulecstr.c

📁 clips源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
   /*******************************************************/   /*      "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 + -