The Java Modeling Language

Software Fiável

Mestrado em Engenharia Informática Mestrado em Informática Faculdade de Ciências da Universidade de Lisboa

2015/2016

Vasco T. Vasconcelos, Antónia Lopes

Software Fiável The Java Modeling Language Contracts

I The key ingredient of , software design methodology promoted by Bertrand Meyer and the Eiffel programming language in 1986. I Inspired by assertions of , contracts place special obligations on both clients and suppliers of a procedure or method.

I What does a method require from it’s caller? I What does the method ensure?

Software Fiável The Java Modeling Language DBC

DBC key idea is to associate a specification with every software element. These specifications (or contracts) govern the interaction of the element with the rest of the world.

I Forces the programmer to write exactly what the method does and needs

I No need to program defensively (defensive checks can be exensive and increases the complexity of the code of the method and worsen its maintainability)

I Assigns blame: specifies who is to blame for not keeping the contract

I Provides a standard way to document classes: client programmers are provided with a proper description of the interface properties of a class that is stripped of all implementation information but retains the essential usage information: the contract.

Software Fiável The Java Modeling Language Language support for Contracts

Language support for contracts exists in different forms:

I Eiffel is an object-oriented language that includes contracts

I JML adds contracts to the Java language. JML specifications are conventional Java boolean expressions, with a few extensions

I Spec# adds contracts to C#

I Code Contracts is an API (part of .NET) to author contracts In this course we focus on JML.

Software Fiável The Java Modeling Language JML Contracts by example

/∗@ @ r e q u i r e s n >= 0 ; @ ensures \ r e s u l t ∗ \ r e s u l t <= n ; @ ensures n < (\ r e s u l t + 1) ∗ (\ r e s u l t + 1 ) ; @∗/ i n t i n t S q r t ( i n t n )

requires says what must be true to call intSqrt (); specifies the client’s obligation ensures says what must be true when intSqrt () terminates; specifies the implementer’s obligations

Software Fiável The Java Modeling Language Overview Flavor Overview Flavor

ManyJML: Many Tools, tools, One one language Language How Tools Complement Each Other

