111 The Java Modeling Language Based on: Gary T. Leavens, et al., JML Tutorial at OOPSLA 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,
222 Outline JML overview Reading and writing JML specifications Abstraction in specification Subtyping and specification inheritance 2
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
444 Basic Approach of JML “Eiffel + Larch for Java” Hoare-style (contracts) Method pre- and post-conditions Invariants 4
555 First JML Specification public class ArrayOps { private Object[] a; public invariant 0 < a.length; requires 0 < ensures this.a == public void init(Object[] arr) { this.a = arr; } 5
666 Field Specification with spec_public public class ArrayOps { private Object[] a; public invariant 0 < a.length; requires 0 < ensures this.a == public void init(Object[] arr) { this.a = arr; } 6
777 Class Invariant public class ArrayOps { private Object[] a; public invariant 0 < a.length; requires 0 < ensures this.a == public void init(Object[] arr) { this.a = arr; } 7
888 Method Specification public class ArrayOps { private Object[] a; public invariant 0 < a.length; requires 0 < ensures this.a == public void init(Object[] arr) { this.a = arr; } 8
99 Interface Specification Java Code JML Specification Functional Behavior Syntactic Interface
10 Interface Specification public void init(Object[] arr) { this.a = arr; } requires 0 < ensures this.a == public void init(Object[] arr); requires 0 < arr.length; ensures this.a == arr; public void init(Object[] arr);
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 Many Tools, One Language
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 Outline JML overview Reading and writing JML specifications Abstraction in specification Subtyping and specification inheritance 14
15 JML Annotations Not Java annotations (starting JML annotation comments –Line starting with –Between starting lines
16 Most Important JML Keywords Top-level in classes and interfaces: –invariant –spec_public –nullable For methods and constructors: –requires –ensures –assignable –pure
17 Example: BoundedStack Specify bounded stacks of objects Steps 1.Data and invariant 2.Constructor 3.Methods like push, pop, and top
18 BoundedStack’s Data and Invariant public class BoundedStack { private spec_public Object[] elems; private int size = 0; public invariant 0 <= size; public invariant elems != && (\forall int size <= i && i < elems[i] ==
19 BoundedStack’s Constructor requires 0 < assignable ensures elems.length == public BoundedStack(int n) { elems = new Object[n]; }
20 BoundedStack’s push Method requires size < elems.length - assignable elems[size], ensures size == \old(size + ensures elems[size - 1] == (\forall int i; 0 <= i && i < size - 1; elems[i] == public void push(Object x) { elems[size] = x; size++; }
21 BoundedStack’s pop Method requires 0 < assignable size, elems[size - ensures size == \old(size - elems[size] == null (\forall int i; 0 <= i && i < size - 1; elems[i] == public void pop() { size--; elems[size] = null; }
22 BoundedStack’s top Method requires 0 < assignable ensures \result == elems[size - public void top() { return elems[size – 1]; }
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 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 Semantics of requires and ensures
26 Semantics of requires and ensures
27 Semantics of requires and ensures
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 Assignable Is a Shorthand assignable gender; ensures gender.equals(g); means ensures \only_assigned(gender) && gender.equals(g);
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 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 Defaults for Omitted Clauses invariant true; requires true; assignable \everything; ensures true;
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 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 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 Object[] elems; private int size = 0;
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 Object[] elems; private int size = 0;
37 Solution ensures (\exists int i; i >= 0 && i < size; elems[i] == o) ? \result > 0 && \result <= size && elems[\result] == o : \result == public pure int search(Object o) { …} Q: the first (or last) from the top? private spec_public Object[] elems; private int size = 0;
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 Solution: Data and Constructor public class BagOfInt { /** Elements. */ private spec_public int[] a; /** Number of active elements in a. */ private int n; public invariant 0 <= n && n <= a.length; /** Initialize to contain input’s elements. */ assignable a, ensures n == ensures (\forall int i; 0 <= i && i < n; a[i] == public int[] input);
40 Solution: Methods /** Return the multiplicity of i. */ ensures \result == (\num_of int j; 0 <= j && j < n; a[j] == public int occurrences(int i); /** Return and delete the minimum element. */ requires 0 < assignable n, a, ensures n == \old(n - ensures \result == \old((\min int j; 0 <= j && j < n; ensures (\forall int j; 0 <= j && j < (\old(a[j]) != \result occurrences(\old(a[j])) == \old(occurrences(a[j]))) (\old(a[j]) == \result occurrences(\old(a[j])) == \old(occurrences(a[j]) - public int extractMin();
41 Exercise Q: What’s wrong with this and how to fix it? Hint: Undefinedness public class ScreenPoint { private 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 Solution A: Undefined expression public class ScreenPoint { private 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 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 Multiple Specification Cases For different preconditions May overlap Used to specify exceptions Used with specification inheritance 44
45 Example private int age; requires 0 <= a && a <= assignable ensures age == requires a assignable ensures age == public void setAge(int a) { if (0 <= a && a <= 150) age = a; }
46 Semantics of Multiple Cases 46
47 Meaning of “also” Rewrite to conjoin (frame must be the same). private int age; requires 0 <= a && a <= assignable ensures age == requires a assignable assignable ensures age == \old(age) && public void setAge(int a) { if (0 <= a && a <= 150) age = a; }
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 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 Specifying Exceptions Use features such as –exceptional_behavior spec cases –signals_only clause –signals clause
51 Example public class Actor { private int age; private int fate; public invariant 0 <= age && age <= fate;
52 Example public requires age < fate - assignable ensures age == public requires age == fate - assignable signals_only signals (DeathException e) age == public void older() throws DeathException
53 Example public requires age < fate - assignable ensures age == public requires age == fate - assignable signals_only signals (DeathException e) age == public void older() throws DeathException semantics: signals (Exception) false; semantics: ensures false; Lightweight vs. heavyweight specs: \not_specified as default
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 Solution requires 0 < requires n % 2 != ensures \result == requires 0 < requires n % 2 == ensures \result == public static int h(int n)
56 Solution Using Nesting requires 0 < {| requires n % 2 != ensures \result == requires n % 2 == ensures \result == public static int h(int n)
57 Outline JML overview Reading and writing JML specifications Abstraction in specification Subtyping and specification inheritance 57
58 Motivating Example public class SetOfObject { private spec_public Object[] a; /** Number of active elements in a. */ private int n; public invariant 0 <= n && n <= a.length; public (\forall int i; 0 <= i && i < (\forall int j; 0 a[i] != /** Remove the argument from this set. */ public void remove(Object o); Specify the remove method given below. Q: Meaning of the second invariant?
59 Solution requires (\exists int i; 0 <= i && i < n; a[i] == assignable n, a, ensures n == \old(n - ensures (\forall int i; 0 <= i && i < (\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] == public void remove(Object o); Long and hard to read and understand! Q: How to know the new set has no other elements?
60 Better Solution requires assignable n, a, ensures n == \old(n - ensures (\forall int i; 0 <= i && i < (\old(a[i]) == o ==> !has(o)) (\old(a[i]) != o ==> public void remove(Object o); ensures \result == (\exists int i; 0 <= i && i < n; a[i] == o); public void has(Object o); Better but still low level; manipulation of concrete representation
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 assignable ensures theSet.equals(\old(theSet.remove(o))); // theSet’ = theSet – public void remove(Object o); Abstract specification using model fields (abstract values) Q: Advantages?
62 Why Use Abstraction in Specification? Ease maintenance by information hiding Readability: –Avoid quantifiers –Repeated expressions Specify when no fields available –Java “interfaces”
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 Model Fields for Data Abstraction Model fields: –Just for specification –Abstraction of Java fields –Value from represents
65 Model Field In an Interface public interface Gendered { public model instance String gender; ensures \result == gender.equals("female"); public boolean isFemale(); } Note a new JML modifier instance because it defaults to static in interfaces.
66 Represents Clauses public class Animal implements Gendered { protected boolean gen; in gender; protected represents gender <- (gen ? "female" : "male"); public boolean isFemale() { return gen; } Use an in clause to specify a data group. Protected represents clause (abstraction function). Specification inheritance.
67 Correctness with Model Fields
68 Example of Using Model Fields protected boolean gen; in gender; protected represents gender <- (gen ? "female" : "male"); requires g.equals("female") || assignable ensures public Animal(final String g) { gen = g.equals("female"); } Q: Is Animal’s constructor (below) correct?
69 Example of Using Model Fields protected boolean gen; in gender; protected represents gender <- (gen ? "female" : "male"); requires g.equals("female") || assignable ensures public Animal(final String g) { gen = g.equals("female"); } Q: Is Animal’s constructor (below) correct? Yes!
70 Semantics of spec_public protected 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 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 Data Groups and Assignable Picture
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 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 Type-Level Specification Features Model fields, in, represents invariant initially constraint
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 List log; public initially log.size() == 0;
77 History Constraints Relate pre-states and post-states Justifies inductive step in datatype induction import java.util.*; public class Patient extends Person { protected List log; public constraint log.size() >= public constraint (\forall int i; 0 <= i && i <
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 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 Outline JML overview Reading and writing JML specifications Abstraction in specification Subtyping and specification inheritance 80
81 Problems Duplication of specifications in subtypes Modular verification when use: –Subtyping, and –Dynamic dispatch
82 Specification Inheritance Approach Inherit: Instance fields Type specifications –Invariants –Initially clauses –History constraints Instance methods Method specification cases
83 Multiple Inheritance Example
84 Age, NormalSetAge, and ExceptionalSetAge public interface Age { model instance int age; } public interface NormalSetAge implements Age { requires 0 <= a && a <= assignable ensures age == public void setAge(int a); } public interface ExceptionalSetAge implements Age { requires a assignable ensures age == public void setAge(int a); }
85 What About Animal’s setAge Method? It’s both. Should obey both specifications.
86 Single Inheritance public interface Gendered { ensures \result == gender.equals("female"); public boolean isFemale(); } public class Animal implements Gendered { public boolean isFemale() { return gen; } Q: What is the specification of Animal’s isFemale method?
87 Adding to Specification in Subtype import java.util.*; public class Patient extends Person { protected boolean ageDiscount = false; in age; requires (0 ensures 65 public void setAge(final int a) { super.setAge(a); if (65 <= age) { ageDiscount = true; } } Use the “also” keyword.
88 Method Specification Inheritance requires 0 <= a && a <= assignable ensures age == requires a < 0 || a < assignable ensures age == requires (0 ensures 65 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 <= assignable ensures age == requires a < 0 || a < assignable ensures age == requires (0 ensures 65 Q: What is the extended specification of Patient’s setAge method? A: The join of the 3 spec cases shown previously
89 Avoiding Duplication of Preconditions requires 0 <= a && a <= assignable ensures age == requires a < 0 || a < assignable ensures age == requires ensures 65 Use \same in the requires clause
90 Outline JML overview Reading and writing JML specifications Abstraction in specification Subtyping and specification inheritance 90