1 / 30

Implementing an ADT

Implementing an ADT. Example: Sum-Constraint ADT Part II Ohad Barzilay May 2004. Cell implementation. /** * A cell contains a value, and may be connected to * several constraint ports. * * @invariant connections != null, "Non - null connections" */ public class Cell {

edith
Download Presentation

Implementing an ADT

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

  2. Cell implementation /** *Acellcontainsavalue,andmaybeconnectedto *severalconstraintports. * *@invariantconnections!=null,"Non-nullconnections" */ publicclassCell { protectedObject_value; protectedListSetconnections;

  3. Cell implementation /** *CreatesanewCellwithnovalue. * *@postvalue()==null,"Nullvalue" */ publicCell() { connections=newListSet(); _value=null; } /** *CreatesanewCellwithagivenvalue. * *@postvalue()==new_val,"Valuestored" */ publicCell(Objectnew_val) { this(); _value=new_val; }

  4. value() /** *ReturnsthevaluestoredinthisCell. */ public Object value() { return _value; } • Don’t access fields directly • No postcondition

  5. add_connection /** *Addsaconnection(a'constraint-port' *pair)totheCell. * *@prec!=null,"Non-nullconstraint" *@prec.port_valid(port),"Validport" */ publicvoid add_connection(Constraint c, int port) { connections.extend(new Pair(c, new Integer(port))); }

  6. set_value /** *SetsthevaluestoredintheCelltothegivenone. *Notifieristheuserprogram. * *@prenew_val!=null,"Non-nullnewvalue" *@postvalue()==new_val,"Valuestored" */ publicvoid set_value(Object new_val) { set_value(new_val, null, 0); }

  7. set_value /** *SetsthevaluestoredintheCelltothegivenone. *Ifnull,notifieristheuserprogram. * *@prenew_val!=null,"Non-nullnewvalue" *@prenotifier==null||notifier.port_valid(port), * "Validport" *@prenotifier==null||value()==null, *"Constraintcannotoverrideexistingvalue" * *@postvalue()==new_val,"Valuestored" */ publicvoid set_value(Object new_val, Constraint notifier, int port)

  8. set_value publicvoid set_value(Object new_val, Constraint notifier, int port) { Set agenda = null; if (_value != null) { agenda = new ListSet(); forget(agenda); } _value = new_val; ...

  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. forget /** *BeginsavalueretractionchainfromthisCell. *Whenfinished,thevalueofthisCell,andeveryvalue *inthenetworkdependingonitwillberetracted.Then *itwillbededucedifpossible. */ publicvoid forget() { Set agenda = new ListSet(); forget(agenda); Linear iter = agenda.iterator(); for (iter.start(); !iter.after(); iter.forth()) ((Constraint)iter.item()).deduce(); }

  11. forget /** *Alinkwithinaretractingchain. *Whenfinished,thevalueofthisCellwillberetracted. * *@preagenda!=null,"Non-nullagenda" *@postvalue()==null */ protectedvoid 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. 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. SumConstraint publicclassSumConstraintextendsConstraint { publicstaticfinalintADDEND=0; publicstaticfinalintAUGEND=1; publicstaticfinalintSUM=2; publicstaticfinalintNUM_OF_PORTS=3; protectedCell[]ports; protectedboolean[]_deduced;

  15. SumConstraint publicSumConstraint(Celladdend,Cellaugend,Cellsum) { ports=newCell[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=newboolean[NUM_OF_PORTS]; for(inti=0;i<NUM_OF_PORTS;i++) _deduced[i]=false; deduce(); }

  16. SumConstraint - contract /** *CreatesanewSumConstraintwhichisconnectedtothe * givenCells. *TheCellsarefixedduringthelifeoftheconstraint. * *@preaddend!=null,"Non-nulladdend" *@preaugend!=null,"Non-nullaugend" *@presum!=null,"Non-nullsum" *@post($prev(addend.value())==null)||defined(ADDEND), *"Addenddefinedifcellhadvalue" *@post($prev(augend.value())==null)||defined(AUGEND), *"Augenddefinedifcellhadvalue" *@post($prev(sum.value())==null)||defined(SUM), *"Sumdefinedifcellhadvalue" */ publicSumConstraint(Celladdend,Cellaugend,Cellsum)

  17. port_valid /** *Returnstrueifthegivenportisoneof * ADDEND,AUGENDorSUM. */ publicboolean port_valid(int port) { return 0 <= port && port < NUM_OF_PORTS; }

  18. get_port /** *Returnsthevaluestoredinthegivenport. * *@preport_valid(port),"Validport" *// @pre known(port), "Port value is known" // * possible,butbetter: *@post!known(port)==($ret==null), * "Unknowniffnull" */ public Object get_port(int port) { return ports[port].value(); }

  19. defined /** *returnstrueiffthegivenportisdefined. * *@preport_valid(port),"Validport" * *@post$ret==(!deduced(port)&&get_port(port)!=null), *"Definediffhasvaluebutnotdeduced" */ publicboolean defined(int port) { return !_deduced[port] && ports[port].value() != null; }

  20. deduced /** *Istheportdeduced? * *@preport_valid(port),"Validport" * *@post$ret==(!defined(port)&&get_port(port)!=null), *"Deducediffhasvaluebutnotdefined" *@post!$ret||(((Integer)get_port(SUM)).intValue()== * ((Integer)get_port(ADDEND)).intValue()+ * ((Integer)get_port(AUGEND)).intValue()), *"Deductionobeysconstraint" */ publicboolean deduced(int port) { return _deduced[port]; }

  21. known /** *Returnstrueifthisportiseitherdefinedordeduced. * *@preport_valid(port),"Validport" * *@post$ret==(get_port(port)!=null), *"Knowniffportisnon-null" */ publicboolean known(int port) { return ports[port].value() != null; }

  22. contradiction /** *Returnstrueifalltheportsaredefined,andthesumoftheaddend *andtheaugendport'svaluesisn'tequaltothevalueofthesumport. * *@post$ret==(defined(ADDEND)&&defined(AUGEND)&&defined(SUM) *&&(((Integer)get_port(ADDEND)).intValue()+ *((Integer)get_port(AUGEND)).intValue()!= *((Integer)get_port(SUM)).intValue())), *"Contradictioniffconstraintnotobeyed" */ publicboolean contradiction() { return defined(ADDEND) && defined(AUGEND) && defined(SUM) && (((Integer)get_port(ADDEND)).intValue() + ((Integer)get_port(AUGEND)).intValue() != ((Integer)get_port(SUM)).intValue()); }

  23. new_port_value /** *Informconstraintofnewvalueinport.Tobecalledby *connectedcellafterchangingthecell'sownvalue. * *@preport_valid(port),"Validport" * *@postdefined(port),"Portdefined" *@post!deduced(port),"Portnotdeduced" */ protectedvoid new_port_value(int port) { deduced[port] = false; deduce(); }

  24. forget /** *Retractsthevaluefromthegivenportrecursively.Tobe *calledbyconnectedcellafteritforgotitsownvalue.Ifthe *givenportisnotdefinedand/orisdeducednothinghappens. *Theconstraintaddsitselftotheagendainordertocheck *deductionsaftertheprocessisfinished. * *@preport_valid(port),"Validport" *@preagenda!=null,"Non-nullagenda" * *@post!defined(port),"Portundefined" */ protectedvoid forget(int port, Set agenda) { agenda.extend(this); retract(agenda); }

  25. retract /**Retractpreviousdeductionifnolongervalid. */ protectedvoid retract(Set agenda) { if (_deduced[ADDEND] && !(defined(AUGEND) && defined(SUM))) { _deduced[ADDEND] = false; ports[ADDEND].forget(agenda); } elseif (_deduced[AUGEND] && !(defined(ADDEND) && defined(SUM))) { _deduced[AUGEND] = false; ports[AUGEND].forget(agenda); } elseif (_deduced[SUM] && !(defined(ADDEND) && defined(AUGEND))) { _deduced[SUM] = false; ports[SUM].forget(agenda); } }

  26. deduce /**Attempttodeducenewinformationforportsinthisconstraint. */ protectedvoid 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. 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. port_string /** *@preport_valid(port),"Validport" */ protected String port_string(int port) { if (defined(port)) return"defined(" + get_port(port).toString() + ")"; elseif (deduced(port)) return"deduced(" + get_port(port).toString() + ")"; elsereturn"---"; }

  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 ?

More Related