Presentation is loading. Please wait.

Presentation is loading. Please wait.

111 The Java Modeling Language Based on: Gary T. Leavens, et al., JML Tutorial at OOPSLA 2009. Gary. T Leavens, et al., Preliminary Design of JML: A Behavioral.

Similar presentations


Presentation on theme: "111 The Java Modeling Language Based on: Gary T. Leavens, et al., JML Tutorial at OOPSLA 2009. Gary. T Leavens, et al., Preliminary Design of JML: A Behavioral."— Presentation transcript:

1 111 The Java Modeling Language Based on: Gary T. Leavens, et al., JML Tutorial at OOPSLA 2009. Gary. T Leavens, et al., Preliminary Design of JML: A Behavioral Interface Specification Language for Java, ACM SIGSOFT Software Engineering Notes, 31(3):1-38, May, 2006. 1

2 222 Outline JML overview Reading and writing JML specifications Abstraction in specification Subtyping and specification inheritance 2

3 333 Overview of JML Java Modeling Language (JML) –Formal –Sequential Java –Functional behavior of APIs JML’s goals –Practical, effective for detailed designs Inter-module interfaces Classes and interfaces Data (fields) Methods –Existing code –Wide range of tools 3

4 444 Basic Approach of JML “Eiffel + Larch for Java” Hoare-style (contracts) Method pre- and post-conditions Invariants 4

