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

📄 cstrnops.c

📁 VC嵌入式CLips专家系统,实现战场环境的目标识别
💻 C
📖 第 1 页 / 共 3 页
字号:
     }
   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.   */
      /*================================================*/

      for (;
           tmpmin2 != NULL;
           tmpmin2 = tmpmin2->nextArg, tmpmax2 = tmpmax2->nextArg)
        {
         /*==============================================*/
         /* Determine the relationship between the four  */
         /* combinations of min/max values (>, <, or =). */
         /*==============================================*/

         cmaxmax = CompareNumbers(theEnv,tmpmax1->type,tmpmax1->value,
                                  tmpmax2->type,tmpmax2->value);

         cminmin = CompareNumbers(theEnv,tmpmin1->type,tmpmin1->value,
                                  tmpmin2->type,tmpmin2->value);

         cmaxmin = CompareNumbers(theEnv,tmpmax1->type,tmpmax1->value,
                                  tmpmin2->type,tmpmin2->value);

         cminmax = CompareNumbers(theEnv,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(theEnv,tmpmin1->type,tmpmin1->value); }
         else
           { theMin = GenConstant(theEnv,tmpmin2->type,tmpmin2->value); }

         /*=======================================*/
         /* Compute the new maximum value for the */
         /* intersected range/min/max values.     */
         /*=======================================*/

         if (cmaxmax == LESS_THAN)
           { theMax = GenConstant(theEnv,tmpmax1->type,tmpmax1->value); }
         else
           { theMax = GenConstant(theEnv,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(theEnv,newConstraint->minValue);
         ReturnExpression(theEnv,newConstraint->maxValue);
         newConstraint->minValue = theMinList;
         newConstraint->maxValue = theMaxList;
        }
      else
        {
         ReturnExpression(theEnv,newConstraint->minFields);
         ReturnExpression(theEnv,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,FALSE);
         newConstraint->integersAllowed = FALSE;
         newConstraint->floatsAllowed = FALSE;
        }
      else
        {
         SetAnyAllowedFlags(newConstraint,TRUE);
         newConstraint->singlefieldsAllowed = FALSE;
         newConstraint->multifieldsAllowed = FALSE;
         newConstraint->anyAllowed = 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(
  CONSTRAINT_RECORD *rv)
  {
   if ((rv->anyRestriction) && (rv->restrictionList == NULL))
     {
      SetAnyAllowedFlags(rv,TRUE);
      rv->anyAllowed = FALSE;
     }

   if ((rv->symbolRestriction) && (rv->symbolsAllowed))
     { rv->symbolsAllowed = FindItemInExpression(SYMBOL,NULL,FALSE,rv->restrictionList); }

   if ((rv->stringRestriction)  && (rv->stringsAllowed))
     { rv->stringsAllowed = FindItemInExpression(STRING,NULL,FALSE,rv->restrictionList); }

   if ((rv->floatRestriction) && (rv->floatsAllowed))
     { rv->floatsAllowed = FindItemInExpression(FLOAT,NULL,FALSE,rv->restrictionList); }

   if ((rv->integerRestriction) && (rv->integersAllowed))
     { rv->integersAllowed = FindItemInExpression(INTEGER,NULL,FALSE,rv->restrictionList); }

   if ((rv->instanceNameRestriction) && (rv->instanceNamesAllowed))
     { rv->instanceNamesAllowed = FindItemInExpression(INSTANCE_NAME,NULL,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(
  int theType,
  void *theValue,
  int useValue,
  struct expr *theList)
  {
   while (theList != NULL)
     {
      if (theList->type == theType)
        {
         if (! useValue) return(TRUE);
         else if (theList->value == theValue) return(TRUE);
        }

      theList = theList->nextArg;
     }

   return(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(
  int theType,
  CONSTRAINT_RECORD *theConstraint)
  {
   if (theConstraint == NULL) return(FALSE);

   if ((theConstraint->anyRestriction) ||
       (theConstraint->symbolRestriction && (theType == SYMBOL)) ||
       (theConstraint->stringRestriction && (theType == STRING)) ||
       (theConstraint->floatRestriction && (theType == FLOAT)) ||
       (theConstraint->integerRestriction && (theType == INTEGER)) ||
       (theConstraint->classRestriction && ((theType == INSTANCE_ADDRESS) ||
                                            (theType == INSTANCE_NAME))) ||
       (theConstraint->instanceNameRestriction && (theType == INSTANCE_NAME)))
     { return(TRUE); }

   return(FALSE);
  }

/**********************************************************/
/* UnionConstraints: Creates a new constraint record that */
/*   is the union of two other constraint records.        */
/**********************************************************/
globle struct constraintRecord *UnionConstraints(
  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)) return(GetConstraintRecord(theEnv));

   /*=====================================================*/
   /* 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(theEnv,c2));

   if (c2 == NULL) return(CopyConstraintRecord(theEnv,c1));

   /*=================================*/
   /* Create a new constraint record. */
   /*=================================*/

   rv = GetConstraintRecord(theEnv);

   /*==========================*/
   /* Union the allowed types. */
   /*==========================*/

   if (c1->multifieldsAllowed || c2->multifieldsAllowed)
     { rv->multifieldsAllowed = TRUE; }

   if (c1->singlefieldsAllowed || c2->singlefieldsAllowed)
     { rv->singlefieldsAllowed = TRUE; }

   if (c1->anyAllowed || c2->anyAllowed) rv->anyAllowed = TRUE;
   else
     {
      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->factAddressesAllowed = (c1->factAddressesAllowed || c2->factAddressesAllowed);
     }

   /*=================================*/
   /* Union the allowed-values flags. */
   /*=================================*/

   if (c1->anyRestriction && c2->anyRestriction) rv->anyRestriction = TRUE;
   else
     {
      if (c1->anyRestriction)
        {
         c1Changed = TRUE;
         SetAnyRestrictionFlags(c1,FALSE);
        }
      else if (c2->anyRestriction)
        {
         c2Changed = TRUE;
         SetAnyRestrictionFlags(c2,FALSE);
        }

      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);

      if (c1Changed) SetAnyRestrictionFlags(c1,FALSE);
      else if (c2Changed) SetAnyRestrictionFlags(c2,FALSE);
     }

   /*========================================*/
   /* Union the allowed values list, the min */
   /* and max values, and the range values.  */
   /*========================================*/

   UnionAllowedValueExpressions(theEnv,c1,c2,rv);
   UnionAllowedClassExpressions(theEnv,c1,c2,rv);
   UnionNumericExpressions(theEnv,c1,c2,rv,TRUE);
   UnionNumericExpressions(theEnv,c1,c2,rv,FALSE);

   /*========================================*/
   /* If multifields are allowed, then union */
   /* the constraint record for them.        */
   /*========================================*/

   if (rv->multifieldsAllowed)
     { rv->multifield = UnionConstraints(theEnv,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(
  void *theEnv,
  CONSTRAINT_RECORD *constraint1,
  CONSTRAINT_RECORD *constraint2,
  CONSTRAINT_RECORD *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;
     }

⌨️ 快捷键说明

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