1 // handles prediate of the following forms: VE<E, VE<=E, VE=E, VE>=E, VE>E
5 #include "ActionAssign.h"
7 #include "normalizer.h"
11 #include "Hashtable.h"
13 #include "processobject.h"
18 ActionAssign::ActionAssign(DomainRelation *drel, model *m) {
23 char * ActionAssign::gettype(Constraint *c,Elementexpr *ee) {
24 switch(ee->gettype()) {
25 case ELEMENTEXPR_LABEL:
26 return getset(c,ee->getlabel()->label());
29 case ELEMENTEXPR_MULT:
31 case ELEMENTEXPR_LIT: {
32 Literal *lit=ee->getliteral();
33 switch(lit->gettype()) {
39 printf("ERROR in gettype\n");
43 case ELEMENTEXPR_SETSIZE:
45 case ELEMENTEXPR_RELATION: {
46 Relation *r=ee->getrelation();
47 DomainRelation *drel=globalmodel->getdomainrelation();
48 return drel->getrelation(r->getname())->getrange();
54 // repairs the given predicate
55 void ActionAssign::repairpredicate(Hashtable *env, CoercePredicate *cp) {
56 Predicate *p=cp->getpredicate();
57 Element *ele=evaluateexpr(p->geteleexpr(),env,globalmodel); //ele=E
58 Element *index=(Element *) env->get(p->getvalueexpr()->getlabel()->label()); // index=V
59 char *rel=p->getvalueexpr()->getrelation()->getname(); // rel=R
60 WorkRelation *relation=domrelation->getrelation(rel)->getrelation();
61 Element *old=(Element *)relation->getobj(index); // old=V.R
63 relation->remove(index,old);
64 DRelation *drel=domrelation->getrelation(rel);
66 if(!equivalentstrings(drel->getdomain(),"int")) {
67 DomainSet *domain=domrelation->getset(drel->getdomain());
68 if (!domain->getset()->contains(index))
69 domrelation->addtoset(index,domain,globalmodel);
73 switch (p->gettype()) {
75 Element *ele2=new Element(ele->intvalue()-1);
77 relation->put(index,ele2);
81 relation->put(index,ele);
84 case PREDICATE_EQUALS: {
85 relation->put(index,ele);
86 if(!equivalentstrings(drel->getrange(),"int")&&
87 !equivalentstrings(drel->getrange(),"token")) {
88 DomainSet *range=domrelation->getset(drel->getrange());
89 if (!range->getset()->contains(ele))
90 domrelation->addtoset(ele,range,globalmodel);
95 relation->put(index,ele);
99 Element *ele2=new Element(ele->intvalue()+1);
101 relation->put(index,ele2);
109 void ActionAssign::breakpredicate(Hashtable *env, CoercePredicate *cp)
112 printf("ActionAssign::breakpredicate CALLED\n");
113 cp->getpredicate()->print(); printf("\n");
116 Predicate *p = cp->getpredicate();
117 Element *ele = evaluateexpr(p->geteleexpr(),env,globalmodel); //ele=E
118 Element *index = (Element *) env->get(p->getvalueexpr()->getlabel()->label()); // index=V
122 printf("index=%s\n", p->getvalueexpr()->getlabel()->label());
124 printf("index - bad\n");
125 else printf("index - ok\n");
128 char *rel = p->getvalueexpr()->getrelation()->getname(); // rel=R
129 WorkRelation *relation = domrelation->getrelation(rel)->getrelation();
132 if (relation == NULL)
133 printf("relation - bad\n");
134 else printf("relation - ok\n");
138 Element *old_ve = (Element *)relation->getobj(index); // old_ve=V.R
141 relation->remove(index,old_ve);
142 DRelation *drel = domrelation->getrelation(rel);
144 if(!equivalentstrings(drel->getdomain(),"int"))
146 DomainSet *domain = domrelation->getset(drel->getdomain());
147 if (!domain->getset()->contains(index))
148 domrelation->addtoset(index,domain,globalmodel);
152 printf("p->gettype() = %d\n", p->gettype());
157 switch (p->gettype()) {
161 // set VE=E which breaks VE<E
162 Element *newele=new Element(ele->intvalue());
164 relation->put(index,newele);
171 // set VE=E+1, which breaks VE<=E
172 Element *newele=new Element(ele->intvalue()+1);
174 relation->put(index,newele);
179 case PREDICATE_EQUALS:
181 DRelation *drel=domrelation->getrelation(rel);
183 // if the V.R is an integer, set VE=E+1, which breaks VE=E
184 if (equivalentstrings(drel->getrange(),"int"))
186 Element *newele=new Element(ele->intvalue()+1);
188 relation->put(index,newele);
192 Element *newele = NULL;
193 printf("PREDICATE_EQUALS for tokens\n");
194 //printf("range name = %s\n", drel->getrange()); fflush(NULL);
195 //printf("Current value: "); old_ve->print(); printf("\n");
197 /* find a value in the actual range that is different from the
198 current value of V.R */
199 char* old_token = old_ve->gettoken();
200 WorkSet *ws = drel->gettokenrange();
202 char *token = (char*) ws->firstelement();
205 printf("Token: %s\n", token);
206 if (!equivalentstrings(token, old_token))
209 newele = new Element(token);
212 token = (char*) ws->getnextelement(token);
217 printf("The following predicate cannot be broken:");
218 cp->getpredicate()->print(); printf("\n");
220 else relation->put(index, newele);
231 // set VE=E-1, which breaks VE>=E
232 Element *newele=new Element(ele->intvalue()-1);
234 relation->put(index,newele);
241 // set VE=E, which breaks VE>E
242 Element *newele=new Element(ele->intvalue());
244 relation->put(index,newele);
252 bool ActionAssign::conflict(Constraint *c1, CoercePredicate *p1,Constraint *c2, CoercePredicate *p2) {
253 assert(canrepairpredicate(p1));
254 if(comparepredicates(c1,p1,c2,p2))
255 return false; /*same predicates don't conflict*/
259 /* Compute bounding set if there is one */
262 DomainRelation *drel=globalmodel->getdomainrelation();
263 char *insertset=drel->getrelation(p1->getpredicate()->getvalueexpr()->getrelation()->getname())->getrange();
265 char *boundset=gettype(c1,p1->getpredicate()->geteleexpr());
267 /* Check conflicts arrising from addition to set */
269 WorkSet *ws=domrelation->conflictaddsets(insertset,NULL,globalmodel);
270 DomainSet *ds=(DomainSet *) ws->firstelement();
272 if (conflictwithaddtoset(ds->getname(),c2,p2)) {
276 ds=(DomainSet *) ws->getnextelement(ds);
280 /* Check conflicts arrising from deletions from set */
282 WorkSet *ws=domrelation->conflictdelsets(insertset, NULL);
283 DomainSet *ds=(DomainSet *) ws->firstelement();
285 if (conflictwithremovefromset(NULL,ds->getname(),c2,p2)) {
289 ds=(DomainSet *) ws->getnextelement(ds);
293 return testforconflict(getset(c1,p1->getpredicate()->getvalueexpr()->getlabel()->label()), NULL,
294 p1->getpredicate()->getvalueexpr()->getrelation()->getname(),c2,p2)||
295 testforconflictremove(getset(c1,p1->getpredicate()->getvalueexpr()->getlabel()->label()), NULL,
296 p1->getpredicate()->getvalueexpr()->getrelation()->getname(),c2,p2);
299 bool ActionAssign::canrepairpredicate(CoercePredicate *cp) {
300 if (cp->getcoercebool()==false)
302 Predicate *p=cp->getpredicate();
305 if (p->gettype()==PREDICATE_LT||
306 p->gettype()==PREDICATE_LTE||
307 p->gettype()==PREDICATE_EQUALS||
308 p->gettype()==PREDICATE_GTE||
309 p->gettype()==PREDICATE_GT) {
310 Valueexpr *ve=p->getvalueexpr();
311 DRelation *dr=domrelation->getrelation(ve->getrelation()->getname());
312 if (dr->isstatic()) /* can't change static relations */
317 /* Coercing set membership */