Beispiel #1
0
static int CheckForVariableMixing(
  struct lhsParseNode *theRestriction)
  {
   struct lhsParseNode *tempRestriction;
   CONSTRAINT_RECORD *theConstraint;
   int multifield = FALSE;
   int singlefield = FALSE;
   int constant = FALSE;
   int singleReturnValue = FALSE;
   int multiReturnValue = FALSE;

   /*================================================*/
   /* If the constraint contains a binding variable, */
   /* determine whether it is a single field or      */
   /* multifield variable.                           */
   /*================================================*/

   if (theRestriction->type == SF_VARIABLE) singlefield = TRUE;
   else if (theRestriction->type == MF_VARIABLE) multifield = TRUE;

   /*===========================================*/
   /* Loop through each of the or (|) connected */
   /* constraints within the constraint.        */
   /*===========================================*/

   for (theRestriction = theRestriction->bottom;
        theRestriction != NULL;
        theRestriction = theRestriction->bottom)
     {
      /*============================================*/
      /* Loop through each of the and (&) connected */
      /* constraints within the or (|) constraint.  */
      /*============================================*/

      for (tempRestriction = theRestriction;
           tempRestriction != NULL;
           tempRestriction = tempRestriction->right)
        {
         /*=====================================================*/
         /* Determine if the constraint contains a single field */
         /* variable, multifield variable, constant (a single   */
         /* field), a return value constraint of a function     */
         /* returning a single field value, or a return value   */
         /* constraint of a function returning a multifield     */
         /* value.                                              */
         /*=====================================================*/

         if (tempRestriction->type == SF_VARIABLE) singlefield = TRUE;
         else if (tempRestriction->type == MF_VARIABLE) multifield = TRUE;
         else if (ConstantType(tempRestriction->type)) constant = TRUE;
         else if (tempRestriction->type == RETURN_VALUE_CONSTRAINT)
           {
            theConstraint = FunctionCallToConstraintRecord(tempRestriction->expression->value);
            if (theConstraint->anyAllowed) { /* Do nothing. */ }
            else if (theConstraint->multifieldsAllowed) multiReturnValue = TRUE;
            else singleReturnValue = TRUE;
            RemoveConstraint(theConstraint);
           }
        }
     }

   /*================================================================*/
   /* Using a single field value (a single field variable, constant, */
   /* or function returning a single field value) together with a    */
   /* multifield value (a multifield variable or function returning  */
   /* a multifield value) is illegal. Return TRUE if this occurs.    */
   /*================================================================*/

   if ((singlefield || constant || singleReturnValue) &&
       (multifield || multiReturnValue))

     {
      PrintErrorID("PATTERN",2,TRUE);
      PrintRouter(WERROR,"Single and multifield constraints cannot be mixed in a field constraint\n");
      return(TRUE);
     }

   /*=======================================*/
   /* Otherwise return FALSE to indicate no */
   /* illegal variable mixing was detected. */
   /*=======================================*/

   return(FALSE);
  }