5 555 First JML Specification public class ArrayOps { private /*@ spec_public @*/ Object[] a; //@ public invariant 0 < a.length; /*@ requires 0 < arr.length; @ ensures this.a == arr; @*/ public void init(Object[] arr) { this.a = arr; } 5

6 666 Field Specification with spec_public public class ArrayOps { private /*@ spec_public @*/ Object[] a; //@ public invariant 0 < a.length; /*@ requires 0 < arr.length; @ ensures this.a == arr; @*/ public void init(Object[] arr) { this.a = arr; } 6

7 777 Class Invariant public class ArrayOps { private /*@ spec_public @*/ Object[] a; //@ public invariant 0 < a.length; /*@ requires 0 < arr.length; @ ensures this.a == arr; @*/ public void init(Object[] arr) { this.a = arr; } 7

8 888 Method Specification public class ArrayOps { private /*@ spec_public @*/ Object[] a; //@ public invariant 0 < a.length; /*@ requires 0 < arr.length; @ ensures this.a == arr; @*/ public void init(Object[] arr) { this.a = arr; } 8

9 99 Interface Specification Java Code JML Specification Functional Behavior Syntactic Interface

10 10 Interface Specification public void init(Object[] arr) { this.a = arr; } /*@ requires 0 < arr.length; @ ensures this.a == arr; @*/ public void init(Object[] arr); requires 0 < arr.length; ensures this.a == arr; public void init(Object[] arr);

11 11 Comparison with Other Formal Specification Languages Like … but for Java –VDM, but OO features –Eiffel, but Features for formal verification –Spec#, but Different invariant methodology More features for formal verification Unlike OCL and Z –More Java-like syntax –Tailored to Java semantics

12 12 Many Tools, One Language

13 13 How JML Tools Complement Each Other Different strengths: –Runtime checking — real errors –Static checking — better coverage –Verification — guarantees Usual ordering: 1.Runtime checker (jmlc and jmlunit) 2.Extended Static Checking (ESC/Java2) 3.Verification tool (e.g., KeY, JACK, Jive)

14 14 Outline JML overview Reading and writing JML specifications Abstraction in specification Subtyping and specification inheritance 14

15 15 JML Annotations Not Java annotations (starting with @) JML annotation comments –Line starting with //@ –Between /*@ and @*/, ignoring @’s starting lines

16 16 Most Important JML Keywords Top-level in classes and interfaces: –invariant –spec_public –nullable For methods and constructors: –requires –ensures –assignable –pure

17 17 Example: BoundedStack Specify bounded stacks of objects Steps 1.Data and invariant 2.Constructor 3.Methods like push, pop, and top

18 18 BoundedStack’s Data and Invariant public class BoundedStack { private /*@ spec_public nullable @*/ Object[] elems; private /*@ spec_public @*/ int size = 0; //@ public invariant 0 <= size; /*@ public invariant elems != null @ && (\forall int i; @ size <= i && i < elems.length; @ elems[i] == null); @*/

19 19 BoundedStack’s Constructor /*@ requires 0 < n; @ assignable elems; @ ensures elems.length == n; @*/ public BoundedStack(int n) { elems = new Object[n]; }

20 20 BoundedStack’s push Method /*@ requires size < elems.length - 1; @ assignable elems[size], size; @ ensures size == \old(size + 1); @ ensures elems[size - 1] == x; @ ensures_redundantly @ (\forall int i; 0 <= i && i < size - 1; elems[i] == \old(elems[i])); @*/ public void push(Object x) { elems[size] = x; size++; }

21 21 BoundedStack’s pop Method /*@ requires 0 < size; @ assignable size, elems[size - 1]; @ ensures size == \old(size - 1); @ ensures_redundantly @ elems[size] == null && @ (\forall int i; 0 <= i && i < size - 1; elems[i] == \old(elems[i])); @*/ public void pop() { size--; elems[size] = null; }

22 22 BoundedStack’s top Method /*@ requires 0 < size; @ assignable \nothing; @ ensures \result == elems[size - 1]; @*/ public /*@ pure @*/ void top() { return elems[size – 1]; }

23 23 JML Keywords Used spec_public –Public visibility –Only public for specification purposes nullable –field (and array elements) may be null –Default is non_null invariant must be: –True at end of constructor –Preserved by each method (except for helper methods)

24 24 JML Keywords Used requires clause: –Precondition –Obligation on callers, after parameter passing –Assumed by implementor ensures clause: –Postcondition –Obligation on implementor, at return –Assumed by caller

25 25 Semantics of requires and ensures

26 26 Semantics of requires and ensures

27 27 Semantics of requires and ensures

28 28 JML Keywords Used assignable –Frame axiom –Locations (fields) in pre-state –New object fields not covered –Mostly checked statically –Synonyms: modifies, modifiable pure –No side effects –Implies assignable \nothing –Allows method’s use in specifications

29 29 Assignable Is a Shorthand assignable gender; ensures gender.equals(g); means ensures \only_assigned(gender) && gender.equals(g);

30 30 JML Keywords Used Redundant clauses (ensures_redundantly) –Alerts reader –States something to prove –Must be implied by: ensures clauses, assignable clause, invariant, and JML semantics. –Also requires_redundantly, etc.

31 31 Multiple Clauses Semantics: requires P; requires Q; is equivalent to: requires P && Q; Similarly for ensures, invariant. Note: checkers give more specific messages with multiple clauses.

32 32 Defaults for Omitted Clauses invariant true; requires true; assignable \everything; ensures true;

33 33 Expression Keywords \result = method’s return value. \old(E) = pre-state value of E. (\forall T x; P; Q) =  {Q | x  T  P} (\exists T x; P; Q) =  {Q | x  T  P} (\min T x; P; E) = min{E | x  T  P} (\sum T x; P; E) =  {E | x  T  P} (\num_of T x; P; Q) =  {1 | x  T  P  Q} …

34 34 Steps for Specifying a Type for Public Clients 1.Specify data (spec_public fields) 2.Specify a public invariant 3.Specify each public method using: 1.requires 2.assignable (or pure) 3.ensures

35 35 Exercise Specify the following stack methods –int capacity(): capacity of this stack? –int size(): no. of elements? –boolean isEmpty(): has no element? –int search(Object o): 1-based position of given object in this stack? private /*@ spec_public nullable @*/ Object[] elems; private /*@ spec_public @*/ int size = 0;

36 36 Solution //@ ensures \result == elems.length; public /*@ pure *@/ int capacity() { …} //@ ensures \result == size; public /*@ pure *@/ int size()() { …} //@ ensures \result == (size == 0); public /*@ pure *@/ boolean isEmpty() { …} private /*@ spec_public nullable @*/ Object[] elems; private /*@ spec_public @*/ int size = 0;

37 37 Solution //*@ ensures (\exists int i; i >= 0 && i < size; elems[i] == o) ? \result > 0 && \result <= size && elems[\result] == o : \result == 0 @*// public /*@ pure *@/ int search(Object o) { …} Q: the first (or last) from the top? private /*@ spec_public nullable @*/ Object[] elems; private /*@ spec_public @*/ int size = 0;

38 38 Exercise: BagOfInt Specify the following public class BagOfInt { private int[] a; private int n; /** Initialize to contain input’s elements. */ public BagOfInt(int[] input); /** Return the multiplicity of i. */ public int occurrences(int i); /** Return and delete the minimum element. */ public int extractMin(); }

39 39 Solution: Data and Constructor public class BagOfInt { /** Elements. */ private /*@ spec_public non_null @*/ int[] a; /** Number of active elements in a. */ private /*@ spec_public @*/ int n; //@ public invariant 0 <= n && n <= a.length; /** Initialize to contain input’s elements. */ /*@ assignable a, n; @ ensures n == input.length; @ ensures (\forall int i; 0 <= i && i < n; a[i] == input[i]); @*/ public BagOfInt(/*@ non_null @*/ int[] input);

40 40 Solution: Methods /** Return the multiplicity of i. */ /*@ ensures \result == (\num_of int j; 0 <= j && j < n; a[j] == i); @*/ public /*@ pure @*/ int occurrences(int i); /** Return and delete the minimum element. */ /*@ requires 0 < n; @ assignable n, a, a[*]; @ ensures n == \old(n - 1); @ ensures \result == \old((\min int j; 0 <= j && j < n; a[j])); @ ensures (\forall int j; 0 <= j && j < \old(n); @ (\old(a[j]) != \result ==> @ occurrences(\old(a[j])) == \old(occurrences(a[j]))) || @ (\old(a[j]) == \result ==> @ occurrences(\old(a[j])) == \old(occurrences(a[j]) - 1))); @*/ public int extractMin();

41 41 Exercise Q: What’s wrong with this and how to fix it? Hint: Undefinedness public class ScreenPoint { private /*@ spec_public @*/ int x, y; //@ public invariant 0 <= x && 0 <= y; //@ requires 0 <= cs[0] && 0 <= cs[1]; //@ assignable x, y; //@ ensures x == cs[0] && y == cs[1]; public ScreenPoint(int[] cs) { x = cs[0]; y = cs[1]; }

42 42 Solution A: Undefined expression public class ScreenPoint { private /*@ spec_public @*/ int x, y; //@ public invariant 0 <= x && 0 <= y; //@ requires 2 <= cs.length; //@ requires 0 <= cs[0] && 0 <= cs[1]; //@ assignable x, y; //@ ensures x == cs[0] && y == cs[1]; public ScreenPoint(int[] cs) { x = cs[0]; y = cs[1]; }

43 43 Writing Protective Specifications Clauses evaluated left to right Short-circuit operators can prevent evaluation –G && P, G || P –G ==> P, G <== P Use multiple clauses (equivalent to &&)

44 44 Multiple Specification Cases For different preconditions May overlap Used to specify exceptions Used with specification inheritance 44

45 45 Example private /*@ spec_public @*/ int age; /*@ requires 0 <= a && a <= 150; @ assignable age; @ ensures age == a; @ also @ requires a 150; @ assignable \nothing; @ ensures age == \old(age); @*/ public void setAge(int a) { if (0 <= a && a <= 150) age = a; }

46 46 Semantics of Multiple Cases 46

47 47 Meaning of “also” Rewrite to conjoin (frame must be the same). private /*@ spec_public @*/ int age; /*@ requires 0 <= a && a <= 150; @ assignable age; @ ensures age == a; @ also @ requires a 150; @ assignable \nothing; @ assignable age; @ ensures age == \old(age) && only_assigned(\nothing); @*/ public void setAge(int a) { if (0 <= a && a <= 150) age = a; }

48 48 Meaning of “also” 48 requires (0 150); assignable age; ensures \old(0 (age == a); ensures \old(a 150) ==> (age == \old(age) && \only_assigned(\nothing));

49 49 Views of Multiple Cases Client can verify by: –Picking one spec case Assert precondition Assume frame and postcondition –Picking several cases Compute their join Assert joined precondition Assume frame and joined postcondition Implementor can: –Verify each case, or –Verify their join 49

50 50 Specifying Exceptions Use features such as –exceptional_behavior spec cases –signals_only clause –signals clause

51 51 Example public class Actor { private /*@ spec_public @*/ int age; private /*@ spec_public @*/ int fate; //@ public invariant 0 <= age && age <= fate;

52 52 Example /*@ public normal_behavior @ requires age < fate - 1; @ assignable age; @ ensures age == \old(age+1); @ also @ public exceptional_behavior @ requires age == fate - 1; @ assignable age; @ signals_only DeathException; @ signals (DeathException e) age == fate; @*/ public void older() throws DeathException

53 53 Example /*@ public normal_behavior @ requires age < fate - 1; @ assignable age; @ ensures age == \old(age+1); @ also @ public exceptional_behavior @ requires age == fate - 1; @ assignable age; @ signals_only DeathException; @ signals (DeathException e) age == fate; @*/ public void older() throws DeathException semantics: signals (Exception) false; semantics: ensures false; Lightweight vs. heavyweight specs: \not_specified as default

54 54 Exercise: Using Multiple Cases Specify the 3x + 1 or “hailstone” function, h, such that: h(n) = (3 *n + 1)/2, if n > 0 and is odd n / 2, if n > 0 and is even and h is undefined on negative numbers. (Collatz conjecture: you shall always eventually reach 1 by repeating the process.)

55 55 Solution /*@ requires 0 < n; @ requires n % 2 != 0; @ ensures \result == (3*n+1)/2; @ also @ requires 0 < n; @ requires n % 2 == 0; @ ensures \result == n/2; @*/ public static /*@ pure @*/ int h(int n)

56 56 Solution Using Nesting /*@ requires 0 < n; @ {| requires n % 2 != 0; @ ensures \result == (3*n+1)/2; @ also @ requires n % 2 == 0; @ ensures \result == n/2; @ |} @*/ public static /*@ pure @*/ int h(int n)

57 57 Outline JML overview Reading and writing JML specifications Abstraction in specification Subtyping and specification inheritance 57

58 58 Motivating Example public class SetOfObject { private /*@ spec_public non_null @*/ Object[] a; /** Number of active elements in a. */ private /*@ spec_public @*/ int n; //@ public invariant 0 <= n && n <= a.length; /*@ public invariant @ (\forall int i; 0 <= i && i < n; @ (\forall int j; 0 a[i] != a[j]); @*/ /** Remove the argument from this set. */ public void remove(Object o); Specify the remove method given below. Q: Meaning of the second invariant?

59 59 Solution /*@ requires (\exists int i; 0 <= i && i < n; a[i] == o); @ assignable n, a, a[*]; @ ensures n == \old(n - 1); @ ensures (\forall int i; 0 <= i && i < \old(n); @ (\old(a[i]) == o ==> !(\exists int j; 0 <= j && j < n; a[j] == o) && @ (\old(a[i]) != o ==> (\exists int j; 0 <= j && j < n; a[j] == o); @*/ public void remove(Object o); Long and hard to read and understand! Q: How to know the new set has no other elements?

60 60 Better Solution /*@ requires has(o); @ assignable n, a, a[*]; @ ensures n == \old(n - 1); @ ensures (\forall int i; 0 <= i && i < \old(n); @ (\old(a[i]) == o ==> !has(o)) && @ (\old(a[i]) != o ==> has(o)) @*/ public void remove(Object o); //@ ensures \result == (\exists int i; 0 <= i && i < n; a[i] == o); public /@ pure @*/ void has(Object o); Better but still low level; manipulation of concrete representation

61 61 Solution Using Abstraction public class SetOfObject { //@ public model JMLObjectSet theSet; private Object[] a; //@ in theSet; private int n; //@ in theSet; //@ private represents theSet <- JMLObjectSet.convertFrom(a, n); /*@ requires theSet.has(o); // o  theSet @ assignable theSet; @ ensures theSet.equals(\old(theSet.remove(o))); // theSet’ = theSet – {o} @*/ public void remove(Object o); Abstract specification using model fields (abstract values) Q: Advantages?

62 62 Why Use Abstraction in Specification? Ease maintenance by information hiding Readability: –Avoid quantifiers –Repeated expressions Specify when no fields available –Java “interfaces”

63 63 Features Supporting Abstraction model fields and represents clauses pure model methods pure methods protected invariants, spec cases, etc. private invariants, spec cases, etc. model classes (JMLObjectSet, etc.)

64 64 Model Fields for Data Abstraction Model fields: –Just for specification –Abstraction of Java fields –Value from represents

65 65 Model Field In an Interface public interface Gendered { //@ public model instance String gender; //@ ensures \result == gender.equals("female"); public /*@ pure @*/ boolean isFemale(); } Note a new JML modifier instance because it defaults to static in interfaces.

66 66 Represents Clauses public class Animal implements Gendered { protected boolean gen; //@ in gender; //@ protected represents gender <- (gen ? "female" : "male"); public /*@ pure @*/ boolean isFemale() { return gen; } Use an in clause to specify a data group. Protected represents clause (abstraction function). Specification inheritance.

67 67 Correctness with Model Fields

68 68 Example of Using Model Fields protected boolean gen; //@ in gender; //@ protected represents gender <- (gen ? "female" : "male"); /*@ requires g.equals("female") || g.equals("male"); @ assignable gender; @ ensures gender.equals(g); @*/ public Animal(final String g) { gen = g.equals("female"); } Q: Is Animal’s constructor (below) correct?

69 69 Example of Using Model Fields protected boolean gen; //@ in gender; //@ protected represents gender <- (gen ? "female" : "male"); /*@ requires g.equals("female") || g.equals("male"); @ assignable gender; @ ensures gender.equals(g); @*/ public Animal(final String g) { gen = g.equals("female"); } Q: Is Animal’s constructor (below) correct? Yes!

70 70 Semantics of spec_public protected /*@ spec_public @*/ int age = 0; shorthand for: //@ public model int age; protected int _age = 0; //@ in age; //@ protected represents age <- _age; and rewriting Java code to use _age.

71 71 Data Groups for Assignable Clauses Each field is a data group Membership by in clauses Model field’s group contains fields used in its represents

72 72 Data Groups and Assignable Picture

73 73 The Semantics of Assignable assignable x, y; means: method only assigns to (concrete) members of DG(x)  DG(y). Q: What does “assignable gender;” mean?

74 74 In Clauses for Declarations private T x; //@ in g; –Immediately follows declaration –Same visibility as declaration JML ensures that: –If f  DG(g), then g visible where f is. –If f and g visible, can tell if f  DG(g).

75 75 Type-Level Specification Features Model fields, in, represents invariant initially constraint

76 76 Initially Clauses Hold in constructor post-states Basis for datatype induction import java.util.*; public class Patient extends Person { //@ public invariant 0 <= age && age <= 150; protected /*@ spec_public @*/ List log; //@ public initially log.size() == 0;

77 77 History Constraints Relate pre-states and post-states Justifies inductive step in datatype induction import java.util.*; public class Patient extends Person { protected /*@ spec_public @*/ List log; /*@ public constraint log.size() >= \old(log.size()); @ public constraint (\forall int i; 0 <= i && i < \old(log.size()); @ log.get(i).equals(\old(log.get(i)))); @*/

78 78 Exercise Specify a bounded counter class by writing invariant, initially, and history constraints. Start with an initial value 0. Return to 0 when it reaches the maximum value, 100. public class BoundedCounter { private int value; /** Increment this counter by one. */ public void increment() { …}

79 79 Helper Methods and Constructors A helper method or constructor is: private Exempt from invariants and history constraints –Cannot assume them –Need not establish them

80 80 Outline JML overview Reading and writing JML specifications Abstraction in specification Subtyping and specification inheritance 80

81 81 Problems Duplication of specifications in subtypes Modular verification when use: –Subtyping, and –Dynamic dispatch

82 82 Specification Inheritance Approach Inherit: Instance fields Type specifications –Invariants –Initially clauses –History constraints Instance methods Method specification cases

83 83 Multiple Inheritance Example

84 84 Age, NormalSetAge, and ExceptionalSetAge public interface Age { //@ model instance int age; } public interface NormalSetAge implements Age { /*@ requires 0 <= a && a <= 150; @ assignable age; @ ensures age == a; @*/ public void setAge(int a); } public interface ExceptionalSetAge implements Age { /*@ requires a 150; @ assignable \nothing; @ ensures age == \old(age); @*/ public void setAge(int a); }

85 85 What About Animal’s setAge Method? It’s both. Should obey both specifications.

86 86 Single Inheritance public interface Gendered { //@ ensures \result == gender.equals("female"); public /*@ pure @*/ boolean isFemale(); } public class Animal implements Gendered { public /*@ pure @*/ boolean isFemale() { return gen; } Q: What is the specification of Animal’s isFemale method?

87 87 Adding to Specification in Subtype import java.util.*; public class Patient extends Person { protected /*@ spec_public @*/ boolean ageDiscount = false; //@ in age; /*@ also @ requires (0 150); @ ensures 65 ageDiscount; @*/ public void setAge(final int a) { super.setAge(a); if (65 <= age) { ageDiscount = true; } } Use the “also” keyword.

88 88 Method Specification Inheritance /*@ requires 0 <= a && a <= 150; @ assignable age; @ ensures age == a; @ also @ requires a < 0 || a < 10; @ assignable age; @ ensures age == \old(age); @*/ /*@ also @ requires (0 150); @ ensures 65 ageDiscount; @*/ Q: What is the extended specification of Patient’s setAge method? A: The join of the 3 spec cases shown previously /*@ requires 0 <= a && a <= 150; @ assignable age; @ ensures age == a; @ also @ requires a < 0 || a < 10; @ assignable age; @ ensures age == \old(age); @*/ /*@ also @ requires (0 150); @ ensures 65 ageDiscount; @*/ Q: What is the extended specification of Patient’s setAge method? A: The join of the 3 spec cases shown previously

89 89 Avoiding Duplication of Preconditions /*@ requires 0 <= a && a <= 150; @ assignable age; @ ensures age == a; @ also @ requires a < 0 || a < 10; @ assignable age; @ ensures age == \old(age); @*/ /*@ also @ requires \same; @ ensures 65 ageDiscount; @*/ Use \same in the requires clause

90 90 Outline JML overview Reading and writing JML specifications Abstraction in specification Subtyping and specification inheritance 90


Download ppt "111 The Java Modeling Language Based on: Gary T. Leavens, et al., JML Tutorial at OOPSLA 2009. Gary. T Leavens, et al., Preliminary Design of JML: A Behavioral."

Similar presentations


Ads by Google