Title: Politecnico di Milano Advanced Topics in Software Engineering
1Politecnico di MilanoAdvanced Topics in Software
Engineering
Domenico Bianculli Alessandro Monguzzi
bianculli, alessandro.monguzzi_at_gmail.com
June 16th, 2005
Rev. 1.3
2Outline
- What is JML?
- Syntax
- Specification cases
- Advanced topics
- Running example
- Tools
- Related works
3What is JML?
- Java Modeling Language
- A behavior interface specification language
(BISL) - describes
- modules interface
- modules behaviour
- evolution of Hoare-style specification
- based on Design by Contract
4Syntax
- Annotations
- Expressions
- Quantification
5Syntax annotations
- Specification written as annotation comments
- Single line//_at_ specification
- Multiline/_at_ specification _at_ _at_/
- Informal//_at_( informal description )
6Syntax expressions
- Expression used in JML annotations cannot have
side effects. - No use of , , , --
- Can only call pure methods
- Extended version of Java expressions
7Syntax quantification
- universal existential (\forall,\exists)
- /_at_ \forall int x
- _at_ x gt 0 x lt a.lenght-1
- _at_ ax-1 lt ax
- _at_/
- general quantifiers (\sum, \product, \min, \max)
- numeric quantifier(\num_of)
declaration
range
body
8Preconditions
- Say what must be true when calling a method
- Introduced by requires clause
- /_at_requires xgt 0
- _at_...
- _at_/
- public double sqrt(double x)
9Normal postconditions
- Say what must be true when a method returns
normally(i.e. without throwing exceptions) - Introduced by ensures clause
- /_at_ requires xgt 0
- _at_ ensures x - \result \result lt 0.0001
- _at_/
- public double sqrt(double x)
- Input parameters in postconditions are always
evaluated in pre-statex \old(x)
10Exceptional postconditions
- Say what must be true when a method throws an
exception of type TIntroduced by signals clause - /_at_ requires xgt 0
- _at_ ensures x - \result \result lt 0.0001
- _at_ signals (IllegalArgumentException ex)
- _at_ ex.getMessage() ! null !(x gt0.0)
- _at_/
- public double sqrt(double x)
11More on exceptional postconditions (1)
- Note that signal clause does not say which
exceptions must be thrown - It just only says if an exception of (sub)type
T is thrown, then its predicate must hold and
not viceversa. - The signals_only clause specifies what exceptions
may be thrown, and implicitly the ones which
cannot be thrown.
12More on exceptional postconditions (2)
- To say that an exception must be thrown in some
situations, exclude that situations from other
signals clauses and from all ensures clauses/_at_
requires true _at_ ensures xgt0 _at_ signals
(Exception e) _at_ xlt0 _at_/public int
foo(int x) throws Exceptions - More on this topic later
13Semantics
- Meaning of JML method specification
- A method is called in a state (pre-state) where
the precondition is satisfied otherwise, nothing
is guaranteed, including the termination of the
call - If a method is called in a proper pre-state, then
there are two possible outcomes (post-state) of
methods execution normal and exceptional
14Kinds of specification specification cases
- Specification cases
- Lightweight
- Heavyweight
- Behaviour
- Normal Behaviour
- Exceptional Behaviour
15Heavyweight vs lightweight specs
- Heavyweight
- Assumes users giving full specification
- Omitted clauses are abbreviations
- Useful for formal verification
- Lightweight
- Dont assume user is giving full specification
- Minimize annotation burden
- Omitted clauses are \not_specified
- Useful for RAC and docs
16Additional Clauses
17Heavyweight specs behavior
- /_at_ behavior
- _at_ requires P
- _at_ diverges D
- _at_ assignable A
- _at_ when W
- _at_ ensures Q
- _at_ signals (E1 e1) R1
- _at_ ...
- _at_ signals (En en) Rn
- _at_ accessible C
- _at_ callable p()
- _at_/
18Heavyweight specsnormal behavior
- It is a behavior specification case with signals
clause implicitly defined as signals
(java.lang.Exception) false - guarantees normal termination ? no exception may
be thrown
19Heavyweight specsexceptional behavior
- It is a behavior specification case with ensures
clause implicitly defined as ensures false - Guarantees that the method throws an exception
20Multiple cases specs
- Normal and exceptional spec cases may be
combined - /_at_ public normal_behavior
- _at_ requires !theStack.isEmpty()
- _at_ assignable size, theStack
- _at_ ensures
- _at_ theStack.equals(\old(theStack.trailer()))
- _at_ \result \old(theStack.first())
- _at_ also
- _at_ public exceptional_behavior
- _at_ requires theStack.isEmpty()
- _at_ assignable \nothing
- _at_ signals_only IllegalStateException
- _at_/
- public Object pop()
21Class invariants
- Properties that must hold in all visible states
of an object//_at_ public invariant x ! null
!name.equals() - Static or Instance invariants
- Implicitly included in preconditions and normal
and exceptional postconditions - Do not hold for methods declared with clause
helper - private invariants state Rep Invariant
22Loop (in)variants
- Loop statements can be annotated with loop
invariants and variant functions. - Help in proving partial and total correctness of
the loop statementlong sum 0int a new
int100int i a.length/_at_ mantaining -1 lt
i i lt a.length _at_ mantaining sum _at_
(\sum int j i lt j 0 lt j _at_
j lt a.length aj) _at_ decreasing i
_at_/while (--igt0) sum ai
23Assertions
- An assertion is a predicate that must always be
true//_at_ assert igt0 - w.r.t. Java 1.4 assert JML assertions cannot
have any side-effects and can use JML expressions.
24History Constraints
- Relationships that should hold for the
combination of each visible state and any visible
state that occurs later in the program execution - Used to constrain the way the values change over
time - int a
- //_at_ constraint a \old(a)
- boolean b
- //_at_ constraint b.lenght gt \old(b.lenght)
25Advanced Topics
- Model fields
- Model methods and types
- Fields visibility
- Abstract models
- Purity
- Data groups
- Specification inheritance
- Refinement
26Model fields
- Represents a field or a variable used only in
specification - Describes abstract values of objects
- They can be mapped on a concrete field using
keyword represents - public class MathFoo
- //_at_ public model eps
- private float error
- //_at_ private represents eps lt- error
27Visibility
- JML imposes visibility rules similar to Java
- Keyword spec_public loosens visibility for specs.
Private spec_public fields are allowed in public
specs. - private /_at_ spec_public _at_/ double x
0.0//_at_requires !Double.isNaN(xdx)public void
moveX(double dx) - Not a good practice! You are exposing internal
representation!
28Abstract models
- JML provides a Java class library for
specification purposes - Package org.jmlspecs.model
- Collections sequence, set, bag
- Algebric functions and relations
- Exceptions and iterators
- Almost all are immutable objects with pure
methods - Can be used during RAC
- Users can define their own models
29Purity
- A pure method is a method without side effects
(\assignable nothing) - It is declared with the modifier pure
- A class is pure if all its methods are pure
- Only pure method are allowed in specifications
30Data groups
- A set of model and concrete fields to which you
refer by a specific name - A declaration of a model field automatically
creates a data group with the same name of the
model field - The main purpose of a data group is to refer to
the elements of this set without exposing their
internal representation - Locations members of a data group may be assigned
during the executions of methods that have
permission to assign to the data group - /_at_ public model int size
- _at_ public model JMLObjectSequence theStack
- _at_ in size
- _at_/
31Specification inheritance
- A subclass inherits specifications of its
superclass and of its implemented interfaces - All instance model fields
- Instance method specifications
- Instance invariants and instance history
constraints - Specifications of a superclass are conjuncted
with new specs with the clause also - Support behavioural notion of subtyping,
accordingly to Liskovs substitution principle - preconditions are disjoined
- postconditions are conjoined as n (old(prei) -gt
posti) - invariants are conjoined
32Refinement files
- Specifications can be separated from
implementations - Specs are written in a file Foo.java-refined
- Implementation is written in file Foo.java which
contains the clause //_at_ refine Foo.java-refined - Useful for adding specifications to existing code
33Example IntSet
- Informal specificationIntSets are unbounded
sets of integers with operations to create a new
empty IntSet, test whether a given integer is an
element of an IntSet, and add or remove
elements.
34IntSet à la Liskov (1)
- public interface IntSet
- public void insert(int x)
- //MODIFIES this
- //EFFECTS Adds x to the elements of this
- public void remove(int x)
- //MODIFIES this
- //EFFECTS Removes x from this
- public boolean isIn(int x)
- //EFFECTS If x is in this returns true, else
returns false.
Mutator
Mutator
Observer
35IntSet à la Liskov (2)
- public class IntSetAs_list implements IntSet
-
- private Vector els
- public IntSetAs_list()
- //EFFECTS Initializes this to be empty.
- els new Vector()
-
-
-
- Abstraction FunctionAF(c) c.els.get(i).intValu
e 0 lt i lt c.els.size - Representation Invariantc.els ! null for all
integers i (0 lt i lt c.els.size gt c.els.get(i)
is an Integer) for all integers i, j (0lt i
lt j lt c.els.size gt c.els.get(i).intValue !
c.els.get(j).intValue)
36IntSet in JML (1)
- public interface IntSet
- /_at_ public model instance JMLValueSet theSet
- _at_ public initially theSet ! null
theSet.isEmpty() - _at_ public instance invariant theSet ! null
- _at_ (\forall JMLType e theSet.has(e)
- _at_ e instanceof
JMLInteger) - _at_/
- / Insert the given integer into this set. /
- /_at_ public normal_behavior
- _at_ assignable theSet
- _at_ ensures theSet.equals(\old(theSet.insert(new
JMLInteger(elem)))) - _at_/
- public void insert(int elem)
- / Tell if the argument is in this set. /
- /_at_ public normal_behavior
- _at_ ensures \result theSet.has(new
JMLInteger(elem)) - _at_/
- public /_at_ pure _at_/ boolean isIn(int elem)
- / Remove the given integer from this set. /
Model Field
Abstract Invariant
37IntSet in JML (2)
- import java.util.
- //_at_ model import org.jmlspecs.models.
- public class IntegerSetAsList implements IntSet
- private Vector els
- //_at_ in theSet
- /_at_ private invariant els ! null
- _at_ (\forall int i 0lti iltels.size()
els.get(i) ! null - _at_ els.get(i) instanceof Integer
- _at_ (\forall int j0 iltj jltels.size()
els.get(i) ! els.get(j))) - _at_/
- //_at_ private represents theSet lt-
abstractValue() - / Return the abstract value of this
IntegerSetAsList. / - /_at_ _at_ private pure model JMLValueSet
abstractValue() - _at_ JMLValueSet ret new JMLValueSet()
- _at_ Iterator iter els.iterator()
- _at_ while (iter.hasNext())
- _at_ ret ret.insert(new
JMLInteger((Integer)
Rep Invariant
Abstraction Function
38IntSet in JML (3)
- / Initialize this set to be the empty set. /
- /_at_ public normal_behavior
- _at_ assignable theSet
- _at_ ensures theSet ! null theSet.isEmpty()
- _at_/
- public IntegerSetAsList()
- els new Vector()
-
- public /_at_ pure _at_/ boolean isIn(int i)
- return els.contains(new Integer(i))
-
- public void insert(int i)
- els.add(new Integer(i))
-
- public void remove(int i)
- els.remove(new Integer(i))
-
39Tools
- Parsing Typechecking
- Runtime assertion checking
- Testing
- Documentation
- Extended static checking
- Program verification
40jmlc
- The JML compiler
- Translates Java code with JML assertions into
bytecode - Adds runtime checks
- During execution, all assertions are tested and
any violation of an assertion produces an Error
(uses jmlrac script).
41jmlunit
- Inserts support for JML within JUnit
- Writes out a JUnit test oracle for given Java
files - Specifications are used to check whether tested
code runs properly ? Tests are only as good as
the quality of the specifications!
42jmldoc
- Produces HTML pages with API and JML
specifications for Java classes
43ESC/Java
- Extended Static Checker for Java
- Tries to prove correctness of specifications at
compile-time, fully automatically - Not sound it may miss an error that is actually
present - Not complete it may warn of errors that are
impossible - It finds a lot of potential bugs quickly
- NullPointer, ArrayIndexOutOfBounds, ClassCast
44LOOP
- Logic of Object Oriented Programming, project of
University of Nijmegen - Based on a formalization of Java and JML
semantics in the theorem prover PVS - LOOP compiler translates JML annotations in PVS
proof obligations, to be proved interactively
45Related Works
- Early programming languages
- Gypsy
- Alphard
- Euclid
- CLU
- DBC based
- Eiffel
- SPARK
- B method
- OCL from UML
- Spec
46Conclusions
- Strenghts
- Easy to learn
- Source code is the formal model
- Gradual introduction
- Support for legacy code
- Wide range of tools
- Weakenesses
- No support for
- concurrency
- object invariants within callbacks
- modeling alias relationships
- Strong definition of pure methods
- many constraints
47References