Beispiel #2
0
globle BOOLEAN ProcessConnectedConstraints(
  struct lhsParseNode *theNode,
  struct lhsParseNode *multifieldHeader,
  struct lhsParseNode *patternHead)
  {
   struct constraintRecord *orConstraints = NULL, *andConstraints;
   struct constraintRecord *tmpConstraints, *rvConstraints;
   struct lhsParseNode *orNode, *andNode;
   struct expr *tmpExpr;

   /*============================================*/
   /* Loop through all of the or (|) constraints */
   /* found in the connected constraint.         */
   /*============================================*/

   for (orNode = theNode->bottom; orNode != NULL; orNode = orNode->bottom)
     {
      /*=================================================*/
      /* Intersect all of the &'ed constraints together. */
      /*=================================================*/

      andConstraints = NULL;
      for (andNode = orNode; andNode != NULL; andNode = andNode->right)
        {
         if (! andNode->negated)
           {
            if (andNode->type == RETURN_VALUE_CONSTRAINT)
              {
               if (andNode->expression->type == FCALL)
                 {
                  rvConstraints = FunctionCallToConstraintRecord(andNode->expression->value);
                  tmpConstraints = andConstraints;
                  andConstraints = IntersectConstraints(andConstraints,rvConstraints);
                  RemoveConstraint(tmpConstraints);
                  RemoveConstraint(rvConstraints);
                 }
              }
            else if (ConstantType(andNode->type))
              {
               tmpExpr = GenConstant(andNode->type,andNode->value);
               rvConstraints = ExpressionToConstraintRecord(tmpExpr);
               tmpConstraints = andConstraints;
               andConstraints = IntersectConstraints(andConstraints,rvConstraints);
               RemoveConstraint(tmpConstraints);
               RemoveConstraint(rvConstraints);
               ReturnExpression(tmpExpr);
              }
            else if (andNode->constraints != NULL)
              {
               tmpConstraints = andConstraints;
               andConstraints = IntersectConstraints(andConstraints,andNode->constraints);
               RemoveConstraint(tmpConstraints);
              }
           }
        }

      /*===========================================================*/
      /* Intersect the &'ed constraints with the slot constraints. */
      /*===========================================================*/

      tmpConstraints = andConstraints;
      andConstraints = IntersectConstraints(andConstraints,theNode->constraints);
      RemoveConstraint(tmpConstraints);

      /*===============================================================*/
      /* Remove any negated constants from the list of allowed values. */
      /*===============================================================*/

      for (andNode = orNode; andNode != NULL; andNode = andNode->right)
        {
         if ((andNode->negated) && ConstantType(andNode->type))
             { RemoveConstantFromConstraint(andNode->type,andNode->value,andConstraints); }
        }

      /*=======================================================*/
      /* Union the &'ed constraints with the |'ed constraints. */
      /*=======================================================*/

      tmpConstraints = orConstraints;
      orConstraints = UnionConstraints(orConstraints,andConstraints);
      RemoveConstraint(tmpConstraints);
      RemoveConstraint(andConstraints);
     }

   /*===============================================*/
   /* Replace the constraints for the slot with the */
   /* constraints derived from the connected        */
   /* constraints (which should be a subset.        */
   /*===============================================*/

   if (orConstraints != NULL)
     {
      if (theNode->derivedConstraints) RemoveConstraint(theNode->constraints);
      theNode->constraints = orConstraints;
      theNode->derivedConstraints = TRUE;
     }

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

   if (CheckForUnmatchableConstraints(theNode,(int) patternHead->whichCE))
     { return(TRUE); }

   /*=========================================*/
   /* If the constraints are for a multifield */
   /* slot, check for cardinality violations. */
   /*=========================================*/

   if ((multifieldHeader != NULL) && (theNode->right == NULL))
     {
      if (MultifieldCardinalityViolation(multifieldHeader))
        {
         ConstraintViolationErrorMessage("The group of restrictions",
                                                  NULL,FALSE,
                                                  (int) patternHead->whichCE,
                                                  multifieldHeader->slot,
                                                  multifieldHeader->index,
                                                  CARDINALITY_VIOLATION,
                                                  multifieldHeader->constraints,TRUE);
          return(TRUE);
         }
      }

   /*=======================================*/
   /* Return FALSE indicating no constraint */
   /* violations were detected.             */
   /*=======================================*/

   return(FALSE);
  }
Beispiel #3
0
globle CONSTRAINT_RECORD *ExpressionToConstraintRecord(
  void *theEnv,
  EXEC_STATUS,
  struct expr *theExpression)
  {
   CONSTRAINT_RECORD *rv;

   /*================================================*/
   /* A NULL expression is converted to a constraint */
   /* record with no values allowed.                 */
   /*================================================*/

   if (theExpression == NULL)
     {
      rv = GetConstraintRecord(theEnv,execStatus);
      rv->anyAllowed = FALSE;
      return(rv);
     }

   /*=============================================================*/
   /* Convert variables and function calls to constraint records. */
   /*=============================================================*/

   if ((theExpression->type == SF_VARIABLE) ||
       (theExpression->type == MF_VARIABLE) ||
#if DEFGENERIC_CONSTRUCT
       (theExpression->type == GCALL) ||
#endif
#if DEFFUNCTION_CONSTRUCT
       (theExpression->type == PCALL) ||
#endif
       (theExpression->type == GBL_VARIABLE) ||
       (theExpression->type == MF_GBL_VARIABLE))
     {
      rv = GetConstraintRecord(theEnv,execStatus);
      rv->multifieldsAllowed = TRUE;
      return(rv);
     }
   else if (theExpression->type == FCALL)
     { return(FunctionCallToConstraintRecord(theEnv,execStatus,theExpression->value)); }

   /*============================================*/
   /* Convert a constant to a constraint record. */
   /*============================================*/

   rv = GetConstraintRecord(theEnv,execStatus);
   rv->anyAllowed = FALSE;

   if (theExpression->type == FLOAT)
     {
      rv->floatRestriction = TRUE;
      rv->floatsAllowed = TRUE;
     }
   else if (theExpression->type == INTEGER)
     {
      rv->integerRestriction = TRUE;
      rv->integersAllowed = TRUE;
     }
   else if (theExpression->type == SYMBOL)
     {
      rv->symbolRestriction = TRUE;
      rv->symbolsAllowed = TRUE;
     }
   else if (theExpression->type == STRING)
     {
      rv->stringRestriction = TRUE;
      rv->stringsAllowed = TRUE;
     }
   else if (theExpression->type == INSTANCE_NAME)
     {
      rv->instanceNameRestriction = TRUE;
      rv->instanceNamesAllowed = TRUE;
     }
   else if (theExpression->type == INSTANCE_ADDRESS)
     { rv->instanceAddressesAllowed = TRUE; }

   if (rv->floatsAllowed || rv->integersAllowed || rv->symbolsAllowed ||
       rv->stringsAllowed || rv->instanceNamesAllowed)
     { rv->restrictionList = GenConstant(theEnv,execStatus,theExpression->type,theExpression->value); }

   return(rv);
  }