Different strengths: Runtime checking — real errors. Static checking — better coverage. Warnings JML Annotated Java Verification — guarantees. ESC/Java2 public class ArrayOps { Usual ordering: jmldoc private /*@ spec_public @*/ Object[] a; //@ public invariant 0 < a.length; 1 Runtime checker (jmlc and jmlunit). Web pages /*@ requires 0 < arr.length; @ ensures this.a == arr; Daikon 2 @*/ Extended Static Checking (ESC/Java2). jmlunit public void init(Object[] arr) { this.a = arr; Data trace file 3 } Verification tool (e.g., KeY, JACK, Jive). Unit tests }

jmlc Bogor JACK, Jive, Krakatoa, KeY, LOOP Class file Model checking Correctness proof XVP

[Picture by G. Leavens] Software Fiável The Java Modeling Language

Gary T. Leavens (ISU UCF) JML Tutorial CAV 2007 18 / 225 Gary T. Leavens (ISU UCF) JML Tutorial CAV 2007 19 / 225 → →

Overview Interest Overview Interest Interest in JML Advantages of Working with JML

Many tools. Reuse language design. State of the art language. Ease communication with researchers. Large and open research community: Share customers. 23 groups, worldwide. Over 135 papers. Join us! See jmlspecs.org

Gary T. Leavens (ISU UCF) JML Tutorial CAV 2007 20 / 225 Gary T. Leavens (ISU UCF) JML Tutorial CAV 2007 21 / 225 → → Runtime Verification

I The most obvious way to use JML annotations is to test them at runtime and report any detected violations I jmlrac, a runtime assertion checker, was the first tool for JML, developed together with jmlc, the compiler of Java code annotated with JML

I jmlc compiles Java programs annotated with JML specifications into Java bytecode. Compiled bytecode includes instructions that check JML specifications I jmlrac a wrapper for java that knows about the necessary runtime libraries for runtime assertion checking

I The fact that JML was developed having runtime assertion checking in mind lead to some design decisions in the language

I Slightly different variants of JML were considered by other tools

Software Fiável The Java Modeling Language Runtime Verification

I When jmlrac is used to run a Java program (compiled with jmlc)

I it runs slower and uses more memory I it halts when any JML contract is violated

I False negatives are possible only if JML assertions that specify invariants are also used.

I But the runtime assertion checker can fail to report assertions that might be false (it is acceptable for the runtime assertion checker to not execute some parts of assertions, especially in )

Software Fiável The Java Modeling Language Runtime Verification

I Typically, the runtime assertion checker will not be used in production. I There are several benefits with respect to conventional testing:

I more properties are tested, at more points in time and providing better feedback I some test code is generated automatically I less time is needed to think about what to test I assertions are useful for other purposes namely program documentation I unlike documentation written in a natural language, assertions can be mechanically checked to agree with the program text (a common problem with informal documentation)

I Runtime verification is limited by the execution paths exercised by the test suite being used and, hence, does not establishes the correctness for all possible execution paths!

Software Fiável The Java Modeling Language JML assertions

I JML assertions are boolean valued Java expressions inserted in special comments: /∗@ assertion goes here; ∗/ or //@ assertion goes here;

I Assertions cannot have side-effects. This both allows assertion checks to be used safely during debugging and supports mathematical reasoning about assertions.

I Do not forget the semicolon at the end of the assertion!

Software Fiável The Java Modeling Language Multiple clauses

I Clauses r e q u i r e s P; r e q u i r e s Q; are equivalent to r e q u i r e s P && Q;

I Similarly for ensures and invariant

I Runtime checker gives better feedback with multiple clauses

Software Fiável The Java Modeling Language

I The requires clause states the conditions under which the method is defined

I It is needed if the method is partial, ie., if the behavior is not defined on some inputs

I If the method is total, ie., if the behavior is defined on all (type correct) inputs, then the is true

I Clauses of the form requires true can be omitted

Software Fiável The Java Modeling Language Postconditions

I The ensures clause describes the behavior of the method for all inputs not ruled out by the requires clause

I It must define what outputs are produced and also what modifications are made to the inputs

I The ensures clause is written under the assumption that the requires clause is satisfied, and says nothing about the method’s behavior when the requires clause is not satisfied

I Clauses of the form ensures true can be omitted

Software Fiável The Java Modeling Language Extensions to the language of Java expressions

Expression Meaning \result method’s return value \old(E) pre-state value of expression 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) P{E | x ∈ T ∧ P} (\num_of T x; P; Q) P{1 | x ∈ T ∧ P ∧ Q} P <==> Q P == Q, lower priority than == P ==> Q !P || Q

Software Fiável The Java Modeling Language Using forall

I Use the second element of the forall to specify the range of the array index. The array is sorted: (\ f o r a l l i n t i; 1< i && i < a.length; a [ i −1] < a [ i ] ) ;

I Use the second element of the forall to specify a predicate over the elements of a collection. All elements in a collection c of Strings start with letter A. (\ f o r a l l String s; c.contains(s); s.startsWith("A"));

Software Fiável The Java Modeling Language Rights and obligations in contracts

/∗@ @ r e q u i r e s n >= 0 ; @ ensures \ r e s u l t ∗ \ r e s u l t <= n ; @ ensures n < (\ r e s u l t + 1) ∗ (\ r e s u l t + 1 ) ; @∗/ i n t i n t S q r t ( i n t n )

Obligation Right Client Provide non-negative Get a square root ap- n proximation of the re- sult Implementer Compute and return a Assume that n is non- square root negative

Software Fiável The Java Modeling Language Blame assignment in contracts

Assertion violation Blame Precondition The client, the caller (intSqrt () has not even started to run) The supplier, the code of intSqrt () (and the methods that it calls)

