globle void RemoveConstantFromConstraint( int theType, void *theValue, CONSTRAINT_RECORD *theConstraint) { struct expr *theList, *lastOne = NULL, *tmpList; if (theConstraint == NULL) return; theList = theConstraint->restrictionList; theConstraint->restrictionList = NULL; while (theList != NULL) { if ((theList->type != theType) || (theList->value != theValue)) { if (lastOne == NULL) { theConstraint->restrictionList = theList; } else { lastOne->nextArg = theList; } lastOne = theList; theList = theList->nextArg; lastOne->nextArg = NULL; } else { tmpList = theList; theList = theList->nextArg; tmpList->nextArg = NULL; ReturnExpression(tmpList); } } UpdateRestrictionFlags(theConstraint); }
globle struct constraintRecord *IntersectConstraints( 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)) { rv = GetConstraintRecord(theEnv); rv->multifieldsAllowed = 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(theEnv,c2)); if (c2 == NULL) return(CopyConstraintRecord(theEnv,c1)); /*=================================*/ /* Create a new constraint record. */ /*=================================*/ rv = GetConstraintRecord(theEnv); /*==============================*/ /* Intersect the allowed types. */ /*==============================*/ if ((c1->multifieldsAllowed != c2->multifieldsAllowed) && (c1->singlefieldsAllowed != c2->singlefieldsAllowed)) { rv->anyAllowed = FALSE; return(rv); } if (c1->multifieldsAllowed && c2->multifieldsAllowed) { rv->multifieldsAllowed = TRUE; } else { rv->multifieldsAllowed = FALSE; } if (c1->singlefieldsAllowed && c2->singlefieldsAllowed) { rv->singlefieldsAllowed = TRUE; } else { rv->singlefieldsAllowed = FALSE; } if (c1->anyAllowed && c2->anyAllowed) rv->anyAllowed = TRUE; else { if (c1->anyAllowed) { c1Changed = TRUE; SetAnyAllowedFlags(c1,FALSE); } else if (c2->anyAllowed) { c2Changed = TRUE; SetAnyAllowedFlags(c2,FALSE); } 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->multifieldsAllowed = (c1->multifieldsAllowed && c2->multifieldsAllowed); rv->factAddressesAllowed = (c1->factAddressesAllowed && c2->factAddressesAllowed); #if FUZZY_DEFTEMPLATES rv->fuzzyValuesAllowed = (c1->fuzzyValuesAllowed && c2->fuzzyValuesAllowed); #endif if (c1Changed) SetAnyAllowedFlags(c1,TRUE); if (c2Changed) SetAnyAllowedFlags(c2,TRUE); } /*=====================================*/ /* Intersect the allowed-values flags. */ /*=====================================*/ if (c1->anyRestriction || c2->anyRestriction) rv->anyRestriction = TRUE; else { 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 FUZZY_DEFTEMPLATES rv->fuzzyValueRestriction = (c1->fuzzyValueRestriction || c2->fuzzyValueRestriction); #endif } /*==================================================*/ /* Intersect the allowed values list, allowed class */ /* list, min and max values, and the range values. */ /*==================================================*/ IntersectAllowedValueExpressions(theEnv,c1,c2,rv); IntersectAllowedClassExpressions(theEnv,c1,c2,rv); IntersectNumericExpressions(theEnv,c1,c2,rv,TRUE); IntersectNumericExpressions(theEnv,c1,c2,rv,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(theEnv,c1->multifield,c2->multifield); if (UnmatchableConstraint(rv->multifield)) { rv->multifieldsAllowed = FALSE; } } /*========================*/ /* Return the intersected */ /* constraint record. */ /*========================*/ return(rv); }