示例#1
0
globle int ConstraintCheckDataObject(
  void *theEnv,
  DATA_OBJECT *theData,
  CONSTRAINT_RECORD *theConstraints)
  {
   long i; /* 6.04 Bug Fix */
   int rv;
   struct field *theMultifield;

   if (theConstraints == NULL) return(NO_VIOLATION);

   if (theData->type == MULTIFIELD)
     {
      if (CheckCardinalityConstraint(theEnv,(theData->end - theData->begin) + 1,
                                     theConstraints) == FALSE)
        { return(CARDINALITY_VIOLATION); }

      theMultifield = ((struct multifield *) theData->value)->theFields;
      for (i = theData->begin; i <= theData->end; i++)
        {
         if ((rv = ConstraintCheckValue(theEnv,theMultifield[i].type,
                                        theMultifield[i].value,
                                        theConstraints)) != NO_VIOLATION)
           { return(rv); }
        }

      return(NO_VIOLATION);
     }

   if (CheckCardinalityConstraint(theEnv,1L,theConstraints) == FALSE)
    { return(CARDINALITY_VIOLATION); }

   return(ConstraintCheckValue(theEnv,theData->type,theData->value,theConstraints));
  }
示例#2
0
文件: cstrnchk.c 项目: atrniv/CLIPS
globle int ConstraintCheckExpressionChain(
  void *theEnv,
  EXEC_STATUS,
  struct expr *theExpression,
  CONSTRAINT_RECORD *theConstraints)
  {
   struct expr *theExp;
   int min = 0, max = 0, vCode;

   /*===========================================================*/
   /* Determine the minimum and maximum number of value which   */
   /* can be derived from the expression chain (max of -1 means */
   /* positive infinity).                                       */
   /*===========================================================*/

   for (theExp = theExpression ; theExp != NULL ; theExp = theExp->nextArg)
     {
      if (ConstantType(theExp->type)) min++;
      else if (theExp->type == FCALL)
        {
         if ((ExpressionFunctionType(theExp) != 'm') &&
             (ExpressionFunctionType(theExp) != 'u')) min++;
         else max = -1;
        }
      else max = -1;
     }

   /*====================================*/
   /* Check for a cardinality violation. */
   /*====================================*/

   if (max == 0) max = min;
   if (CheckRangeAgainstCardinalityConstraint(theEnv,execStatus,min,max,theConstraints) == FALSE)
     { return(CARDINALITY_VIOLATION); }

   /*========================================*/
   /* Check for other constraint violations. */
   /*========================================*/

   for (theExp = theExpression ; theExp != NULL ; theExp = theExp->nextArg)
     {
      vCode = ConstraintCheckValue(theEnv,execStatus,theExp->type,theExp->value,theConstraints);
      if (vCode != NO_VIOLATION)
        return(vCode);
     }

   return(NO_VIOLATION);
  }
示例#3
0
globle int ConstraintCheckExpression(
  void *theEnv,
  struct expr *theExpression,
  CONSTRAINT_RECORD *theConstraints)
  {
   int rv = NO_VIOLATION;

   if (theConstraints == NULL) return(rv);

   while (theExpression != NULL)
     {
      rv = ConstraintCheckValue(theEnv,theExpression->type,
                                theExpression->value,
                                theConstraints);
      if (rv != NO_VIOLATION) return(rv);
      rv = ConstraintCheckExpression(theEnv,theExpression->argList,theConstraints);
      if (rv != NO_VIOLATION) return(rv);
      theExpression = theExpression->nextArg;
     }

   return(rv);
  }