Software Fiável The Java Modeling Language Design by Contract and Hoare logic

I The triple below says “if x ≥ 0 and S terminates, then result 2 ≤ x < (result + 1)2 holds”

{x ≥ 0} S {result2 ≤ x < (result + 1)2}

I The contract below says “It is an error to call the method intSqrt with x < 0” //@ r e q u i r e s x >= 0 ; i n t i n t S q r t ( i n t x )

Software Fiável The Java Modeling Language Design by Contract and Hoare logic

I The triple below says “if x ≥ 0 and S terminates, then result 2 ≤ n < (result + 1)2 holds”

{x ≥ 0} S {result2 ≤ n < (result + 1)2}

I The contract below says “If the method intSqrt was called with x ≥ 0 then it is an error to return an integer that does not satisfy result 2 ≤ x < (result + 1)2 ” //@ r e q u i r e s x >= 0 ; //@ ensures \ r e s u l t ∗ \ r e s u l t <= x ; //@ ensures x < (\ r e s u l t +1) ∗ (\ r e s u l t +1); i n t i n t S q r t ( i n t x )

Software Fiável The Java Modeling Language Practical issues

/∗@ @ r e q u i r e s (\ f o r a l l i n t i; 1< i && i < a.length; @ a [ i −1] < a [ i ] ) ; @ ensures \ r e s u l t == −1 | | a [ \ r e s u l t ] == x ; @∗/ i n t binarySearch ( i n t [ ] a , i n t x )

I The order of the terms in the post-condition is important; the following post-condition does not work; why? ensures a [ \ r e s u l t ] == x | | \ r e s u l t == −1;

I Checking the precondition costs a time linear to the size of the array, but the binary search routine is expected to run in logarithmic time

Software Fiável The Java Modeling Language Type Specifications

I So far we have seen how JML annotations can be used in the specification of procedures (static methods)

I JML can also be used to specify abstract data types (ADTs) I This can be achieved making use of additional mechanisms, namely

I Invariants: properties that have to hold in all visible states I Assignable clause: to express frame conditions I Model fields: fields declared for specification purpose only I ... I Different strategies exist:

I Property-based specifications I Representation-exposing specifications I Model-based specifications

Software Fiável The Java Modeling Language Property-based specifications

I The meaning of a type should not be given by any of its implementations

I Most of the specification consists on explaining what the operations on the objects of the type do

I We start with a specification technique known as Property-based specification

I Basically, we divide methods in observers and mutators; observers have no postconditions; mutators have postconditions described in terms of the observers

I We use the example of a simple bank account to explain the method

Software Fiável The Java Modeling Language Observers and pure methods

public class BankAccount { p u b l i c /∗@ pure @∗/ i n t b a l a n c e ( ) ... }

I balance() is an observer, returns information about the state of the method but does not change the state

I In order to be used in JML assertions we must declare it as pure, meaning “does not change the state of the computation or perform any I/O”

I Observers are usually defined on all object states (but not necessarily on all inputs)

I Postconditions for constructors and mutator methods are defined based on the observers

I For the simple bank account we elect balance() as the only observer

Software Fiável The Java Modeling Language Constructors

public class BankAccount { ... /∗@ @ ensures balance() == 0; @∗/ p u b l i c BankAccount () {...} /∗@ @ r e q u i r e s initialBalance >= 0; @ ensures balance() == initialBalance; @∗/ p u b l i c BankAccount ( i n t initialBalance) {...} ... }

I Constructors (a particular case of mutators) initialize newly created objects I Postconditions should mention the impact on the object’s observer(s)

Software Fiável The Java Modeling Language More mutators

public class BankAccount { ... /∗@ @ r e q u i r e s amount > 0 ; @ r e q u i r e s balance() >= amount; @ ensures balance() == \ old (balance()) − amount ; @∗/ p u b l i c void withdraw ( i n t amount) {...} ... }

