// behavior of constraints (i.e. reducing given an assignment) Constraint { public void print() to * (PrintVisitor); traversal toAll(UniversalVisitor) { to *; } // deep copy the constraint Constraint copy() {{ CopyVisitor cv = new CopyVisitor(Constraint.class); toAll(cv); return (Constraint)cv.get_return_val(); }} // generate a copy of this constraint with its // relation number simplified by the assignment Constraint reduce(Assignment a) {{ Constraint c = copy(); c.reduceBang(a, c.get_relation()); return c; }} // mutate this constraint by simplifying with // assignment a and mutating relation r // return value is a hack to get a temp variable; it is always 0 int reduceBang(Assignment a, Relation r) to Variable { // uses return_val to count down variable positions init (@ return_val = 2; @) before Variable (@ Literal l = a.lookup(host); if (l != null) { r.set_relationNumber(solver.Relation.reduce( r.get_relationNumber(), return_val, l.toInt())); } return_val--; @) } }