[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This chapter discusses JML's model programs, which are adapted from the refinement calculus [Back88] [Back-vonWright89a] [Buechi-Weck00] [Morgan94] [Morris87].
14.1 Ideas Behind Model Programs 14.2 Details of Model Programs 14.3 Nondeterministic Choice Statement 14.4 Nondeterministic If Statement 14.5 Specification Statements
The basic idea of a model program is that it is a specification that is written as an abstract algorithm. Such an abstract algorithm specifies a method in the sense that the method's execution should be a refinement of the model program.
In JML adopt the semantics of the "greybox approach" to refinement calculus [Buechi-Weck00] [Buechi00]. In this semantics, calls to non-pure methods in a model program must occur in the same states in a correct implementation. That is, the notion of refinement is restricted to not permit all implementations with equivalent behavior, but to require that the implementation make certain method calls in the model program. This turns out to be very nice for describing both higher-order features and callbacks.
Consider the following example (from a survey on behavioral subtyping by Leavens and Dhara [Leavens-Dhara00]). In this example, both the methods are specified using model programs, which are explained below.
package org.jmlspecs.samples.dirobserver; //@ model import org.jmlspecs.models.JMLString; //@ model import org.jmlspecs.models.JMLObjectSetEnumerator; /** Directories that can be both read and written. */ public interface Directory extends RODirectory { /** Add a mapping from the given string to the given file to this directory. */ /*@ public model_program { @ normal_behavior @ requires !in_notifier && n != null && n != "" && f != null; @ assignable entries; @ ensures entries != null @ && entries.equals(\old(entries.extend(new JMLString(n), f))); @ @ maintaining !in_notifier && n != null && n != "" && f != null @ && e != null; @ decreasing e.uniteratedElems.size(); @ for (JMLObjectSetEnumerator e = listeners.elements(); @ e.hasMoreElements(); ) { @ set in_notifier = true; @ ((DirObserver)e.nextElement()).addNotification(this, n); @ set in_notifier = false; @ } @ } @*/ public void addEntry(String n, File f); /** Remove the entry with the given name from this directory. */ /*@ public model_program { @ normal_behavior @ requires !in_notifier && n != null && n != ""; @ assignable entries; @ ensures entries != null @ && entries.equals @ (\old(entries.removeDomainElement(new JMLString(n)))); @ @ maintaining !in_notifier && n != null && n != "" && e != null; @ decreasing e.uniteratedElems.size(); @ for (JMLObjectSetEnumerator e = listeners.elements(); @ e.hasMoreElements(); ) { @ set in_notifier = true; @ ((DirObserver)e.nextElement()).removeNotification(this, n); @ set in_notifier = false; @ } @ } @*/ public void removeEntry(String n); } |
Both model programs in the above example are formed from a specification
statement, which begins with the keyword normal_behavior
in these
examples, and a for-loop. The key event in the for loop bodies is a
method call to a non-pure method (addNotification
or removeNotification
). These calls must occur in a state
equivalent to the one reached in the model program for the
implementation to be legal.
The behavior statements abstract away part of a correct implementation.
The normal_behavior
statements in these examples both have a
precondition, a frame axiom, and a postcondition. These mean that the
statements that they abstract away from must be able to, in any state
satisfying the precondition, finish in a state satisfying the
postcondition, while only assigning to the locations (and their
dependees) named in the frame axiom.
For example, the first behavior statements says that whenever
in_notifier
is false, n
is not null and not empty, and
f
is not null, then this part of the method can assign to
entries
something that isn't null and that is equal to the old
value of entries
extended with a pair consisting of the string
n
and the file f
.
The model field entries
, of type JMLValueToObjectMap
,
is declared in the supertype RODirectory
[Leavens-Dhara00].
The following gives the syntax of model programs. See section 12. Statements and Annotation Statements, for the parts of the syntax of statements that are unchanged from Java. The jml-compound-statement and jml-statement syntax is the same as the compound-statement and statement syntax, except that model-prog-statements are not flagged as errors within the jml-compound-statement and jml-statements.
model-program ::= [ privacy ] |
The syntax of the nondeterministic-choice statement is as follows.
nondeterministic-choice ::= |
nondeterministic-if ::= |
The grammar for specification statements appears below. It is
unusual, compared to specification statements in refinement calculus,
in that it allows one to specify statements that can signal
exceptions, or terminate abruptly. The reasons for this are based on
verification logics for Java [Huisman01] [Poll-Jacobs00], which have
these possibilities. The meaning of an abrupt-spec-case is that
the normal termination and signaling an exception are forbidden; that
is, the equivalent spec-statement using behavior
would
have ensures false;
and signals (Exception) false;
clauses. Hence in an abrupt-spec-case, JML does not allow use
of an ensures-clause, signals-only-clause, or
signals-clause.
spec-statement ::= [ privacy ] behavior-keyword generic-spec-statement-case | [ privacy ] exceptional-behavior-keyword exceptional-spec-case | [ privacy ] normal-behavior-keyword normal-spec-case | [ privacy ] abrupt-behavior-keyword abrupt-spec-case generic-spec-statement-case ::= [ spec-var-decls ] generic-spec-statement-body | [ spec-var-decls ] spec-header [ generic-spec-statement-body ] generic-spec-statement-body ::= simple-spec-statement-body | |
14.5.1 Continues Clause 14.5.2 Breaks Clause 14.5.3 Returns Clause
continues-clause ::= continues-keyword [ target-label ] [ pred-or-not ] |
breaks-clause ::= breaks-keyword [ target-label ] [ pred-or-not ] |
returns-clause ::= returns-keyword [ pred-or-not ] |
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |