revert runtime file.
[repair.git] / Repair / RepairInterpreter / Action.cc
1 #include <stdlib.h>
2 #include "Action.h"
3 #include "omodel.h"
4 #include "model.h"
5 #include "dmodel.h"
6 #include "set.h"
7 #include "normalizer.h"
8
9 char * Action::calculatebound(Constraint *c, Label *clabel) {
10   return getset(c,clabel->label());
11 }
12
13 char * Action::getset(Constraint *c, char *v) {
14   char *set=NULL;
15   if (c==NULL||v==NULL)
16     return NULL;
17   for(int i=0;i<c->numquants();i++) {
18     if(equivalentstrings(c->getquant(i)->getlabel()->label(),v)) {
19       if (c->getquant(i)->getset()->gettype()==SET_label)
20         set=c->getquant(i)->getset()->getname();
21       break;
22     }
23   }
24   return set;
25 }
26
27 bool Action::possiblysameset(char *v1, Constraint *c1, char *v2, Constraint *c2) {
28   return possiblysameset(getset(c1,v1),getset(c2,v2));
29 }
30
31 bool Action::comparepredicates(Constraint *c1, CoercePredicate *cp1, Constraint *c2, CoercePredicate *cp2) {
32   if (cp1->getcoercebool()!=cp2->getcoercebool())
33     return false;
34   Predicate *p1=cp1->getpredicate();
35   Predicate *p2=cp2->getpredicate();
36   if (p1->gettype()!=p2->gettype())
37     return false;
38   int type=p1->gettype();
39   if (type==PREDICATE_LT ||
40       type==PREDICATE_LTE ||
41       type==PREDICATE_EQUALS ||
42       type==PREDICATE_GTE ||
43       type==PREDICATE_GT) {
44     char *v1=p1->getvalueexpr()->getlabel()->label();
45     char *v2=p2->getvalueexpr()->getlabel()->label();
46     if (!equivalentstrings(p1->getvalueexpr()->getrelation()->getname(),
47                           p2->getvalueexpr()->getrelation()->getname()))
48       return false;
49     if (!(compareee(p1->geteleexpr(),v1,p2->geteleexpr(),v2)))
50       return false;
51     else
52       return true;
53   }
54   if (type==PREDICATE_SET) {
55     char *v1=p1->getlabel()->label();
56     char *v2=p2->getlabel()->label();
57     return comparesetexpr(p1->getsetexpr(),v1,p2->getsetexpr(),v2);
58   }
59   if (type==PREDICATE_EQ1||type==PREDICATE_GTE1) {
60     if(p1->getsetexpr()->gettype()!=p2->getsetexpr()->gettype())
61       return false;
62     switch(p1->getsetexpr()->gettype()) {
63     case SETEXPR_LABEL: {
64       return equivalentstrings(p1->getsetexpr()->getsetlabel()->getname(), p2->getsetexpr()->getsetlabel()->getname());
65     }
66     case SETEXPR_REL:
67     case SETEXPR_INVREL: {
68       /* these can't interfere....*/
69       return equivalentstrings(p1->getsetexpr()->getrelation()->getname(), p2->getsetexpr()->getrelation()->getname());
70     }
71     }
72   }
73   return false; /* by default */
74 }
75  
76 bool Action::comparesetexpr(Setexpr *s1,char *v1,Setexpr *s2,char *v2) {
77   if (s1->gettype()!=s2->gettype())
78     return false;
79   switch(s1->gettype()) {
80   case SETEXPR_LABEL:
81     if (!equivalentstrings(s1->getsetlabel()->getname(),
82                            s2->getsetlabel()->getname()))
83       return false;
84     else return true; 
85   case SETEXPR_REL:
86   case SETEXPR_INVREL:
87     if (!equivalentstrings(v1, s1->getlabel()->label()))
88       return false;
89     if (!equivalentstrings(v2, s2->getlabel()->label()))
90       return false;
91     if (!equivalentstrings(s1->getrelation()->getname(),
92                            s2->getrelation()->getname()))
93       return false;
94     else return true;
95   default:
96     return false;
97   }
98 }
99
100 bool Action::compareee(Elementexpr *ee1,char *v1,Elementexpr *ee2,char *v2) {
101   if (ee1->gettype()!=ee2->gettype())
102     return false;
103   switch(ee1->gettype()) {
104   case ELEMENTEXPR_LABEL:
105     if (!equivalentstrings(ee1->getlabel()->label(),v1))
106       return false;
107     if (!equivalentstrings(ee2->getlabel()->label(),v2))
108       return false;
109     return true;
110   case ELEMENTEXPR_SUB:
111     if (compareee(ee1->getleft(),v1,ee2->getleft(),v2) &&
112         compareee(ee1->getright(),v1,ee2->getright(),v2))
113       return true;
114     else return false;
115   case ELEMENTEXPR_RELATION:
116     if (compareee(ee1->getleft(),v1,ee2->getleft(),v2) &&
117         equivalentstrings(ee1->getrelation()->getname(),ee2->getrelation()->getname()))
118       return true;
119     else return false;
120   case ELEMENTEXPR_ADD:
121   case ELEMENTEXPR_MULT:
122     if ((compareee(ee1->getleft(),v1,ee2->getleft(),v2) &&
123          compareee(ee1->getright(),v1,ee2->getright(),v2))||
124         (compareee(ee1->getleft(),v1,ee2->getright(),v2) &&
125          compareee(ee1->getright(),v1,ee2->getleft(),v2)))
126       return true;
127     else return false;
128   case ELEMENTEXPR_LIT:
129     if (ee1->getliteral()->gettype()!=
130         ee2->getliteral()->gettype())
131       return false;
132     switch(ee1->getliteral()->gettype()) {
133     case LITERAL_NUMBER:
134       return (ee1->getliteral()->number()==ee2->getliteral()->number());
135     case LITERAL_TOKEN:
136       return (equivalentstrings(ee1->getliteral()->token(),ee2->getliteral()->token()));
137     default:
138       return false;
139     }
140   case ELEMENTEXPR_SETSIZE:
141     return comparesetexpr(ee1->getsetexpr(),v1,ee2->getsetexpr(),v2);
142   default:
143     return false;
144   }
145 }
146
147 bool Action::possiblysameset(char *set1, char *v2, Constraint *c2) {
148   return possiblysameset(set1,getset(c2,v2));
149 }
150
151 bool Action::possiblysameset(char *set1,char *set2) {
152   if (set1==NULL||set2==NULL)
153     return true; /* At least one variable isn't spanning over a set...could be from any set*/
154   DomainSet *dset1=domrelation->getset(set1);
155   DomainSet *dset2=domrelation->getset(set2);
156   WorkSet *ws=new WorkSet(true);
157   while(dset1!=NULL) {
158     ws->addobject(dset1);
159     dset1=domrelation->getsuperset(dset1);
160   }
161   bool sameset=false;
162   if (!ws->contains(dset2)) {
163     while(dset2!=NULL) {
164       if (ws->contains(dset2)) {
165         if (dset2->gettype()==DOMAINSET_PARTITION&&
166             dset2!=dset1)
167           sameset=false;
168         else
169           sameset=true;
170         break;
171       }
172       dset2=domrelation->getsuperset(dset2);
173     }
174   }
175   delete(ws);
176   return sameset;
177 }
178
179 bool Action::conflictwithaddtoset(char *set, Constraint *c, CoercePredicate *p) {
180   /* Test for conflict with abstraction function */
181   if (!p->isrule()&&
182       equivalentstrings(p->gettriggerset(),set))
183     return true;
184       
185   /* Test for add new constraint */
186   if (c!=NULL) {
187     for(int i=0;i<c->numquants();i++) {
188       if (c->getquant(i)->getset()->gettype()==SET_label)
189         if (equivalentstrings(c->getquant(i)->getset()->getname(),set)) {
190           return true; /*we're adding this constraint because of inclusion*/ 
191         }
192     }
193   }
194   /* Test for conflict with a \notin set */
195   if (p->isrule()&&
196       (p->getcoercebool()==false)&&
197       (p->getpredicate()->gettype()==PREDICATE_SET)&&
198       (p->getpredicate()->getsetexpr()->gettype()==SETEXPR_LABEL)) {
199     char *psetname=p->getpredicate()->getsetexpr()->getsetlabel()->getname();
200     if (equivalentstrings(psetname,set)) {
201       return true;
202     }
203   }
204   /* Test for conflict with setsize=1 */
205   if (p->isrule()&&
206       (p->getcoercebool()==true)&&
207       (p->getpredicate()->gettype()==PREDICATE_EQ1)&&
208       (p->getpredicate()->getsetexpr()->gettype()==SETEXPR_LABEL)) {
209     char *psetname=p->getpredicate()->getsetexpr()->getsetlabel()->getname();
210     if (equivalentstrings(psetname,set)) 
211       return true;
212   }
213   return false;
214 }
215
216 bool Action::conflictwithremovefromset(WorkSet * checkother,char *set, Constraint *c, CoercePredicate *p) {
217   /* Check for conflict with set size predicate */
218   if (p->isrule() &&
219       (p->getcoercebool()==true)&&
220       ((p->getpredicate()->gettype()==PREDICATE_EQ1)||
221        (p->getpredicate()->gettype()==PREDICATE_GTE1)) &&
222       (p->getpredicate()->getsetexpr()->gettype()==SETEXPR_LABEL)) {
223     char *psetname=p->getpredicate()->getsetexpr()->getsetlabel()->getname();
224     if (equivalentstrings(psetname,set)) 
225       return true;
226   }
227
228   /* Check for conflict with a in SET */
229   if (p->isrule() &&
230       (p->getcoercebool()==true)&&
231       (p->getpredicate()->gettype()==PREDICATE_SET)&&
232       (p->getpredicate()->getsetexpr()->gettype()==SETEXPR_LABEL)) {
233     char *psetname=p->getpredicate()->getsetexpr()->getsetlabel()->getname();
234     if (equivalentstrings(psetname,set))
235       return true;
236   }
237
238   /* Check for domain's of relation */
239   DomainRelation *domrelation=globalmodel->getdomainrelation();
240   for(int i=0;i<domrelation->getnumrelation();i++) {
241     DRelation *drelation=domrelation->getrelation(i);
242     char *domain=drelation->getdomain();
243     if(equivalentstrings(domain,set)) {
244       testforconflictremove(set,NULL,drelation->getname(),c,p);
245       if(drelation->isstatic()) {
246         bool flag=false;
247         if(checkother==NULL) {
248           flag=true;
249           checkother=new WorkSet((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
250         }
251         if(!checkother->contains(drelation->getrange())) {
252           checkother->addobject(drelation->getrange());
253           if (conflictwithremovefromset(checkother, drelation->getrange(),c,p))
254             return true;
255           checkother->removeobject(drelation->getrange());
256         }
257         if(flag)
258           delete(checkother);
259       }
260     }
261   }
262   /* Check for range's of relation */
263   for(int i=0;i<domrelation->getnumrelation();i++) {
264     DRelation *drelation=domrelation->getrelation(i);
265     char *range=drelation->getrange();
266     if (equivalentstrings(range,set)) {
267       testforconflictremove(NULL,set,drelation->getname(),c,p);
268     }
269   }
270   return false;
271 }
272
273 /* remove <v,a> from r */
274 bool Action::testforconflictremove(char *setv, char *seta, char *rel, Constraint *c, CoercePredicate *p) {
275   /* check for conflict with v.r=? */
276   if (p->isrule()) {
277   int type=p->getpredicate()->gettype();
278   if ((type==PREDICATE_LT||type==PREDICATE_LTE||type==PREDICATE_EQUALS||type==PREDICATE_GT||type==PREDICATE_GTE) &&
279       possiblysameset(setv,p->getpredicate()->getvalueexpr()->getlabel()->label(),c) &&
280       equivalentstrings(rel,p->getpredicate()->getvalueexpr()->getrelation()->getname()))
281     return true;
282
283   /* check for conflict with |v'.r|?=1 */
284   if ((p->getpredicate()->gettype()==PREDICATE_EQ1||p->getpredicate()->gettype()==PREDICATE_GTE1)&&
285       p->getpredicate()->getsetexpr()->gettype()==SETEXPR_REL&&
286       possiblysameset(setv,p->getpredicate()->getsetexpr()->getlabel()->label(),c)&&
287     equivalentstrings(rel,p->getpredicate()->getsetexpr()->getrelation()->getname()))
288     return true;
289
290   /* check for conflict with |a'.~r|?=1 */
291   if ((p->getpredicate()->gettype()==PREDICATE_EQ1||p->getpredicate()->gettype()==PREDICATE_GTE1) &&
292       p->getpredicate()->getsetexpr()->gettype()==SETEXPR_INVREL &&
293       possiblysameset(seta,p->getpredicate()->getsetexpr()->getlabel()->label(),c)&&
294       equivalentstrings(rel,p->getpredicate()->getsetexpr()->getrelation()->getname()))
295     return true;
296   
297   /* check for conflit with (a' in v'.r)*/
298   if (p->getcoercebool()&&
299       p->getpredicate()->gettype()==PREDICATE_SET&&
300       p->getpredicate()->getsetexpr()->gettype()==SETEXPR_REL&&
301       possiblysameset(seta,p->getpredicate()->getlabel()->label(),c)&&
302       possiblysameset(setv,p->getpredicate()->getsetexpr()->getlabel()->label(),c)&&
303       equivalentstrings(rel,p->getpredicate()->getsetexpr()->getrelation()->getname()))
304     return true;
305   
306   /* check for conflict with (a' in v'.~r)*/
307   if (p->getcoercebool()&&
308       p->getpredicate()->gettype()==PREDICATE_SET&&
309       p->getpredicate()->getsetexpr()->gettype()==SETEXPR_INVREL &&
310       possiblysameset(seta,p->getpredicate()->getsetexpr()->getlabel()->label(),c) &&
311       possiblysameset(setv,p->getpredicate()->getlabel()->label(),c) &&
312       equivalentstrings(rel,p->getpredicate()->getsetexpr()->getrelation()->getname()))
313     return true;
314   }
315   return false;
316 }
317
318
319 /* add <v,a> to r */
320 bool Action::testforconflict(char *setv, char *seta, char *rel, Constraint *c, CoercePredicate *p) {
321   /* check for conflict with valueexpr*/
322   if (p->isrule()&&
323       (p->getpredicate()->gettype()==PREDICATE_LT ||
324        p->getpredicate()->gettype()==PREDICATE_LTE ||
325        p->getpredicate()->gettype()==PREDICATE_EQUALS ||
326        p->getpredicate()->gettype()==PREDICATE_GTE ||
327        p->getpredicate()->gettype()==PREDICATE_GT) &&
328       possiblysameset(setv,p->getpredicate()->getvalueexpr()->getlabel()->label(),c) &&
329       equivalentstrings(rel,p->getpredicate()->getvalueexpr()->getrelation()->getname()))
330     return true;
331   
332   /* check for conflict with |v'.r'|=1 */
333   if (p->isrule() &&
334       p->getpredicate()->gettype()==PREDICATE_EQ1&&
335       p->getpredicate()->getsetexpr()->gettype()==SETEXPR_REL&&
336       possiblysameset(setv,p->getpredicate()->getsetexpr()->getlabel()->label(),c)&&
337       equivalentstrings(rel,p->getpredicate()->getsetexpr()->getrelation()->getname()))
338     return true;
339
340   /* try to catch case of |a'.~r|=1 */
341   if (p->isrule() &&
342       p->getpredicate()->gettype()==PREDICATE_EQ1 &&
343       p->getpredicate()->getsetexpr()->gettype()==SETEXPR_INVREL &&
344       possiblysameset(seta,p->getpredicate()->getsetexpr()->getlabel()->label(),c)&&
345       equivalentstrings(rel,p->getpredicate()->getsetexpr()->getrelation()->getname()))
346     return true;
347
348   /* try to catch case of !(a' in v'.r)*/
349   if (p->isrule() &&
350       !p->getcoercebool()&&
351       p->getpredicate()->gettype()==PREDICATE_SET&&
352       p->getpredicate()->getsetexpr()->gettype()==SETEXPR_REL&&
353       possiblysameset(seta,p->getpredicate()->getlabel()->label(),c)&&
354       possiblysameset(setv,p->getpredicate()->getsetexpr()->getlabel()->label(),c)&&
355       equivalentstrings(rel,p->getpredicate()->getsetexpr()->getrelation()->getname()))
356     return true;
357   
358   
359   /* try to catch case of !(a' in v'.~r)*/
360   if (p->isrule() &&
361       !p->getcoercebool()&&
362       p->getpredicate()->gettype()==PREDICATE_SET&&
363       p->getpredicate()->getsetexpr()->gettype()==SETEXPR_INVREL&&
364       possiblysameset(seta,p->getpredicate()->getsetexpr()->getlabel()->label(),c)&&
365       possiblysameset(setv,p->getpredicate()->getlabel()->label(),c)&&
366       equivalentstrings(rel,p->getpredicate()->getsetexpr()->getrelation()->getname()))
367   return true;
368   
369   return false;
370 }