I Mutators modify the state of the object

I As in constructors, postconditions should mention the impact on the object’s observer(s)

I Notice the usage of \old() to describe the value of an expression at method entry

Software Fiável The Java Modeling Language Public and private class members in assertions

Public assertions can only reference public members (fields, methods, . . . ) //@ r e q u i r e s balance() >= amount; p u b l i c void withdraw ( i n t amount) {...} // OK : )

p r i v a t e i n t b a l a n c e ; //@ r e q u i r e s balance >= amount; p u b l i c void withdraw ( i n t amount) {...} // ERROR

p r i v a t e /∗@ spec_public @∗/ b a l a n c e ; //@ r e q u i r e s balance >= amount; p u b l i c void withdraw ( i n t amount) {...} // OK : ( spec_public has public visibility, but only for specification purposes (more later)

Software Fiável The Java Modeling Language Invariants

public class BankAccount { ... //@ private invariant balance >= 0; ... }

I The invariant specifies internal constraints of the class, describing the valid states. In our case valid states are those of non-negative balance I Invariants must be

I True at end of constructor I Preserved by each method

I We will come back to invariants later

Software Fiável The Java Modeling Language Non-null by default

I Any declaration (other than that of a local variable) whose type is a reference type is implicitly declared non_null unless (explicitly or implicitly) declared nullable .

I Would we require method deposit(String description , int amount) to accept a null String, we would write p u b l i c void d e p o s i t ( /∗@ n u l l a b l e @∗/String description , i n t amount )

Software Fiável The Java Modeling Language Non-null values in data structures

I References are non-null by default

I Elements in data structures must be dealt with explicitly, usually within invariants

I Example: all elements in v between low and high are non-null /∗@ @ private invariant (\ f o r a l l i n t i ; @ low<= i && i < high; @ v [ i ] != n u l l ); @∗/

Software Fiável The Java Modeling Language Limitations of property-based specifications

I Imagine a stack of double values: void push ( double x ) // mutator double top ( ) // o b s e r v e r boolean empty ( ) // o b s e r v e r void pop ( ) // mutator

I What can we say of the post condition for method push?

I Observer top is easy! “x is the element at the top”: ensures top ( ) == x ;

I What about observer pop? “If we pop we get the old stack”: ensures pop(). equals(\ old ( t h i s ));

Software Fiável The Java Modeling Language Pitfall: \old(this)

I this is a reference (a 32 bit pointer); \old(this) is a copy of this reference; since this always denotes the same reference within a given method, it is always the case that \ old ( t h i s ) == t h i s

I What we want is ensures pop(). equals(\ old ( c l o n e ( ) ) ;

I We then must write equal() and clone() methods for stacks

I However one difficulty remains: pop cannot be used in contracts, since is not pure. How can we get around this limitation?

Software Fiável The Java Modeling Language Representation-exposing specifications

I In this second technique we expose the representation using the spec_public clause

I The representation is available only for specification purposes; encapsulation is maintained: the representation is not available to client code

I We use the example of an array-based implementation of a stack to explain the method

I Exposing private details is not our best strategy. We will see a more advanced technique that uses public model fields to represent (abstract away from) private implementation details

Software Fiável The Java Modeling Language Stack: Representation

public class Stack { p r i v a t e /∗@ spec_public @∗/ Object[] elems; p r i v a t e /∗@ spec_public @∗/ i n t s i z e = 0 ; ... }

I Private fields size and elems will be used in contracts

I There will be one invariant for each of these fields

I The post condition for observers are described in terms of \result and the fields

I The post condition for modifiers (including the constructors) describe the impact on the two fields

Software Fiável The Java Modeling Language The invariant revisited

I The representation invariant arises when one investigates how to implement the various operations in the class

I It captures common assumptions on which the implementation is based

I Allows to consider the implementation of each operation in isolation of the others I Together with the abstraction function, it provides valuable documentation:

I To the implementer if private I To clients as well if public

Software Fiável The Java Modeling Language The invariant revisited

I Invariants must hold in all visible states I A state is visible to an object o of class C if it is reached at one of the following moments in a program’s execution: 1. at the end of a constructor invocation that is initializing o, 2. at the beginning of a finalizer invocation that is finalizing o, 3. at the beginning and the end of a nonstatic method invocation with o as the receiver, i.e., a method like o.m() is called, 4. at the beginning and the end of a static method invocation of class C, 5. when none of the aforementioned invocations are in progress.

I There is a way to avoid the requirement that the invariant has to hold upon callback: this is by specifying that a method is a helper method.

I Helper methods cannot depend on the invariant to hold, and they do not guarantee that the invariant will hold afterwards

Software Fiável The Java Modeling Language Stack: Invariant

I size indexes the array; it will always be a valid index

//@ private invariant 0<=size && size<=elems.length;

I For memory efficiency purposes, all elements in the array beyond size are null //@ private invariant (\ f o r a l l i n t i ; //@ size <= i && i < elems.length; //@ elems[i] == n u l l );

I We will however allow null elements in our stacks (why not?)

Software Fiável The Java Modeling Language Stack: Queries

/∗@ @ r e q u i r e s s i z e > 0 ; @ ensures \ r e s u l t == elems[size − 1 ] ; @∗/ p u b l i c /∗@ pure nullable @∗/ Object top() { return elems [ s i z e − 1 ] ; } /∗@ @ ensures \ r e s u l t <==> s i z e == 0 ; @∗/ p u b l i c /∗@ pure @∗/ boolean isEmpty ( ) { return s i z e == 0 ; }

I Notice: post conditions of the form \result == ...

I pop may return a null value

Software Fiável The Java Modeling Language Stack: Constructor

/∗@ @ ensures s i z e == 0 ; @∗/ p u b l i c Stack ( ) { elems = new Object [ DEFAULT_SIZE ] ; }

I The number of elements in the stack is zero

I The invariant ensures that all its elements are null

Software Fiável The Java Modeling Language Stack: More modifiers (pop)

/∗@ @ r e q u i r e s s i z e > 0 ; @ ensures s i z e == \ old ( s i z e − 1 ) ; @ ensures elems[size] == n u l l ; @∗/ p u b l i c void pop ( ) { s i z e −−; elems[size] = n u l l ; }

I Post-conditions describe the impact of the method on the two spec_public fields

Software Fiável The Java Modeling Language Stack: More modifiers (push)

/∗@ @ ensures s i z e == \ old ( s i z e + 1 ) ; @ ensures elems [ s i z e − 1 ] == x ; @∗/ p u b l i c void push ( /∗@ n u l l a b l e @∗/ Object x ) { i f (size == elems.length) grow(); elems[size] = x; size++; } private void grow () { ...}

I Post-conditions describe the impact on the two spec_public fields

I push accepts null values

I The fact that the array may grow need not be reflected in the contract

Software Fiável The Java Modeling Language Stack: Nothing else changes

I Recall /∗@ @ r e q u i r e s s i z e > 0 ; @ ensures s i z e == \ old ( s i z e − 1 ) ; @ ensures elems[size] == n u l l ; @∗/ p u b l i c void pop ( ) { . . . } }

I Post condition says that element at (post) size changes

I What about all the other values in the array, below size ? (those above remain null, by the invariant)

I We could write one forall assertion, but there is a more economic way

Software Fiável The Java Modeling Language Frame axioms

/∗@ @ ... as before @ assignable size , elems[size − 1 ] ; @∗/ p u b l i c void pop ( ) { . . . } }

