1 / 41

Design by Contract with JML

Design by Contract with JML. CS 3331 Fall 2009 Gary T. Leavens and Yoonsik Cheon. Design by Contract with JML . Available from http://www.jmlspecs.org Tool support from http://www.cs.utep.edu/cheon/download/jet/. Outline. Design by contract (DBC) Java Modeling Language (JML) DBC with JML

eshana
Download Presentation

Design by Contract with JML

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. Design by Contract with JML CS 3331 Fall 2009 Gary T. Leavens and Yoonsik Cheon. Design by Contract with JML. Available from http://www.jmlspecs.org Tool support from http://www.cs.utep.edu/cheon/download/jet/

  2. Outline • Design by contract (DBC) • Java Modeling Language (JML) • DBC with JML • JML tools – JML compiler (jmlc)

  3. Contracts in Real World • Contracts specify: • Agreements • Obligations and rights • Contracts for buying cars • Buyers: give money; receive cars • Dealers: give cars; receive money

  4. Obligations Rights Client Implementor Contracts in Software /** Returns a square root approximation of a non-negative number x. * @param x A non-negative number. * @returns A square root approximation of x. */ publicstaticdouble sqrt(double x) { … } Gets square root approximation Passes non-negative number Assumes argument is non-negative Computes and returns square root

  5. Design by Contract (DBC) /*@requires x >= 0.0; @ensures (Math.abs(\result * \result - x) <= 0.00001); @*/ publicstaticdouble sqrt(double x) { … } • Advantages over informal contracts? • Unambiguous • Machine manipulation

  6. Pre and Postconditions • Definition • A method’s precondition says what must be true to call it. • A method’s normal postcondition says what is true when it returns normally (i.e., without throwing an exception). • A method’s exceptional postcondition says what is true when a method throws an exception. //@ signals (IllegalArgumentException e) x < 0;

  7. precondition 0 0  postcondition  10 100 -10   Output Input Relational Model of Methods • Can think of a method as a relation: Inputs  Outputs

  8. Contracts as Documentation • For each method say: • What it requires (if anything), and • What it ensures. • Contracts are: • More abstract than code, • Not necessarily constructive, • Often machine checkable, so can help with debugging, and • Machine checkable contracts can always be up-to-date.

  9. Abstraction by Specification • A contract can be satisfied in many ways: E.g., for square root: • Linear search • Binary search • Newton’s method • … • These will have varying non-functional properties • Efficiency • Memory usage • So, a contract abstracts from all these implementations, and thus can change implementations later.

  10. More Advantages of Contracts • Blame assignment • Who is to blame if: • Precondition doesn’t hold? • Postcondition doesn’t hold? • Avoids inefficient defensive checks //@ requires a != null && (* a is sorted *); publicstaticint binarySearch(Thing[] a, Thing x) { … }

  11. Modularity of Reasoning • Typical OO code: … source.close(); dest.close(); getFile().setLastModified(loc.modTime().getTime()); … • How to understand this code? • Read the code for all methods? • Read the contracts for all methods?

  12. Rules for Reasoning • Client code • Must work for every implementation that satisfies the contract, and • Can thus only use the contract (not the code!), i.e., • Must establish precondition, and • Gets to assume the postcondition //@ assert 9.0 >= 0; double result = sqrt(9.0); //@ assert result * result  9.0; // can assume result == 3.0? • Implementation code • Must satisfy contract, i.e., • Gets to assume precondition • Must establish postcondition • But can do anything permitted by it.

  13. Contracts and Intent • Code makes a poor contract, because can’t separate: • What is intended (contract) • What is an implementation decision E.g., if the square root gives an approximation good to 3 decimal places, can that be changed in the next release? • By contrast, contracts: • Allow vendors to specify intent, • Allow vendors freedom to change details, and • Tell clients what they can count on. • Question • What kinds of changes might vendors want to make that don’t break existing contracts?

  14. Outline • Design by contract (DBC) • Java Modeling Language (JML) • DBC with JML • JML tools – JML compiler (jmlc)

  15. JML • What is it? • Stands for “Java Modeling Language” • A formal behavioral interface specification language for Java • Design by contract for Java • Uses Java 1.4 or later • Available from www.jmlspecs.org • JET from http://www.cs.utep.edu/cheon/download/jet/

  16. Annotations • JML specifications are contained in annotations, which are comments like: //@ … or /*@ … @ … @*/ At-signs (@) at the beginning of lines are ignored within annotations. • Question • What’s the advantage of using annotations?

  17. Outline • Design by contract (DBC) • Java Modeling Language (JML) • DBC with JML • JML tools – JML compiler (jmlc)

  18. Informal Description • An informal description looks like: (* some text describing a property *) • It is treated as a boolean value by JML, and • Allows • Escape from formality, and • Organize English as contracts. publicclass IMath { /*@ requires (* x is positive *); @ ensures \result >= 0 && @ (* \result is an int approximation to square root of x *) @*/ publicstaticint isqrt(int x) { … } }

  19. Question What does the reserved word \result denote? What's its type in this particular case? /** * Returns an approximation to the square root of <code>x</code>. */ /*@ requires (* x is positive *); @ ensures \result >= 0 && @ (* \result is an approximation to the square root of x *); @*/ publicstaticdouble sqrt(double x) { // ... }

  20. Exercise • Write informal pre and postconditions. • publicvoid addKgs(int kgs) { • weight += kgs; • } • public Person(String n) { • name = n; weight = 0; • } • } publicclass Person { private String name; privateint weight; /*@ also @ ensures \result != null && @ (* \result is a displayable @ form of this person *); @*/ public String toString() { return “Person(\” + name + “\”, “ + weight + ”)”; } publicint getWeight() { return weight; }

  21. Syntax Meaning \resultresult of method call a ==> b a implies b a <== b b implies a a <==> b a iff b a <=!=> b !(a <==> b) \old(E) value of E in the pre-state Formal Specifications • Formal assertions are written as Java expressions, but: • Can’t have side effects • No use of =, ++, --, etc., and • Can only call pure methods. • Can use some extensions to Java:

  22. Example • publicclass Person { • private /*@ spec_publicnon_null@*/ String name; • private /*@ spec_public @*/ int weight; • //@ publicinvariant !name.equals(“”) && weight >= 0; • /*@ also • @ ensures \result != null; • @*/ • public String toString() { … } • //@ ensures \result == weight; • publicint getWeight() { … } • <<continues to next slide>>

  23. Example (Cont.) • /*@ requires kgs > 0; • @ ensures weight == \old(kgs + weight); @*/ • publicvoid addKgs(int kgs) { … } • /*@ requires !n.equals(“”); • @ ensures n.equals(name) && weight == 0; • @*/ • public Person(/*@ non_null @*/ String n) { … } • }

  24. Better addKgs? • /*@ requires kgs > 0; • @ ensures weight == \old(kgs + weight); • @ also • @ requires kgs <= 0; • @ signals_onlyIllegalArgumentException; • @*/ • publicvoid addKgs(int kgs) { • if (kgs > 0) { • weight += kgs; • } else { • thrownew IllegalArgumentException(“positive kgs required!”); • } • }

  25. normal (return) exceptional (throw) ensures … kgs > 0 … signals … kgs <= 0; Meaning of Postconditions

  26. More Examples //@ ensures \result == (x % 2 == 0); publicstaticboolean mystery0(int x) { /* … */ } //@ ensures \result == (x > y ? x : y); publicstaticint mystery1(int x, int y) { /* … */ } //@ ensures (x > y ==> \result == x) && (x <= y ==> \result == y); publicstaticint mystery2(int x, int y) { /* … */ } //@ ensures \result == Math.max(x, y); publicstaticint mystery3(int x, int y) { /* … */ }

  27. Invariants • Definition • An invariant is a property that is always true of an object’s state (when control is not inside the object’s methods). • Invariants allow you to define: • Acceptable states of an object, and • Consistency of an object’s state. //@ publicinvariant !name.equals(“”) && weight >= 0; private /*@ spec_publicnon_null @*/ String name;

  28. Exercise • Formally specify the following method (in Person) publicvoid changeName(String newName) { name = newName; } Hint: Watch out for the invariant!

  29. Quantifiers • JML supports several forms of quantifiers • Universal and existential (\forall and \exists) • General quantifiers (\sum, \product, \min, \max) • Numeric quantifier (\num_of) (\forall Student s; juniors.contains(s) ==> s.getAdvisor() != null) (\forall Student s; juniors.contains(s); s.getAdvisor() != null)

  30. Examples /*@ requires a != null && a.length > 0; @ ensures (\existsint i; 0 <= i && i < a.length; \result == a[i]) && @ (\forallint i; 0 <= i && i < a.length; \result >= a[i]); @*/ publicstaticint mystery1(int[] a) { /* … */ } /*@ requires a != null; @ ensures \result == (\sumint i; 0 <= i && i < a.length; a[i]); @*/ publicstaticint mystery2(int a[]) { /* … */ } /*@ requires a != null; @ ensures \result == (\num_ofint i; 0 <= i && i < a.length; x > a[i]); @*/ publicstaticint mystery3(int a[], int x) { /* … */ }

  31. Exercise • Formally specify the missing part, i.e., the fact that a is sorted in ascending order. /*@ oldboolean hasx = (\existsint i; i >= 0 && i < a.length; a[i] == x); @ requires @ @ @ ensures (hasx ==> a[\result] == x) && (!hasx ==> \result == -1); @ requires_redundantly (* a is sorted in ascending order *); @*/ publicstaticint binarySearch(/*@ non_null @*/ int[] a, int x) { … } Hint: Use a nested quantification, e.g., (\forall int i, j; …)

  32. Model Declarations • What if you want to change a spec_public field’s name? private /*@ spec_publicnon_null @*/ String name; to private /*@ non_null @*/ String fullName; • For specification: • need to keep the old name public • but don’t want two strings. • So, use a model field: //@ publicmodelnon_null String path; and a represents clause //@ privaterepresents path <- fullName;

  33. name abstract (model) represented by fullName concrete (real) Model Variables • Specification-only variables • Like domain-level constructs • Values are given only by represents clauses:

  34. Question • What changes would you make to change the representation of a person’s weight from kilograms to pounds?

  35. Outline • Design by contract (DBC) • Java Modeling Language (JML) • DBC with JML • JML tools – JML compiler (jmlc)

  36. Tools for JML • JML compiler (jmlc) • JML/Java interpreter (jmlrac) • JML/JUnit unit test tool (jmlunit) • HTML generator (jmldoc)

  37. JML Compiler (jmlc) • Basic usage $ jmlc Person.java produces Person.class $ jmlc –Q *.java produces *.class, quietly $ jmlc –d ../bin Person.java produces ../bin/Person.class

  38. Running Code Compiled with jmlc • Must have JML’s runtime classes (jmlruntime.jar) in Java’s boot class path • Automatic if you use script jmlrac, e.g., $ jmlrac PersonMain

  39. A Main Program public class PersonMain { public static void main(String[] args) { System.out.println(new Person(“Yoonsik”)); System.out.println(new Person(null)); } }

  40. Example (Formatted) $ jmlc –Q Person.java $ javac PersonMain.java $ jmlrac PersonMain Person(“Yoonsik”,0) Exception in thread "main" org.jmlspecs.jmlrac.runtime.JMLEntryPreconditionError : by method Person.Person regarding specifications at File "Person.refines-java", line 52, character 20 when 'n' is null at org.jmlspecs.samples.jmltutorial.Person.checkPre$$init$$Person( Person.refines-java:1060) at org.jmlspecs.samples.jmltutorial.Person.<init>(Person.refines-java:51) at org.jmlspecs.samples.jmltutorial.PersonMain.main(PersonMain.java:27)

  41. Summary • DBC is a way of recording: • Details of method responsibilities • Avoiding constantly checking arguments • Assigning blame across interfaces • JML is a DBC tool for Java • For details on JML, refer to its web page at www.jmlspecs.org

More Related