1 // Repairs and destroys size propositions of the form "size(SE)=1"
6 #include "normalizer.h"
11 #include "Hashtable.h"
14 ActionEQ1::ActionEQ1(DomainRelation *drel, model *m) {
19 void ActionEQ1::repairpredicate(Hashtable *env,CoercePredicate *p) {
20 switch(p->getpredicate()->getsetexpr()->gettype()) {
23 char *setname=p->getpredicate()->getsetexpr()->getsetlabel()->getname();
24 DomainSet *ds=domrelation->getset(setname);
25 if (ds->getset()->size()>1) {
26 Guidance *g=globalmodel->getguidance();
27 WorkSet *ws=ds->getset();
29 Element *e=(Element *)ws->firstelement();
30 domrelation->delfromsetmovetoset(e,domrelation->getset(setname), globalmodel);
33 this->ActionGEQ1::repairpredicate(env,p);
39 DRelation *dr=domrelation->getrelation(p->getpredicate()->getsetexpr()->getrelation()->getname());
40 WorkRelation *wr=dr->getrelation();
41 Element *key=(Element *)env->get(p->getpredicate()->getsetexpr()->getlabel()->label());
42 WorkSet *ws=wr->getset(key);
44 if (ws!=NULL&&ws->size()>1) {
47 for(int i=0;i<(size-1);i++) {
48 void *objtoremove=ws->firstelement();
49 wr->remove(key,objtoremove);
52 this->ActionGEQ1::repairpredicate(env,p);
57 case SETEXPR_INVREL: {
58 DRelation *dr=domrelation->getrelation(p->getpredicate()->getsetexpr()->getrelation()->getname());
59 WorkRelation *wr=dr->getrelation();
60 Element *key=(Element *)env->get(p->getpredicate()->getsetexpr()->getlabel()->label());
61 WorkSet *ws=wr->invgetset(key);
63 if (ws!=NULL&&ws->size()>1) {
66 for(int i=0;i<(size-1);i++) {
67 void *objtoremove=ws->firstelement();
68 wr->remove(objtoremove,key);
71 this->ActionGEQ1::repairpredicate(env,p);
80 void ActionEQ1::breakpredicate(Hashtable *env, CoercePredicate *p)
83 printf("ActionEQ1::breakpredicate CALLED\n");
84 p->getpredicate()->print(); printf("\n");
87 this->ActionGEQ1::breakpredicate(env, p);
93 bool ActionEQ1::conflict(Constraint *c1, CoercePredicate *p1,Constraint *c2, CoercePredicate *p2) {
94 assert(canrepairpredicate(p1));
95 Setexpr *pse=p1->getpredicate()->getsetexpr();
96 if(comparepredicates(c1,p1,c2,p2))
97 return false; /*same predicates don't conflict*/
99 switch(pse->gettype()) {
100 case SETEXPR_LABEL: {
101 char *boundname=NULL;
102 Guidance *g=globalmodel->getguidance();
103 //DomainSet *fromset=domrelation->getsource(domrelation->getset(pse->getsetlabel()->getname()));
104 char *setname=pse->getsetlabel()->getname();
106 DomainSet *fromset=domrelation->getset(setname);
109 Source s=g->sourceforsetsize(fromset->getname());
115 /* See what additional addsets we get*/
117 WorkSet *ws=domrelation->conflictaddsets(pse->getsetlabel()->getname(),boundname,globalmodel);
118 DomainSet *ds=(DomainSet *) ws->firstelement();
120 if (conflictwithaddtoset(ds->getname(),c2,p2)) {
124 ds=(DomainSet *) ws->getnextelement(ds);
129 /* What additions do we get from removal */
130 WorkSet *ws=domrelation->removeconflictaddsets(pse->getsetlabel()->getname(),globalmodel);
131 DomainSet *ds=(DomainSet *) ws->firstelement();
133 if (conflictwithaddtoset(ds->getname(),c2,p2)) {
137 ds=(DomainSet *) ws->getnextelement(ds);
142 /* Check what removals addition into set can cause */
143 if (boundname!=NULL) {
144 WorkSet *ws=domrelation->conflictdelsets(pse->getsetlabel()->getname(), boundname);
145 DomainSet *ds=(DomainSet *) ws->firstelement();
147 if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) {
151 ds=(DomainSet *) ws->getnextelement(ds);
155 /* What sets will removal cause removal from */
157 WorkSet *ws=domrelation->removeconflictdelsets(pse->getsetlabel()->getname());
158 DomainSet *ds=(DomainSet *) ws->firstelement();
160 if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) {
164 ds=(DomainSet *) ws->getnextelement(ds);
172 /* we have a in v.r */
175 (p2->getpredicate()->gettype()==PREDICATE_GTE1||
176 p2->getpredicate()->gettype()==PREDICATE_EQ1)&&
177 p2->getpredicate()->getsetexpr()->gettype()==SETEXPR_REL) {
181 /* Compute bounding set if there is one */
184 DomainRelation *drel=globalmodel->getdomainrelation();
185 char *insertset=drel->getrelation(pse->getrelation()->getname())->getrange();
186 Guidance *g=globalmodel->getguidance();
187 Source s=g->sourceforsetsize(insertset);
190 /* Check conflicts arrising from addition to set */
192 WorkSet *ws=domrelation->conflictaddsets(insertset,s.setname,globalmodel);
193 DomainSet *ds=(DomainSet *) ws->firstelement();
195 if (conflictwithaddtoset(ds->getname(),c2,p2)) {
199 ds=(DomainSet *) ws->getnextelement(ds);
203 /* Check conflicts arrising from deletions from set */
205 WorkSet *ws=domrelation->conflictdelsets(insertset, s.setname);
206 DomainSet *ds=(DomainSet *) ws->firstelement();
208 if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) {
212 ds=(DomainSet *) ws->getnextelement(ds);
218 return testforconflict(getset(c1,p1->getpredicate()->getsetexpr()->getlabel()->label()), fromname,
219 p1->getpredicate()->getsetexpr()->getrelation()->getname(),c2,p2)||testforconflictremove(getset(c1,p1->getpredicate()->getsetexpr()->getlabel()->label()), fromname,
220 p1->getpredicate()->getsetexpr()->getrelation()->getname(),c2,p2);
222 case SETEXPR_INVREL: {
224 /* we have a in v.r */
227 (p2->getpredicate()->gettype()==PREDICATE_GTE1||
228 p2->getpredicate()->gettype()==PREDICATE_EQ1)&&
229 p2->getpredicate()->getsetexpr()->gettype()==SETEXPR_INVREL) {
233 /* Compute bounding set if there is one */
236 DomainRelation *drel=globalmodel->getdomainrelation();
237 char *insertset=drel->getrelation(pse->getrelation()->getname())->getdomain();
238 Guidance *g=globalmodel->getguidance();
239 Source s=g->sourceforsetsize(insertset);
242 /* Check conflicts arrising from addition to set */
244 WorkSet *ws=domrelation->conflictaddsets(insertset,s.setname,globalmodel);
245 DomainSet *ds=(DomainSet *) ws->firstelement();
247 if (conflictwithaddtoset(ds->getname(),c2,p2)) {
251 ds=(DomainSet *) ws->getnextelement(ds);
255 /* Check conflicts arrising from deletions from set */
257 WorkSet *ws=domrelation->conflictdelsets(insertset, s.setname);
258 DomainSet *ds=(DomainSet *) ws->firstelement();
260 if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) {
264 ds=(DomainSet *) ws->getnextelement(ds);
269 return testforconflict(fromname,
270 getset(c1,p1->getpredicate()->getsetexpr()->getlabel()->label()),
271 p1->getpredicate()->getsetexpr()->getrelation()->getname(),c2,p2)||
272 testforconflictremove(fromname,
273 getset(c1,p1->getpredicate()->getsetexpr()->getlabel()->label()),
274 p1->getpredicate()->getsetexpr()->getrelation()->getname(),c2,p2);
282 bool ActionEQ1::canrepairpredicate(CoercePredicate *cp) {
283 if (cp->getcoercebool()==false)
285 Predicate *p=cp->getpredicate();
288 if (p->gettype()!=PREDICATE_EQ1)
291 /* Coercing set membership */
292 Setexpr *se=p->getsetexpr();
293 int setexprtype=se->gettype();
294 if (setexprtype==SETEXPR_REL||
295 setexprtype==SETEXPR_INVREL) {
296 DRelation *dr=domrelation->getrelation(se->getrelation()->getname());
298 return false; /* Can't change static domain relations */