1 // evaluates constraints in the ICL
4 #include "processobject.h"
5 #include "processabstract.h"
14 #include "normalizer.h"
17 static int modelcheck=0;
18 static int modeltrigger=0;
20 processobject::processobject(model *m) {
22 repair=m->getrepair();
25 void processobject::printstats() {
26 printf("Models Rules Checked: %d Triggered: %d\n",modelcheck,modeltrigger);
29 // evaluates the truth value of the given predicate
30 int processobject::processpredicate(Predicate *p, Hashtable *env) {
31 switch(p->gettype()) {
33 Element *left=evaluatevalueexpr(p->getvalueexpr(),env,globalmodel);
34 Element *right=evaluateexpr(p->geteleexpr(),env,globalmodel);
42 int t=left->intvalue()<right->intvalue();
47 Element *left=evaluatevalueexpr(p->getvalueexpr(),env,globalmodel);
48 Element *right=evaluateexpr(p->geteleexpr(),env,globalmodel);
49 if (right==NULL) {return PFAIL;}
54 bool t=left->intvalue()<=right->intvalue();
58 case PREDICATE_EQUALS: {
59 Element *left=evaluatevalueexpr(p->getvalueexpr(),env,globalmodel);
60 Element *right=evaluateexpr(p->geteleexpr(),env,globalmodel);
61 if (right==NULL) {return PFAIL;}
66 /* Can have more than just int's here */
67 bool t=left->equals(right); /*Just ask the equals method*/
72 Element *left=evaluatevalueexpr(p->getvalueexpr(),env,globalmodel);
73 Element *right=evaluateexpr(p->geteleexpr(),env,globalmodel);
74 if (right==NULL) {return PFAIL;}
79 bool t=left->intvalue()>=right->intvalue();
84 Element *left=evaluatevalueexpr(p->getvalueexpr(),env,globalmodel);
85 Element *right=evaluateexpr(p->geteleexpr(),env,globalmodel);
86 if (right==NULL) {return PFAIL;}
91 bool t=left->intvalue()>right->intvalue();
96 Label *label=p->getlabel();
97 Setexpr * setexpr=p->getsetexpr();
98 Element *labelele=(Element *) env->get(label->label());
99 switch(setexpr->gettype()) {
101 return globalmodel->getdomainrelation()->getset(setexpr->getsetlabel()->getname())->getset()->contains(labelele);
103 return globalmodel->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->getset(setexpr->getlabel()->label())->contains(labelele);
105 return globalmodel->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->invgetset(setexpr->getlabel()->label())->contains(labelele);
109 case PREDICATE_GTE1: {
111 Setexpr * setexpr=p->getsetexpr();
112 switch(setexpr->gettype()) {
114 setsize=globalmodel->getdomainrelation()->getset(setexpr->getsetlabel()->getname())->getset()->size();
117 Element *key=(Element *)env->get(setexpr->getlabel()->label());
118 WorkSet *ws=globalmodel->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->getset(key);
125 case SETEXPR_INVREL: {
126 Element *key=(Element *)env->get(setexpr->getlabel()->label());
127 WorkSet *ws=globalmodel->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->invgetset(key);
135 return ((p->gettype()==PREDICATE_EQ1)&&(setsize==1))||
136 ((p->gettype()==PREDICATE_GTE1)&&(setsize>=1));
142 // evaluates the truth value of the given statement
143 int processobject::processstatement(Statement *s, Hashtable *env) {
144 switch (s->gettype()) {
146 int l=processstatement(s->getleft(),env);
147 int r=processstatement(s->getright(),env);
148 if (l==PFAIL&&(r==PFAIL||r==PFALSE)) return PFAIL;
149 if ((l==PFAIL||l==PFALSE)&&r==PFAIL) return PFAIL;
152 case STATEMENT_AND: {
153 int l=processstatement(s->getleft(),env);
154 int r=processstatement(s->getright(),env);
155 if (l==PFAIL&&(r==PFAIL||r==PTRUE)) return PFAIL;
156 if (r==PFAIL&&(l==PFAIL||l==PTRUE)) return PFAIL;
159 case STATEMENT_NOT: {
160 int l=processstatement(s->getleft(),env);
161 if (l==PFAIL) return PFAIL;
165 return processpredicate(s->getpredicate(),env);
170 // returns true if and only if the given constraint is satisfied
171 bool processobject::issatisfied(Constraint *c)
173 State *st=new State(c,globalmodel->gethashtable());
174 bool satisfied = true;
175 if (st->initializestate(globalmodel))
178 if (c->getstatement()!=NULL)
179 if (processstatement(c->getstatement(),st->env)!=PTRUE)
181 if (!st->increment(globalmodel))
191 /* processed the given constraint and if it's not satisfied,
192 displays a message and tries to repair the constraint
193 The function returns true only if the constraint was initially
195 bool processobject::processconstraint(Constraint *c) {
196 State *st=new State(c,globalmodel->gethashtable());
198 if (st->initializestate(globalmodel)) {
200 if (c->getstatement()!=NULL) {
202 if (processstatement(c->getstatement(),st->env)!=PTRUE) {
205 printf("Constraint violation\n");
206 printf(" Violated constraint: "); c->print();
207 printf(" State for which it was violated: "); st->print(globalmodel);
208 printf(" Current value(s):");
209 c->getstatement()->print_sets(st->env, globalmodel);
215 printf("Repairing...\n");
217 printf("Fatal program error violating special constraint.\n");
220 repair->repairconstraint(c,this,st->env);
226 if (!st->increment(globalmodel))
236 /* breaks the given constraint by invalidating each of its satisfied sentences */
237 void processobject::breakconstraint(Constraint *c)
240 printf("Constraint to be broken: ");
246 // first, get get the constraint in normal form
247 NormalForm *nf = globalmodel->getnormalform(c);
249 // for each CoerceSentence in nf, find if it's satisfied. If so, break it.
250 for (int i=0; i<nf->getnumsentences(); i++)
253 printf("In processobject::breakconstraint, i=%d \n", i);
257 CoerceSentence *s = nf->getsentence(i);
259 // find if s is satisfied
260 bool satisfied = true;
261 State *st = new State(c, globalmodel->gethashtable());
262 if (st->initializestate(globalmodel))
265 if (!s->issatisfied(this, st->env))
268 if (!st->increment(globalmodel))
274 // if s is satisfied, then break it
278 // first, select an arbitrary binding, for ex. the first one
279 st = new State(c, globalmodel->gethashtable());
281 if (st->initializestate(globalmodel))
284 printf("numpredicates = %d\n", s->getnumpredicates());
287 for (int j=0; j<s->getnumpredicates(); j++)
289 CoercePredicate *cp = s->getpredicate(j);
290 // break this predicate with probability prob_breakpredicate
291 if (random()<model::prob_breakpredicate*RAND_MAX)
294 printf("po::breakconstraint: We break predicate %d\n",j);
298 Action *action = repair->findbreakaction(cp);
299 action->breakpredicate(st->env, cp);
302 printf("After action->breakpredicate was called\n");
316 /* satisfies the given satisfied contraint in another way */
317 void processobject::modifyconstraint(Constraint *c)
320 printf("Constraint to be modified: ");
326 // first, get the constraint in normal form
327 NormalForm *nf = globalmodel->getnormalform(c);
329 /* for each CoerceSentence in nf, find if it's satisfied.
330 If it's satisfied, we break it with probability prob_breaksatisfiedsentence;
331 If it's not satisfied, we repair it with probability prob_repairbrokensentence
334 bool still_valid = false;
336 for (int i=0; i<nf->getnumsentences(); i++)
339 printf("In processobject::modifyconstraint, i=%d \n", i);
343 CoerceSentence *s = nf->getsentence(i);
345 // find if s is satisfied
346 bool satisfied = true;
347 State *st = new State(c, globalmodel->gethashtable());
348 if (st->initializestate(globalmodel))
351 if (!s->issatisfied(this, st->env))
354 if (!st->increment(globalmodel))
359 // if s is satisfied, then break it
361 if (random()<model::prob_breaksatisfiedsentence*RAND_MAX) // then break it
363 // first, select an arbitrary binding, for ex. the first one
364 st = new State(c, globalmodel->gethashtable());
366 if (st->initializestate(globalmodel))
368 for (int j=0; j<s->getnumpredicates(); j++)
370 CoercePredicate *cp = s->getpredicate(j);
371 // break this predicate with probability prob_breakpredicate
372 if (random()<model::prob_breakpredicate*RAND_MAX)
375 printf("po::modifyconstraint: We break predicate %d\n",j);
379 Action *action = repair->findbreakaction(cp);
380 action->breakpredicate(st->env, cp);
383 printf("After action->modifypredicate was called\n");
391 else still_valid = true;
392 else // if not satisfied, then repair it with prob_repairbrokensentence
393 if (random()<model::prob_repairbrokensentence)
395 // first, select an arbitrary binding, for ex. the first one
396 st = new State(c, globalmodel->gethashtable());
398 if (st->initializestate(globalmodel))
400 for (int j=0; j<s->getnumpredicates(); j++)
402 CoercePredicate *cp = s->getpredicate(j);
403 Action *action = repair->findrepairaction(cp);
404 action->repairpredicate(st->env, cp);
407 printf("After action->repairpredicate was called\n");
418 if (!still_valid) // if all sentences are broken, repair the first one
420 CoerceSentence *saux = nf->getsentence(0);
421 // first, select an arbitrary binding, for ex. the first one
422 State *st = new State(c, globalmodel->gethashtable());
424 if (st->initializestate(globalmodel))
426 for (int j=0; j<saux->getnumpredicates(); j++)
428 CoercePredicate *cp = saux->getpredicate(j);
429 Action *action = repair->findrepairaction(cp);
430 action->repairpredicate(st->env, cp);
433 printf("After action->repairpredicate was called\n");
445 processobject::~processobject() {
450 Element * evaluatevalueexpr(Valueexpr *ve, Hashtable *env, model *m) {
452 if (ve->gettype()==0) {
453 e=(Element *) env->get(ve->getlabel()->label());
455 e=evaluatevalueexpr(ve->getvalueexpr(),env,m);
458 if (ve->getinverted())
459 return (Element *)m->getdomainrelation()->getrelation(ve->getrelation()->getname())->getrelation()->invgetobj(e);
461 return (Element *)m->getdomainrelation()->getrelation(ve->getrelation()->getname())->getrelation()->getobj(e);
466 // evaluates E = V | number | string | E-E | E+E | E*E | E/E | E.R |size(SE)
467 Element * evaluateexpr(Elementexpr *ee, Hashtable *env, model *m) {
468 switch(ee->gettype()) {
469 case ELEMENTEXPR_LABEL: {
470 return new Element((Element *)env->get(ee->getlabel()->label()));
472 case ELEMENTEXPR_SUB: {
473 Elementexpr *left=ee->getleft();
474 Elementexpr *right=ee->getright();
475 Element *leftval=evaluateexpr(left,env,m);
476 if(leftval==NULL) return NULL;
477 Element *rightval=evaluateexpr(right,env,m);
478 if(rightval==NULL) {delete(leftval);return NULL;}
479 Element *diff=new Element(leftval->intvalue()-rightval->intvalue());
480 delete(leftval);delete(rightval);
483 case ELEMENTEXPR_ADD: {
484 Elementexpr *left=ee->getleft();
485 Elementexpr *right=ee->getright();
486 Element *leftval=evaluateexpr(left,env,m);
487 if(leftval==NULL) return NULL;
488 Element *rightval=evaluateexpr(right,env,m);
489 if(rightval==NULL) {delete(leftval);return NULL;}
490 Element *sum=new Element(leftval->intvalue()+rightval->intvalue());
491 delete(leftval);delete(rightval);
494 case ELEMENTEXPR_RELATION: {
495 Elementexpr *left=ee->getleft();
496 Relation *rel=ee->getrelation();
497 Element *leftval=evaluateexpr(left,env,m);
498 if(leftval==NULL) return NULL;
499 Element *retval=(Element *)m->getdomainrelation()->getrelation(rel->getname())->getrelation()->getobj(leftval);
501 return new Element(retval);
503 case ELEMENTEXPR_MULT: {
504 Elementexpr *left=ee->getleft();
505 Elementexpr *right=ee->getright();
506 Element *leftval=evaluateexpr(left,env,m);
507 if(leftval==NULL) return NULL;
508 Element *rightval=evaluateexpr(right,env,m);
509 if(rightval==NULL) {delete(leftval);return NULL;}
510 Element *diff=new Element(leftval->intvalue()*rightval->intvalue());
511 delete(leftval);delete(rightval);
514 case ELEMENTEXPR_LIT: {
515 Literal *l=ee->getliteral();
516 switch(l->gettype()) {
518 return new Element(l->number());
520 return new Element(copystr(l->token()));
522 printf("ERROR with lit type\n");
526 /* case ELEMENTEXPR_PARAM: {
527 Element *ele=evaluateexpr(ee->getleft(),env,m);
528 Element *eec=ele->paramvalue(ee->getliteral()->number());
529 Element *retval=new Element(eec);
532 }*/ //NO OBJECT PARAMETERS
533 case ELEMENTEXPR_SETSIZE:
534 Setexpr * setexpr=ee->getsetexpr();
535 switch(setexpr->gettype()) {
537 return new Element(m->getdomainrelation()->getset(setexpr->getsetlabel()->getname())->getset()->size());
539 Element *key=(Element *)env->get(setexpr->getlabel()->label());
540 WorkSet *ws=m->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->getset(key);
542 return new Element(0);
544 return new Element(ws->size());
546 case SETEXPR_INVREL: {
547 Element *key=(Element *)env->get(setexpr->getlabel()->label());
548 WorkSet *ws=m->getdomainrelation()->getrelation(setexpr->getrelation()->getname())->getrelation()->invgetset(key);
550 return new Element(0);
552 return new Element(ws->size());