示例#4
0
globle intBool CheckConstraintParseConflicts(
  void *theEnv,
  CONSTRAINT_RECORD *constraints)
  {
   /*===================================================*/
   /* Check to see if any of the allowed-... attributes */
   /* conflict with the type attribute.                 */
   /*===================================================*/

   if (constraints->anyAllowed == TRUE)
     { /* Do Nothing */ }
   else if (constraints->symbolRestriction &&
            (constraints->symbolsAllowed == FALSE))
     {
      AttributeConflictErrorMessage(theEnv,"type","allowed-symbols");
      return(FALSE);
     }
   else if (constraints->stringRestriction &&
            (constraints->stringsAllowed == FALSE))
     {
      AttributeConflictErrorMessage(theEnv,"type","allowed-strings");
      return(FALSE);
     }
   else if (constraints->integerRestriction &&
            (constraints->integersAllowed == FALSE))
     {
      AttributeConflictErrorMessage(theEnv,"type","allowed-integers/numbers");
      return(FALSE);
     }
   else if (constraints->floatRestriction &&
            (constraints->floatsAllowed == FALSE))
     {
      AttributeConflictErrorMessage(theEnv,"type","allowed-floats/numbers");
      return(FALSE);
     }
   else if (constraints->classRestriction &&
            (constraints->instanceAddressesAllowed == FALSE) &&
            (constraints->instanceNamesAllowed == FALSE))
     {
      AttributeConflictErrorMessage(theEnv,"type","allowed-classes");
      return(FALSE);
     }
   else if (constraints->instanceNameRestriction &&
            (constraints->instanceNamesAllowed == FALSE))
     {
      AttributeConflictErrorMessage(theEnv,"type","allowed-instance-names");
      return(FALSE);
     }
   else if (constraints->anyRestriction)
     {
      struct expr *theExp;

      for (theExp = constraints->restrictionList;
           theExp != NULL;
           theExp = theExp->nextArg)
        {
         if (ConstraintCheckValue(theEnv,theExp->type,theExp->value,constraints) != NO_VIOLATION)
           {
            AttributeConflictErrorMessage(theEnv,"type","allowed-values");
            return(FALSE);
           }
        }
     }

   /*================================================================*/
   /* Check to see if range attribute conflicts with type attribute. */
   /*================================================================*/

   if ((constraints->maxValue != NULL) &&
       (constraints->anyAllowed == FALSE))
     {
      if (((constraints->maxValue->type == INTEGER) &&
          (constraints->integersAllowed == FALSE)) ||
          ((constraints->maxValue->type == FLOAT) &&
           (constraints->floatsAllowed == FALSE)))
        {
         AttributeConflictErrorMessage(theEnv,"type","range");
         return(FALSE);
        }
     }

   if ((constraints->minValue != NULL) &&
       (constraints->anyAllowed == FALSE))
     {
      if (((constraints->minValue->type == INTEGER) &&
          (constraints->integersAllowed == FALSE)) ||
          ((constraints->minValue->type == FLOAT) &&
           (constraints->floatsAllowed == FALSE)))
        {
         AttributeConflictErrorMessage(theEnv,"type","range");
         return(FALSE);
        }
     }

   /*=========================================*/
   /* Check to see if allowed-class attribute */
   /* conflicts with type attribute.          */
   /*=========================================*/

   if ((constraints->classList != NULL) &&
       (constraints->anyAllowed == FALSE) &&
       (constraints->instanceNamesAllowed == FALSE) &&
       (constraints->instanceAddressesAllowed == FALSE))
     {
      AttributeConflictErrorMessage(theEnv,"type","allowed-class");
      return(FALSE);
     }

   /*=====================================================*/
   /* Return TRUE to indicate no conflicts were detected. */
   /*=====================================================*/

   return(TRUE);
  }
示例#5
0
static intBool UnboundVariablesInPattern(
  void *theEnv,
  struct lhsParseNode *theSlot,
  int pattern)
  {
   struct lhsParseNode *andField;
   struct lhsParseNode *rv;
   int result;
   struct lhsParseNode *orField;
   struct symbolHashNode *slotName;
   CONSTRAINT_RECORD *theConstraints;
   int theField;

   /*===================================================*/
   /* If a multifield slot is being checked, then check */
   /* each of the fields grouped with the multifield.   */
   /*===================================================*/

   if (theSlot->multifieldSlot)
     {
      theSlot = theSlot->bottom;
      while (theSlot != NULL)
        {
         if (UnboundVariablesInPattern(theEnv,theSlot,pattern))
           { return(TRUE); }
         theSlot = theSlot->right;
        }

      return(FALSE);
     }

   /*=======================*/
   /* Check a single field. */
   /*=======================*/

   slotName = theSlot->slot;
   theField = theSlot->index;
   theConstraints = theSlot->constraints;

   /*===========================================*/
   /* Loop through each of the '|' constraints. */
   /*===========================================*/

   for (orField = theSlot->bottom;
        orField != NULL;
        orField = orField->bottom)
     {
      /*===========================================*/
      /* Loop through each of the fields connected */
      /* by the '&' within the '|' constraint.     */
      /*===========================================*/

      for (andField = orField;
           andField != NULL;
           andField = andField->right)
        {
         /*=======================================================*/
         /* If this is not a binding occurence of a variable and  */
         /* there is no previous binding occurence of a variable, */
         /* then generate an error message for a variable that is */
         /* referred to but not bound.                            */
         /*=======================================================*/

         if (((andField->type == SF_VARIABLE) || (andField->type == MF_VARIABLE)) &&
             (andField->referringNode == NULL))
           {
            VariableReferenceErrorMessage(theEnv,(SYMBOL_HN *) andField->value,NULL,pattern,
                                          slotName,theField);
            return(TRUE);
           }

         /*==============================================*/
         /* Check predicate and return value constraints */
         /* to insure that all variables used within the */
         /* constraint have been previously bound.       */
         /*==============================================*/

         else if ((andField->type == PREDICATE_CONSTRAINT) ||
                  (andField->type == RETURN_VALUE_CONSTRAINT))
           {
            rv = CheckExpression(theEnv,andField->expression,NULL,pattern,slotName,theField);
            if (rv != NULL) return(TRUE);
           }

         /*========================================================*/
         /* If static constraint checking is being performed, then */
         /* determine if constant values have violated the set of  */
         /* derived constraints for the slot/field (based on the   */
         /* deftemplate definition and propagated constraints).    */
         /*========================================================*/

         else if (((andField->type == INTEGER) || (andField->type == FLOAT) ||
                   (andField->type == SYMBOL) || (andField->type == STRING) ||
                   (andField->type == INSTANCE_NAME)) &&
                  EnvGetStaticConstraintChecking(theEnv))
           {
            result = ConstraintCheckValue(theEnv,andField->type,andField->value,theConstraints);
            if (result != NO_VIOLATION)
              {
               ConstraintViolationErrorMessage(theEnv,"A literal restriction value",
                                               NULL,FALSE,pattern,
                                               slotName,theField,result,
                                               theConstraints,TRUE);
               return(TRUE);
              }
           }
        }
     }

   /*===============================*/
   /* Return FALSE to indicate that */
   /* no errors were detected.      */
   /*===============================*/

   return(FALSE);
  }