I assignable describes a frame axiom

I It says that, from the client’s point of view, only the locations named can be assigned to during the execution of the method

I assignable size is a shorthand for ensures \only_assigned(size) meaning that, at runtime, it is tested at method exit

Software Fiável The Java Modeling Language Stack: Frame axiom for push

I For push we can try /∗@ ... as before @ assignable elems[size], size; @∗/ p u b l i c void push(Object x) { i f (size == elems.length) grow(); elems[size] = x; size++; }

I But then JML2 complains: Method “StackSpecPublic(Object)” can assign to fields in set “{size}”; therefore it cannot call “StackSpecPublic.grow()” (which assigns to elems)

I To fix use assignable elems, elems[size], size;

Software Fiável The Java Modeling Language Multiple specification cases

I For different preconditions

I Cases may overlap

I Can be used to specify exceptions

I Can be used with specification inheritance

Software Fiável The Java Modeling Language Multiple specification cases

/∗@ r e q u i r e s 0 <= a && a <= 150; @ assignable age ; @ ensures age == a ; @ al so @ r e q u i r e s a < 0 ; @ assignable \ nothing ; @ ensures age == \ old ( age ) ; @∗/ p u b l i c void setAge ( i n t a ) { i f (0 <= a && a <= 150) age = a; } Could we have written if (0 <= a) age = a; instead?

