bug..forgot to return value
[repair.git] / Repair / RepairInterpreter / ActionInSet.cc
1 #include <assert.h>
2 #include "ActionInSet.h"
3 #include "dmodel.h"
4 #include "model.h"
5 #include "normalizer.h"
6 #include "omodel.h"
7 #include "Relation.h"
8 #include "set.h"
9 #include "Hashtable.h"
10 #include "ActionNotInSet.h"
11
12 ActionInSet::ActionInSet(DomainRelation *drel,model *m) {
13   domrelation=drel;
14   globalmodel=m;
15 }
16
17 void ActionInSet::repairpredicate(Hashtable *env,CoercePredicate *p) {
18   Element *ele=(Element*) env->get(p->getpredicate()->getlabel()->label());
19   switch(p->getpredicate()->getsetexpr()->gettype()) {
20   case SETEXPR_LABEL:
21     domrelation->addtoset(ele, domrelation->getset(p->getpredicate()->getsetexpr()->getsetlabel()->getname()),
22                           globalmodel);
23     break;
24   case SETEXPR_REL: {
25     Element *key=(Element*) env->get(p->getpredicate()->getsetexpr()->getlabel()->label());
26     domrelation->getrelation(p->getpredicate()->getsetexpr()->getrelation()->getname())->getrelation()->put(key,ele);
27     char *rangename=domrelation->getrelation(p->getpredicate()->getsetexpr()->getrelation()->getname())->getrange();
28     if (!equivalentstrings(rangename,"int")) {
29       DomainSet *range=domrelation->getset(rangename);
30       if (!range->getset()->contains(ele))
31         domrelation->addtoset(ele,range,globalmodel);
32     }
33   }
34   break;
35   case SETEXPR_INVREL: {
36     Element *key=(Element*) env->get(p->getpredicate()->getsetexpr()->getlabel()->label());
37     domrelation->getrelation(p->getpredicate()->getsetexpr()->getrelation()->getname())->getrelation()->put(ele,key);
38     char *domainname=domrelation->getrelation(p->getpredicate()->getsetexpr()->getrelation()->getname())->getdomain();
39     if (!equivalentstrings(domainname,"int")) {
40       DomainSet *domain=domrelation->getset(domainname);
41       if (!domain->getset()->contains(ele))
42         domrelation->addtoset(ele,domain,globalmodel);
43     }
44   }
45   break;
46   }
47 }
48
49
50
51 void ActionInSet::breakpredicate(Hashtable *env,CoercePredicate *p) 
52 {
53 #ifdef DEBUGMESSAGES
54   printf("ActionInSet::breakpredicate CALLED\n");
55   p->getpredicate()->print(); printf("\n");
56 #endif
57
58   ActionNotInSet *a = new ActionNotInSet(domrelation, globalmodel);
59   a->repairpredicate(env, p);
60 }
61
62
63
64 bool ActionInSet::conflict(Constraint *c1, CoercePredicate *p1,Constraint *c2, CoercePredicate *p2) {
65   assert(canrepairpredicate(p1));
66   if(comparepredicates(c1,p1,c2,p2))
67     return false; /*same predicates don't conflict*/
68   Setexpr *pse=p1->getpredicate()->getsetexpr();
69   switch(pse->gettype()) {
70   case SETEXPR_LABEL: {
71     /* Compute bounding set if there is one */
72     char *boundname=calculatebound(c1,p1->getpredicate()->getlabel());
73     /* Check conflicts arrising from addition to set */
74     {
75       WorkSet *ws=domrelation->conflictaddsets(pse->getsetlabel()->getname(),boundname,globalmodel);
76       DomainSet *ds=(DomainSet *) ws->firstelement();
77       while(ds!=NULL) {
78         if (conflictwithaddtoset(ds->getname(),c2,p2)) {
79           delete(ws);
80           return true;
81         }
82         ds=(DomainSet *) ws->getnextelement(ds);
83       }
84       delete(ws);
85     }
86     /* Check conflicts arrising from deletions from set */
87     {
88       WorkSet *ws=domrelation->conflictdelsets(pse->getsetlabel()->getname(), boundname);    
89       DomainSet *ds=(DomainSet *) ws->firstelement();
90       while (ds!=NULL) {
91         if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) {
92           delete(ws);
93           return true;
94         }
95         ds=(DomainSet *) ws->getnextelement(ds);
96       }
97       delete(ws);
98     }
99     return false;
100   }
101   case SETEXPR_REL: {
102
103     /* Compute bounding set if there is one */
104     char *boundname=calculatebound(c1,p1->getpredicate()->getlabel());
105     DomainRelation *drel=globalmodel->getdomainrelation();
106     char *insertset=drel->getrelation(pse->getrelation()->getname())->getrange();
107
108     /* Check conflicts arrising from addition to set */
109     {
110       WorkSet *ws=domrelation->conflictaddsets(insertset,boundname,globalmodel);
111       DomainSet *ds=(DomainSet *) ws->firstelement();
112       while(ds!=NULL) {
113         if (conflictwithaddtoset(ds->getname(),c2,p2)) {
114           delete(ws);
115           return true;
116         }
117         ds=(DomainSet *) ws->getnextelement(ds);
118       }
119       delete(ws);
120     }
121     /* Check conflicts arrising from deletions from set */
122     {
123       WorkSet *ws=domrelation->conflictdelsets(insertset, boundname);    
124       DomainSet *ds=(DomainSet *) ws->firstelement();
125       while (ds!=NULL) {
126         if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) {
127           delete(ws);
128           return true;
129         }
130         ds=(DomainSet *) ws->getnextelement(ds);
131       }
132       delete(ws);
133     }
134   
135     /* we have a in v.r */
136     /* add <v,a> to r */
137     return testforconflict(getset(c1,p1->getpredicate()->getsetexpr()->getlabel()->label()),
138                            getset(c1,p1->getpredicate()->getlabel()->label()),
139                            p1->getpredicate()->getsetexpr()->getrelation()->getname(),c2,p2);
140   }
141   case SETEXPR_INVREL: {
142     /* Compute bounding set if there is one */
143     char *boundname=calculatebound(c1,p1->getpredicate()->getlabel());
144     DomainRelation *drel=globalmodel->getdomainrelation();
145     char *insertset=drel->getrelation(pse->getrelation()->getname())->getdomain();
146     
147     /* Check conflicts arrising from addition to set */
148     {
149       WorkSet *ws=domrelation->conflictaddsets(insertset,boundname,globalmodel);
150       DomainSet *ds=(DomainSet *) ws->firstelement();
151       while(ds!=NULL) {
152         if (conflictwithaddtoset(ds->getname(),c2,p2)) {
153           delete(ws);
154           return true;
155         }
156         ds=(DomainSet *) ws->getnextelement(ds);
157       }
158       delete(ws);
159     }
160     /* Check conflicts arrising from deletions from set */
161     {
162       WorkSet *ws=domrelation->conflictdelsets(insertset, boundname);    
163       DomainSet *ds=(DomainSet *) ws->firstelement();
164       while (ds!=NULL) {
165         if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) {
166           delete(ws);
167           return true;
168         }
169         ds=(DomainSet *) ws->getnextelement(ds);
170       }
171       delete(ws);
172     }
173     /* add <a,v> to r */
174     return testforconflict(getset(c1,p1->getpredicate()->getlabel()->label()),
175                            getset(c1,p1->getpredicate()->getsetexpr()->getlabel()->label()),
176                            p1->getpredicate()->getsetexpr()->getrelation()->getname(),c2,p2);
177   }
178   }
179 }
180
181 bool ActionInSet::canrepairpredicate(CoercePredicate *cp) {
182   if (cp->getcoercebool()==false)
183     return false;
184   Predicate *p=cp->getpredicate();
185   if (p==NULL)
186     return false;
187   if (p->gettype()!=PREDICATE_SET)
188     return false;
189   Setexpr *se=p->getsetexpr();
190   int setexprtype=se->gettype();
191   if (setexprtype==SETEXPR_REL||
192       setexprtype==SETEXPR_INVREL) {
193     DRelation *dr=domrelation->getrelation(se->getrelation()->getname());
194     if (dr->isstatic())
195       return false; /* Can't change static domain relations */
196   }
197
198   /* Coercing set membership */
199   return true;
200 }