[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

14. Model Programs

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  


14.1 Ideas Behind Model Programs

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].


14.2 Details of Model Programs

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 ] model_program
                  jml-compound-statement
jml-compound-statement ::= compound-statement
jml-statement ::= statement
model-prog-statement ::= nondeterministic-choice
        | nondeterministic-if
        | spec-statement
        | invariant


14.3 Nondeterministic Choice Statement

The syntax of the nondeterministic-choice statement is as follows.

 
nondeterministic-choice ::= choose alternative-statements
alternative-statements ::= jml-compound-statement
             [ or jml-compound-statement ] ...


14.4 Nondeterministic If Statement

 
nondeterministic-if ::= choose_if guarded-statements
             [ else jml-compound-statement ]
guarded-statements ::= guarded-statement
             [ or guarded-statement ] ...
guarded-statement ::= {
             assume-statement
             jml-statement [ jml-statement] ... }


14.5 Specification Statements

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
        | {| generic-spec-statement-case-seq |}
generic-spec-statement-body-seq ::= generic-spec-statement-case
             [ also generic-spec-statement-case ] ...
simple-spec-statement-body ::= simple-spec-statement-clause
                               [ simple-spec-statement-clause ] ... 
simple-spec-statement-clause ::= diverges-clause
        | assignable-clause
        | when-clause | working-space-clause | duration-clause
        | ensures-clause | signals-only-clause | signals-clause
        | continues-clause | breaks-clause | returns-clause
abrupt-behavior-keyword ::= abrupt_behavior | abrupt_behaviour
abrupt-spec-case ::= generic-spec-statement-case

14.5.1 Continues Clause  
14.5.2 Breaks Clause  
14.5.3 Returns Clause  


14.5.1 Continues Clause

 
continues-clause ::= continues-keyword [ target-label ]
                     [ pred-or-not ] ;
continues-keyword ::= continues | continues_redundantly
target-label ::= -> ( ident )


14.5.2 Breaks Clause

 
breaks-clause ::= breaks-keyword [ target-label ]
                  [ pred-or-not ] ;
breaks-keyword ::= breaks | breaks_redundantly


14.5.3 Returns Clause

 
returns-clause ::= returns-keyword [ pred-or-not ] ;
returns-keyword ::= returns | returns_redundantly


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by leavens on January, 11 2006 using texi2html