Software Fiável The Java Modeling Language Meaning of also

r e q u i r e s 0 <= a && a <= 150; ensures age == a ; al s o r e q u i r e s a < 0 ; ensures age == \ old ( age ) ; means r e q u i r e s (0<= a && a<= 150) || a < 0; ensures \ old (0 <= a && a <= 150) ==> (age == a); ensures \ old (a < 0) ==> (age == \ old ( age ) )

Software Fiável The Java Modeling Language Aliasing and object identity

I For objects x and y, x == y means:

I x and y have same address I x and y are aliased I Changing of x. f also changes y. f I Aliasing caused by:

I Assignment, x = y I Method calls:

I Passing field o.y to formal x I Passing both x and y to different formals I Etc

Software Fiável The Java Modeling Language Pitfall: aliasing

/∗@ @ r e q u i r e s balance() >= amount; @ ensures balance() == \ old (balance()) − amount ; @ ensures other.balance() == @\ old (other.balance()) + amount; @∗/ p u b l i c void transfer(BankAccount other , i n t amount ) { t h i s .withdraw(amount); other. deposit(amount); }

I What is wrong with this code?

I How to fix it?

Software Fiável The Java Modeling Language Transfer: A first solution

/∗@ @ requires this != o t h e r ; @ r e q u i r e s balance() >= amount; @ ensures balance() == \ old (balance()) − amount ; @ ensures other.balance() == @\ old (other.balance()) + amount; @∗/ p u b l i c void transfer(BankAccount other , i n t amount ) { t h i s .withdraw(amount); other. deposit(amount); }

I We can do better than that: we can accept the transferring to this

I But we need two different contracts: one for this == other, the other for this != other

Software Fiável The Java Modeling Language Transfer: A more general solution

/∗@ @ requires this != o t h e r ; @ r e q u i r e s balance() >= amount; @ ensures balance() == \ old (balance()) − amount ; @ ensures other.balance() == @\ old (other.balance()) + amount; @ al so @ requires this == o t h e r ; @ ensures balance() == \ old (balance()); @∗/ p u b l i c void transfer(BankAccount other , i n t amount ) { i f ( t h i s != o t h e r ) { t h i s .withdraw(amount); other. deposit(amount); } }

Software Fiável The Java Modeling Language Behavioral subtyping

Suppose that type (class or interface) B extends type A.

Behavioral subtyping Objects from subtype B “behave like” objects from supertype A Principle of substitutivity (Liskov) Code will behave as expected if we provide a B object where an A object is expected

Software Fiável The Java Modeling Language Behavioral subtyping and contracts

I The invariant in the subclass must be stronger than that in the superclass

I The precondition in the subclass must be weaker than that in the superclass

I The postcondition in the subclass must be stronger than that in the superclass

