8 # include <ctype.h> /* for isdigit */
9 # include "lclintMacros.nf"
11 # include "cgrammar.h"
12 # include "cgrammar_tokens.h"
14 # include "exprChecks.h"
15 # include "exprNodeSList.h"
18 /*@access constraint, exprNode @*/
21 static constraint inequalitySubstitute (/*@returned@*/ constraint p_c, constraintList p_p);
24 static bool rangeCheck (arithType p_ar1, /*@observer@*/ constraintExpr p_expr1, arithType p_ar2, /*@observer@*/ constraintExpr p_expr2);
26 static constraint inequalitySubstituteUnsound (/*@returned@*/ constraint p_c, constraintList p_p);
28 static constraint inequalitySubstituteStrong (/*@returned@*/ constraint p_c, constraintList p_p);
30 static constraint constraint_searchandreplace (/*@returned@*/ constraint p_c, constraintExpr p_old, constraintExpr p_newExpr);
33 static constraint constraint_addOr (/*@returned@*/ constraint p_orig, /*@observer@*/ constraint p_orConstr);
35 static bool resolveOr (/*@temp@*/constraint p_c, /*@observer@*/ /*@temp@*/ constraintList p_list);
37 static /*@only@*/ constraintList reflectChangesEnsuresFree1 (/*@only@*/ constraintList p_pre2, constraintList p_post1);
39 /*********************************************/
44 /*@only@*/ constraintList constraintList_mergeEnsuresFreeFirst (constraintList list1, constraintList list2)
48 ret = constraintList_mergeEnsures (list1, list2);
50 constraintList_free(list1);
54 /*@only@*/ constraintList constraintList_mergeEnsures (constraintList list1, constraintList list2)
59 //ret = constraintList_makeNew();
61 llassert(constraintList_isDefined(list1) );
62 llassert(constraintList_isDefined(list2) );
64 DPRINTF(( message ("constraintList_mergeEnsures: list1 %s list2 %s",
65 constraintList_print(list1), constraintList_print(list2)
68 ret = constraintList_fixConflicts (list1, list2);
69 ret = reflectChangesEnsuresFree1 (ret, list2);
70 temp = constraintList_subsumeEnsures (ret, list2);
71 constraintList_free(ret);
74 temp = constraintList_subsumeEnsures (list2, ret);
76 temp = constraintList_addList (temp, ret);
77 constraintList_free(ret);
79 DPRINTF(( message ("constraintList_mergeEnsures: returning %s ",
80 constraintList_print(temp) )
85 //ret = constraintList_addList (ret, list2);
90 /*@only@*/ constraintList constraintList_mergeRequiresFreeFirst (/*@only@*/ constraintList list1, constraintList list2)
94 ret = constraintList_mergeRequires(list1, list2);
96 constraintList_free(list1);
101 /*@only@*/ constraintList constraintList_mergeRequires (constraintList list1, constraintList list2)
106 DPRINTF((message ("constraintList_mergeRequires: merging %s and %s ", constraintList_print (list1), constraintList_print(list2) ) ) );
108 /* get constraints in list1 not satified by list2 */
109 temp = constraintList_reflectChanges(list1, list2);
110 DPRINTF((message ("constraintList_mergeRequires: temp = %s", constraintList_print(temp) ) ) );
112 /*get constraints in list2 not satified by temp*/
113 ret = constraintList_reflectChanges(list2, temp);
115 DPRINTF((message ("constraintList_mergeRequires: ret = %s", constraintList_print(ret) ) ) );
117 ret = constraintList_addListFree (ret, temp);
119 DPRINTF((message ("constraintList_mergeRequires: returning %s", constraintList_print(ret) ) ) );
124 /* old name mergeResolve renamed for czech naming convention */
125 void exprNode_mergeResolve (exprNode parent, exprNode child1, exprNode child2)
127 constraintList temp, temp2;
129 DPRINTF( (message ("magically merging constraint into parent:%s for", exprNode_unparse (parent) )) );
131 DPRINTF( (message (" children: %s and %s", exprNode_unparse (child1), exprNode_unparse(child2) ) ) );
133 if (exprNode_isError (child1) || exprNode_isError(child2) )
135 if (exprNode_isError (child1) && !exprNode_isError(child2) )
137 constraintList_free(parent->requiresConstraints);
139 parent->requiresConstraints = constraintList_copy (child2->requiresConstraints);
140 constraintList_free(parent->ensuresConstraints);
142 parent->ensuresConstraints = constraintList_copy (child2->ensuresConstraints);
143 DPRINTF((message ("Copied child constraints: pre: %s and post: %s",
144 constraintList_print( child2->requiresConstraints),
145 constraintList_print (child2->ensuresConstraints)
152 llassert(exprNode_isError(child2) );
153 //parent->requiresConstraints = constraintList_makeNew();
154 //parent->ensuresConstraints = constraintList_makeNew();
159 llassert(!exprNode_isError (child1) && ! exprNode_isError(child2) );
161 DPRINTF( (message ("Child constraints are %s %s and %s %s",
162 constraintList_print (child1->requiresConstraints),
163 constraintList_print (child1->ensuresConstraints),
164 constraintList_print (child2->requiresConstraints),
165 constraintList_print (child2->ensuresConstraints)
169 constraintList_free(parent->requiresConstraints);
171 parent->requiresConstraints = constraintList_copy (child1->requiresConstraints);
173 if ( context_getFlag (FLG_ORCONSTRAINT) )
174 temp = constraintList_reflectChangesOr (child2->requiresConstraints, child1->ensuresConstraints);
176 temp = constraintList_reflectChanges(child2->requiresConstraints, child1->ensuresConstraints);
178 temp2 = constraintList_mergeRequires (parent->requiresConstraints, temp);
179 constraintList_free(parent->requiresConstraints);
180 constraintList_free(temp);
182 parent->requiresConstraints = temp2;
184 DPRINTF( (message ("Parent requires constraints are %s ",
185 constraintList_print (parent->requiresConstraints)
188 constraintList_free(parent->ensuresConstraints);
190 parent->ensuresConstraints = constraintList_mergeEnsures(child1->ensuresConstraints,
191 child2->ensuresConstraints);
194 DPRINTF( (message ("Parent constraints are %s and %s ",
195 constraintList_print (parent->requiresConstraints),
196 constraintList_print (parent->ensuresConstraints)
204 /*@only@*/ constraintList constraintList_subsumeEnsures (constraintList list1, constraintList list2)
207 ret = constraintList_makeNew();
208 constraintList_elements (list1, el)
211 DPRINTF ((message ("Examining %s", constraint_print (el) ) ) );
212 if (!constraintList_resolve (el, list2) )
215 temp = constraint_copy(el);
216 ret = constraintList_add (ret, temp);
220 DPRINTF ( (message ("Subsuming %s", constraint_print (el) ) ) );
222 } end_constraintList_elements;
229 /*used to be reflectChangesFreePre renamed for Czech naming conventino*/
230 /* tries to resolve constraints in list pre2 using post1 */
231 /*@only@*/ constraintList constraintList_reflectChangesFreePre (/*@only@*/ constraintList pre2, /*@observer@*/ constraintList post1)
235 ret = constraintList_reflectChanges(pre2, post1);
237 constraintList_free (pre2);
244 /* tries to resolve constraints in list pre2 using post1 */
246 static /*@only@*/ constraintList reflectChangesNoOr (/*@observer@*/ /*@temp@*/ constraintList pre2, /*@observer@*/ /*@temp@*/ constraintList post1)
253 llassert (! context_getFlag (FLG_ORCONSTRAINT) );
255 ret = constraintList_makeNew();
256 DPRINTF((message ("reflectChanges: lists %s and %s", constraintList_print(pre2), constraintList_print(post1) )));
258 constraintList_elements (pre2, el)
260 if (!constraintList_resolve (el, post1) )
262 temp = constraint_substitute (el, post1);
263 if (!constraintList_resolve (temp, post1) )
265 // try inequality substitution
268 // the inequality substitution may cause us to lose information
269 //so we don't want to store the result but we do it anyway
270 temp2 = constraint_copy (temp);
271 // if (context_getFlag (FLG_ORCONSTRAINT) )
272 temp2 = inequalitySubstitute (temp2, post1);
273 if (!constraintList_resolve (temp2, post1) )
275 temp2 = inequalitySubstituteUnsound (temp2, post1);
276 if (!constraintList_resolve (temp2, post1) )
277 ret = constraintList_add (ret, temp2);
279 constraint_free(temp2);
283 constraint_free(temp2);
286 constraint_free(temp);
288 } end_constraintList_elements;
290 DPRINTF((message ("reflectChanges: returning %s", constraintList_print(ret) ) ) );
294 /* tries to resolve constraints in list pre2 using post1 */
295 /*@only@*/ constraintList constraintList_reflectChanges(/*@observer@*/ constraintList pre2, /*@observer@*/ constraintList post1)
299 if ( context_getFlag (FLG_ORCONSTRAINT) )
301 temp = constraintList_reflectChangesOr (pre2, post1);
303 temp = reflectChangesNoOr(pre2, post1);
308 static constraint constraint_addOr (/*@returned@*/ constraint orig, /*@observer@*/ constraint orConstr)
313 DPRINTF((message("constraint_addor: oring %s onto %s", constraint_printOr(orConstr), constraint_printOr(orig) ) ));
315 while (c->or != NULL)
319 c->or = constraint_copy(orConstr);
321 DPRINTF((message("constraint_addor: returning %s",constraint_printOr(orig) ) ));
327 static bool resolveOr ( /*@temp@*/ constraint c, /*@observer@*/ /*@temp@*/ constraintList list)
331 DPRINTF(( message("resolveOr: constraint %s and list %s", constraint_printOr(c), constraintList_print(list) ) ));
336 if (constraintList_resolve (temp, list) )
340 while (constraint_isDefined(temp));
345 /*This is a "helper" function for doResolveOr */
347 static /*@only@*/ constraint doResolve (/*@only@*/ constraint c, constraintList post1, bool * resolved)
351 if (!resolveOr (c, post1) )
354 temp = constraint_substitute (c, post1);
356 if (!resolveOr (temp, post1) )
358 // try inequality substitution
361 // the inequality substitution may cause us to lose information
362 //so we don't want to store the result but we do anyway
363 temp2 = constraint_copy (c);
364 // if (context_getFlag (FLG_ORCONSTRAINT) )
365 temp2 = inequalitySubstitute (temp2, post1);
366 if (!resolveOr (temp2, post1) )
369 temp3 = constraint_copy(temp2);
371 temp3 = inequalitySubstituteStrong (temp3, post1);
372 if (!resolveOr (temp3, post1) )
374 temp2 = inequalitySubstituteUnsound (temp2, post1);
375 if (!resolveOr (temp2, post1) )
377 if (!constraint_same (temp, temp2) )
378 temp = constraint_addOr (temp, temp2);
380 if (!constraint_same (temp, temp3) && !constraint_same (temp3, temp2) )
381 temp = constraint_addOr (temp, temp3);
385 constraint_free(temp2);
386 constraint_free(temp3);
391 constraint_free(temp2);
392 constraint_free(temp3);
396 constraint_free(temp2);
397 constraint_free(temp3);
402 constraint_free(temp2);
406 constraint_free(temp);
415 static /*@only@*/ constraint doResolveOr (constraint c, constraintList post1, /*@out@*/bool * resolved)
422 ret = constraint_copy(c);
426 ret = doResolve (ret, post1, resolved);
431 constraint_free(next);
433 /*we don't need to free ret when resolved is false because ret is null*/
434 llassert(ret == NULL);
445 curr = doResolve (curr, post1, resolved);
448 /* curr is null so we don't try to free it*/
449 llassert(curr == NULL);
452 constraint_free(next);
454 constraint_free(ret);
457 ret = constraint_addOr (ret, curr);
458 constraint_free(curr);
468 /* tries to resolve constraints in list pr2 using post1 */
469 /*@only@*/ constraintList constraintList_reflectChangesOr (constraintList pre2, constraintList post1)
474 ret = constraintList_makeNew();
475 DPRINTF((message ("constraintList_reflectChangesOr: lists %s and %s", constraintList_print(pre2), constraintList_print(post1) )));
477 constraintList_elements (pre2, el)
479 temp = doResolveOr (el, post1, &resolved);
483 ret = constraintList_add(ret, temp);
487 /*we don't need to free ret when resolved is false because ret is null*/
488 llassert(temp == NULL);
491 } end_constraintList_elements;
493 DPRINTF((message ("constraintList_reflectChangesOr: returning %s", constraintList_print(ret) ) ) );
496 static /*@only@*/ constraintList reflectChangesEnsures (/*@observer@*/ constraintList pre2, constraintList post1)
500 ret = constraintList_makeNew();
501 constraintList_elements (pre2, el)
503 if (!constraintList_resolve (el, post1) )
505 temp = constraint_substitute (el, post1);
506 llassert (temp != NULL);
508 if (!constraintList_resolve (temp, post1) )
509 ret = constraintList_add (ret, temp);
511 constraint_free(temp);
515 DPRINTF ( (message ("Resolved away %s ", constraint_print(el) ) ) );
517 } end_constraintList_elements;
523 static /*@only@*/ constraintList reflectChangesEnsuresFree1 (/*@only@*/ constraintList pre2, constraintList post1)
527 ret = reflectChangesEnsures (pre2, post1);
529 constraintList_free(pre2);
535 static bool constraint_conflict (constraint c1, constraint c2)
538 if (constraintExpr_similar(c1->lexpr, c2->lexpr) )
541 if (c1->ar == c2->ar)
543 DPRINTF ( (message ("%s conflicts with %s ", constraint_print (c1), constraint_print(c2) ) ) );
548 DPRINTF ( (message ("%s doesn't conflict with %s ", constraint_print (c1), constraint_print(c2) ) ) );
554 static void constraint_fixConflict (/*@temp@*/ constraint good, /*@temp@*/ /*@observer@*/ constraint conflicting) /*@modifies good@*/
556 if (conflicting->ar ==EQ )
558 good->expr = constraintExpr_searchandreplace (good->expr, conflicting->lexpr, conflicting->expr);
559 good = constraint_simplify (good);
565 static bool conflict (constraint c, constraintList list)
568 constraintList_elements (list, el)
570 if ( constraint_conflict(el, c) )
572 constraint_fixConflict (el, c);
575 } end_constraintList_elements;
581 //check if constraint in list1 conflicts with constraints in List2. If so we
582 //remove form list1 and change list2.
583 constraintList constraintList_fixConflicts (constraintList list1, constraintList list2)
586 ret = constraintList_makeNew();
587 llassert(constraintList_isDefined(list1) );
588 constraintList_elements (list1, el)
590 if (! conflict (el, list2) )
593 temp = constraint_copy(el);
594 ret = constraintList_add (ret, temp);
596 } end_constraintList_elements;
601 /*returns true if constraint post satifies cosntriant pre */
602 static bool satifies (constraint pre, constraint post)
604 if (constraint_isAlwaysTrue (pre) )
607 if (!constraintExpr_similar (pre->lexpr, post->lexpr) )
611 if (constraintExpr_isUndefined(post->expr))
617 return rangeCheck (pre->ar, pre->expr, post->ar, post->expr);
621 bool constraintList_resolve (/*@temp@*/ /*@observer@*/ constraint c, /*@temp@*/ /*@observer@*/ constraintList p)
623 constraintList_elements (p, el)
625 if ( satifies (c, el) )
627 DPRINTF ( (message ("\n%s Satifies %s\n ", constraint_print(el), constraint_print(c) ) ) );
630 DPRINTF ( (message ("\n%s does not satify %s\n ", constraint_print(el), constraint_print(c) ) ) );
632 end_constraintList_elements;
633 DPRINTF ( (message ("no constraints satify %s", constraint_print(c) ) ));
637 static bool arithType_canResolve (arithType ar1, arithType ar2)
643 if ( (ar2 == GT) || (ar2 == GTE) || (ar2 == EQ) )
657 if ( (ar2 == LT) || (ar2 == LTE) || (ar2 == EQ) )
666 /* We look for constraint which are tautologies */
668 bool constraint_isAlwaysTrue (/*@observer@*/ /*@temp@*/ constraint c)
671 bool /*@unused@*/ lHasConstant, rHasConstant;
672 int /*@unused@*/ lConstant, rConstant;
677 DPRINTF(( message("constraint_IsAlwaysTrue:examining %s", constraint_print(c) ) ));
679 if (constraintExpr_canGetValue(l) && constraintExpr_canGetValue(r) )
682 cmp = constraintExpr_compare (l, r);
703 if (constraintExpr_similar (l,r) )
722 l = constraintExpr_copy (c->lexpr);
723 r = constraintExpr_copy (c->expr);
725 // l = constraintExpr_propagateConstants (l, &lHasConstant, &lConstant);
726 r = constraintExpr_propagateConstants (r, &rHasConstant, &rConstant);
728 if (constraintExpr_similar (l,r) && (rHasConstant ) )
730 DPRINTF(( message("constraint_IsAlwaysTrue: after removing constants %s and %s are similar", constraintExpr_unparse(l), constraintExpr_unparse(r) ) ));
731 DPRINTF(( message("constraint_IsAlwaysTrue: rconstant is %d", rConstant ) ));
733 constraintExpr_free(l);
734 constraintExpr_free(r);
739 return (rConstant == 0);
741 return (rConstant > 0);
743 return (rConstant >= 0);
745 return (rConstant <= 0);
747 return (rConstant < 0);
757 constraintExpr_free(l);
758 constraintExpr_free(r);
759 DPRINTF(( message("Constraint %s is not always true", constraint_print(c) ) ));
766 static bool rangeCheck (arithType ar1, /*@observer@*/ constraintExpr expr1, arithType ar2, /*@observer@*/ constraintExpr expr2)
769 DPRINTF ((message ("Doing Range CHECK %s and %s", constraintExpr_unparse(expr1), constraintExpr_unparse(expr2) ) ));
771 if (! arithType_canResolve (ar1, ar2) )
777 if (constraintExpr_similar (expr1, expr2) )
781 if (! (constraintExpr_canGetValue (expr1) &&
782 constraintExpr_canGetValue (expr2) ) )
784 constraintExpr e1, e2;
788 e1 = constraintExpr_copy(expr1);
789 e2 = constraintExpr_copy(expr2);
791 e1 = constraintExpr_propagateConstants (e1, &p1, &const1);
793 e2 = constraintExpr_propagateConstants (e2, &p2, &const2);
803 if (const1 <= const2)
804 if (constraintExpr_similar (e1, e2) )
806 constraintExpr_free(e1);
807 constraintExpr_free(e2);
811 DPRINTF( ("Can't Get value"));
813 constraintExpr_free(e1);
814 constraintExpr_free(e2);
818 if (constraintExpr_compare (expr2, expr1) >= 0)
823 if (constraintExpr_similar (expr1, expr2) )
828 if (constraintExpr_similar (expr1, expr2) )
832 if (! (constraintExpr_canGetValue (expr1) &&
833 constraintExpr_canGetValue (expr2) ) )
835 constraintExpr e1, e2;
839 e1 = constraintExpr_copy(expr1);
840 e2 = constraintExpr_copy(expr2);
842 e1 = constraintExpr_propagateConstants (e1, &p1, &const1);
844 e2 = constraintExpr_propagateConstants (e2, &p2, &const2);
854 if (const1 >= const2)
855 if (constraintExpr_similar (e1, e2) )
857 constraintExpr_free(e1);
858 constraintExpr_free(e2);
862 constraintExpr_free(e1);
863 constraintExpr_free(e2);
865 DPRINTF( ("Can't Get value"));
869 if (constraintExpr_compare (expr2, expr1) <= 0)
875 llcontbug((message("Unhandled case in switch: %q", arithType_print(ar1) ) ) );
880 static constraint constraint_searchandreplace (/*@returned@*/ constraint c, constraintExpr old, constraintExpr newExpr)
882 DPRINTF (("Doing replace for lexpr") );
883 c->lexpr = constraintExpr_searchandreplace (c->lexpr, old, newExpr);
884 DPRINTF (("Doing replace for expr") );
885 c->expr = constraintExpr_searchandreplace (c->expr, old, newExpr);
889 bool constraint_search (constraint c, constraintExpr old) /*@*/
894 ret = constraintExpr_search (c->lexpr, old);
895 ret = ret || constraintExpr_search (c->expr, old);
899 //adjust file locs and stuff
900 static constraint constraint_adjust (/*@returned@*/ constraint substitute, /*@observer@*/ constraint old)
902 fileloc loc1, loc2, loc3;
904 DPRINTF ( (message("Start adjust on %s and %s", constraint_print(substitute),
905 constraint_print(old))
908 loc1 = constraint_getFileloc (old);
910 loc2 = constraintExpr_getFileloc (substitute->lexpr);
912 loc3 = constraintExpr_getFileloc (substitute->expr);
915 // special case of an equality that "contains itself"
916 if (constraintExpr_search (substitute->expr, substitute->lexpr) )
917 if (fileloc_closer (loc1, loc3, loc2))
920 DPRINTF ( (message("Doing adjust on %s", constraint_print(substitute) )
922 temp = substitute->lexpr;
923 substitute->lexpr = substitute->expr;
924 substitute->expr = temp;
925 substitute = constraint_simplify(substitute);
936 /* If function preforms substitutes based on inequality
938 It uses the rule x >= y && b < y ===> x >= b + 1
940 Warning this is sound but throws out information
943 constraint inequalitySubstitute (/*@returned@*/ constraint c, constraintList p)
948 constraintList_elements (p, el)
950 if ( (el->ar == LT ) )
951 // if (!constraint_conflict (c, el) )
954 constraintExpr temp2;
958 //temp = constraint_copy(el);
960 // temp = constraint_adjust(temp, c);
962 if (constraintExpr_same (el->expr, c->expr) )
964 DPRINTF((message ("inequalitySubstitute Replacing %q in %q with %q",
965 constraintExpr_print (c->expr),
966 constraint_print (c),
967 constraintExpr_print (el->expr) )
969 temp2 = constraintExpr_copy (el->lexpr);
970 constraintExpr_free(c->expr);
971 c->expr = constraintExpr_makeIncConstraintExpr (temp2);
977 end_constraintList_elements;
979 c = constraint_simplify(c);
986 THis function is like inequalitySubstitute but it adds the rule
987 added the rules x >= y && y <= b ===> x >= b
988 x >= y && y < b ===> x >= b + 1
990 This is sound but sonce it throws out additional information it should only one used
991 if we're oring constraints.
994 static constraint inequalitySubstituteStrong (/*@returned@*/ constraint c, constraintList p)
996 DPRINTF (( message ("inequalitySubstituteStrong examining substituting for %q", constraint_print(c) ) ));
1001 DPRINTF (( message ("inequalitySubstituteStrong examining substituting for %q with %q",
1002 constraint_print(c), constraintList_print(p) ) ));
1003 constraintList_elements (p, el)
1005 DPRINTF (( message ("inequalitySubstituteStrong examining substituting %s on %s", constraint_print(el), constraint_print(c) ) ));
1007 if ( (el->ar == LT ) || (el->ar == LTE ) )
1008 // if (!constraint_conflict (c, el) )
1011 constraintExpr temp2;
1015 //temp = constraint_copy(el);
1017 // temp = constraint_adjust(temp, c);
1019 if (constraintExpr_same (el->lexpr, c->expr) )
1021 DPRINTF((message ("inequalitySubstitute Replacing %s in %s with %s",
1022 constraintExpr_print (c->expr),
1023 constraint_print (c),
1024 constraintExpr_print (el->expr) )
1026 temp2 = constraintExpr_copy (el->expr);
1027 constraintExpr_free(c->expr);
1028 if ( (el->ar == LTE ) )
1034 c->expr = constraintExpr_makeIncConstraintExpr (temp2);
1040 end_constraintList_elements;
1042 c = constraint_simplify(c);
1047 /* This function performs substitutions based on the rule:
1048 for a constraint of the form expr1 >= expr2; a < b =>
1049 a = b -1 for all a in expr1. This will work in most cases.
1051 Like inequalitySubstitute we're throwing away some information
1054 static constraint inequalitySubstituteUnsound (/*@returned@*/ constraint c, constraintList p)
1056 DPRINTF (( message ("Doing inequalitySubstituteUnsound " ) ));
1061 constraintList_elements (p, el)
1063 DPRINTF (( message ("inequalitySubstituteUnsound examining substituting %s on %s", constraint_print(el), constraint_print(c) ) ));
1064 if ( ( el->ar == LTE) || (el->ar == LT) )
1065 // if (!constraint_conflict (c, el) )
1068 constraintExpr temp2;
1070 //temp = constraint_copy(el);
1072 // temp = constraint_adjust(temp, c);
1073 temp2 = constraintExpr_copy (el->expr);
1076 temp2 = constraintExpr_makeDecConstraintExpr (temp2);
1078 DPRINTF((message ("Replacing %s in %s with %s",
1079 constraintExpr_print (el->lexpr),
1080 constraintExpr_print (c->lexpr),
1081 constraintExpr_print (temp2) ) ));
1083 c->lexpr = constraintExpr_searchandreplace (c->lexpr, el->lexpr, temp2);
1084 constraintExpr_free(temp2);
1087 end_constraintList_elements;
1089 c = constraint_simplify(c);
1093 /*@only@*/ constraint constraint_substitute (/*@observer@*/ /*@temp@*/ constraint c, constraintList p)
1097 ret = constraint_copy(c);
1098 constraintList_elements (p, el)
1101 if (!constraint_conflict (ret, el) )
1106 temp = constraint_copy(el);
1108 temp = constraint_adjust(temp, ret);
1110 DPRINTF((message ("Substituting %s in the constraint %s",
1111 constraint_print (temp), constraint_print (ret)
1115 ret = constraint_searchandreplace (ret, temp->lexpr, temp->expr);
1116 DPRINTF(( message ("The new constraint is %s", constraint_print (ret) ) ));
1117 constraint_free(temp);
1120 end_constraintList_elements;
1121 DPRINTF(( message ("The finial new constraint is %s", constraint_print (ret) ) ));
1123 ret = constraint_simplify(ret);
1128 /*@only@*/ constraintList constraintList_substituteFreeTarget (/*@only@*/ constraintList target, /*@observer@*/ constraintList subList)
1132 ret = constraintList_substitute (target, subList);
1134 constraintList_free(target);
1139 /* we try to do substitutions on each constraint in target using the constraint in sublist*/
1141 /*@only@*/ constraintList constraintList_substitute (constraintList target,/*2observer@*/ constraintList subList)
1146 ret = constraintList_makeNew();
1148 constraintList_elements(target, el)
1151 //drl possible problem : warning make sure that a side effect is not expected
1153 temp = constraint_substitute(el, subList);
1154 ret = constraintList_add (ret, temp);
1156 end_constraintList_elements;
1161 static constraint constraint_solve (/*@returned@*/ constraint c)
1163 DPRINTF( (message ("Solving %s\n", constraint_print(c) ) ) );
1164 c->expr = constraintExpr_solveBinaryExpr (c->lexpr, c->expr);
1165 DPRINTF( (message ("Solved and got %s\n", constraint_print(c) ) ) );
1170 static arithType flipAr (arithType ar)
1185 llcontbug (message("unexpected value: case not handled"));
1190 static constraint constraint_swapLeftRight (/*@returned@*/ constraint c)
1192 constraintExpr temp;
1193 c->ar = flipAr (c->ar);
1197 DPRINTF(("Swaped left and right sides of constraint"));
1203 constraint constraint_simplify ( /*@returned@*/ constraint c)
1205 c->lexpr = constraintExpr_simplify (c->lexpr);
1206 c->expr = constraintExpr_simplify (c->expr);
1208 if (constraintExpr_isBinaryExpr (c->lexpr) )
1210 c = constraint_solve (c);
1212 c->lexpr = constraintExpr_simplify (c->lexpr);
1213 c->expr = constraintExpr_simplify (c->expr);
1216 if (constraintExpr_isLit(c->lexpr) && (!constraintExpr_isLit(c->expr) ) )
1218 c = constraint_swapLeftRight(c);
1219 /*I don't think this will be an infinate loop*/
1220 c = constraint_simplify(c);
1228 /* returns true if fileloc for term1 is closer to file for term2 than term3*/
1230 bool fileloc_closer (fileloc loc1, fileloc loc2, fileloc loc3)
1233 if (!fileloc_isDefined (loc1) )
1236 if (!fileloc_isDefined (loc2) )
1239 if (!fileloc_isDefined (loc3) )
1245 if (fileloc_equal (loc2, loc3) )
1248 if (fileloc_equal (loc1, loc2) )
1251 if (fileloc_equal (loc1, loc3) )
1254 if ( fileloc_lessthan (loc1, loc2) )
1256 if (fileloc_lessthan (loc2, loc3) )
1258 llassert (fileloc_lessthan (loc1, loc3) );
1267 if ( !fileloc_lessthan (loc1, loc2) )
1269 if (!fileloc_lessthan (loc2, loc3) )
1271 llassert (!fileloc_lessthan (loc1, loc3) );