Presentation is loading. Please wait.

Presentation is loading. Please wait.

Implementing an ADT Example: Sum-Constraint ADT Part II Ohad Barzilay May 2004.

Similar presentations


Presentation on theme: "Implementing an ADT Example: Sum-Constraint ADT Part II Ohad Barzilay May 2004."— Presentation transcript:

1 Implementing an ADT Example: Sum-Constraint ADT Part II Ohad Barzilay May 2004

2 Ohad Barzilay, April 2004 2 Cell implementation /** * A cell contains a value, and may be connected to * several constraint ports. * * @invariant connections != null, "Non-null connections" */ public class Cell { protected Object _value; protected ListSet connections;

3 Ohad Barzilay, April 2004 3 Cell implementation /** * Creates a new Cell with no value. * * @post value() == null, "Null value" */ public Cell() { connections = new ListSet(); _value = null; } /** * Creates a new Cell with a given value. * * @post value() == new_val, "Value stored" */ public Cell(Object new_val) { this(); _value = new_val; }

4 Ohad Barzilay, April 2004 4 value() /** * Returns the value stored in this Cell. */ public Object value() { return _value; } Don’t access fields directly No postcondition

5 Ohad Barzilay, April 2004 5 add_connection /** * Adds a connection (a 'constraint - port' * pair) to the Cell. * * @pre c != null, "Non-null constraint" * @pre c.port_valid(port), "Valid port" */ public void add_connection(Constraint c, int port) { connections.extend(new Pair(c, new Integer(port))); }

6 Ohad Barzilay, April 2004 6 set_value /** * Sets the value stored in the Cell to the given one. * Notifier is the user program. * * @pre new_val != null, "Non-null new value" * @post value() == new_val, "Value stored" */ public void set_value(Object new_val) { set_value(new_val, null, 0); }

7 Ohad Barzilay, April 2004 7 set_value /** * Sets the value stored in the Cell to the given one. * If null, notifier is the user program. * * @pre new_val != null, "Non-null new value" * @pre notifier == null || notifier.port_valid(port), * "Valid port" * @pre notifier == null || value() == null, * "Constraint cannot override existing value" * * @post value() == new_val, "Value stored" */ public void set_value(Object new_val, Constraint notifier, int port)

8 Ohad Barzilay, April 2004 8 set_value public void set_value(Object new_val, Constraint notifier, int port) { Set agenda = null; if (_value != null) { agenda = new ListSet(); forget(agenda); } _value = new_val;...

9 Ohad Barzilay, April 2004 9 set_value... Linear iter = connections.iterator(); for (iter.start(); !iter.after(); iter.forth()) { Pair connection = (Pair)iter.item(); Constraint c = (Constraint)connection.car(); int p = ((Integer)connection.cdr()).intValue(); if (!(c == notifier && p == port)) c.new_port_value(p); } if (agenda != null) { iter = agenda.iterator(); for (iter.start(); !iter.after(); iter.forth()) ((Constraint)iter.item()).deduce(); }

10 Ohad Barzilay, April 2004 10 forget /** * Begins a value retraction chain from this Cell. * When finished, the value of this Cell, and every value * in the network depending on it will be retracted. Then * it will be deduced if possible. */ public void forget() { Set agenda = new ListSet(); forget(agenda); Linear iter = agenda.iterator(); for (iter.start(); !iter.after(); iter.forth()) ((Constraint)iter.item()).deduce(); }

11 Ohad Barzilay, April 2004 11 forget /** * A link within a retracting chain. * When finished, the value of this Cell will be retracted. * * @pre agenda != null, "Non-null agenda" * @post value() == null */ protected void forget(Set agenda) { if (_value != null) { _value = null; Linear iter = connections.iterator(); for (iter.start(); !iter.after(); iter.forth()) { Pair connection = (Pair)iter.item(); Constraint c = (Constraint)connection.car(); int p = ((Integer)connection.cdr()).intValue(); c.forget(p, agenda); }

12 Ohad Barzilay, April 2004 12 toString public String toString() { StringBuffer result = new StringBuffer("<Cell: "); result.append(value() == null ? "---" : value().toString()); result.append(">"); return result.toString(); }

13 The Solution Implementing SumConstraint

14 Ohad Barzilay, April 2004 14 SumConstraint public class SumConstraint extends Constraint { public static final int ADDEND = 0; public static final int AUGEND = 1; public static final int SUM = 2; public static final int NUM_OF_PORTS = 3; protected Cell[] ports; protected boolean[] _deduced;

15 Ohad Barzilay, April 2004 15 SumConstraint public SumConstraint(Cell addend, Cell augend, Cell sum) { ports = new Cell[NUM_OF_PORTS]; ports[ADDEND] = addend; ports[AUGEND] = augend; ports[SUM] = sum; addend.add_connection(this, ADDEND); augend.add_connection(this, AUGEND); sum.add_connection(this, SUM); _deduced = new boolean[NUM_OF_PORTS]; for (int i = 0; i < NUM_OF_PORTS; i++) _deduced[i] = false; deduce(); }

16 Ohad Barzilay, April 2004 16 SumConstraint - contract /** * Creates a new SumConstraint which is connected to the * given Cells. * The Cells are fixed during the life of the constraint. * * @pre addend != null, "Non-null addend" * @pre augend != null, "Non-null augend" * @pre sum != null, "Non-null sum" * @post ($prev(addend.value()) == null) || defined(ADDEND), * "Addend defined if cell had value" * @post ($prev(augend.value()) == null) || defined(AUGEND), * "Augend defined if cell had value" * @post ($prev(sum.value()) == null) || defined(SUM), * "Sum defined if cell had value" */ public SumConstraint(Cell addend, Cell augend, Cell sum)

17 Ohad Barzilay, April 2004 17 port_valid /** * Returns true if the given port is one of * ADDEND, AUGEND or SUM. */ public boolean port_valid(int port) { return 0 <= port && port < NUM_OF_PORTS; }

18 Ohad Barzilay, April 2004 18 get_port /** * Returns the value stored in the given port. * * @pre port_valid(port), "Valid port" * // @pre known(port), "Port value is known" // * possible, but better: * @post !known(port) == ($ret == null), * "Unknown iff null" */ public Object get_port(int port) { return ports[port].value(); }

19 Ohad Barzilay, April 2004 19 defined /** * returns true iff the given port is defined. * * @pre port_valid(port), "Valid port" * * @post $ret == (!deduced(port) && get_port(port) != null), * "Defined iff has value but not deduced" */ public boolean defined(int port) { return !_deduced[port] && ports[port].value() != null; }

20 Ohad Barzilay, April 2004 20 deduced /** * Is the port deduced? * * @pre port_valid(port), "Valid port" * * @post $ret == (!defined(port) && get_port(port) != null), * "Deduced iff has value but not defined" * @post !$ret || (((Integer)get_port(SUM)).intValue() == * ((Integer)get_port(ADDEND)).intValue() + *((Integer)get_port(AUGEND)).intValue()), * "Deduction obeys constraint" */ public boolean deduced(int port) { return _deduced[port]; }

21 Ohad Barzilay, April 2004 21 known /** * Returns true if this port is either defined or deduced. * * @pre port_valid(port), "Valid port" * * @post $ret == (get_port(port) != null), * "Known iff port is non-null" */ public boolean known(int port) { return ports[port].value() != null; }

22 Ohad Barzilay, April 2004 22 contradiction /** * Returns true if all the ports are defined, and the sum of the addend * and the augend port's values isn't equal to the value of the sum port. * * @post $ret == (defined(ADDEND) && defined(AUGEND) && defined(SUM) * && (((Integer)get_port(ADDEND)).intValue() + * ((Integer)get_port(AUGEND)).intValue() != * ((Integer)get_port(SUM)).intValue())), * "Contradiction iff constraint not obeyed" */ public boolean contradiction() { return defined(ADDEND) && defined(AUGEND) && defined(SUM) && (((Integer)get_port(ADDEND)).intValue() + ((Integer)get_port(AUGEND)).intValue() != ((Integer)get_port(SUM)).intValue()); }

23 Ohad Barzilay, April 2004 23 new_port_value /** * Inform constraint of new value in port. To be called by * connected cell after changing the cell's own value. * * @pre port_valid(port), "Valid port" * * @post defined(port), "Port defined" * @post !deduced(port), "Port not deduced" */ protected void new_port_value(int port) { deduced[port] = false; deduce(); }

24 Ohad Barzilay, April 2004 24 forget /** * Retracts the value from the given port recursively. To be * called by connected cell after it forgot its own value. If the * given port is not defined and/or is deduced nothing happens. * The constraint adds itself to the agenda in order to check * deductions after the process is finished. * * @pre port_valid(port), "Valid port" * @pre agenda != null, "Non-null agenda" * * @post !defined(port), "Port undefined" */ protected void forget(int port, Set agenda) { agenda.extend(this); retract(agenda); }

25 Ohad Barzilay, April 2004 25 retract /** Retract previous deduction if no longer valid. */ protected void retract(Set agenda) { if (_deduced[ADDEND] && !(defined(AUGEND) && defined(SUM))) { _deduced[ADDEND] = false; ports[ADDEND].forget(agenda); } else if (_deduced[AUGEND] && !(defined(ADDEND) && defined(SUM))) { _deduced[AUGEND] = false; ports[AUGEND].forget(agenda); } else if (_deduced[SUM] && !(defined(ADDEND) && defined(AUGEND))) { _deduced[SUM] = false; ports[SUM].forget(agenda); }

26 Ohad Barzilay, April 2004 26 deduce /** Attempt to deduce new information for ports in this constraint. */ protected void deduce() { if (defined(ADDEND) && defined(AUGEND) && !known(SUM)) { _deduced[SUM] = true; ports[SUM].set_value( new Integer(((Integer)get_port(ADDEND)).intValue() + ((Integer)get_port(AUGEND)).intValue()), this, SUM); }...

27 Ohad Barzilay, April 2004 27 deduce... if (defined(ADDEND) && !known(AUGEND) && defined(SUM)) { _deduced[AUGEND] = true; ports[AUGEND].set_value (new Integer(((Integer)get_port(SUM)).intValue() - ((Integer)get_port(ADDEND)).intValue()), this, AUGEND); } if (!known(ADDEND) && defined(AUGEND) && defined(SUM)) { _deduced[ADDEND] = true; ports[ADDEND].set_value (new Integer(((Integer)get_port(SUM)).intValue() - ((Integer)get_port(AUGEND)).intValue()), this, ADDEND); }

28 Ohad Barzilay, April 2004 28 port_string /** * @pre port_valid(port), "Valid port" */ protected String port_string(int port) { if (defined(port)) return "defined(" + get_port(port).toString() + ")"; else if (deduced(port)) return "deduced(" + get_port(port).toString() + ")"; else return "---"; }

29 Ohad Barzilay, April 2004 29 toString public String toString() { StringBuffer result = new StringBuffer("<Sum: "); result.append(port_string(ADDEND)); result.append(" + "); result.append(port_string(AUGEND)); result.append(" = "); result.append(port_string(SUM)); if (contradiction()) result.append(" ***"); result.append(">"); return result.toString(); }

30 Questions ?


Download ppt "Implementing an ADT Example: Sum-Constraint ADT Part II Ohad Barzilay May 2004."

Similar presentations


Ads by Google