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

📄 cstrnops.c

📁 NASA 开发使用的一个专家系统
💻 C
📖 第 1 页 / 共 3 页
字号:
   /*******************************************************/   /*      "C" Language Integrated Production System      */   /*                                                     */   /*             CLIPS Version 6.05  04/09/97            */   /*                                                     */   /*            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:                                         *//*                                                           *//*************************************************************/#define _CSTRNOPS_SOURCE_#include "setup.h"#include <stdio.h>#define _CLIPS_STDIO_#if ANSI_COMPILER#include <stdlib.h>#endif#if (! RUN_TIME)#include "constant.h"#include "clipsmem.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 *//***************************************/#if ANSI_COMPILER   static VOID                     IntersectNumericExpressions(CONSTRAINT_RECORD *,                                                             CONSTRAINT_RECORD *,                                                             CONSTRAINT_RECORD *,int);   static VOID                     IntersectAllowedValueExpressions(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(struct expr *,                                                                 struct expr *,                                                                 struct expr **,                                                                 struct expr **);   static VOID                     UnionNumericExpressions(CONSTRAINT_RECORD *,                                                         CONSTRAINT_RECORD *,                                                         CONSTRAINT_RECORD *,int);   static struct expr             *AddToUnionList(struct expr *,struct expr *,                                                  CONSTRAINT_RECORD *);   static VOID                     UnionAllowedValueExpressions(CONSTRAINT_RECORD *,                                                                CONSTRAINT_RECORD *,                                                                CONSTRAINT_RECORD *);   static int                      RestrictionOnType(int,CONSTRAINT_RECORD *);#endif#else   static VOID                     IntersectNumericExpressions();   static VOID                     IntersectAllowedValueExpressions();   static int                      FindItemInExpression();   static VOID                     UpdateRestrictionFlags();#if (! BLOAD_ONLY)   static VOID                     UnionRangeMinMaxValueWithList();   static VOID                     UnionNumericExpressions();   static struct expr             *AddToUnionList();   static VOID                     UnionAllowedValueExpressions();   static int                      RestrictionOnType();#endif#endif   /**************************************************************//* IntersectConstraints: Creates a new constraint record that *//*   is the intersection of two other constraint records.     *//**************************************************************/globle struct constraintRecord *IntersectConstraints(c1,c2)  CONSTRAINT_RECORD *c1, *c2;  {   struct constraintRecord *rv;   int c1Changed = CLIPS_FALSE, c2Changed = CLIPS_FALSE;      /*=================================================*/   /* If both constraint records are NULL,then create */   /* a constraint record that allows any value.      */   /*=================================================*/      if ((c1 == NULL) && (c2 == NULL))      {      rv = GetConstraintRecord();      rv->multifieldsAllowed = CLIPS_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(c2));        if (c2 == NULL) return(CopyConstraintRecord(c1));             /*=================================*/   /* Create a new constraint record. */   /*=================================*/      rv = GetConstraintRecord();            /*==============================*/   /* Intersect the allowed types. */   /*==============================*/      if ((c1->multifieldsAllowed != c2->multifieldsAllowed) &&        (c1->singlefieldsAllowed != c2->singlefieldsAllowed))      {       rv->anyAllowed = CLIPS_FALSE;      return(rv);      }      if (c1->multifieldsAllowed && c2->multifieldsAllowed)      { rv->multifieldsAllowed = CLIPS_TRUE; }   else     { rv->multifieldsAllowed = CLIPS_FALSE; }        if (c1->singlefieldsAllowed && c2->singlefieldsAllowed)     { rv->singlefieldsAllowed = CLIPS_TRUE; }   else     { rv->singlefieldsAllowed = CLIPS_FALSE; }         if (c1->anyAllowed && c2->anyAllowed) rv->anyAllowed = CLIPS_TRUE;   else     {      if (c1->anyAllowed)         {         c1Changed = CLIPS_TRUE;         SetAnyAllowedFlags(c1,CLIPS_FALSE);        }      else if (c2->anyAllowed)         {         c2Changed = CLIPS_TRUE;         SetAnyAllowedFlags(c2,CLIPS_FALSE);        }              rv->anyAllowed = CLIPS_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->multifieldsAllowed = (c1->multifieldsAllowed && c2->multifieldsAllowed);      rv->factAddressesAllowed = (c1->factAddressesAllowed && c2->factAddressesAllowed);      if (c1Changed) SetAnyAllowedFlags(c1,CLIPS_TRUE);      if (c2Changed) SetAnyAllowedFlags(c2,CLIPS_TRUE);     }      /*=====================================*/   /* Intersect the allowed-values flags. */   /*=====================================*/      if (c1->anyRestriction || c2->anyRestriction) rv->anyRestriction = CLIPS_TRUE;   else     {      rv->anyRestriction = CLIPS_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->instanceNameRestriction = (c1->instanceNameRestriction || c2->instanceNameRestriction);     }      /*============================================*/   /* Intersect the allowed values list, the min */   /* and max values, and the range values.      */   /*============================================*/      IntersectAllowedValueExpressions(c1,c2,rv);   IntersectNumericExpressions(c1,c2,rv,CLIPS_TRUE);   IntersectNumericExpressions(c1,c2,rv,CLIPS_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(c1->multifield,c2->multifield);      if (UnmatchableConstraint(rv->multifield))         { rv->multifieldsAllowed = CLIPS_FALSE; }     }   /*========================*/   /* Return the intersected */   /* constraint record.     */   /*========================*/      return(rv);  }   /*************************************************//* IntersectAllowedValueExpressions: Creates the *//*   intersection of two allowed-values lists.   *//*************************************************/static VOID IntersectAllowedValueExpressions(constraint1,constraint2,newConstraint)  CONSTRAINT_RECORD *constraint1, *constraint2, *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(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,CLIPS_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(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;  }  /*********************************************************//* IntersectNumericExpressions: Creates the intersection *//*   of two range or two min/max-fields constraints.     *//*********************************************************/static VOID IntersectNumericExpressions(constraint1,constraint2,newConstraint,range)  CONSTRAINT_RECORD *constraint1, *constraint2, *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;     }   else     {      tmpmin1 = constraint1->minFields;      tmpmax1 = constraint1->maxFields;     }      /*===========================================*/   /* Loop through each of range/min/max values */   /* from the first constraint record.         */   /*===========================================*/      for (;        tmpmin1 != NULL;        tmpmin1 = tmpmin1->nextArg, tmpmax1 = tmpmax1->nextArg)     {      /*============================================*/      /* Get the appropriate values from the second */      /* constraint record for comparison.          */      /*============================================*/            if (range)        {         tmpmin2 = constraint2->minValue;         tmpmax2 = constraint2->maxValue;        }      else        {         tmpmin2 = constraint2->minFields;         tmpmax2 = constraint2->maxFields;        }              /*================================================*/      /* Loop through each of range/min/max values from */      /* the second constraint record comparing it to   */      /* the values from the first constraint record.   */      /*================================================*/

⌨️ 快捷键说明

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