I JML ensures this by using specification inheritance

Software Fiável The Java Modeling Language Specification inheritance: Invariants

c l a s s Parent { //@ i n v a r i a n t i n v P a r e n t ... } c l a s s C h i l d extends Parent { //@ i n v a r i a n t i n v C h i l d ... }

I In JML, the invariant for class Child is invChild && invParent

I Notice that invChild && invParent implies invParent, as required by behavioural subtyping

Software Fiável The Java Modeling Language Specification inheritance: Pre and postconditions

c l a s s Parent { //@ r e q u i r e s 0 <= a && a <= 150; //@ ensures age == a ; p u b l i c void setAge ( i n t a ) { . . . } ... } c l a s s C h i l d extends Parent { //@ al s o //@ r e q u i r e s a < 0 ; //@ ensures age == \ old ( age ) ; p u b l i c void setAge ( i n t a ) { . . . } ... } Keyword also indicates that there are inherited specifications

Software Fiável The Java Modeling Language The nullable modifier is also inherited

I Consider p u b l i c /∗@ pure @∗/ boolean equals(Object obj)

I JML complains The nullity of parameter "obj" of the overriding method "equals" does not match the nullity of the corresponding parameter in the supertype "java/lang/Object" I Solution: use the nullable modifier also in the subtype ... boolean e q u a l s ( /∗@ n u l l a b l e @∗/ Object obj)

Software Fiável The Java Modeling Language Model-based specification

I Our third modelling technique

I Modeling is an abstraction technique for system design and specification

I A model is a representation of the desired system

I A formal model is one that has a precise description in a formal language I A model differs from an implementation in that it might:

I capture only some aspects of the system I be partial, leaving some parts unspecified I not be executable

I An implementation of the system can be compared to the model

Software Fiável The Java Modeling Language Specifications for data abstractions

I The meaning of a type should not be given by any of its implementations (cf. Stack with spec_public earlier in these slides)

I Instead, a specification should define its behavior; most of the specifications consist of explaining what the operations in the class do I Model based specification includes a way of viewing objects in terms of “well-understood” concepts:

I A model for the objects describes these in terms of other objects that the user is expected to understand I For example, stacks might be defined in terms of mathematical sequences

I Methods specify their behavior based on the model for the objects

Software Fiável The Java Modeling Language JML models

I JML provides specifications for the standard Java classes, as well as a library of model classes for mathematical constructions like sets, bags, integers:

I org. jmlspecs .models.JMLObjectSequence I org. jmlspecs .models.JMLObjectBag I org. jmlspecs .models.JMLObjectSet I org. jmlspecs .models.JMLObjectToObjectMap I org ... models.JMLObjectToObjectRelation I org. jmlspecs .models. InfiniteInteger I ... I Be sure to read the documentation for these classes! Example: in class JMLObjectSet

I Method has() uses == rather than equals() for comparisons I The number of elements in the set is given by method int_size ()

Software Fiável The Java Modeling Language Stack specification: The model

//@ model import org. jmlspecs .models.JMLObjectSequence; public interface Stack {

//@ public model instance JMLObjectSequence theStack; //@ public initially theStack != n u l l && //@ theStack.isEmpty(); ... }

I Each stack is modeled as a JMLObjectSequence known as theStack I We use instance because we are describing objects (instances of the classes that implement interface Stack), and not the classes themselves I initially : the model field appears (to clients) to have started out initially as empty; this is the post-condition for all constructors of all classes that implement the interface

Software Fiável The Java Modeling Language Stack specification: Queries I/II

//@ ensures \ r e s u l t == theStack.isEmpty(); /∗@ pure @∗/ boolean isEmpty ( ) ;

//@ ensures \ r e s u l t == theStack.length(); /∗@ pure @∗/ i n t s i z e ( ) ;

I isEmpty() and length() are methods in class JMLObjectSequence

Software Fiável The Java Modeling Language Stack specification: Queries II/II

//@ r e q u i r e s !theStack.isEmpty(); //@ ensures \ r e s u l t == theStack. first (); /∗@ pure @∗/ Object top();

I Method first () in class JMLObjectSequence returns the first element in the sequence

Software Fiável The Java Modeling Language Stack specification: Modifiers

//@ ensures theStack.equals( //@\ old (theStack.insertFront(x))); void push(Object x);

//@ r e q u i r e s !theStack.isEmpty(); //@ ensures theStack.equals( //@\ old (theStack. trailer ())); void pop ( ) ;

I Method insertFront () returns a similar sequence, but with the given item placed at the end

I Method trailer () returns a sequence containing all but the first element

I These are not void methods, each returns a new JMLObjectSequence

Software Fiável The Java Modeling Language Implementing data abstractions

I The specification (in interface Stack) constitutes the definition of the type

I Classes that implement the interface provide the implementation I To implement a data abstraction we select a representation for its objects:

I Constructors initialize the representation properly and I The methods use/modify the representation properly

Software Fiável The Java Modeling Language An array-based implementation of a Stack

public class ArrayStack implements Stack { p r i v a t e Object[] elems; p r i v a t e i n t s i z e ; p u b l i c void push(Object x) { i f (size == elems.length) grow(); elems[size] = x; size++; } p u b l i c void pop ( ) { s i z e −−; elems[size] = n u l l ; } p u b l i c Object top() { return elems [ s i z e − 1 ] ; } public boolean isEmpty ( ) { return s i z e == 0 ; } ... }

Software Fiável The Java Modeling Language An implementation of a Stack (cont’d)

p u b l i c ArrayStack() { elems = new Object [ DEFAULT_SIZE ] ; s i z e = 0 ; }

I Object constructors are not part of Java interfaces, so. . .

I The initially clause in the interface //@ public initially theStack.isEmpty(); says that the model stack is created empty

I No further contract is need for the implementation of ArrayStack inherits the contract in supertype Stack

Software Fiável The Java Modeling Language The abstraction function

I The abstraction function captures the designer’s intent in choosing a particular representation

I How does the representation relates to the model?

I When choosing a representation, the implementer has in mind a relationship between the representation and the abstract objects in the model

I For example, the array [5,9,11,17, null , null , null ] ( size ==4) may map into the JMLObjectSequence <5,9,11,17>

I The abstractionFunction maps objects of class ArrayStack to objects of class JMLObjectSequence

Software Fiável The Java Modeling Language The abstraction function in JML

import org. jmlspecs .models.JMLObjectSequence; public class ArrayStack implements Stack { //@ private represents theStack <− //@ abstractionFunction(); p r i v a t e /∗@ pure @∗/ JMLObjectSequence abstractionFunction () { return JMLObjectSequence.convertFrom(elems , size ); }... }

I JMLObjectSequence offers a convenient method convertFrom(Object[] a, int n) that converts the first n elements in array a

I Otherwise code could be written that copies the relevant elements in elems into a new array of appropriate length and then use method convertFrom(Object[]), or into a Collection and then use method convertFrom(Collection)

Software Fiável The Java Modeling Language Other JML advanced features

I Support for partial correctness with diverges

I Support for the specification of the exceptional behaviour of classes, using signals, signals_only, exceptional_behavior

I Other constructs for specification for verification will be addressed in the next classes

Software Fiável The Java Modeling Language Bibliography

I Leavens and Cheon, Design by Contract with JML (available from http://jmlspecs.org)

I Leavens, Baker, and Ruby, Preliminary Design of JML (available from http://jmlspecs.org)

I Huisman, et al, Formal Specification with JML (available from course site)

I The JML reference manual (available from http://jmlspecs.org)

I Barbara Liskov with John Guttag, Program Development in Java. Addison Wesley, 2001. Chapters 1, 3, 5 (this in particular), 9.

Software Fiável The Java Modeling Language