]> andersk Git - splint.git/blame - src/constraintResolve.c
It mostly works but it has a convolted API that needs fixxing.
[splint.git] / src / constraintResolve.c
CommitLineData
361091cc 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
18int constraintExpr_getValue (constraintExpr expr)
19{
20 if (expr->expr != NULL)
21 {
22 TPRINTF( ( "Not Implemented" ));
23 llassert(FALSE);
24 }
25 return (constraintTerm_getValue (expr->term) );
26}
27
28// returns 1 0 -1 like strcopy
29int constraintExpr_compare (constraintExpr expr1, constraintExpr expr2)
30{
31 int value1, value2;
32
33 value1 = constraintExpr_getValue(expr1);
34 value2 = constraintExpr_getValue(expr2);
35
36 if (value1 > value2)
37 return 1;
38
39 if (value1 == value2)
40 return 0;
41
42 else
43 return -1;
44}
45
46bool constraintExpr_canCompare (constraintExpr expr1, constraintExpr expr2)
47{
48 if (expr1->expr != NULL)
49 {
50 return FALSE;
51 }
52
53 if (expr2->expr != NULL)
54 {
55 return FALSE;
56 }
57
58 return TRUE;
59}
60
61bool rangeCheck (arithType ar1, constraintExpr expr1, arithType ar2, constraintExpr expr2)
62
63{
64 switch (ar1)
65 {
66 case GTE:
67 case GT:
68 /*irst constraint is > only > => or == cosntraint can satify it */
69 if ( (ar2 == GT) || (ar2 == GTE) || (ar2 == EQ) )
70 {
71 if (! constraintExpr_canCompare (expr1, expr2) )
72 return FALSE;
73
74 if (constraintExpr_compare (expr2, expr1) >= 0)
75 return TRUE;
76
77 }
78 return FALSE;
79 default:
80 TPRINTF(("case not handled"));
81 }
82 return FALSE;
83}
84
85/*returns true if cosntraint post satifies cosntriant pre */
86bool satifies (constraint pre, constraint post)
87{
88 if (!constraintTerm_same(pre->lexpr->term, post->lexpr->term) )
89 {
90 return FALSE;
91 }
bf92e32c 92 if (post->expr == NULL)
361091cc 93 return FALSE;
bf92e32c 94
361091cc 95 return rangeCheck (pre->ar, pre->expr, post->ar, post->expr);
361091cc 96}
97
98constraintExpr constraintExpr_simplify (constraintExpr expr)
99{
100
101 expr->term = constraintTerm_simplify (expr->term);
102 if (expr->expr == NULL)
bf92e32c 103 {
104 if ( (expr->term->kind == CONSTRAINTEXPR) && (expr->term->constrType == VALUE) )
105 {
106 expr->op = expr->term->value.constrExpr->op;
107 expr->expr = expr->term->value.constrExpr->expr;
108 expr->term = expr->term->value.constrExpr->term;
109 }
110
111 return expr;
112 }
361091cc 113
114 expr->expr = constraintExpr_simplify (expr->expr);
bf92e32c 115
116
117
118 if ( (expr->term->kind == INTLITERAL) && (expr->expr->term->kind == INTLITERAL) )
361091cc 119 {
bf92e32c 120 DPRINTF( ("INTLITERAL MERGE " ));
361091cc 121
bf92e32c 122 DPRINTF ( (message ("Expression is %s ", constraintExpr_print (expr) ) ) );
361091cc 123
124 if (expr->op == PLUS )
125 {
bf92e32c 126 DPRINTF( (message ("Adding %d and %d ", expr->term->value.intlit,
361091cc 127 expr->expr->term->value.intlit) ) );
128 expr->term->value.intlit += expr->expr->term->value.intlit;
129 }
130 else if (expr->op == MINUS )
131 {
132 expr->term->value.intlit -= expr->expr->term->value.intlit;
133 }
134 expr->op = expr->expr->op;
135
136 expr->expr = expr->expr->expr;
137 }
bf92e32c 138
361091cc 139 return expr;
140
141}
142
143constraintExpr constraintExpr_add (constraintExpr e, constraintTerm term, constraintExprOp op)
144{
145 constraintExpr p;
146
147 p = e;
148 while (p->expr != NULL)
149 {
150 p = p->expr;
151 }
152
153 p->op = op;
154 p->expr = constraintExpr_alloc();
155 p->expr->term = term;
156
157 return e;
158}
159
160constraintExpr termMove (constraintExpr dst, constraintExpr src)
161{
162 constraintTerm term;
163 llassert (src->expr != NULL);
164 term = src->expr->term;
165 if (src->op == PLUS)
166 dst = constraintExpr_add (dst, term, MINUS);
167 else
168 if (src->op == MINUS)
169 dst = constraintExpr_add (dst, term, PLUS);
170
171 return dst;
172}
173
174constraint solveforterm (constraint c)
175{
176 constraintExpr p;
177 p = c->lexpr;
178 while (p->expr != NULL)
179 {
bf92e32c 180 DPRINTF( (message("Moving %s", constraintExpr_print (c->expr) ) ) );
361091cc 181 c->expr = termMove(c->expr, p);
182 p->op = p->expr->op;
183 #warning memleak
184
185 p->expr = p->expr->expr;
186 }
187 return c;
188}
189
6364363c 190constraint solveforOther (constraint c)
191{
192 constraintExpr p;
193 p = c->expr;
194 while (p->expr != NULL)
195 {
196 TPRINTF( (message("Moving %s", constraintExpr_print (c->expr) ) ) );
197 c->lexpr = termMove(c->lexpr, p);
198 p->op = p->expr->op;
199 #warning memleak
200
201 p->expr = p->expr->expr;
202 }
203 return c;
204}
205
361091cc 206constraint constraint_simplify (constraint c)
207{
208 c = solveforterm (c);
209 c->lexpr = constraintExpr_simplify (c->lexpr);
210 c->expr = constraintExpr_simplify (c->expr);
211 return c;
212}
213
214bool resolve (constraint c, constraintList p)
215{
216 constraintList_elements (p, el)
217 {
218 if ( satifies (c, el) )
219 {
bf92e32c 220 DPRINTF ( (message ("\n%s Satifies %s\n ", constraint_print(el), constraint_print(c) ) ) );
361091cc 221 return TRUE;
222 }
223 }
224 end_constraintList_elements;
bf92e32c 225 DPRINTF ( (message ("no constraints satify %s", constraint_print(c) ) ));
361091cc 226 return FALSE;
227}
228
bf92e32c 229
230constraintTerm constraintTerm_substituteTerm (constraintTerm term, constraintTerm oldterm, constraintExpr replacement)
231{
232 if ( constraintTerm_similar (term, oldterm) )
233 {
234 // do the substitution
235 term->kind = CONSTRAINTEXPR;
236 term->value.constrExpr = constraintExpr_copy (replacement);
237 }
238 return term;
239}
240
241constraintExpr constraintExpr_substituteTerm (constraintExpr expr, constraintTerm oldterm, constraintExpr replacement)
242{
243 expr->term = constraintTerm_substituteTerm (expr->term, oldterm, replacement);
244 if (expr->expr != NULL)
245 expr->expr = constraintExpr_substituteTerm (expr->expr, oldterm, replacement);
246
247 return expr;
248}
6364363c 249
250/* returns true if fileloc for term2 is closer to file for term1 than is term3*/
251
252bool fileloc_closer (constraintTerm term1, constraintTerm term2, constraintTerm term3)
bf92e32c 253{
6364363c 254 if ( fileloc_lessthan (term1->loc, term2->loc) )
255 {
256 if (fileloc_lessthan (term2->loc, term3->loc) )
257 {
258 llassert (fileloc_lessthan (term1->loc, term3->loc) );
259 return TRUE;
260 }
261 else
262 {
263 return FALSE;
264 }
265 }
266
267 if ( ! (fileloc_lessthan (term1->loc, term2->loc) ) )
268 {
269 if (!fileloc_lessthan (term2->loc, term3->loc) )
270 {
271 llassert (fileloc_lessthan (term3->loc, term1->loc) );
272 return TRUE;
273 }
274 else
275 {
276 return FALSE;
277
278 }
279 }
280
281 llassert(FALSE);
282 return FALSE;
283}
284
285constraint constraint_substituteTerm (constraint c, constraint subs)
286{
287 constraintTerm oldterm;
288 constraintExpr replacement;
289
290 llassert(subs->lexpr->expr == NULL);
291
292
293 oldterm = subs->lexpr->term;
294 replacement = subs->expr;
295
296 // Chessy hack assumes that subs always has the form g:1 = g:2 + expr
297
298 /*@i2*/
299
300 /*find out which value to substitute*/
301 TPRINTF((message ("doing substitute for %s and %s", constraint_print (c), constraint_print(subs) ) ) );
302 if ( constraintExpr_containsTerm (subs->expr, subs->lexpr->term) )
303 {
304 TPRINTF(("doing new stuff"));
305 if (fileloc_closer (c->lexpr->term, subs->expr->term, subs->lexpr->term) )
306 {
307 // use the other term
308 constraint new;
309 new = constraint_copy (subs);
310 new = solveforOther(new);
311 oldterm = new->expr->term;
312 replacement = new->lexpr;
313 }
314 }
315
316 c->lexpr = constraintExpr_substituteTerm (c->lexpr, oldterm, replacement);
317 c->expr = constraintExpr_substituteTerm (c->expr, oldterm, replacement);
318 return c;
bf92e32c 319}
320
361091cc 321constraint substitute (constraint c, constraintList p)
322{
323 constraintList_elements (p, el)
324 {
bf92e32c 325 if ( el->ar == EQ)
326 if (constraint_hasTerm (c, el->lexpr->term) )
bf92e32c 327 {
6364363c 328 llassert(el->lexpr->expr == NULL);
bf92e32c 329 DPRINTF((message ("doing substitute for %s", constraint_print (c) ) ) );
6364363c 330
331 c = constraint_substituteTerm (c, el);
bf92e32c 332 DPRINTF((message ("substituted constraint is now %s", constraint_print (c) ) ) );
333 // c->lexpr = constraintExpr_copy (el->expr);
334 c = constraint_simplify(c);
335 c = constraint_simplify(c);
361091cc 336 c = constraint_simplify(c);
337 return c;
6364363c 338 }
361091cc 339 }
340 end_constraintList_elements;
341
342 c = constraint_simplify(c);
343 return c;
344}
345
346
347constraintList reflectChanges (constraintList pre2, constraintList post1)
348{
349
350 constraintList ret;
351 constraint temp;
352 ret = constraintList_new();
353 constraintList_elements (pre2, el)
354 {
355 if (!resolve (el, post1) )
356 {
357 temp = substitute (el, post1);
358 ret = constraintList_add (ret, temp);
359 }
360 } end_constraintList_elements;
361
362 return ret;
363}
364
6364363c 365bool constraintExpr_containsTerm (constraintExpr p, constraintTerm term)
366{
367 TPRINTF(("constraintExpr_containsTerm"));
368
369 while (p != NULL)
370 {
371 if (constraintTerm_similar (p->term, term) )
372 return TRUE;
373
374 p = p->expr->expr;
375 }
376 DPRINTF((
377 message ("constraintExpr_hasTerm returned fallse for %s %S",
378 constraint_print(c), constraintTerm_print(term)
379 )
380 ));
381 return FALSE;
382}
383
361091cc 384
385/*check if rvalue side has term*/
386bool constraintExpr_hasTerm (constraint c, constraintTerm term)
387{
388 constraintExpr p;
389 p = c->expr;
390 while (p != NULL)
391 {
392 if (constraintTerm_same (p->term, term) )
393 return TRUE;
394
395 p = p->expr->expr;
396 }
bf92e32c 397 DPRINTF((
361091cc 398 message ("constraintExpr_hasTerm returned fallse for %s %S",
399 constraint_print(c), constraintTerm_print(term)
400 )
401 ));
402 return FALSE;
403}
404
405constraintExpr solveEq (constraint c, constraintTerm t)
406{
407 constraintExpr p;
408 c = constraint_copy (c);
bf92e32c 409 DPRINTF(("\ndoing solveEq\n"));
361091cc 410 if (! constraintTerm_same (c->expr->term, t) )
411 {
bf92e32c 412 DPRINTF ( (message ("\n\nconstraintTerms: %s %s not same ", constraintTerm_print(c->expr->term),
361091cc 413 constraintTerm_print(t) )
414 ) );
415 return NULL;
416 }
417
418 p = c->expr;
419 while (p->expr != NULL)
420 {
bf92e32c 421 DPRINTF( (message("\n\nMoving %s", constraintExpr_print (c->expr) ) ) );
361091cc 422 c->lexpr = termMove(c->lexpr, p);
423 p->expr = p->expr->expr;
424 }
425
426 return c->lexpr;
427
428}
429
430constraint updateConstraint (constraint c, constraintList p)
431{
6364363c 432 TPRINTF(("start updateConstraints"));
361091cc 433 constraintList_elements (p, el)
434 {
435
436 if (constraintTerm_same(c->lexpr->term, el->lexpr->term) )
437 {
6364363c 438 TPRINTF((""));
361091cc 439 if ( el->ar == EQ)
440 {
6364363c 441 TPRINTF(("j"));
361091cc 442
443 if (constraintExpr_hasTerm (el, c->lexpr->term) )
444 {
445 constraintExpr solve;
446 TPRINTF((""));
447 solve = solveEq (el, c->lexpr->term);
448 if (solve)
449 {
450 c->lexpr = constraintExpr_copy (solve);
451 c = constraint_simplify(c);
452 return c;
453 }
454 }
455 }
456 }
457 }
458 end_constraintList_elements;
459 c = constraint_simplify(c);
460
bf92e32c 461 DPRINTF(("end updateConstraints"));
361091cc 462 return c;
463}
464
465
466constraintList reflectChangesEnsures (constraintList pre2, constraintList post1)
467{
468 constraintList ret;
469 constraint temp;
470 ret = constraintList_new();
471 constraintList_elements (pre2, el)
472 {
473 if (!resolve (el, post1) )
474 {
6364363c 475 temp = substitute (el, post1);
361091cc 476 if (temp != NULL)
477 ret = constraintList_add (ret, temp);
478 }
479 } end_constraintList_elements;
480
481 return ret;
482}
483
484void mergeResolve (exprNode parent, exprNode child1, exprNode child2)
485{
486 constraintList temp;
bf92e32c 487 DPRINTF( (message ("magically merging constraint into parent:%s for children: %s and %s", exprNode_unparse (parent), exprNode_unparse (child1), exprNode_unparse(child2) )
361091cc 488 ) );
6364363c 489 if (exprNode_isError (child1) || exprNode_isError(child2) )
490 {
491 if (exprNode_isError (child1) && !exprNode_isError(child2) )
492 {
493 parent->requiresConstraints = constraintList_copy (child2->requiresConstraints);
494 parent->ensuresConstraints = constraintList_copy (child2->ensuresConstraints);
495 DPRINTF((message ("Copied child constraints: pre: %s and post: %s",
496 constraintList_print( child2->requiresConstraints),
497 constraintList_print (child2->ensuresConstraints)
498 )
499 ));
500 return;
501 }
502 else
503 {
504 llassert(exprNode_isError(child2) );
505 parent->requiresConstraints = constraintList_new();
506 parent->ensuresConstraints = constraintList_new();
507 return;
508 }
509 }
510
511 llassert(!exprNode_isError (child1) && ! exprNode_isError(child2) );
512
bf92e32c 513 DPRINTF( (message ("Child constraints are %s %s and %s %s",
361091cc 514 constraintList_print (child1->requiresConstraints),
939083e7 515 constraintList_print (child1->ensuresConstraints),
516 constraintList_print (child2->requiresConstraints),
517 constraintList_print (child2->ensuresConstraints)
361091cc 518 ) ) );
519
520 parent->requiresConstraints = constraintList_new();
521 parent->ensuresConstraints = constraintList_new();
522
523 parent->requiresConstraints = constraintList_copy (child1->requiresConstraints);
524
525 temp = reflectChanges (child2->requiresConstraints, child1->ensuresConstraints);
526 parent->requiresConstraints = constraintList_addList (parent->requiresConstraints, temp);
527
528
529 temp = reflectChangesEnsures (child1->ensuresConstraints, child2->ensuresConstraints);
530 // temp = constraintList_copy (child1->ensuresConstraints);
531
532
533 parent->ensuresConstraints = constraintList_copy (child2->ensuresConstraints);
534 parent->ensuresConstraints = constraintList_addList (parent->ensuresConstraints, temp);
535
bf92e32c 536 DPRINTF( (message ("Parent constraints are %s and %s ",
361091cc 537 constraintList_print (parent->requiresConstraints),
538 constraintList_print (parent->ensuresConstraints)
539 ) ) );
540
541}
542
bf92e32c 543
This page took 2.652396 seconds and 5 git commands to generate.