[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Following Leino [Leino98],
JML uses data groups, with in
and maps \into
clauses
to relate model fields to the concrete fields of objects.
For example, in the following
private ArrayList theElems; //@ in size; |
the in
clause
says that theElems
is in the data group of the model field
size
. This allows theElems
to be assigned to
whenever size
is assignable, and also says that the
value of size
can be partly determined by theElems
.
One can also use a represents
clause to say how the model field
size
and the concrete field theElems
are related.
For example, the following says that the value of size
is
determined by calling the size()
method of theElems
.
private represents size <- theElems.size(); |
The represents
clause
gives additional facts that can be used
in reasoning about the specification.
This clause serves the same purpose as an abstraction function in various
proof methods for abstract data types (such as [Hoare72a]).
The represents
clause above tells how to extract
the value of size
from the value of theElems
.
A represents clause has to be declared to be private
if, as
in this example, some variables mentioned in it are private
(as is usually the case).
JML also has history constraints [Liskov-Wing94]. A history constraint is used to say how values can change between earlier and later states, such as a method's pre-state and its post-state. This prohibits subtypes from making certain state changes, even if they implement more methods than are specified in a given class. For example, the following history constraint
public constraint MAX_SIZE == \old(MAX_SIZE); |
MAX_SIZE
cannot change.
JML has the ability to specify what methods a method may call,
using a callable
clause.
This allows one to know which methods need to be looked at
when overriding a method [Kiczales-Lamping92],
and to apply the ideas of "reuse contracts"
[Steyaert-etal96].
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |