7 public class RepairGenerator {
9 java.io.PrintWriter outputrepair = null;
10 java.io.PrintWriter outputaux = null;
11 java.io.PrintWriter outputhead = null;
14 static VarDescriptor oldmodel=null;
15 static VarDescriptor newmodel=null;
16 static VarDescriptor worklist=null;
17 static VarDescriptor repairtable=null;
18 static VarDescriptor goodflag=null;
19 Rule currentrule=null;
20 Hashtable updatenames;
22 Termination termination;
25 static boolean DEBUG=false;
29 public RepairGenerator(State state, Termination t) {
31 updatenames=new Hashtable();
32 usedupdates=new HashSet();
35 togenerate=new HashSet();
36 togenerate.addAll(termination.conjunctions);
37 togenerate.removeAll(removed);
38 GraphNode.computeclosure(togenerate,removed);
41 sources=new Sources(state);
42 Repair.repairgenerator=this;
45 private void name_updates() {
47 for(Iterator it=termination.updatenodes.iterator();it.hasNext();) {
48 GraphNode gn=(GraphNode) it.next();
49 TermNode tn=(TermNode) gn.getOwner();
50 MultUpdateNode mun=tn.getUpdate();
51 if (togenerate.contains(gn))
52 for (int i=0;i<mun.numUpdates();i++) {
53 UpdateNode un=mun.getUpdate(i);
54 String name="update"+String.valueOf(count++);
55 updatenames.put(un,name);
60 public void generate(OutputStream outputrepair, OutputStream outputaux,OutputStream outputhead, String st) {
61 this.outputrepair = new java.io.PrintWriter(outputrepair, true);
62 this.outputaux = new java.io.PrintWriter(outputaux, true);
63 this.outputhead = new java.io.PrintWriter(outputhead, true);
67 generate_tokentable();
68 generate_hashtables();
69 generate_stateobject();
75 CodeWriter crhead = new StandardCodeWriter(this.outputhead);
76 CodeWriter craux = new StandardCodeWriter(this.outputaux);
77 crhead.outputline("};");
78 craux.outputline("}");
82 String ststate="state";
83 String stmodel="model";
84 String strepairtable="repairtable";
86 String stright="right";
88 private void generate_updates() {
90 CodeWriter crhead = new StandardCodeWriter(outputhead);
91 CodeWriter craux = new StandardCodeWriter(outputaux);
95 for (Iterator it=this.state.stGlobals.descriptors();it.hasNext();) {
96 VarDescriptor vd=(VarDescriptor)it.next();
97 craux.outputline("#define "+vd.getSafeSymbol()+" "+ststate+"->"+vd.getSafeSymbol());
100 for(Iterator it=termination.updatenodes.iterator();it.hasNext();) {
101 GraphNode gn=(GraphNode) it.next();
102 TermNode tn=(TermNode) gn.getOwner();
103 MultUpdateNode mun=tn.getUpdate();
104 boolean isrelation=(mun.getDescriptor() instanceof RelationDescriptor);
105 if (togenerate.contains(gn))
106 for (int i=0;i<mun.numUpdates();i++) {
107 UpdateNode un=mun.getUpdate(i);
108 String methodname=(String)updatenames.get(un);
111 case MultUpdateNode.ADD:
113 crhead.outputline("void "+methodname+"("+name+"_state * " +ststate+","+name+" * "+stmodel+", RepairHash * "+strepairtable+", int "+stleft+", int "+stright+");");
114 craux.outputline("void "+methodname+"("+name+"_state * "+ ststate+","+name+" * "+stmodel+", RepairHash * "+strepairtable+", int "+stleft+", int "+stright+")");
116 crhead.outputline("void "+methodname+"("+name+"_state * "+ ststate+","+name+" * "+stmodel+", RepairHash * "+strepairtable+", int "+stleft+");");
117 craux.outputline("void "+methodname+"("+name+"_state * "+ststate+","+name+" * "+stmodel+", RepairHash * "+strepairtable+", int "+stleft+")");
120 final SymbolTable st = un.getRule().getSymbolTable();
121 CodeWriter cr = new StandardCodeWriter(outputaux) {
122 public SymbolTable getSymbolTable() { return st; }
124 un.generate(cr, false, stleft,stright,this);
127 case MultUpdateNode.REMOVE:
129 String methodcall="void "+methodname+"("+name+"_state * "+ststate+","+name+" * "+stmodel+", RepairHash * "+strepairtable;
130 for(int j=0;j<r.numQuantifiers();j++) {
131 Quantifier q=r.getQuantifier(j);
132 if (q instanceof SetQuantifier) {
133 SetQuantifier sq=(SetQuantifier) q;
134 methodcall+=","+sq.getVar().getType().getGenerateType().getSafeSymbol()+" "+sq.getVar().getSafeSymbol();
135 } else if (q instanceof RelationQuantifier) {
136 RelationQuantifier rq=(RelationQuantifier) q;
138 methodcall+=","+rq.x.getType().getGenerateType().getSafeSymbol()+" "+rq.x.getSafeSymbol();
139 methodcall+=","+rq.y.getType().getGenerateType().getSafeSymbol()+" "+rq.y.getSafeSymbol();
140 } else if (q instanceof ForQuantifier) {
141 ForQuantifier fq=(ForQuantifier) q;
142 methodcall+=",int "+fq.getVar().getSafeSymbol();
146 crhead.outputline(methodcall+";");
147 craux.outputline(methodcall);
149 final SymbolTable st2 = un.getRule().getSymbolTable();
150 CodeWriter cr2 = new StandardCodeWriter(outputaux) {
151 public SymbolTable getSymbolTable() { return st2; }
153 un.generate(cr2, true, null,null,this);
156 case MultUpdateNode.MODIFY:
158 throw new Error("Nonimplement Update");
164 private void generate_call() {
165 CodeWriter cr = new StandardCodeWriter(outputrepair);
166 VarDescriptor vdstate=VarDescriptor.makeNew("repairstate");
167 cr.outputline(name+"_state * "+vdstate.getSafeSymbol()+"=new "+name+"_state();");
168 Iterator globals=state.stGlobals.descriptors();
169 while (globals.hasNext()) {
170 VarDescriptor vd=(VarDescriptor) globals.next();
171 cr.outputline(vdstate.getSafeSymbol()+"->"+vd.getSafeSymbol()+"=("+vd.getType().getGenerateType().getSafeSymbol()+")"+vd.getSafeSymbol()+";");
173 /* Insert repair here */
174 cr.outputline(vdstate.getSafeSymbol()+"->doanalysis();");
175 globals=state.stGlobals.descriptors();
176 while (globals.hasNext()) {
177 VarDescriptor vd=(VarDescriptor) globals.next();
178 cr.outputline("*(("+vd.getType().getGenerateType().getSafeSymbol()+"*) &"+vd.getSafeSymbol()+")="+vdstate.getSafeSymbol()+"->"+vd.getSafeSymbol()+";");
180 cr.outputline("delete "+vdstate.getSafeSymbol()+";");
183 private void generate_tokentable() {
184 CodeWriter cr = new StandardCodeWriter(outputrepair);
185 Iterator tokens = TokenLiteralExpr.tokens.keySet().iterator();
188 cr.outputline("// Token values");
191 while (tokens.hasNext()) {
192 Object token = tokens.next();
193 cr.outputline("// " + token.toString() + " = " + TokenLiteralExpr.tokens.get(token).toString());
200 private void generate_stateobject() {
201 CodeWriter crhead = new StandardCodeWriter(outputhead);
202 crhead.outputline("class "+name+"_state {");
203 crhead.outputline("public:");
204 Iterator globals=state.stGlobals.descriptors();
205 while (globals.hasNext()) {
206 VarDescriptor vd=(VarDescriptor) globals.next();
207 crhead.outputline(vd.getType().getGenerateType().getSafeSymbol()+" "+vd.getSafeSymbol()+";");
211 private void generate_hashtables() {
212 CodeWriter craux = new StandardCodeWriter(outputaux);
213 CodeWriter crhead = new StandardCodeWriter(outputhead);
214 crhead.outputline("#include \"SimpleHash.h\"");
215 crhead.outputline("#include <stdio.h>");
216 crhead.outputline("#include <stdlib.h>");
217 crhead.outputline("class "+name+" {");
218 crhead.outputline("public:");
219 crhead.outputline(name+"();");
220 crhead.outputline("~"+name+"();");
221 craux.outputline("#include \""+headername+"\"");
223 craux.outputline(name+"::"+name+"() {");
224 craux.outputline("// creating hashtables ");
227 Iterator sets = state.stSets.descriptors();
229 /* first pass create all the hash tables */
230 while (sets.hasNext()) {
231 SetDescriptor set = (SetDescriptor) sets.next();
232 crhead.outputline("SimpleHash* " + set.getSafeSymbol() + "_hash;");
233 craux.outputline(set.getSafeSymbol() + "_hash = new SimpleHash();");
236 /* second pass build relationships between hashtables */
237 sets = state.stSets.descriptors();
239 while (sets.hasNext()) {
240 SetDescriptor set = (SetDescriptor) sets.next();
241 Iterator subsets = set.subsets();
243 while (subsets.hasNext()) {
244 SetDescriptor subset = (SetDescriptor) subsets.next();
245 craux.outputline(subset.getSafeSymbol() + "_hash->addParent(" + set.getSafeSymbol() + "_hash);");
249 /* build relations */
250 Iterator relations = state.stRelations.descriptors();
252 /* first pass create all the hash tables */
253 while (relations.hasNext()) {
254 RelationDescriptor relation = (RelationDescriptor) relations.next();
256 if (relation.testUsage(RelationDescriptor.IMAGE)) {
257 crhead.outputline("SimpleHash* " + relation.getSafeSymbol() + "_hash;");
258 craux.outputline(relation.getSafeSymbol() + "_hash = new SimpleHash();");
261 if (relation.testUsage(RelationDescriptor.INVIMAGE)) {
262 crhead.outputline("SimpleHash* " + relation.getSafeSymbol() + "_hashinv;");
263 craux.outputline(relation.getSafeSymbol() + "_hashinv = new SimpleHash();");
267 craux.outputline("}");
268 crhead.outputline("};");
269 craux.outputline(name+"::~"+name+"() {");
270 craux.outputline("// deleting hashtables");
272 /* build destructor */
273 sets = state.stSets.descriptors();
275 /* first pass create all the hash tables */
276 while (sets.hasNext()) {
277 SetDescriptor set = (SetDescriptor) sets.next();
278 craux.outputline("delete "+set.getSafeSymbol() + "_hash;");
281 /* destroy relations */
282 relations = state.stRelations.descriptors();
284 /* first pass create all the hash tables */
285 while (relations.hasNext()) {
286 RelationDescriptor relation = (RelationDescriptor) relations.next();
288 if (relation.testUsage(RelationDescriptor.IMAGE)) {
289 craux.outputline("delete "+relation.getSafeSymbol() + "_hash;");
292 if (relation.testUsage(RelationDescriptor.INVIMAGE)) {
293 craux.outputline("delete " + relation.getSafeSymbol() + ";");
296 craux.outputline("}");
299 private void generate_worklist() {
300 CodeWriter crhead = new StandardCodeWriter(outputhead);
301 CodeWriter craux = new StandardCodeWriter(outputaux);
302 oldmodel=VarDescriptor.makeNew("oldmodel");
303 newmodel=VarDescriptor.makeNew("newmodel");
304 worklist=VarDescriptor.makeNew("worklist");
305 goodflag=VarDescriptor.makeNew("goodflag");
306 repairtable=VarDescriptor.makeNew("repairtable");
307 crhead.outputline("void doanalysis();");
308 craux.outputline("void "+name +"_state::doanalysis()");
310 craux.outputline(name+ " * "+oldmodel.getSafeSymbol()+"=0;");
311 craux.outputline("WorkList * "+worklist.getSafeSymbol()+" = new WorkList();");
312 craux.outputline("RepairHash * "+repairtable.getSafeSymbol()+"=0;");
313 craux.outputline("while (1)");
315 craux.outputline("int "+goodflag.getSafeSymbol()+"=1;");
316 craux.outputline(name+ " * "+newmodel.getSafeSymbol()+"=new "+name+"();");
319 private void generate_teardown() {
320 CodeWriter cr = new StandardCodeWriter(outputaux);
324 private void generate_rules() {
325 /* first we must sort the rules */
326 Iterator allrules = state.vRules.iterator();
327 Vector emptyrules = new Vector(); // rules with no quantifiers
328 Vector worklistrules = new Vector(); // the rest of the rules
329 RelationDescriptor.prefix = newmodel.getSafeSymbol()+"->";
330 SetDescriptor.prefix = newmodel.getSafeSymbol()+"->";
332 while (allrules.hasNext()) {
333 Rule rule = (Rule) allrules.next();
334 ListIterator quantifiers = rule.quantifiers();
335 boolean noquantifiers = true;
336 while (quantifiers.hasNext()) {
337 Quantifier quantifier = (Quantifier) quantifiers.next();
338 if (quantifier instanceof ForQuantifier) {
339 // ok, because integers exist already!
342 noquantifiers = false;
347 emptyrules.add(rule);
349 worklistrules.add(rule);
353 Iterator iterator_er = emptyrules.iterator();
354 while (iterator_er.hasNext()) {
355 Rule rule = (Rule) iterator_er.next();
357 final SymbolTable st = rule.getSymbolTable();
358 CodeWriter cr = new StandardCodeWriter(outputaux) {
359 public SymbolTable getSymbolTable() { return st; }
361 cr.outputline("// build " +escape(rule.toString()));
363 ListIterator quantifiers = rule.quantifiers();
364 while (quantifiers.hasNext()) {
365 Quantifier quantifier = (Quantifier) quantifiers.next();
366 quantifier.generate_open(cr);
371 rule.getGuardExpr().prettyPrint(cr);
374 /* now we have to generate the guard test */
375 VarDescriptor guardval = VarDescriptor.makeNew();
376 rule.getGuardExpr().generate(cr, guardval);
377 cr.outputline("if (" + guardval.getSafeSymbol() + ")");
380 /* now we have to generate the inclusion code */
382 rule.getInclusion().generate(cr);
384 while (quantifiers.hasPrevious()) {
385 Quantifier quantifier = (Quantifier) quantifiers.previous();
394 CodeWriter cr2 = new StandardCodeWriter(outputaux);
396 cr2.outputline("while ("+goodflag.getSafeSymbol()+"&&"+worklist.getSafeSymbol()+"->hasMoreElements())");
398 VarDescriptor idvar=VarDescriptor.makeNew("id");
399 cr2.outputline("int "+idvar.getSafeSymbol()+"="+worklist.getSafeSymbol()+"->getid();");
401 String elseladder = "if";
403 Iterator iterator_rules = worklistrules.iterator();
404 while (iterator_rules.hasNext()) {
406 Rule rule = (Rule) iterator_rules.next();
407 int dispatchid = rule.getNum();
410 final SymbolTable st = rule.getSymbolTable();
411 CodeWriter cr = new StandardCodeWriter(outputaux) {
412 public SymbolTable getSymbolTable() { return st; }
416 cr.outputline(elseladder + " ("+idvar.getSafeSymbol()+" == " + dispatchid + ")");
418 VarDescriptor typevar=VarDescriptor.makeNew("type");
419 VarDescriptor leftvar=VarDescriptor.makeNew("left");
420 VarDescriptor rightvar=VarDescriptor.makeNew("right");
421 cr.outputline("int "+typevar.getSafeSymbol()+"="+worklist.getSafeSymbol()+"->gettype();");
422 cr.outputline("int "+leftvar.getSafeSymbol()+"="+worklist.getSafeSymbol()+"->getlvalue();");
423 cr.outputline("int "+rightvar.getSafeSymbol()+"="+worklist.getSafeSymbol()+"->getrvalue();");
424 cr.outputline("// build " +escape(rule.toString()));
427 for (int j=0;j<rule.numQuantifiers();j++) {
428 Quantifier quantifier = rule.getQuantifier(j);
429 quantifier.generate_open(cr, typevar.getSafeSymbol(),j,leftvar.getSafeSymbol(),rightvar.getSafeSymbol());
435 rule.getGuardExpr().prettyPrint(cr);
438 /* now we have to generate the guard test */
440 VarDescriptor guardval = VarDescriptor.makeNew();
441 rule.getGuardExpr().generate(cr, guardval);
443 cr.outputline("if (" + guardval.getSafeSymbol() + ")");
446 /* now we have to generate the inclusion code */
448 rule.getInclusion().generate(cr);
451 for (int j=0;j<rule.numQuantifiers();j++) {
455 // close startblocks generated by DotExpr memory checks
456 //DotExpr.generate_memory_endblocks(cr);
458 cr.endblock(); // end else-if WORKLIST ladder
460 elseladder = "else if";
464 cr2.outputline("else");
466 cr2.outputline("printf(\"VERY BAD !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\\n\\n\");");
467 cr2.outputline("exit(1);");
469 // end block created for worklist
470 cr2.outputline(worklist.getSafeSymbol()+"->pop();");
474 public static String escape(String s) {
476 for(int i=0;i<s.length();i++) {
486 private void generate_checks() {
488 /* do constraint checks */
489 Vector constraints = state.vConstraints;
491 for (int i = 0; i < constraints.size(); i++) {
493 Constraint constraint = (Constraint) constraints.elementAt(i);
497 final SymbolTable st = constraint.getSymbolTable();
499 CodeWriter cr = new StandardCodeWriter(outputaux) {
500 public SymbolTable getSymbolTable() { return st; }
503 cr.outputline("// checking " + escape(constraint.toString()));
506 ListIterator quantifiers = constraint.quantifiers();
508 while (quantifiers.hasNext()) {
509 Quantifier quantifier = (Quantifier) quantifiers.next();
510 quantifier.generate_open(cr);
513 cr.outputline("int maybe = 0;");
515 /* now we have to generate the guard test */
517 VarDescriptor constraintboolean = VarDescriptor.makeNew("constraintboolean");
518 constraint.getLogicStatement().generate(cr, constraintboolean);
520 cr.outputline("if (maybe)");
522 cr.outputline("printf(\"maybe fail " + escape(constraint.toString()) + ". \");");
523 cr.outputline("exit(1);");
526 cr.outputline("else if (!" + constraintboolean.getSafeSymbol() + ")");
529 cr.outputline("printf(\"fail " + escape(constraint.toString()) + ". \");");
532 /* Build new repair table */
533 cr.outputline("if ("+repairtable.getSafeSymbol()+")");
534 cr.outputline("delete "+repairtable.getSafeSymbol()+";");
535 cr.outputline(repairtable.getSafeSymbol()+"=new RepairHash();");
538 /* Compute cost of each repair */
539 VarDescriptor mincost=VarDescriptor.makeNew("mincost");
540 VarDescriptor mincostindex=VarDescriptor.makeNew("mincostindex");
541 DNFConstraint dnfconst=constraint.dnfconstraint;
542 if (dnfconst.size()<=1) {
543 cr.outputline("int "+mincostindex.getSafeSymbol()+"=0;");
545 if (dnfconst.size()>1) {
546 cr.outputline("int "+mincostindex.getSafeSymbol()+";");
548 for(int j=0;j<dnfconst.size();j++) {
549 Conjunction conj=dnfconst.get(j);
550 GraphNode gn=(GraphNode)termination.conjtonodemap.get(conj);
551 if (removed.contains(gn))
554 VarDescriptor costvar;
558 costvar=VarDescriptor.makeNew("cost");
559 for(int k=0;k<conj.size();k++) {
560 DNFPredicate dpred=conj.get(k);
561 Predicate p=dpred.getPredicate();
562 boolean negate=dpred.isNegated();
563 VarDescriptor predvalue=VarDescriptor.makeNew("Predicatevalue");
564 p.generate(cr,predvalue);
566 cr.outputline("if (maybe||"+predvalue.getSafeSymbol()+")");
568 cr.outputline("if (maybe||!"+predvalue.getSafeSymbol()+")");
570 cr.outputline("int "+costvar.getSafeSymbol()+"="+cost.getCost(dpred)+";");
572 cr.outputline(costvar.getSafeSymbol()+"+="+cost.getCost(dpred)+";");
576 cr.outputline("if ("+costvar.getSafeSymbol()+"<"+mincost.getSafeSymbol()+")");
578 cr.outputline(mincost.getSafeSymbol()+"="+costvar.getSafeSymbol()+";");
579 cr.outputline(mincostindex.getSafeSymbol()+"="+j+";");
582 cr.outputline(mincostindex.getSafeSymbol()+"="+j+";");
586 cr.outputline("switch("+mincostindex.getSafeSymbol()+") {");
587 for(int j=0;j<dnfconst.size();j++) {
588 Conjunction conj=dnfconst.get(j);
589 GraphNode gn=(GraphNode)termination.conjtonodemap.get(conj); if (removed.contains(gn))
591 cr.outputline("case "+j+":");
592 for(int k=0;k<conj.size();k++) {
593 DNFPredicate dpred=conj.get(k);
594 Predicate p=dpred.getPredicate();
595 boolean negate=dpred.isNegated();
596 VarDescriptor predvalue=VarDescriptor.makeNew("Predicatevalue");
597 p.generate(cr,predvalue);
599 cr.outputline("if (maybe||"+predvalue.getSafeSymbol()+")");
601 cr.outputline("if (maybe||!"+predvalue.getSafeSymbol()+")");
603 if (p instanceof InclusionPredicate)
604 generateinclusionrepair(conj,dpred, cr);
605 else if (p instanceof ExprPredicate) {
606 ExprPredicate ep=(ExprPredicate)p;
607 if (ep.getType()==ExprPredicate.SIZE)
608 generatesizerepair(conj,dpred,cr);
609 else if (ep.getType()==ExprPredicate.COMPARISON)
610 generatecomparisonrepair(conj,dpred,cr);
611 } else throw new Error("Unrecognized Predicate");
616 cr.outputline("break;");
620 cr.outputline(goodflag.getSafeSymbol()+"=0;");
621 cr.outputline("if ("+oldmodel.getSafeSymbol()+")");
622 cr.outputline("delete "+oldmodel.getSafeSymbol()+";");
623 cr.outputline(oldmodel.getSafeSymbol()+"="+newmodel.getSafeSymbol()+";");
624 cr.outputline("goto rebuild;"); /* Rebuild model and all */
628 while (quantifiers.hasPrevious()) {
629 Quantifier quantifier = (Quantifier) quantifiers.previous();
632 cr.outputline("if ("+goodflag.getSafeSymbol()+")");
634 cr.outputline("if ("+repairtable.getSafeSymbol()+")");
635 cr.outputline("delete "+repairtable.getSafeSymbol()+";");
636 cr.outputline("if ("+oldmodel.getSafeSymbol()+")");
637 cr.outputline("delete "+oldmodel.getSafeSymbol()+";");
638 cr.outputline("delete "+newmodel.getSafeSymbol()+";");
639 cr.outputline("delete "+worklist.getSafeSymbol()+";");
640 cr.outputline("break;");
642 cr.outputline("rebuild:");
651 private MultUpdateNode getmultupdatenode(Conjunction conj, DNFPredicate dpred, int repairtype) {
652 MultUpdateNode mun=null;
653 GraphNode gn=(GraphNode) termination.conjtonodemap.get(conj);
654 for(Iterator edgeit=gn.edges();(mun==null)&&edgeit.hasNext();) {
655 GraphNode gn2=((GraphNode.Edge) edgeit.next()).getTarget();
656 TermNode tn2=(TermNode)gn2.getOwner();
657 if (tn2.getType()==TermNode.ABSTRACT) {
658 AbstractRepair ar=tn2.getAbstract();
659 if (((repairtype==-1)||(ar.getType()==repairtype))&&
660 ar.getPredicate()==dpred) {
661 for(Iterator edgeit2=gn2.edges();edgeit2.hasNext();) {
662 GraphNode gn3=((GraphNode.Edge) edgeit2.next()).getTarget();
663 if (!removed.contains(gn3)) {
664 TermNode tn3=(TermNode)gn3.getOwner();
665 if (tn3.getType()==TermNode.UPDATE) {
677 public void generatecomparisonrepair(Conjunction conj, DNFPredicate dpred, CodeWriter cr){
678 MultUpdateNode munremove=getmultupdatenode(conj,dpred,AbstractRepair.REMOVEFROMRELATION);
679 MultUpdateNode munadd=getmultupdatenode(conj,dpred,AbstractRepair.ADDTORELATION);
680 ExprPredicate ep=(ExprPredicate)dpred.getPredicate();
681 RelationDescriptor rd=(RelationDescriptor)ep.getDescriptor();
682 boolean usageimage=rd.testUsage(RelationDescriptor.IMAGE);
683 boolean usageinvimage=rd.testUsage(RelationDescriptor.INVIMAGE);
684 boolean inverted=ep.inverted();
685 boolean negated=dpred.isNegated();
686 OpExpr expr=(OpExpr)ep.expr;
687 Opcode opcode=expr.getOpcode();
688 VarDescriptor leftside=VarDescriptor.makeNew("leftside");
689 VarDescriptor rightside=VarDescriptor.makeNew("rightside");
690 VarDescriptor newvalue=VarDescriptor.makeNew("newvalue");
692 expr.getLeftExpr().generate(cr,leftside);
693 expr.getRightExpr().generate(cr,newvalue);
694 cr.outputline(rd.getRange().getType().getGenerateType().getSafeSymbol()+" "+rightside.getSafeSymbol()+";");
695 cr.outputline(rd.getSafeSymbol()+"_hash->get("+leftside.getSafeSymbol()+","+rightside.getSafeSymbol()+");");
697 expr.getLeftExpr().generate(cr,rightside);
698 expr.getRightExpr().generate(cr,newvalue);
699 cr.outputline(rd.getDomain().getType().getGenerateType().getSafeSymbol()+" "+leftside.getSafeSymbol()+";");
700 cr.outputline(rd.getSafeSymbol()+"_hashinv->get("+leftside.getSafeSymbol()+","+leftside.getSafeSymbol()+");");
703 if (opcode==Opcode.GT) {
705 } else if (opcode==Opcode.GE) {
707 } else if (opcode==Opcode.LT) {
709 } else if (opcode==Opcode.LE) {
711 } else if (opcode==Opcode.EQ) {
713 } else if (opcode==Opcode.NE) {
716 throw new Error("Unrecognized Opcode");
719 if (opcode==Opcode.GT) {
720 cr.outputline(newvalue.getSafeSymbol()+"++;");
721 } else if (opcode==Opcode.GE) {
723 } else if (opcode==Opcode.LT) {
724 cr.outputline(newvalue.getSafeSymbol()+"--;");
725 } else if (opcode==Opcode.LE) {
727 } else if (opcode==Opcode.EQ) {
729 } else if (opcode==Opcode.NE) {
730 cr.outputline(newvalue.getSafeSymbol()+"++;");
732 throw new Error("Unrecognized Opcode");
734 /* Do abstract repairs */
736 cr.outputline(rd.getSafeSymbol()+"_hash->remove("+leftside.getSafeSymbol()+","+rightside.getSafeSymbol()+");");
738 cr.outputline(rd.getSafeSymbol()+"_hash->add("+leftside.getSafeSymbol()+","+newvalue.getSafeSymbol()+");");
740 cr.outputline(rd.getSafeSymbol()+"_hash->add("+newvalue.getSafeSymbol()+","+rightside.getSafeSymbol()+");");
744 cr.outputline(rd.getSafeSymbol()+"_hashinv->remove("+rightside.getSafeSymbol()+","+leftside.getSafeSymbol()+");");
746 cr.outputline(rd.getSafeSymbol()+"_hashinv->add("+newvalue.getSafeSymbol()+","+leftside.getSafeSymbol()+");");
748 cr.outputline(rd.getSafeSymbol()+"_hashinv->add("+rightside.getSafeSymbol()+","+newvalue.getSafeSymbol()+");");
751 /* Do concrete repairs */
752 /* Start with scheduling removal */
753 for(int i=0;i<state.vRules.size();i++) {
754 Rule r=(Rule)state.vRules.get(i);
755 if (r.getInclusion().getTargetDescriptors().contains(rd)) {
756 for(int j=0;j<munremove.numUpdates();j++) {
757 UpdateNode un=munremove.getUpdate(i);
758 if (un.getRule()==r) {
759 /* Update for rule r */
760 String name=(String)updatenames.get(un);
761 cr.outputline(repairtable.getSafeSymbol()+"->addrelation("+rd.getNum()+","+r.getNum()+","+leftside.getSafeSymbol()+","+rightside.getSafeSymbol()+",(int) &"+name+");");
766 /* Now do addition */
767 UpdateNode un=munadd.getUpdate(0);
768 String name=(String)updatenames.get(un);
770 cr.outputline(name+"(this,"+newmodel.getSafeSymbol()+","+repairtable.getSafeSymbol()+","+leftside.getSafeSymbol()+","+newvalue.getSafeSymbol()+");");
772 cr.outputline(name+"(this,"+newmodel.getSafeSymbol()+","+repairtable.getSafeSymbol()+","+newvalue.getSafeSymbol()+","+rightside.getSafeSymbol()+");");
776 public void generatesizerepair(Conjunction conj, DNFPredicate dpred, CodeWriter cr) {
777 ExprPredicate ep=(ExprPredicate)dpred.getPredicate();
778 OpExpr expr=(OpExpr)ep.expr;
779 Opcode opcode=expr.getOpcode();
781 boolean negated=dpred.isNegated();
783 if (opcode==Opcode.GT) {
785 } else if (opcode==Opcode.GE) {
787 } else if (opcode==Opcode.LT) {
789 } else if (opcode==Opcode.LE) {
791 } else if (opcode==Opcode.EQ) {
793 } else if (opcode==Opcode.NE) {
796 throw new Error("Unrecognized Opcode");
799 MultUpdateNode munremove;
801 MultUpdateNode munadd;
802 if (ep.getDescriptor() instanceof RelationDescriptor) {
803 munremove=getmultupdatenode(conj,dpred,AbstractRepair.REMOVEFROMRELATION);
804 munadd=getmultupdatenode(conj,dpred,AbstractRepair.ADDTORELATION);
806 munremove=getmultupdatenode(conj,dpred,AbstractRepair.REMOVEFROMSET);
807 munadd=getmultupdatenode(conj,dpred,AbstractRepair.ADDTOSET);
809 int size=ep.leftsize();
810 VarDescriptor sizevar=VarDescriptor.makeNew("size");
811 ((OpExpr)expr).left.generate(cr, sizevar);
812 VarDescriptor change=VarDescriptor.makeNew("change");
813 cr.outputline("int "+change.getSafeSymbol()+";");
814 boolean generateadd=false;
815 boolean generateremove=false;
816 if (opcode==Opcode.GT) {
817 cr.outputline(change.getSafeSymbol()+"="+String.valueOf(size+1)+"-"+sizevar.getSafeSymbol()+";");
819 generateremove=false;
820 } else if (opcode==Opcode.GE) {
821 cr.outputline(change.getSafeSymbol()+"="+String.valueOf(size)+"-"+sizevar.getSafeSymbol()+";");
823 generateremove=false;
824 } else if (opcode==Opcode.LT) {
825 cr.outputline(change.getSafeSymbol()+"="+String.valueOf(size-1)+"-"+sizevar.getSafeSymbol()+";");
828 } else if (opcode==Opcode.LE) {
829 cr.outputline(change.getSafeSymbol()+"="+String.valueOf(size)+"-"+sizevar.getSafeSymbol()+";");
832 } else if (opcode==Opcode.EQ) {
833 cr.outputline(change.getSafeSymbol()+"="+String.valueOf(size)+"-"+sizevar.getSafeSymbol()+";");
836 } else if (opcode==Opcode.NE) {
837 cr.outputline(change.getSafeSymbol()+"="+String.valueOf(size+1)+"-"+sizevar.getSafeSymbol()+";");
839 generateremove=false;
841 throw new Error("Unrecognized Opcode");
843 Descriptor d=ep.getDescriptor();
844 if (generateremove) {
845 cr.outputline("for(;"+change.getSafeSymbol()+"<0;"+change.getSafeSymbol()+"++)");
847 /* Find element to remove */
848 VarDescriptor leftvar=VarDescriptor.makeNew("leftvar");
849 VarDescriptor rightvar=VarDescriptor.makeNew("rightvar");
850 if (d instanceof RelationDescriptor) {
852 rightvar=((ImageSetExpr)((SizeofExpr)((OpExpr)expr).left).setexpr).getVar();
853 cr.outputline("int "+leftvar.getSafeSymbol()+";");
854 cr.outputline(d.getSafeSymbol()+"_hashinv->get((int)"+rightvar.getSafeSymbol()+","+leftvar.getSafeSymbol()+");");
856 leftvar=((ImageSetExpr)((SizeofExpr)((OpExpr)expr).left).setexpr).getVar();
857 cr.outputline("int "+rightvar.getSafeSymbol()+";");
858 cr.outputline(d.getSafeSymbol()+"_hash->get((int)"+leftvar.getSafeSymbol()+","+rightvar.getSafeSymbol()+");");
861 cr.outputline("int "+leftvar.getSafeSymbol()+"="+d.getSafeSymbol()+"_hash->firstkey();");
863 /* Generate abstract remove instruction */
864 if (d instanceof RelationDescriptor) {
865 RelationDescriptor rd=(RelationDescriptor) d;
866 boolean usageimage=rd.testUsage(RelationDescriptor.IMAGE);
867 boolean usageinvimage=rd.testUsage(RelationDescriptor.INVIMAGE);
869 cr.outputline(rd.getSafeSymbol() + "_hash->remove((int)" + leftvar + ", (int)" + rightvar + ");");
871 cr.outputline(rd.getSafeSymbol() + "_hashinv->remove((int)" + rightvar + ", (int)" + leftvar + ");");
873 cr.outputline(d.getSafeSymbol() + "_hash->remove((int)" + leftvar + ", (int)" + leftvar + ");");
875 /* Generate concrete remove instruction */
876 for(int i=0;i<state.vRules.size();i++) {
877 Rule r=(Rule)state.vRules.get(i);
878 if (r.getInclusion().getTargetDescriptors().contains(d)) {
879 for(int j=0;j<munremove.numUpdates();j++) {
880 UpdateNode un=munremove.getUpdate(i);
881 if (un.getRule()==r) {
882 /* Update for rule rule r */
883 String name=(String)updatenames.get(un);
884 if (d instanceof RelationDescriptor) {
885 cr.outputline(repairtable.getSafeSymbol()+"->addrelation("+d.getNum()+","+r.getNum()+","+leftvar.getSafeSymbol()+","+rightvar.getSafeSymbol()+",(int) &"+name+");");
887 cr.outputline(repairtable.getSafeSymbol()+"->addset("+d.getNum()+","+r.getNum()+","+leftvar.getSafeSymbol()+",(int) &"+name+");");
897 cr.outputline("for(;"+change.getSafeSymbol()+">0;"+change.getSafeSymbol()+"--)");
899 VarDescriptor newobject=VarDescriptor.makeNew("newobject");
900 if (d instanceof RelationDescriptor) {
901 VarDescriptor otherside=((ImageSetExpr)((SizeofExpr)ep.expr).setexpr).vd;
902 RelationDescriptor rd=(RelationDescriptor)d;
903 if (sources.relsetSource(rd,!ep.inverted())) {
905 SetDescriptor sd=sources.relgetSourceSet(rd,!ep.inverted());
906 VarDescriptor iterator=VarDescriptor.makeNew("iterator");
907 cr.outputline(sd.getType().getGenerateType().getSafeSymbol() +" "+newobject.getSafeSymbol()+";");
908 cr.outputline("for("+iterator.getSafeSymbol()+"="+sd.getSafeSymbol()+"_hash->iterator();"+iterator.getSafeSymbol()+".hasNext();)");
911 cr.outputline("if !"+rd.getSafeSymbol()+"_hashinv->contains("+iterator.getSafeSymbol()+"->key(),"+otherside.getSafeSymbol()+")");
913 cr.outputline("if !"+rd.getSafeSymbol()+"_hash->contains("+otherside.getSafeSymbol()+","+iterator.getSafeSymbol()+"->key())");
915 cr.outputline(newobject.getSafeSymbol()+"="+iterator.getSafeSymbol()+".key();");
916 cr.outputline(iterator.getSafeSymbol()+"->next();");
918 } else if (sources.relallocSource(rd,!ep.inverted())) {
919 /* Allocation Source*/
920 sources.relgenerateSourceAlloc(cr,newobject,rd,!ep.inverted());
921 } else throw new Error("No source for adding to Relation");
923 boolean usageimage=rd.testUsage(RelationDescriptor.IMAGE);
924 boolean usageinvimage=rd.testUsage(RelationDescriptor.INVIMAGE);
926 cr.outputline(rd.getSafeSymbol()+"_hash->add("+newobject.getSafeSymbol()+","+otherside.getSafeSymbol()+");");
928 cr.outputline(rd.getSafeSymbol()+"_hashinv->add("+otherside.getSafeSymbol()+","+newobject.getSafeSymbol()+");");
930 UpdateNode un=munadd.getUpdate(0);
931 String name=(String)updatenames.get(un);
932 cr.outputline(name+"(this,"+newmodel.getSafeSymbol()+","+repairtable.getSafeSymbol()+","+newobject.getSafeSymbol()+","+otherside.getSafeSymbol()+");");
934 boolean usageimage=rd.testUsage(RelationDescriptor.IMAGE);
935 boolean usageinvimage=rd.testUsage(RelationDescriptor.INVIMAGE);
937 cr.outputline(rd.getSafeSymbol()+"_hash->add("+otherside.getSafeSymbol()+","+newobject.getSafeSymbol()+");");
939 cr.outputline(rd.getSafeSymbol()+"_hashinv->add("+newobject.getSafeSymbol()+","+otherside.getSafeSymbol()+");");
940 UpdateNode un=munadd.getUpdate(0);
941 String name=(String)updatenames.get(un);
942 cr.outputline(name+"(this,"+newmodel.getSafeSymbol()+","+repairtable.getSafeSymbol()+","+otherside.getSafeSymbol()+","+newobject.getSafeSymbol()+");");
945 SetDescriptor sd=(SetDescriptor)d;
946 if (sources.setSource(sd)) {
949 SetDescriptor sourcesd=sources.getSourceSet(sd);
950 VarDescriptor iterator=VarDescriptor.makeNew("iterator");
951 cr.outputline(sourcesd.getType().getGenerateType().getSafeSymbol() +" "+newobject.getSafeSymbol()+";");
952 cr.outputline("for("+iterator.getSafeSymbol()+"="+sourcesd.getSafeSymbol()+"_hash->iterator();"+iterator.getSafeSymbol()+".hasNext();)");
954 cr.outputline("if !"+sd.getSafeSymbol()+"_hash->contains("+iterator.getSafeSymbol()+"->key())");
955 cr.outputline(newobject.getSafeSymbol()+"="+iterator.getSafeSymbol()+".key();");
956 cr.outputline(iterator.getSafeSymbol()+"->next();");
958 } else if (sources.allocSource(sd)) {
959 /* Allocation Source*/
960 sources.generateSourceAlloc(cr,newobject,sd);
961 } else throw new Error("No source for adding to Set");
962 cr.outputline(sd.getSafeSymbol()+"_hash->add("+newobject.getSafeSymbol()+","+newobject.getSafeSymbol()+");");
963 UpdateNode un=munadd.getUpdate(0);
964 String name=(String)updatenames.get(un);
965 cr.outputline(name+"(this,"+newmodel.getSafeSymbol()+","+repairtable.getSafeSymbol()+","+newobject.getSafeSymbol()+");");
971 public void generateinclusionrepair(Conjunction conj, DNFPredicate dpred, CodeWriter cr){
972 InclusionPredicate ip=(InclusionPredicate) dpred.getPredicate();
973 boolean negated=dpred.isNegated();
974 MultUpdateNode mun=getmultupdatenode(conj,dpred,-1);
975 VarDescriptor leftvar=VarDescriptor.makeNew("left");
976 ip.expr.generate(cr, leftvar);
979 if (ip.setexpr instanceof ImageSetExpr) {
980 ImageSetExpr ise=(ImageSetExpr) ip.setexpr;
981 VarDescriptor rightvar=ise.getVar();
982 boolean inverse=ise.inverted();
983 RelationDescriptor rd=ise.getRelation();
984 boolean usageimage=rd.testUsage(RelationDescriptor.IMAGE);
985 boolean usageinvimage=rd.testUsage(RelationDescriptor.INVIMAGE);
988 cr.outputline(rd.getSafeSymbol() + "_hash->remove((int)" + rightvar + ", (int)" + leftvar + ");");
990 cr.outputline(rd.getSafeSymbol() + "_hashinv->remove((int)" + leftvar + ", (int)" + rightvar + ");");
993 cr.outputline(rd.getSafeSymbol() + "_hash->remove((int)" + leftvar + ", (int)" + rightvar + ");");
995 cr.outputline(rd.getSafeSymbol() + "_hashinv->remove((int)" + rightvar + ", (int)" + leftvar + ");");
997 for(int i=0;i<state.vRules.size();i++) {
998 Rule r=(Rule)state.vRules.get(i);
999 if (r.getInclusion().getTargetDescriptors().contains(rd)) {
1000 for(int j=0;j<mun.numUpdates();j++) {
1001 UpdateNode un=mun.getUpdate(i);
1002 if (un.getRule()==r) {
1003 /* Update for rule rule r */
1004 String name=(String)updatenames.get(un);
1006 cr.outputline(repairtable.getSafeSymbol()+"->addrelation("+rd.getNum()+","+r.getNum()+","+rightvar.getSafeSymbol()+","+leftvar.getSafeSymbol()+",(int) &"+name+");");
1008 cr.outputline(repairtable.getSafeSymbol()+"->addrelation("+rd.getNum()+","+r.getNum()+","+leftvar.getSafeSymbol()+","+rightvar.getSafeSymbol()+",(int) &"+name+");");
1015 SetDescriptor sd=ip.setexpr.sd;
1016 cr.outputline(sd.getSafeSymbol() + "_hash->remove((int)" + leftvar + ", (int)" + leftvar + ");");
1018 for(int i=0;i<state.vRules.size();i++) {
1019 Rule r=(Rule)state.vRules.get(i);
1020 if (r.getInclusion().getTargetDescriptors().contains(sd)) {
1021 for(int j=0;j<mun.numUpdates();j++) {
1022 UpdateNode un=mun.getUpdate(i);
1023 if (un.getRule()==r) {
1024 /* Update for rule rule r */
1025 String name=(String)updatenames.get(un);
1026 cr.outputline(repairtable.getSafeSymbol()+"->addset("+sd.getNum()+","+r.getNum()+","+leftvar.getSafeSymbol()+",(int) &"+name+");");
1033 /* Generate update */
1034 if (ip.setexpr instanceof ImageSetExpr) {
1035 ImageSetExpr ise=(ImageSetExpr) ip.setexpr;
1036 VarDescriptor rightvar=ise.getVar();
1037 boolean inverse=ise.inverted();
1038 RelationDescriptor rd=ise.getRelation();
1039 boolean usageimage=rd.testUsage(RelationDescriptor.IMAGE);
1040 boolean usageinvimage=rd.testUsage(RelationDescriptor.INVIMAGE);
1043 cr.outputline(rd.getSafeSymbol() + "_hash->add((int)" + rightvar + ", (int)" + leftvar + ");");
1045 cr.outputline(rd.getSafeSymbol() + "_hashinv->add((int)" + leftvar + ", (int)" + rightvar + ");");
1048 cr.outputline(rd.getSafeSymbol() + "_hash->add((int)" + leftvar + ", (int)" + rightvar + ");");
1050 cr.outputline(rd.getSafeSymbol() + "_hashinv->add((int)" + rightvar + ", (int)" + leftvar + ");");
1052 UpdateNode un=mun.getUpdate(0);
1053 String name=(String)updatenames.get(un);
1055 cr.outputline(name+"(this,"+newmodel.getSafeSymbol()+","+repairtable.getSafeSymbol()+","+rightvar.getSafeSymbol()+","+leftvar.getSafeSymbol()+");");
1057 cr.outputline(name+"(this,"+newmodel.getSafeSymbol()+","+repairtable.getSafeSymbol()+","+leftvar.getSafeSymbol()+","+rightvar.getSafeSymbol()+");");
1060 SetDescriptor sd=ip.setexpr.sd;
1061 cr.outputline(sd.getSafeSymbol() + "_hash->add((int)" + leftvar + ", (int)" + leftvar + ");");
1063 UpdateNode un=mun.getUpdate(0);
1064 /* Update for rule rule r */
1065 String name=(String)updatenames.get(un);
1066 cr.outputline(name+"(this,"+newmodel.getSafeSymbol()+","+repairtable.getSafeSymbol()+","+leftvar.getSafeSymbol()+");");
1073 public static Vector getrulelist(Descriptor d) {
1074 Vector dispatchrules = new Vector();
1075 Vector rules = State.currentState.vRules;
1077 for (int i = 0; i < rules.size(); i++) {
1078 Rule rule = (Rule) rules.elementAt(i);
1079 Set requiredsymbols = rule.getRequiredDescriptors();
1081 // #TBD#: in general this is wrong because these descriptors may contain descriptors
1082 // bound in "in?" expressions which need to be dealt with in a topologically sorted
1085 if (rule.getRequiredDescriptors().contains(d)) {
1086 dispatchrules.addElement(rule);
1089 return dispatchrules;
1092 private boolean need_compensation(Rule r) {
1093 GraphNode gn=(GraphNode)termination.scopefalsify.get(r);
1094 for(Iterator edgeit=gn.edges();edgeit.hasNext();) {
1095 GraphNode.Edge edge=(GraphNode.Edge)edgeit.next();
1096 GraphNode gn2=edge.getTarget();
1097 if (!removed.contains(gn2)) {
1098 TermNode tn2=(TermNode)gn2.getOwner();
1099 if (tn2.getType()==TermNode.CONSEQUENCE)
1106 private UpdateNode find_compensation(Rule r) {
1107 GraphNode gn=(GraphNode)termination.scopefalsify.get(r);
1108 for(Iterator edgeit=gn.edges();edgeit.hasNext();) {
1109 GraphNode.Edge edge=(GraphNode.Edge)edgeit.next();
1110 GraphNode gn2=edge.getTarget();
1111 if (!removed.contains(gn2)) {
1112 TermNode tn2=(TermNode)gn2.getOwner();
1113 if (tn2.getType()==TermNode.UPDATE) {
1114 MultUpdateNode mun=tn2.getUpdate();
1115 for(int i=0;i<mun.numUpdates();i++) {
1116 UpdateNode un=mun.getUpdate(i);
1117 if (un.getRule()==r)
1123 throw new Error("No Compensation Update could be found");
1126 public void generate_dispatch(CodeWriter cr, RelationDescriptor rd, String leftvar, String rightvar) {
1127 boolean usageimage=rd.testUsage(RelationDescriptor.IMAGE);
1128 boolean usageinvimage=rd.testUsage(RelationDescriptor.INVIMAGE);
1130 if (!(usageinvimage||usageimage)) /* not used at all*/
1133 cr.outputline("// RELATION DISPATCH ");
1134 cr.outputline("if ("+oldmodel.getSafeSymbol()+"&&");
1136 cr.outputline("!"+oldmodel.getSafeSymbol() +"->"+rd.getJustSafeSymbol()+"_hash->contains("+leftvar+","+rightvar+"))");
1138 cr.outputline("!"+oldmodel.getSafeSymbol() +"->"+rd.getJustSafeSymbol()+"_hashinv->contains("+rightvar+","+leftvar+"))");
1140 /* Adding new item */
1141 /* Perform safety checks */
1142 cr.outputline("if ("+repairtable.getSafeSymbol()+"&&");
1143 cr.outputline(repairtable.getSafeSymbol()+"->containsrelation("+rd.getNum()+","+currentrule.getNum()+","+leftvar+","+rightvar+"))");
1145 /* Have update to call into */
1146 VarDescriptor funptr=VarDescriptor.makeNew("updateptr");
1148 for(int i=0;i<currentrule.numQuantifiers();i++) {
1149 if (currentrule.getQuantifier(i) instanceof RelationQuantifier)
1150 parttype=parttype+", int, int";
1152 parttype=parttype+", int";
1154 cr.outputline("void (*"+funptr.getSafeSymbol()+") ("+name+"_state *,"+name+"*,RepairHash *"+parttype+")=");
1155 cr.outputline("(void (*) ("+name+"_state *,"+name+"*,RepairHash *"+parttype+")) "+repairtable.getSafeSymbol()+"->getrelation("+rd.getNum()+","+currentrule.getNum()+","+leftvar+","+rightvar+");");
1156 String methodcall="("+funptr.getSafeSymbol()+") (this,"+oldmodel.getSafeSymbol()+","+repairtable.getSafeSymbol();
1157 for(int i=0;i<currentrule.numQuantifiers();i++) {
1158 Quantifier q=currentrule.getQuantifier(i);
1159 if (q instanceof SetQuantifier) {
1160 SetQuantifier sq=(SetQuantifier) q;
1161 methodcall+=","+sq.getVar().getSafeSymbol();
1162 } else if (q instanceof RelationQuantifier) {
1163 RelationQuantifier rq=(RelationQuantifier) q;
1164 methodcall+=","+rq.x.getSafeSymbol();
1165 methodcall+=","+rq.y.getSafeSymbol();
1166 } else if (q instanceof ForQuantifier) {
1167 ForQuantifier fq=(ForQuantifier) q;
1168 methodcall+=","+fq.getVar().getSafeSymbol();
1172 cr.outputline(methodcall);
1173 cr.outputline(goodflag.getSafeSymbol()+"=0;");
1174 cr.outputline("continue;");
1177 /* Build standard compensation actions */
1178 if (need_compensation(currentrule)) {
1179 UpdateNode un=find_compensation(currentrule);
1180 String name=(String)updatenames.get(un);
1181 usedupdates.add(un); /* Mark as used */
1182 String methodcall=name+"(this,"+oldmodel.getSafeSymbol()+","+repairtable.getSafeSymbol();
1183 for(int i=0;i<currentrule.numQuantifiers();i++) {
1184 Quantifier q=currentrule.getQuantifier(i);
1185 if (q instanceof SetQuantifier) {
1186 SetQuantifier sq=(SetQuantifier) q;
1187 methodcall+=","+sq.getVar().getSafeSymbol();
1188 } else if (q instanceof RelationQuantifier) {
1189 RelationQuantifier rq=(RelationQuantifier) q;
1190 methodcall+=","+rq.x.getSafeSymbol();
1191 methodcall+=","+rq.y.getSafeSymbol();
1192 } else if (q instanceof ForQuantifier) {
1193 ForQuantifier fq=(ForQuantifier) q;
1194 methodcall+=","+fq.getVar().getSafeSymbol();
1198 cr.outputline(methodcall);
1199 cr.outputline(goodflag.getSafeSymbol()+"=0;");
1200 cr.outputline("continue;");
1205 String addeditem = (VarDescriptor.makeNew("addeditem")).getSafeSymbol();
1206 cr.outputline("int " + addeditem + ";");
1207 if (rd.testUsage(RelationDescriptor.IMAGE)) {
1208 cr.outputline(addeditem + " = " + rd.getSafeSymbol() + "_hash->add((int)" + leftvar + ", (int)" + rightvar + ");");
1211 if (rd.testUsage(RelationDescriptor.INVIMAGE)) {
1212 cr.outputline(addeditem + " = " + rd.getSafeSymbol() + "_hashinv->add((int)" + rightvar + ", (int)" + leftvar + ");");
1215 cr.outputline("if (" + addeditem + ")");
1218 Vector dispatchrules = getrulelist(rd);
1220 if (dispatchrules.size() == 0) {
1221 cr.outputline("// nothing to dispatch");
1226 for(int i = 0; i < dispatchrules.size(); i++) {
1227 Rule rule = (Rule) dispatchrules.elementAt(i);
1228 if (rule.getGuardExpr().getRequiredDescriptors().contains(rd)) {
1229 /* Guard depends on this relation, so we recomput everything */
1230 cr.outputline(worklist.getSafeSymbol()+"->add("+rule.getNum()+",-1,0,0);");
1232 for (int j=0;j<rule.numQuantifiers();j++) {
1233 Quantifier q=rule.getQuantifier(j);
1234 if (q.getRequiredDescriptors().contains(rd)) {
1236 cr.outputline(worklist.getSafeSymbol()+"->add("+rule.getNum()+","+j+","+leftvar+","+rightvar+");");
1245 public void generate_dispatch(CodeWriter cr, SetDescriptor sd, String setvar) {
1247 cr.outputline("// SET DISPATCH ");
1249 cr.outputline("if ("+oldmodel.getSafeSymbol()+"&&");
1250 cr.outputline("!"+oldmodel.getSafeSymbol() +"->"+sd.getJustSafeSymbol()+"_hash->contains("+setvar+"))");
1252 /* Adding new item */
1253 /* Perform safety checks */
1254 cr.outputline("if ("+repairtable.getSafeSymbol()+"&&");
1255 cr.outputline(repairtable.getSafeSymbol()+"->containsset("+sd.getNum()+","+currentrule.getNum()+","+setvar+"))");
1257 /* Have update to call into */
1258 VarDescriptor funptr=VarDescriptor.makeNew("updateptr");
1260 for(int i=0;i<currentrule.numQuantifiers();i++) {
1261 if (currentrule.getQuantifier(i) instanceof RelationQuantifier)
1262 parttype=parttype+", int, int";
1264 parttype=parttype+", int";
1266 cr.outputline("void (*"+funptr.getSafeSymbol()+") ("+name+"_state *,"+name+"*,RepairHash *"+parttype+")=");
1267 cr.outputline("(void (*) ("+name+"_state *,"+name+"*,RepairHash *"+parttype+")) "+repairtable.getSafeSymbol()+"->getset("+sd.getNum()+","+currentrule.getNum()+","+setvar+");");
1268 String methodcall="("+funptr.getSafeSymbol()+") (this,"+oldmodel.getSafeSymbol()+","+
1269 repairtable.getSafeSymbol();
1270 for(int i=0;i<currentrule.numQuantifiers();i++) {
1271 Quantifier q=currentrule.getQuantifier(i);
1272 if (q instanceof SetQuantifier) {
1273 SetQuantifier sq=(SetQuantifier) q;
1274 methodcall+=","+sq.getVar().getSafeSymbol();
1275 } else if (q instanceof RelationQuantifier) {
1276 RelationQuantifier rq=(RelationQuantifier) q;
1277 methodcall+=","+rq.x.getSafeSymbol();
1278 methodcall+=","+rq.y.getSafeSymbol();
1279 } else if (q instanceof ForQuantifier) {
1280 ForQuantifier fq=(ForQuantifier) q;
1281 methodcall+=","+fq.getVar().getSafeSymbol();
1285 cr.outputline(methodcall);
1286 cr.outputline(goodflag.getSafeSymbol()+"=0;");
1287 cr.outputline("continue;");
1290 /* Build standard compensation actions */
1291 if (need_compensation(currentrule)) {
1292 UpdateNode un=find_compensation(currentrule);
1293 String name=(String)updatenames.get(un);
1294 usedupdates.add(un); /* Mark as used */
1296 String methodcall=name+"(this,"+oldmodel.getSafeSymbol()+","+
1297 repairtable.getSafeSymbol();
1298 for(int i=0;i<currentrule.numQuantifiers();i++) {
1299 Quantifier q=currentrule.getQuantifier(i);
1300 if (q instanceof SetQuantifier) {
1301 SetQuantifier sq=(SetQuantifier) q;
1302 methodcall+=","+sq.getVar().getSafeSymbol();
1303 } else if (q instanceof RelationQuantifier) {
1304 RelationQuantifier rq=(RelationQuantifier) q;
1305 methodcall+=","+rq.x.getSafeSymbol();
1306 methodcall+=","+rq.y.getSafeSymbol();
1307 } else if (q instanceof ForQuantifier) {
1308 ForQuantifier fq=(ForQuantifier) q;
1309 methodcall+=","+fq.getVar().getSafeSymbol();
1313 cr.outputline(methodcall);
1314 cr.outputline(goodflag.getSafeSymbol()+"=0;");
1315 cr.outputline("continue;");
1320 String addeditem = (VarDescriptor.makeNew("addeditem")).getSafeSymbol();
1321 cr.outputline("int " + addeditem + " = 1;");
1322 cr.outputline(addeditem + " = " + sd.getSafeSymbol() + "_hash->add((int)" + setvar + ", (int)" + setvar + ");");
1324 Vector dispatchrules = getrulelist(sd);
1326 if (dispatchrules.size() == 0) {
1327 cr.outputline("// nothing to dispatch");
1332 for(int i = 0; i < dispatchrules.size(); i++) {
1333 Rule rule = (Rule) dispatchrules.elementAt(i);
1334 if (SetDescriptor.expand(rule.getGuardExpr().getRequiredDescriptors()).contains(sd)) {
1335 /* Guard depends on this relation, so we recompute everything */
1336 cr.outputline(worklist.getSafeSymbol()+"->add("+rule.getNum()+",-1,0,0);");
1338 for (int j=0;j<rule.numQuantifiers();j++) {
1339 Quantifier q=rule.getQuantifier(j);
1340 if (SetDescriptor.expand(q.getRequiredDescriptors()).contains(sd)) {
1342 cr.outputline(worklist.getSafeSymbol()+"->add("+rule.getNum()+","+j+","+setvar+",0);");