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

📄 cstrnops.c

📁 clips源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
   /*******************************************************/   /*      "C" Language Integrated Production System      */   /*                                                     */   /*             CLIPS Version 6.24  07/01/05            */   /*                                                     */   /*            CONSTRAINT OPERATIONS MODULE             */   /*******************************************************//*************************************************************//* Purpose: Provides functions for performing operations on  *//*   constraint records including computing the intersection *//*   and union of constraint records.                        *//*                                                           *//* Principal Programmer(s):                                  *//*      Gary D. Riley                                        *//*                                                           *//* Contributing Programmer(s):                               *//*                                                           *//* Revision History:                                         *//*                                                           *//*      6.24: Added allowed-classes slot facet.              *//*                                                           *//*************************************************************/#define _CSTRNOPS_SOURCE_#include "setup.h"#include <stdio.h>#define _STDIO_INCLUDED_#include <stdlib.h>#if (! RUN_TIME)#include "constant.h"#include "envrnmnt.h"#include "memalloc.h"#include "router.h"#include "extnfunc.h"#include "scanner.h"#include "multifld.h"#include "constrnt.h"#include "cstrnchk.h"#include "cstrnutl.h"#include "cstrnops.h"/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/   static void                     IntersectNumericExpressions(void *,                                                               CONSTRAINT_RECORD *,                                                               CONSTRAINT_RECORD *,                                                               CONSTRAINT_RECORD *,int);   static void                     IntersectAllowedValueExpressions(void *,                                                                    CONSTRAINT_RECORD *,                                                                    CONSTRAINT_RECORD *,                                                                    CONSTRAINT_RECORD *);   static void                     IntersectAllowedClassExpressions(void *,                                                                    CONSTRAINT_RECORD *,                                                                    CONSTRAINT_RECORD *,                                                                    CONSTRAINT_RECORD *);   static int                      FindItemInExpression(int,void *,int,struct expr *);   static void                     UpdateRestrictionFlags(CONSTRAINT_RECORD *);#if (! BLOAD_ONLY)   static void                     UnionRangeMinMaxValueWithList(void *,                                                                 struct expr *,                                                                 struct expr *,                                                                 struct expr **,                                                                 struct expr **);   static void                     UnionNumericExpressions(void *,                                                         CONSTRAINT_RECORD *,                                                         CONSTRAINT_RECORD *,                                                         CONSTRAINT_RECORD *,int);   static struct expr             *AddToUnionList(void *,                                                  struct expr *,struct expr *,                                                  CONSTRAINT_RECORD *);   static void                     UnionAllowedValueExpressions(void *,                                                                CONSTRAINT_RECORD *,                                                                CONSTRAINT_RECORD *,                                                                CONSTRAINT_RECORD *);   static void                     UnionAllowedClassExpressions(void *,                                                                CONSTRAINT_RECORD *,                                                                CONSTRAINT_RECORD *,                                                                CONSTRAINT_RECORD *);   static int                      RestrictionOnType(int,CONSTRAINT_RECORD *);#endif/**************************************************************//* IntersectConstraints: Creates a new constraint record that *//*   is the intersection of two other constraint records.     *//**************************************************************/globle struct constraintRecord *IntersectConstraints(  void *theEnv,  CONSTRAINT_RECORD *c1,  CONSTRAINT_RECORD *c2)  {   struct constraintRecord *rv;   int c1Changed = FALSE, c2Changed = FALSE;   /*=================================================*/   /* If both constraint records are NULL,then create */   /* a constraint record that allows any value.      */   /*=================================================*/   if ((c1 == NULL) && (c2 == NULL))     {      rv = GetConstraintRecord(theEnv);      rv->multifieldsAllowed = TRUE;      return(rv);     }   /*=================================================*/   /* If one of the constraint records is NULL, then  */   /* the intersection is the other constraint record */   /* (a NULL value means no constraints).            */   /*=================================================*/   if (c1 == NULL) return(CopyConstraintRecord(theEnv,c2));   if (c2 == NULL) return(CopyConstraintRecord(theEnv,c1));   /*=================================*/   /* Create a new constraint record. */   /*=================================*/   rv = GetConstraintRecord(theEnv);   /*==============================*/   /* Intersect the allowed types. */   /*==============================*/   if ((c1->multifieldsAllowed != c2->multifieldsAllowed) &&       (c1->singlefieldsAllowed != c2->singlefieldsAllowed))     {      rv->anyAllowed = FALSE;      return(rv);     }   if (c1->multifieldsAllowed && c2->multifieldsAllowed)     { rv->multifieldsAllowed = TRUE; }   else     { rv->multifieldsAllowed = FALSE; }   if (c1->singlefieldsAllowed && c2->singlefieldsAllowed)     { rv->singlefieldsAllowed = TRUE; }   else     { rv->singlefieldsAllowed = FALSE; }   if (c1->anyAllowed && c2->anyAllowed) rv->anyAllowed = TRUE;   else     {      if (c1->anyAllowed)        {         c1Changed = TRUE;         SetAnyAllowedFlags(c1,FALSE);        }      else if (c2->anyAllowed)        {         c2Changed = TRUE;         SetAnyAllowedFlags(c2,FALSE);        }      rv->anyAllowed = FALSE;      rv->symbolsAllowed = (c1->symbolsAllowed && c2->symbolsAllowed);      rv->stringsAllowed = (c1->stringsAllowed && c2->stringsAllowed);      rv->floatsAllowed = (c1->floatsAllowed && c2->floatsAllowed);      rv->integersAllowed = (c1->integersAllowed && c2->integersAllowed);      rv->instanceNamesAllowed = (c1->instanceNamesAllowed && c2->instanceNamesAllowed);      rv->instanceAddressesAllowed = (c1->instanceAddressesAllowed && c2->instanceAddressesAllowed);      rv->externalAddressesAllowed = (c1->externalAddressesAllowed && c2->externalAddressesAllowed);      rv->voidAllowed = (c1->voidAllowed && c2->voidAllowed);      rv->multifieldsAllowed = (c1->multifieldsAllowed && c2->multifieldsAllowed);      rv->factAddressesAllowed = (c1->factAddressesAllowed && c2->factAddressesAllowed);      if (c1Changed) SetAnyAllowedFlags(c1,TRUE);      if (c2Changed) SetAnyAllowedFlags(c2,TRUE);     }   /*=====================================*/   /* Intersect the allowed-values flags. */   /*=====================================*/   if (c1->anyRestriction || c2->anyRestriction) rv->anyRestriction = TRUE;   else     {      rv->anyRestriction = FALSE;      rv->symbolRestriction = (c1->symbolRestriction || c2->symbolRestriction);      rv->stringRestriction = (c1->stringRestriction || c2->stringRestriction);      rv->floatRestriction = (c1->floatRestriction || c2->floatRestriction);      rv->integerRestriction = (c1->integerRestriction || c2->integerRestriction);      rv->classRestriction = (c1->classRestriction || c2->classRestriction);      rv->instanceNameRestriction = (c1->instanceNameRestriction || c2->instanceNameRestriction);     }   /*==================================================*/   /* Intersect the allowed values list, allowed class */   /* list, min and max values, and the range values.  */   /*==================================================*/   IntersectAllowedValueExpressions(theEnv,c1,c2,rv);   IntersectAllowedClassExpressions(theEnv,c1,c2,rv);   IntersectNumericExpressions(theEnv,c1,c2,rv,TRUE);   IntersectNumericExpressions(theEnv,c1,c2,rv,FALSE);   /*==========================================*/   /* Update the allowed-values flags based on */   /* the previous intersection for allowed,   */   /* min and max, and range values.           */   /*==========================================*/   UpdateRestrictionFlags(rv);   /*============================================*/   /* If multifields are allowed, then intersect */   /* the constraint record for them.            */   /*============================================*/   if (rv->multifieldsAllowed)     {      rv->multifield = IntersectConstraints(theEnv,c1->multifield,c2->multifield);      if (UnmatchableConstraint(rv->multifield))        { rv->multifieldsAllowed = FALSE; }     }   /*========================*/   /* Return the intersected */   /* constraint record.     */   /*========================*/   return(rv);  }/*************************************************//* IntersectAllowedValueExpressions: Creates the *//*   intersection of two allowed-values lists.   *//*************************************************/static void IntersectAllowedValueExpressions(  void *theEnv,  CONSTRAINT_RECORD *constraint1,  CONSTRAINT_RECORD *constraint2,  CONSTRAINT_RECORD *newConstraint)  {   struct expr *theList1, *theList2;   struct expr *theHead = NULL, *tmpExpr;   /*===========================================*/   /* Loop through each value in allowed-values */   /* list of the first constraint record. Add  */   /* each value to a list if it satisfies the  */   /* restrictions for both constraint records. */   /*===========================================*/   for (theList1 = constraint1->restrictionList;        theList1 != NULL;        theList1 = theList1->nextArg)     {      if (CheckAllowedValuesConstraint(theList1->type,theList1->value,constraint1) &&          CheckAllowedValuesConstraint(theList1->type,theList1->value,constraint2))        {         tmpExpr = GenConstant(theEnv,theList1->type,theList1->value);         tmpExpr->nextArg = theHead;         theHead = tmpExpr;        }     }   /*===========================================*/   /* Loop through each value in allowed-values */   /* list of the second constraint record. Add */   /* each value to a list if it satisfies the  */   /* restrictions for both constraint records. */   /*===========================================*/   for (theList2 = constraint2->restrictionList;        theList2 != NULL;        theList2 = theList2->nextArg)     {      if (FindItemInExpression(theList2->type,theList2->value,TRUE,theHead))        { /* The value is already in the list--Do nothing */ }      else if (CheckAllowedValuesConstraint(theList2->type,theList2->value,constraint1) &&               CheckAllowedValuesConstraint(theList2->type,theList2->value,constraint2))        {         tmpExpr = GenConstant(theEnv,theList2->type,theList2->value);         tmpExpr->nextArg = theHead;         theHead = tmpExpr;        }     }   /*================================================*/   /* Set the allowed values list for the constraint */   /* record to the intersected values of the two    */   /* other constraint records.                      */   /*================================================*/   newConstraint->restrictionList = theHead;  }  /*************************************************//* IntersectAllowedClassExpressions: Creates the *//*   intersection of two allowed-classes lists.  *//*************************************************/static void IntersectAllowedClassExpressions(  void *theEnv,  CONSTRAINT_RECORD *constraint1,  CONSTRAINT_RECORD *constraint2,  CONSTRAINT_RECORD *newConstraint)  {   struct expr *theList1, *theList2;   struct expr *theHead = NULL, *tmpExpr;   /*============================================*/   /* Loop through each value in allowed-classes */   /* list of the first constraint record. Add   */   /* each value to a list if it satisfies the   */   /* restrictions for both constraint records.  */   /*============================================*/      for (theList1 = constraint1->classList;        theList1 != NULL;        theList1 = theList1->nextArg)     {      if (CheckAllowedClassesConstraint(theEnv,theList1->type,theList1->value,constraint1) &&          CheckAllowedClassesConstraint(theEnv,theList1->type,theList1->value,constraint2))        {         tmpExpr = GenConstant(theEnv,theList1->type,theList1->value);         tmpExpr->nextArg = theHead;         theHead = tmpExpr;        }     }   /*============================================*/   /* Loop through each value in allowed-classes */   /* list of the second constraint record. Add  */   /* each value to a list if it satisfies the   */   /* restrictions for both constraint records.  */   /*============================================*/   for (theList2 = constraint2->classList;        theList2 != NULL;        theList2 = theList2->nextArg)     {      if (FindItemInExpression(theList2->type,theList2->value,TRUE,theHead))        { /* The value is already in the list--Do nothing */ }      else if (CheckAllowedClassesConstraint(theEnv,theList2->type,theList2->value,constraint1) &&               CheckAllowedClassesConstraint(theEnv,theList2->type,theList2->value,constraint2))        {         tmpExpr = GenConstant(theEnv,theList2->type,theList2->value);         tmpExpr->nextArg = theHead;         theHead = tmpExpr;        }     }   /*=================================================*/   /* Set the allowed classes list for the constraint */   /* record to the intersected values of the two     */   /* other constraint records.                       */   /*=================================================*/   newConstraint->classList = theHead;  }  /*********************************************************//* IntersectNumericExpressions: Creates the intersection *//*   of two range or two min/max-fields constraints.     *//*********************************************************/static void IntersectNumericExpressions(  void *theEnv,  CONSTRAINT_RECORD *constraint1,  CONSTRAINT_RECORD *constraint2,  CONSTRAINT_RECORD *newConstraint,  int range)  {   struct expr *tmpmin1, *tmpmax1, *tmpmin2, *tmpmax2, *theMin, *theMax;   struct expr *theMinList, *theMaxList, *lastMin = NULL, *lastMax = NULL;   int cmaxmax, cminmin, cmaxmin, cminmax;   /*==========================================*/   /* Initialize the new range/min/max values  */   /* for the intersection of the constraints. */   /*==========================================*/   theMinList = NULL;   theMaxList = NULL;   /*=================================*/   /* Determine the min/max values of */   /* the first constraint record.    */   /*=================================*/   if (range)     {      tmpmin1 = constraint1->minValue;      tmpmax1 = constraint1->maxValue;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -