globle struct lhsParseNode *GetExpressionVarConstraints( struct lhsParseNode *theExpression) { struct lhsParseNode *list1 = NULL, *list2; for (; theExpression != NULL; theExpression = theExpression->bottom) { if (theExpression->right != NULL) { list2 = GetExpressionVarConstraints(theExpression->right); list1 = AddToVariableConstraints(list2,list1); } if (theExpression->type == SF_VARIABLE) { list2 = GetLHSParseNode(); if (theExpression->referringNode != NULL) { list2->type = theExpression->referringNode->type; } else { list2->type = SF_VARIABLE; } list2->value = theExpression->value; list2->derivedConstraints = TRUE; list2->constraints = CopyConstraintRecord(theExpression->constraints); list1 = AddToVariableConstraints(list2,list1); } } return(list1); }
globle struct lhsParseNode *DeriveVariableConstraints( void *theEnv, struct lhsParseNode *theNode) { struct lhsParseNode *orNode, *andNode; struct lhsParseNode *list1, *list2, *list3 = NULL; int first = TRUE; /*===============================*/ /* Process the constraints for a */ /* single connected constraint. */ /*===============================*/ for (orNode = theNode->bottom; orNode != NULL; orNode = orNode->bottom) { /*=================================================*/ /* Intersect all of the &'ed constraints together. */ /*=================================================*/ list2 = NULL; for (andNode = orNode; andNode != NULL; andNode = andNode->right) { if ((andNode->type == RETURN_VALUE_CONSTRAINT) || (andNode->type == PREDICATE_CONSTRAINT)) { list1 = GetExpressionVarConstraints(theEnv,andNode->expression); list2 = AddToVariableConstraints(theEnv,list2,list1); } } if (first) { list3 = list2; first = FALSE; } else { list3 = UnionVariableConstraints(theEnv,list3,list2); } } return(list3); }
static int TestCEAnalysis( void *theEnv, struct lhsParseNode *patternPtr, struct lhsParseNode *theExpression, int secondary, int *errorFlag, struct nandFrame *theNandFrames) { struct lhsParseNode *rv, *theList, *tempList, *tempRight; if (theExpression == NULL) return FALSE; /*=====================================================*/ /* Verify that all variables were referenced properly. */ /*=====================================================*/ rv = CheckExpression(theEnv,theExpression,NULL,(int) patternPtr->whichCE,NULL,0); /*====================================================================*/ /* Temporarily disconnect the right nodes. If this is a pattern node */ /* with an attached test CE, we only want to propagate to following */ /* patterns, not to nodes of this pattern which preceded the test CE. */ /*====================================================================*/ tempRight = patternPtr->right; patternPtr->right = NULL; /*=========================================================*/ /* Determine the type and value constraints implied by the */ /* expression and propagate these constraints to other */ /* variables in the LHS. For example, the expression */ /* (+ ?x 1) implies that ?x is a number. */ /*=========================================================*/ theList = GetExpressionVarConstraints(theEnv,theExpression); for (tempList = theList; tempList != NULL; tempList = tempList->right) { if (PropagateVariableDriver(theEnv,patternPtr,patternPtr,NULL,SF_VARIABLE, (SYMBOL_HN *) tempList->value,tempList,FALSE,TEST_CE)) { ReturnLHSParseNodes(theEnv,theList); patternPtr->right = tempRight; return(TRUE); } } ReturnLHSParseNodes(theEnv,theList); /*============================*/ /* Reconnect the right nodes. */ /*============================*/ patternPtr->right = tempRight; /*========================================================*/ /* If the variables in the expression were all referenced */ /* properly, then create the expression to use in the */ /* join network. */ /*========================================================*/ if (rv != NULL) { *errorFlag = TRUE; } else if (secondary) { patternPtr->secondaryNetworkTest = CombineExpressions(theEnv,patternPtr->secondaryNetworkTest,GetvarReplace(theEnv,theExpression,FALSE,theNandFrames)); } else { patternPtr->networkTest = CombineExpressions(theEnv,patternPtr->networkTest,GetvarReplace(theEnv,theExpression,FALSE,theNandFrames)); } return FALSE; }