Beispiel #4
0
static bool CheckForVariableMixing(
  Environment *theEnv,
  struct lhsParseNode *theRestriction)
  {
   struct lhsParseNode *tempRestriction;
   CONSTRAINT_RECORD *theConstraint;
   bool multifield = false;
   bool singlefield = false;
   bool constant = false;
   bool singleReturnValue = false;
   bool multiReturnValue = false;

   /*================================================*/
   /* If the constraint contains a binding variable, */
   /* determine whether it is a single field or      */
   /* multifield variable.                           */
   /*================================================*/

   if (theRestriction->pnType == SF_VARIABLE_NODE) singlefield = true;
   else if (theRestriction->pnType == MF_VARIABLE_NODE) multifield = true;

   /*===========================================*/
   /* Loop through each of the or (|) connected */
   /* constraints within the constraint.        */
   /*===========================================*/

   for (theRestriction = theRestriction->bottom;
        theRestriction != NULL;
        theRestriction = theRestriction->bottom)
     {
      /*============================================*/
      /* Loop through each of the and (&) connected */
      /* constraints within the or (|) constraint.  */
      /*============================================*/

      for (tempRestriction = theRestriction;
           tempRestriction != NULL;
           tempRestriction = tempRestriction->right)
        {
         /*=====================================================*/
         /* Determine if the constraint contains a single field */
         /* variable, multifield variable, constant (a single   */
         /* field), a return value constraint of a function     */
         /* returning a single field value, or a return value   */
         /* constraint of a function returning a multifield     */
         /* value.                                              */
         /*=====================================================*/

         if (tempRestriction->pnType == SF_VARIABLE_NODE) singlefield = true;
         else if (tempRestriction->pnType == MF_VARIABLE_NODE) multifield = true;
         else if (ConstantNode(tempRestriction)) constant = true;
         else if (tempRestriction->pnType == RETURN_VALUE_CONSTRAINT_NODE)
           {
            theConstraint = FunctionCallToConstraintRecord(theEnv,tempRestriction->expression->value);
            if (theConstraint->anyAllowed) { /* Do nothing. */ }
            else if (theConstraint->multifieldsAllowed) multiReturnValue = true;
            else singleReturnValue = true;
            RemoveConstraint(theEnv,theConstraint);
           }
        }
     }

   /*================================================================*/
   /* Using a single field value (a single field variable, constant, */
   /* or function returning a single field value) together with a    */
   /* multifield value (a multifield variable or function returning  */
   /* a multifield value) is illegal. Return true if this occurs.    */
   /*================================================================*/

   if ((singlefield || constant || singleReturnValue) &&
       (multifield || multiReturnValue))

     {
      PrintErrorID(theEnv,"PATTERN",2,true);
      WriteString(theEnv,STDERR,"Single and multifield constraints cannot be mixed in a field constraint.\n");
      return true;
     }

   /*=======================================*/
   /* Otherwise return false to indicate no */
   /* illegal variable mixing was detected. */
   /*=======================================*/

   return false;
  }