import draw.*; import geometry.*; // IBERs represent boolean expressions with variable symbols: // // A boolean expression (BER) is one of: // -- boolean // -- variable symbol // -- ! BER // -- BER && BER // ++ show(BER) // The lines with -- are represented as last time, the one with ++ is new. // the interface is the _external_ view, specifying those services that the // 'customer' ordered (or that the rest of the program demands) // the external view includes the constructors for the implementing classes interface IBER { // evaluate this closed expression to a String representation of true & false; // unless it contains a variable in which case it produces "*error*" // example 1: evaluating show(not(false),true) displays true, returns true // example 2: evaluating and(show(false),x) displays nothing, yields "*error*" String evaluator(); // replace all occurrences of variables with the representation of b // example: and(show(false),x).substitute(false) produces a // representation of and(show(false),false) IBER substitute(boolean b); } // ----------------------------------------------------------------------------- // the abstract class is the _interal_ view, specifying how the representations // of boolean expression are to be viewed from the implementing classes abstract class ABER implements IBER { public String evaluator() { if (this.open()) { return "*error*"; } else { if (this.eval()) { return "true"; } else { return "false"; } } } // evaluate this closed expression to a boolean protected abstract boolean eval(); // does this expression contain any variable symbols? protected abstract boolean open(); } class Show extends ABER { private ABER sub; private Canvas c; private Posn where; Show(IBER sub, Canvas c, Posn where) { this.sub = (ABER)sub; this.c = c; this.where = where; } // evaluate this closed expression to a boolean protected boolean eval() { boolean s = this.sub.eval(); boolean b = this.c.drawString(this.where,String.valueOf(s)); return s; } // does this expression contain any variable symbols? protected boolean open() { return this.sub.open(); } public IBER substitute(boolean b) { return new Show(sub.substitute(b),c,where); } } // represent a boolean constant class Bool extends ABER { private boolean b; public Bool(boolean b) { this.b = b; } protected boolean eval() { return this.b; } protected boolean open() { return false; } public IBER substitute(boolean b) { return this; } } // represent a variable symbol in a boolean expression class Symbol extends ABER { private String x; public Symbol(String x) { this.x = x; } protected boolean eval() { return this.eval(); // Util.error("*error*"); } protected boolean open() { return true; } public IBER substitute(boolean b) { return new Bool(b); } } // represent a not expression class Not extends ABER { private ABER sub; public Not(IBER sub) { this.sub = (ABER)sub; } protected boolean eval() { return !this.sub.eval(); } protected boolean open() { return this.sub.open(); } public IBER substitute(boolean b) { return new Not(this.sub.substitute(b)); } } // represent an and expression class And extends ABER { private ABER lft; private ABER rgt; public And(IBER lft, IBER rgt) { this. lft = (ABER)lft; this. rgt = (ABER)rgt; } protected boolean eval() { return this.lft.eval() && this.rgt.eval(); } protected boolean open() { return this.lft.open() || this.rgt.open(); } public IBER substitute(boolean b) { return new And(lft.substitute(b),rgt.substitute(b)); } } // ----------------------------------------------------------------------------- // examples class Examples { IBER xx = new Symbol("x"); IBER tt = new Bool(true); IBER ff = new Bool(false); IBER n1 = new Not(xx); IBER n1tt = new Not(tt); IBER n1ff = new Not(ff); IBER n2 = new Not(tt); IBER n3 = new Not(ff); IBER a1 = new And(n2,n1); IBER a1tt = new And(n2,n1tt); IBER a1ff = new And(n2,n1ff); IBER a2 = new And(n2,n2); IBER a3 = new And(n3,n2); IBER a4 = new And(n2,n3); IBER a5 = new And(n3,tt); boolean b2 = check ((ABER) tt).eval() expect true; boolean b3 = check ((ABER) ff).eval() expect false; boolean b5 = check ((ABER) n2).eval() expect false; boolean b6 = check ((ABER) n3).eval() expect true; boolean b8 = check ((ABER) a2).eval() expect false; boolean b9 = check ((ABER) a3).eval() expect false; boolean bA = check ((ABER) a4).eval() expect false; boolean bB = check ((ABER) a5).eval() expect true; boolean c1 = check ((ABER) xx).open() expect true; boolean c2 = check ((ABER) tt).open() expect false; boolean c3 = check ((ABER) ff).open() expect false; boolean c4 = check ((ABER) n1).open() expect true; boolean c5 = check ((ABER) n2).open() expect false; boolean c6 = check ((ABER) n3).open() expect false; boolean c7 = check ((ABER) a1).open() expect true; boolean c8 = check ((ABER) a2).open() expect false; boolean c9 = check ((ABER) a3).open() expect false; boolean cA = check ((ABER) a4).open() expect false; boolean cB = check ((ABER) a5).open() expect false; boolean d1 = check xx.evaluator() expect "*error*"; boolean d2 = check tt.evaluator() expect "true"; boolean d3 = check ff.evaluator() expect "false"; boolean d4 = check n1.evaluator() expect "*error*"; boolean d5 = check n2.evaluator() expect "false"; boolean d6 = check n3.evaluator() expect "true"; boolean d7 = check a1.evaluator() expect "*error*"; boolean d8 = check a2.evaluator() expect "false"; boolean d9 = check a3.evaluator() expect "false"; boolean dA = check a4.evaluator() expect "false"; boolean dB = check a5.evaluator() expect "true"; // example 1: show(not(false),true) // display false and true on canvas Canvas showSomething = new Canvas(200,50); boolean s1 = showSomething.show(); boolean t1 = showSomething.drawString(new Posn(160,40),"show!!"); IBER a6 = new Not(new Show(this.a5,showSomething,new Posn(10,10))); IBER a7 = new And(new Show(a5,showSomething,new Posn(50,10)), new Show(a6,showSomething,new Posn(50,20))); boolean dC = check this.a6.evaluator() expect "false"; boolean dD = check this.a7.evaluator() expect "false"; // example 2: and(show(false),x) // display empty canvas Canvas shouldStayEmpty = new Canvas(200,50); boolean s2 = shouldStayEmpty.show(); boolean t2 = shouldStayEmpty.drawString(new Posn(160,40),"empty!!"); Posn p = new Posn(100,100); boolean dE = check new And(new Show(new Bool(false),shouldStayEmpty,p), new Symbol("x")).evaluator() expect "*error*"; // consider abstracting over these examples with a method boolean e1 = check n1.substitute(true) expect n1tt; boolean e2 = check n1.substitute(false) expect n1ff; boolean e3 = check a1.substitute(false) expect a1ff; boolean e4 = check a1.substitute(true) expect a1tt; boolean f1 = check n1.substitute(true).evaluator() expect "false"; boolean f2 = check a1.substitute(true).evaluator() expect "false"; boolean f3 = check a1.substitute(false).evaluator() expect "false"; boolean f4 = check a5.substitute(false).evaluator() expect "true"; }