Download presentation
Presentation is loading. Please wait.
1
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.
2
Outline JML overview Reading and writing JML specifications
Abstraction in specification Subtyping and specification inheritance 2 2 2
3
Overview of JML Java Modeling Language (JML) JML’s goals 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 3 3
4
Basic Approach of JML “Eiffel + Larch for Java”
Hoare-style (contracts) Method pre- and post-conditions Invariants 4 4 4
5
First JML Specification
public class ArrayOps { private Object[] a; public invariant 0 < a.length; requires 0 < arr.length; @ ensures this.a == arr; @*/ public void init(Object[] arr) { this.a = arr; } 5 5 5
6
Field Specification with spec_public
public class ArrayOps { private Object[] a; public invariant 0 < a.length; requires 0 < arr.length; @ ensures this.a == arr; @*/ public void init(Object[] arr) { this.a = arr; } 6 6 6
7
Class Invariant public class ArrayOps {
private Object[] a; public invariant 0 < a.length; requires 0 < arr.length; @ ensures this.a == arr; @*/ public void init(Object[] arr) { this.a = arr; } 7 7 7
8
Method Specification public class ArrayOps {
private Object[] a; public invariant 0 < a.length; requires 0 < arr.length; @ ensures this.a == arr; @*/ public void init(Object[] arr) { this.a = arr; } 8 8 8
9
Interface Specification
JML Specification Syntactic Interface Functional Behavior Java Code 9
10
Interface Specification
requires 0 < arr.length; @ ensures this.a == public void init(Object[] arr); requires 0 < arr.length; ensures this.a == arr; public void init(Object[] arr); public void init(Object[] arr) { this.a = arr; } 10
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 11
12
Many Tools, One Language
12
13
How JML Tools Complement Each Other
Different strengths: Runtime checking — real errors Static checking — better coverage Verification — guarantees Usual ordering: Runtime checker (jmlc and jmlunit) Extended Static Checking (ESC/Java2) Verification tool (e.g., KeY, JACK, Jive) 13
14
Outline JML overview Reading and writing JML specifications
Abstraction in specification Subtyping and specification inheritance 14 14 14
15
JML Annotations Not Java annotations (starting with @)
JML annotation comments Line starting with Between starting lines 15
16
Most Important JML Keywords
Top-level in classes and interfaces: invariant spec_public nullable For methods and constructors: requires ensures assignable pure 16
17
Example: BoundedStack
Specify bounded stacks of objects Steps Data and invariant Constructor Methods like push, pop, and top 17
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 != null @ && (\forall int i; @ size <= i && i < elems.length; @ elems[i] == null); @*/ Nullable for elems itself or its elements? size <= elems.length? 18
19
BoundedStack’s Constructor
requires 0 < n; @ assignable elems; @ ensures elems.length == n; @*/ public BoundedStack(int n) { elems = new Object[n]; } 19
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++; } 20
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; } 21
22
BoundedStack’s top Method
requires 0 < size; @ assignable \nothing; @ ensures \result == elems[size - 1]; @*/ public Object top() { return elems[size – 1]; } 22
23
JML Keywords Used spec_public nullable invariant must be:
Public visibility Only 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) 23
24
JML Keywords Used requires clause: ensures clause: Precondition
Obligation on callers, after parameter passing Assumed by implementor ensures clause: Postcondition Obligation on implementor, at return Assumed by caller 24
25
Semantics of requires and ensures
25
26
Semantics of requires and ensures
26
27
Semantics of requires and ensures
27
28
JML Keywords Used (Cont.)
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 28
29
Assignable Is a Shorthand
assignable gender; ensures gender.equals(g); means ensures \only_assigned(gender) && gender.equals(g); 29
30
JML Keywords Used (Cont.)
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. 30
31
Multiple Clauses Semantics: is equivalent to:
requires P; requires Q; is equivalent to: requires P && Q; Similarly for ensures, invariant. Note: checkers give more specific messages with multiple clauses. 31
32
Defaults for Omitted Clauses
invariant true; requires true; assignable \everything; ensures true; 32
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} … 33
34
Steps for Specifying a Type for Public Clients
Specify data (spec_public fields) Specify a public invariant Specify each public method using: requires assignable (or pure) ensures 34
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; 35
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; 36
37
Solution /** Return a 1-based position of given object in this stack. */ ensures (\exists int i; i >= 0 && i < size; elems[i] == o) ? \result > 0 && \result <= size && elems[\result - 1] == 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; 37
38
Exercise: BagOfInt Specify the following. public class BagOfInt {
private int[] a; private int n; // number of elements contained in a /** Initialize to contain input’s elements. */ public BagOfInt(int[] input); /** Return the multiplicity of i. */ public int occurrences(int i); // Hint: use (\num_of T x, P; Q) /** Return and delete the minimum element. */ public int extractMin(); } 38
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, n; @ ensures n == input.length; @ ensures (\forall int i; 0 <= i && i < n; a[i] == public int[] input); non_null for int array? 39
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 n > 0; @ 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(); 40
41
Thought: Using Java 8 Streams
Problem JML quantifiers (\forall and \exists) for arrays and collections Low level assertions (long and less readable), e.g., (\exists int i; i >= 0 && i < size; elems[i] == obj) High-level abstractions like OCL collection iterators? Use Java 8 streams and lambda expressions E.g., Stream.of(elems).matchAny(e -> e == obj) Concise and more readable assertions Refer to Java 8 Stream API Q: Effectiveness and comparison with OCL? 41
42
Java 8 Stream API boolean allMatch(predicate)
boolean anyMatch(predicate) boolean nonMatch(predicate) Stream<T> filter(predicate) Stream<R> map(mapper) Stream<R> flatMap(mapper) Optional<T> reduce(identity, accumulator) Optional<T> reduce(identity, accumulator, combiner) Optional<T> findAny() Optional<T> findFirst() Optional<T> max(comparator) Optional<T> min(comparator) … 42
43
Example: Ship public class Ship {
Place 0..1 0..* public class Ship { private final List<Place> places; // Q: Meaning? why? sufficient? public invariant (\forall int i; 0 <= i && i < places.size(); @ places.get(i).getShip() == this); @*/ public invariant places.stream().matchAll(p -> p.getShip() == this); // Q: A row of consecutive places, either horizontally or vertically? 43
44
Question for You 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]; } 44
45
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]; } 45
46
Writing Protective Specifications
Clauses evaluated left to right Short-circuit operators can prevent evaluation G && P, G || P G ==> P, G <== P (implication and backward implication) Use multiple clauses (equivalent to &&) 46
47
Multiple Specification Cases
For different preconditions May overlap Used to specify exceptions Used with specification inheritance 47
48
Example private /*@ spec_public @*/ int age;
requires 0 <= a && a <= 150; @ assignable age; @ ensures age == a; @ also @ requires a < 0 || a > 150; @ assignable \nothing; @ ensures age == \old(age); @*/ public void setAge(int a) { if (0 <= a && a <= 150) age = a; } 48
49
Semantics of Multiple Cases
49
50
Meaning of “also” Rewrite to conjoin (frame must be the same).
private int age; requires 0 <= a && a <= 150; @ assignable age; @ ensures age == a; @ also @ requires a < 0 || a > 150; @ assignable \nothing; @ ensures age == \old(age) && only_assigned(\nothing); @*/ public void setAge(int a) { if (0 <= a && a <= 150) age = a; } 50
51
Meaning of “also” requires (0 <= a && a <= 150) || (a < 0 || a > 150); assignable age; ensures \old(0 <= a && a <= 150) ==> (age == a); ensures \old(a < 0 || a > 150) ==> (age == \old(age) && \only_assigned(\nothing)); 51
52
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 52
53
Specifying Exceptions
Use features such as exceptional_behavior spec cases signals_only clause signals clause
54
Example public class Actor { private /*@ spec_public @*/ int age;
private int fate; public invariant 0 <= age && age <= fate; 54
55
Example /*@ public normal_behavior @ requires age < fate - 1;
@ assignable age; @ ensures age == \old(age+1); @ also @ public exceptional_behavior @ requires age == fate - 1; @ signals_only DeathException; @ signals (DeathException e) age == fate; @*/ public void older() throws DeathException 55
56
signals (Exception) false;
Example public normal_behavior @ requires age < fate - 1; @ assignable age; @ ensures age == \old(age+1); @ also @ public exceptional_behavior @ requires age == fate - 1; @ 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
57
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.) 57
58
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 int h(int n) 58
59
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 int h(int n) 59
60
Exercise: Ship Specify the addPlace() method. public class Ship {
0..1 0..* Specify the addPlace() method. public class Ship { private final List<Place> places; /** Append the given place to the list of places on which this ship is placed. */ public void addPlace(Place place) { if (!places.contains(place)) { places.add(place); } if (place.ship() != this) { place.placeShip(this); } } public class Place { private spec_public Ship ship; 60
61
Outline JML overview Reading and writing JML specifications
Abstraction in specification Subtyping and specification inheritance 61 61 61
62
Motivating Example Specify the remove method given below.
Q: Meaning of the second invariant? 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 invariant @ (\forall int i; 0 <= i && i < n; @ (\forall int j; 0 <= j && j < n; i != j ==> a[i] != /** Remove the argument from this set. */ public void remove(Object o); non_null for int array? 62
63
Solution Q: How to know the new set has no other elements?
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! Implementation details exposed! 63
64
Better but still low level; manipulation of concrete representation
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 void has(Object o); Better but still low level; manipulation of concrete representation 64
65
Need to rewrite all assertions!
Another Problem Q: What happens if a representation is changed? public class SetOfObject { private spec_public Object[] a; ArrayList<Object> list; /** Number of active elements in a. */ private int n; public invariant 0 <= n && n <= a.length; public invariant @ (\forall int i; 0 <= i && i < n; @ (\forall int j; 0 <= j && j < n; i != j ==> a[i] != /** Remove the argument from this set. */ public void remove(Object o); Need to rewrite all assertions! non_null for int array? 65
66
Writing Abstract Specification: Key Idea
public T m; abstract state (representation) requires Q(m); public void remove(Object o); <<use>> abstraction function m = f(a, n) Evaluation: Q(f(a,n)) non_null for int array? private Object[] a; private int n; <<use>> requires P(a, n); public void remove(Object o); concrete state (representation)
67
Solution Using Abstraction
Abstract specification using model fields (abstract values) Q: Advantages? 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); Model field Data group Abstraction function non_null for int array?
68
Why Use Abstraction in Specification?
Ease of maintenance by information hiding Readability: Avoid quantifiers Repeated expressions Specify when no fields available Java “interfaces”
69
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.)
70
Model Fields for Data Abstraction
Just for specification Abstraction of Java fields Value from represents
71
Model Methods Q: What’s wrong with the following specification and how to fix it? Ship Place 0..1 0..* public class Ship { private final List<Place> places; ensures \result == places; public Iterable places() { return places; } 71
72
Model Methods (Cont.) public class Ship {
private final List<Place> places; ensures \result == places; ensures toList(\result).equals(places); public Iterable<Place> places() { … } public static pure model <T> List<T> toList(Iterable<T> iter) { @ ArrayList<List> result = new ArrayList<>(); @ for(T t: iter) { @ result.add(t); @ } @ return result; @ } @*/ } 72
73
Exercise: Stack Revisited
Rewrite the specification of BoundedStack using model fields. public class BoundedStack { private Object[] elems; private int size; // num of elems contained public BoundedStack(int capacity) { … } public void push(Object o) { … } public void pop() { … } public Object top() { … } public int search(Object o) { … } … } non_null for int array?
74
Model Fields In Interfaces
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.
75
Represents Clauses Use an in clause to specify a data group.
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.
76
Correctness with Model Fields
77
Example of Using Model Fields
Q: Is Animal’s constructor (below) correct? protected boolean gen; in gender; protected represents gender <- (gen ? "female" : "male"); requires g.equals("female") || g.equals("male"); @ assignable gender; @ ensures public Animal(final String g) { gen = g.equals("female"); }
78
Example of Using Model Fields
Q: Is Animal’s constructor (below) correct? protected boolean gen; in gender; protected represents gender <- (gen ? "female" : "male"); requires g.equals("female") || g.equals("male"); @ assignable gender; @ ensures public Animal(final String g) { gen = g.equals("female"); } Yes!
79
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.
80
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
81
Data Groups and Assignable Picture
82
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?
83
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).
84
Type-Level Specification Features
Model fields, in, represents invariant initially constraint
85
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;
86
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() >= \old(log.size()); @ public constraint (\forall int i; 0 <= i && i < \old(log.size()); @ log.get(i).equals(\old(log.get(i)))); @*/
87
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() { …}
88
Helper Methods and Constructors
A helper method or constructor is: private Exempt from invariants and history constraints Cannot assume them Need not establish them
89
Outline JML overview Reading and writing JML specifications
Abstraction in specification Subtyping and specification inheritance 89 89 89
90
Problems Duplication of specifications in subtypes
Modular verification when use: Subtyping, and Dynamic dispatch
91
Specification Inheritance Approach
Instance fields Type specifications Invariants Initially clauses History constraints Instance methods Method specification cases
92
Multiple Inheritance Example
93
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 == public void setAge(int a); public interface ExceptionalSetAge implements Age { requires a < 0 || a > 150; @ assignable \nothing; @ ensures age ==
94
What About Animal’s setAge Method?
It’s both. Should obey both specifications.
95
Single Inheritance Q: What is the specification of Animal’s isFemale method? public interface Gendered { ensures \result == gender.equals("female"); public boolean isFemale(); } public class Animal implements Gendered { public boolean isFemale() { return gen;
96
Adding to Specification in Subtype
Use the “also” keyword. import java.util.*; public class Patient extends Person { protected boolean ageDiscount = false; in age; also @ requires (0 <= a && a <= 150) || (a < 0 || a > 150); @ ensures 65 <= age ==> public void setAge(final int a) { super.setAge(a); if (65 <= age) { ageDiscount = true; } }
97
Method Specification Inheritance
Q: What is the extended specification of Patient’s setAge method? A: The join of the 3 spec cases shown previously 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; @ ensures age == also @ requires (0 <= a && a <= 150) || (a < 0 || a > 150); @ ensures 65 <= age ==> requires 0 <= a && a <= 150; @ assignable age; @ ensures age == a; @ also @ requires a < 0 || a < 10; @ ensures age == also @ requires (0 <= a && a <= 150) || (a < 0 || a > 150); @ ensures 65 <= age ==>
98
Avoiding Duplication of Preconditions
Use \same in the requires clause requires 0 <= a && a <= 150; @ assignable age; @ ensures age == a; @ also @ requires a < 0 || a < 10; @ ensures age == also @ requires \same; @ ensures 65 <= age ==>
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.