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

📄 cstrnops.c

📁 一套美国国家宇航局人工智能中心NASA的专家系统工具源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
      for (;           tmpmin2 != NULL;           tmpmin2 = tmpmin2->nextArg, tmpmax2 = tmpmax2->nextArg)        {         /*==============================================*/         /* Determine the relationship between the four  */         /* combinations of min/max values (>, <, or =). */         /*==============================================*/                  cmaxmax = CompareNumbers(tmpmax1->type,tmpmax1->value,                                  tmpmax2->type,tmpmax2->value);                                    cminmin = CompareNumbers(tmpmin1->type,tmpmin1->value,                                  tmpmin2->type,tmpmin2->value);                                        cmaxmin = CompareNumbers(tmpmax1->type,tmpmax1->value,                                  tmpmin2->type,tmpmin2->value);                                    cminmax = CompareNumbers(tmpmin1->type,tmpmin1->value,                                  tmpmax2->type,tmpmax2->value);                      /*============================================*/         /* If the range/min/max values don't overlap, */         /* then proceed to the next pair of numbers   */         /* to see if they overlap.                    */         /*============================================*/                  if ((cmaxmin == LESS_THAN) || (cminmax == GREATER_THAN))           { continue; }             /*=======================================*/         /* Compute the new minimum value for the */         /* intersected range/min/max values.     */         /*=======================================*/                   if (cminmin == GREATER_THAN)           { theMin = GenConstant(tmpmin1->type,tmpmin1->value); }         else           { theMin = GenConstant(tmpmin2->type,tmpmin2->value); }                    /*=======================================*/         /* Compute the new maximum value for the */         /* intersected range/min/max values.     */         /*=======================================*/                       if (cmaxmax == LESS_THAN)           { theMax = GenConstant(tmpmax1->type,tmpmax1->value); }         else           { theMax = GenConstant(tmpmax2->type,tmpmax2->value); }                       /*==================================*/         /* Add the new range/min/max values */         /* to the intersection list.        */         /*==================================*/                  if (lastMin == NULL)            {            theMinList = theMin;            theMaxList = theMax;           }         else           {            lastMin->nextArg = theMin;            lastMax->nextArg = theMax;           }                       lastMin = theMin;         lastMax = theMax;        }     }        /*============================================================*/   /* If the intersection produced a pair of valid range/min/max */   /* values, then replace the previous values of the constraint */   /* record to the new intersected values.                      */   /*============================================================*/      if (theMinList != NULL)     {      if (range)        {         ReturnExpression(newConstraint->minValue);         ReturnExpression(newConstraint->maxValue);         newConstraint->minValue = theMinList;         newConstraint->maxValue = theMaxList;        }      else        {         ReturnExpression(newConstraint->minFields);         ReturnExpression(newConstraint->maxFields);         newConstraint->minFields = theMinList;         newConstraint->maxFields = theMaxList;        }     }        /*===============================================================*/   /* Otherwise, the intersection produced no valid range/min/max   */   /* values. For the range attribute, this means that no numbers   */   /* can satisfy the constraint. For the min/max fields attribute, */   /* it means that no value can satisfy the constraint.            */   /*===============================================================*/      else     {      if (range)        {         if (newConstraint->anyAllowed) SetAnyAllowedFlags(newConstraint,CLIPS_FALSE);         newConstraint->integersAllowed = CLIPS_FALSE;         newConstraint->floatsAllowed = CLIPS_FALSE;        }      else        {         SetAnyAllowedFlags(newConstraint,CLIPS_TRUE);         newConstraint->singlefieldsAllowed = CLIPS_FALSE;         newConstraint->multifieldsAllowed = CLIPS_FALSE;         newConstraint->anyAllowed = CLIPS_FALSE;        }     }  }/************************************************************//* UpdateRestrictionFlags: Updates the types allowed flags  *//*   based on the allowed values in a constraint record.    *//*   Intended to be called after the allowed values list    *//*   has been changed (for example after intersecting the   *//*   allowed-values list there may no be any values of a    *//*   particular type left even though the type is allowed). *//************************************************************/static VOID UpdateRestrictionFlags(rv)  CONSTRAINT_RECORD *rv;  {   if ((rv->anyRestriction) && (rv->restrictionList == NULL))     {      SetAnyAllowedFlags(rv,CLIPS_TRUE);      rv->anyAllowed = CLIPS_FALSE;     }        if ((rv->symbolRestriction) && (rv->symbolsAllowed))     { rv->symbolsAllowed = FindItemInExpression(SYMBOL,NULL,CLIPS_FALSE,rv->restrictionList); }        if ((rv->stringRestriction)  && (rv->stringsAllowed))     { rv->stringsAllowed = FindItemInExpression(STRING,NULL,CLIPS_FALSE,rv->restrictionList); }        if ((rv->floatRestriction) && (rv->floatsAllowed))     { rv->floatsAllowed = FindItemInExpression(FLOAT,NULL,CLIPS_FALSE,rv->restrictionList); }        if ((rv->integerRestriction) && (rv->integersAllowed))      { rv->integersAllowed = FindItemInExpression(INTEGER,NULL,CLIPS_FALSE,rv->restrictionList); }           if ((rv->instanceNameRestriction) && (rv->instanceNamesAllowed))     { rv->instanceNamesAllowed = FindItemInExpression(INSTANCE_NAME,NULL,CLIPS_FALSE,rv->restrictionList); }  }/*************************************************************//* FindItemInExpression: Determines if a particular constant */ /*   (such as 27) or a class of constants (such as integers) *//*   can be found in a list of constants. Returns TRUE if    *//*   such a constant can be found, otherwise FALSE.          *//*************************************************************/static int FindItemInExpression(theType,theValue,useValue,theList)  int theType;  VOID *theValue;  int useValue;  struct expr *theList;  {   while (theList != NULL)     {      if (theList->type == theType)         {         if (! useValue) return(CLIPS_TRUE);         else if (theList->value == theValue) return(CLIPS_TRUE);        }            theList = theList->nextArg;     }        return(CLIPS_FALSE);  }  #if (! BLOAD_ONLY)/**************************************************//* RestrictionOnType: Determines if a restriction *//*   is present for a specific type. Returns TRUE *//*   if there is, otherwise FALSE.                *//**************************************************/static int RestrictionOnType(theType,theConstraint)  int theType;  CONSTRAINT_RECORD *theConstraint;  {   if (theConstraint == NULL) return(CLIPS_FALSE);      if ((theConstraint->anyRestriction) ||       (theConstraint->symbolRestriction && (theType == SYMBOL)) ||       (theConstraint->stringRestriction && (theType == STRING)) ||       (theConstraint->floatRestriction && (theType == FLOAT)) ||       (theConstraint->integerRestriction && (theType == INTEGER)) ||       (theConstraint->instanceNameRestriction && (theType == INSTANCE_NAME)))     { return(CLIPS_TRUE); }        return(CLIPS_FALSE);  }   /**********************************************************//* UnionConstraints: Creates a new constraint record that *//*   is the union of two other constraint records.        *//**********************************************************/globle struct constraintRecord *UnionConstraints(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)) return(GetConstraintRecord());      /*=====================================================*/   /* If one of the constraint records is NULL, then the  */   /* union is the other constraint record. Note that     */   /* this is different from the way that intersections   */   /* were handled (a NULL constraint record implied that */   /*  any value was legal which in turn would imply that */   /* the union would allow any value as well).           */   /*=====================================================*/   if (c1 == NULL) return(CopyConstraintRecord(c2));      if (c2 == NULL) return(CopyConstraintRecord(c1));             /*=================================*/   /* Create a new constraint record. */   /*=================================*/             rv = GetConstraintRecord();      /*==========================*/   /* Union the allowed types. */   /*==========================*/         if (c1->multifieldsAllowed || c2->multifieldsAllowed)      { rv->multifieldsAllowed = CLIPS_TRUE; }        if (c1->singlefieldsAllowed || c2->singlefieldsAllowed)      { rv->singlefieldsAllowed = CLIPS_TRUE; }         if (c1->anyAllowed || c2->anyAllowed) rv->anyAllowed = CLIPS_TRUE;   else     {      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->factAddressesAllowed = (c1->factAddressesAllowed || c2->factAddressesAllowed);     }        /*=================================*/   /* Union the allowed-values flags. */   /*=================================*/      if (c1->anyRestriction && c2->anyRestriction) rv->anyRestriction = CLIPS_TRUE;   else     {      if (c1->anyRestriction)        {         c1Changed = CLIPS_TRUE;         SetAnyRestrictionFlags(c1,CLIPS_FALSE);        }      else if (c2->anyRestriction)        {         c2Changed = CLIPS_TRUE;         SetAnyRestrictionFlags(c2,CLIPS_FALSE);        }              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);      if (c1Changed) SetAnyRestrictionFlags(c1,CLIPS_FALSE);      else if (c2Changed) SetAnyRestrictionFlags(c2,CLIPS_FALSE);     }           /*========================================*/   /* Union the allowed values list, the min */   /* and max values, and the range values.  */   /*========================================*/     UnionAllowedValueExpressions(c1,c2,rv);   UnionNumericExpressions(c1,c2,rv,CLIPS_TRUE);   UnionNumericExpressions(c1,c2,rv,CLIPS_FALSE);      /*========================================*/   /* If multifields are allowed, then union */   /* the constraint record for them.        */   /*========================================*/   if (rv->multifieldsAllowed)      { rv->multifield = UnionConstraints(c1->multifield,c2->multifield); }      /*====================*/   /* Return the unioned */   /* constraint record. */   /*====================*/    return(rv);  }     /**************************************************//* UnionNumericExpressions: Creates the union of  *//*   two range or two min/max-fields constraints. *//**************************************************/static VOID UnionNumericExpressions(constraint1,constraint2,newConstraint,range)  CONSTRAINT_RECORD *constraint1, *constraint2, *newConstraint;  int range;  {   struct expr *tmpmin, *tmpmax;   struct expr *theMinList, *theMaxList;      /*=========================================*/   /* Initialize the new range/min/max values */   /* for the union of the constraints.       */   /*=========================================*/      theMinList = NULL;   theMaxList = NULL;      /*=================================*/   /* Determine the min/max values of */   /* the first constraint record.    */   /*=================================*/   if (range)     {      tmpmin = constraint1->minValue;      tmpmax = constraint1->maxValue;     }   else     {      tmpmin = constraint1->minFields;      tmpmax = constraint1->maxFields;     }      /*============================================*/   /* Add each range/min/max pair from the first */   /* constraint record to the union list.       */   /*============================================*/

⌨️ 快捷键说明

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