]> andersk Git - splint.git/blob - src/constraintResolve.c
Converted to new API for constraintExpr
[splint.git] / src / constraintResolve.c
1 /*
2 /*
3 ** constraintResolve.c
4 */
5
6 # include <ctype.h> /* for isdigit */
7 # include "lclintMacros.nf"
8 # include "basic.h"
9 # include "cgrammar.h"
10 # include "cgrammar_tokens.h"
11
12 # include "exprChecks.h"
13 # include "aliasChecks.h"
14 # include "exprNodeSList.h"
15 # include "exprData.i"
16
17 #include "constraintExpr.h"
18
19 constraintList reflectChanges (constraintList pre2, constraintList post1);
20 constraint substitute (constraint c, constraintList p);
21 constraint constraint_searchandreplace (constraint c, constraintExpr old, constraintExpr new);
22 bool rangeCheck (arithType ar1, constraintExpr expr1, arithType ar2, constraintExpr expr2);
23 bool satifies (constraint pre, constraint post);
24 bool resolve (constraint c, constraintList p);
25 constraintList reflectChangesEnsures (constraintList pre2, constraintList post1);
26 constraint constraint_simplify (constraint c);
27
28 void mergeResolve (exprNode parent, exprNode child1, exprNode child2)
29 {
30   constraintList temp;
31   TPRINTF( (message ("magically merging constraint into parent:%s for children:  %s and %s", exprNode_unparse (parent), exprNode_unparse (child1), exprNode_unparse(child2) )
32             ) );
33    if (exprNode_isError (child1)  || exprNode_isError(child2) )
34      {
35        if (exprNode_isError (child1) && !exprNode_isError(child2) )
36          {
37            parent->requiresConstraints = constraintList_copy (child2->requiresConstraints);
38            parent->ensuresConstraints = constraintList_copy (child2->ensuresConstraints);
39            TPRINTF((message ("Copied child constraints: pre: %s and post: %s",
40                              constraintList_print( child2->requiresConstraints),
41                              constraintList_print (child2->ensuresConstraints)
42                              )
43                     ));
44            return;
45          }
46        else
47          {
48            llassert(exprNode_isError(child2) );
49            parent->requiresConstraints = constraintList_new();
50            parent->ensuresConstraints = constraintList_new();
51            return;
52          }
53      }
54
55    llassert(!exprNode_isError (child1)  && ! exprNode_isError(child2) );
56    
57   TPRINTF( (message ("Child constraints are %s %s and %s %s",
58                      constraintList_print (child1->requiresConstraints),
59                      constraintList_print (child1->ensuresConstraints),
60                      constraintList_print (child2->requiresConstraints),
61                      constraintList_print (child2->ensuresConstraints)
62                      ) ) );
63  
64   parent->requiresConstraints = constraintList_new();
65   parent->ensuresConstraints = constraintList_new();
66
67   parent->requiresConstraints = constraintList_copy (child1->requiresConstraints);
68   
69   temp = reflectChanges (child2->requiresConstraints, child1->ensuresConstraints);
70   parent->requiresConstraints = constraintList_addList (parent->requiresConstraints, temp);
71
72   
73   temp = reflectChangesEnsures (child1->ensuresConstraints, child2->ensuresConstraints);
74   // temp = constraintList_copy (child1->ensuresConstraints);
75
76   temp = constraintList_fixConflicts (temp, child2->ensuresConstraints);
77   
78   parent->ensuresConstraints = constraintList_copy (child2->ensuresConstraints);
79   parent->ensuresConstraints = constraintList_addList (parent->ensuresConstraints, temp);
80   
81   TPRINTF( (message ("Parent constraints are %s and %s ",
82                      constraintList_print (parent->requiresConstraints),
83                      constraintList_print (parent->ensuresConstraints)
84                      ) ) );
85  
86 }
87
88
89   
90 constraintList reflectChanges (constraintList pre2, constraintList post1)
91 {
92   
93   constraintList ret;
94   constraint temp;
95   ret = constraintList_new();
96   constraintList_elements (pre2, el)
97     {
98       if (!resolve (el, post1) )
99         {
100           temp = substitute (el, post1);
101           ret = constraintList_add (ret, temp);
102         }
103     } end_constraintList_elements;
104
105     return ret;
106 }
107
108
109
110 constraintList reflectChangesEnsures (constraintList pre2, constraintList post1)
111 {  
112   constraintList ret;
113   constraint temp;
114   ret = constraintList_new();
115   constraintList_elements (pre2, el)
116     {
117       if (!resolve (el, post1) )
118         {
119           temp = substitute (el, post1);
120           if (temp != NULL)
121             ret = constraintList_add (ret, temp);
122         }
123     } end_constraintList_elements;
124
125     return ret;
126 }
127
128
129 bool constraint_conflict (constraint c1, constraint c2)
130 {
131   
132   if (constraintExpr_similar(c1->lexpr, c2->lexpr) )
133     {
134       if (c1->ar == c2->ar)
135         {
136           TPRINTF ( (message ("%s conflicts with %s ", constraint_print (c1), constraint_print(c2) ) ) );
137           return TRUE;
138         }
139     }  
140
141   TPRINTF ( (message ("%s conflicts with %s ", constraint_print (c1), constraint_print(c2) ) ) );
142
143   return FALSE; 
144
145 }
146
147 void constraint_fixConflict (constraint good, constraint conflicting)
148 {
149   constraint temp;
150   if (conflicting->ar ==EQ )
151     {
152       good->expr = constraintExpr_searchandreplace (good->expr, conflicting->lexpr, conflicting->expr);
153       temp = constraint_simplify (good);
154       constraint_overWrite (good, temp);
155     }
156
157
158 }
159
160 bool conflict (constraint c, constraintList list)
161 {
162   
163    constraintList_elements (list, el)
164     {
165       if ( constraint_conflict(el, c) )
166         {
167           constraint_fixConflict (el, c);
168           return TRUE;
169         }
170     } end_constraintList_elements;
171
172     return FALSE;
173   
174
175 }
176
177 //check if constraint in list1 and conflict with constraints in List2.  If so we
178 //remove form list1 and (optionally) change list2.
179 constraintList constraintList_fixConflicts (constraintList list1, constraintList list2)
180 {
181   constraintList ret;
182   ret = constraintList_new();
183   constraintList_elements (list1, el)
184     {
185       if (! conflict (el, list2) )
186         {
187             ret = constraintList_add (ret, el);
188         }
189     } end_constraintList_elements;
190
191     return ret;
192   
193     
194 }
195
196 bool resolve (constraint c, constraintList p)
197 {
198   constraintList_elements (p, el)
199     {
200       if ( satifies (c, el) )
201         {
202           TPRINTF ( (message ("\n%s Satifies %s\n ", constraint_print(el), constraint_print(c) ) ) );
203           return TRUE;
204         }
205     }
206   end_constraintList_elements;
207   TPRINTF ( (message ("no constraints satify %s", constraint_print(c) ) ));
208   return FALSE;
209 }
210
211
212 /*returns true if cosntraint post satifies cosntriant pre */
213 bool satifies (constraint pre, constraint post)
214 {
215   if (!constraintExpr_similar (pre->lexpr, post->lexpr) )
216     {
217       return FALSE;
218     }
219   if (post->expr == NULL)
220     {
221       llassert(FALSE);
222       return FALSE;
223     }
224
225   return rangeCheck (pre->ar, pre->expr, post->ar, post->expr);
226 }
227
228
229 bool rangeCheck (arithType ar1, constraintExpr expr1, arithType ar2, constraintExpr expr2)
230
231 {
232   TPRINTF ((message ("Doing Range CHECK %s and %s", constraintExpr_unparse(expr1), constraintExpr_unparse(expr2) ) ));
233   switch (ar1)
234  {
235  case GTE:
236  case GT:
237       /*irst constraint is > only > => or == cosntraint can satify it */
238       if ( (ar2 == GT) || (ar2 == GTE) || (ar2 == EQ) )
239         {
240           if (! constraintExpr_canGetValue (expr1) )
241             {
242               TPRINTF( ("Can't Get value"));
243               return FALSE;
244             }
245           if (! constraintExpr_canGetValue (expr2) )
246             {
247               TPRINTF( ("Can't Get value"));
248               return FALSE;
249             }
250           
251           if (constraintExpr_compare (expr2, expr1) >= 0)
252             return TRUE;
253           
254         }
255       
256       return FALSE;
257  default:
258    TPRINTF(("case not handled"));
259  }
260   return FALSE;
261 }
262
263 constraint constraint_searchandreplace (constraint c, constraintExpr old, constraintExpr new)
264 {
265   TPRINTF (("Doing replace for lexpr") );
266   c->lexpr = constraintExpr_searchandreplace (c->lexpr, old, new);
267   TPRINTF (("Doing replace for expr") );
268   c->expr = constraintExpr_searchandreplace (c->expr, old, new);
269   return c;
270 }
271
272
273 constraint constraint_adjust (constraint substitute, constraint old)
274 {
275   fileloc loc1, loc2, loc3;
276
277   loc1 = constraint_getFileloc (old);
278
279   loc2 = constraintExpr_getFileloc (substitute->lexpr);
280
281   loc3 = constraintExpr_getFileloc (substitute->expr);
282
283   if (fileloc_closer (loc1, loc3, loc2))
284       {
285         constraintExpr temp;
286         temp = substitute->lexpr;
287         substitute->lexpr = substitute->expr;
288         substitute->expr  = temp;
289         substitute = constraint_simplify(substitute);
290       }
291
292   return substitute;
293   
294 }
295
296 constraint substitute (constraint c, constraintList p)
297 {
298   constraintList_elements (p, el)
299     {
300        if ( el->ar == EQ)
301          if (!constraint_conflict (c, el) )
302
303            {
304           
305              constraint temp;
306              temp = constraint_copy(el);
307              
308              temp = constraint_adjust(temp, c);
309           
310              c = constraint_searchandreplace (c, el->lexpr, el->expr);
311            }
312     }
313   end_constraintList_elements;
314
315   c = constraint_simplify(c);
316   return c;
317 }
318
319
320 constraint constraint_solve (constraint c)
321 {
322   TPRINTF( (message ("Solving %s\n", constraint_print(c) ) ) );
323   c->expr = constraintExpr_solveBinaryExpr (c->lexpr, c->expr);
324   TPRINTF( (message ("Solved and got %s\n", constraint_print(c) ) ) );
325
326   return c;
327 }
328
329
330 constraint constraint_simplify (constraint c)
331 {
332   c->lexpr = constraintExpr_simplify (c->lexpr);
333   c->expr  = constraintExpr_simplify (c->expr);
334   
335   c = constraint_solve (c);
336   /*
337   c->lexpr = constraintExpr_simplify (c->lexpr);
338   c->expr  = constraintExpr_simplify (c->expr);
339   */
340   return c;
341 }
342
343
344
345
346 /* returns true  if fileloc for term1 is closer to file for term2 than term3*/
347
348 bool fileloc_closer (fileloc  loc1, fileloc  loc2, fileloc  loc3)
349 {
350    if ( fileloc_lessthan (loc1, loc2) )
351      {
352        if (fileloc_lessthan (loc2, loc3) )
353          {
354            llassert (fileloc_lessthan (loc1, loc3) );
355            return TRUE;
356          }
357        else
358          {
359            return FALSE;
360          }
361      }
362
363    if ( !fileloc_lessthan (loc1, loc2) )
364      {
365        if (!fileloc_lessthan (loc2, loc3) )
366          {
367            llassert (!fileloc_lessthan (loc1, loc3) );
368            return TRUE;
369          }
370        else
371          {
372            return FALSE;
373          }
374      }
375
376    llassert(FALSE);
377    return FALSE;
378 }
379
This page took 0.1534 seconds and 5 git commands to generate.