Skip to content

Commit 54afdc4

Browse files
author
davidcok
committed
Editing
1 parent 7d9fdbc commit 54afdc4

11 files changed

+91
-20
lines changed

tutorial/FrameConditions.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ ensures clause that states that `counter2 == \old(counter2)`. This specification
3737
verifies as correct.
3838

3939
But this is not a practical solution. We can't add to `increment1()`'s specification a clause stating that every visible variable is unchanged.
40-
Instead we use a *frame condition* whose purpose is to state what memory
40+
Instead we use a *frame condition* whose purpose is to state which memory
4141
locations a method might have modified. There are a variety of names for
42-
the frame clause: traditionally it is `assignable`, but `assigns` is also permitted.
42+
the frame clause: traditionally it is `assignable`, but `assigns` and `writes` are also permitted.
4343
Note that `modifies` is also an
4444
(implemented) synonym, but in some tools it has a slightly different meaning,
4545
so its use is not recommended.
@@ -69,8 +69,7 @@ that is written to in the body of `m`.
6969
* `a[*]` for array expression `a` means all elements of that array
7070
* `a[i..j]` for expressions `a`, `i`, and `j` means the stated range of array elements, from `i` to `j` inclusive.
7171

72-
If there is no frame condition at all, then a default is used, namely `assigns \everything;`--- which means exactly that: after a call of this method, any memory location in the state might have been written to and might be changed. It is very difficult to prove anything about a program that includes a call to a method with such a frame condition. Thus
73-
*you must include a frame condition for any method that is called within a program*.
72+
If there is no frame condition at all, then a default is used, namely `assigns \everything;`--- which means exactly that: after a call of this method, any memory location in the state might have been written to and might be changed. It is very difficult to prove anything about a program that includes a call to a method with such a frame condition. Thus *you must include a frame condition for any method that is called within a program*.
7473

7574
A shorthand way to say that a method `assigns \nothing;` is to designate it `pure`, as in
7675
```
@@ -84,7 +83,7 @@ though there are a few other details to purity --- see the [lesson on pure](Meth
8483
There are two other points to know about frame conditions. First, where a frame condition clause includes expressions, such as the indices of array expressions, those expressions are evaluated in the pre-state, not the post-state.
8584

8685
Second, a frame condition is a method specification clause like `requires` and `ensures`. A method specification may contain more than one such clause.
87-
However, note that each cluase is considered individually. That is, each clause
86+
However, note that each clause is considered individually. That is, each clause
8887
by itself lists the memory locations that may be written to by the method.
8988
As each frame condition clause must be valid on its own, the effect of multiple clauses is the same as one clause with the _intersection_ of the sets of locations given by the separate clauses.
9089
For example,
@@ -110,7 +109,7 @@ result of mutiple assigns clauses was the *union* of their contents, but that is
110109
not the case, for historical reasons. The advice is then to
111110
*have only one frame condition clause per specification (case)*, even if that
112111
means the clause has a long list. (All the method specifications in the
113-
tutorial lessons so far have just one specification case; an advanced lesson
112+
tutorial lessons so far have just one specification case; a subsequent lesson
114113
presents [multiple specification cases](MultipleBehaviors).)
115114

116115

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
title: JML Tutorial - Java Errors and Exceptions
3+
___
4+
5+
_To be written_

tutorial/MethodCalls.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ The callee, on the right, is a simple standalone method. When the method is
2020
verified, the logical engine
2121
* assumes its preconditions are true
2222
* symbolically represents the actions of the method body
23-
* asserts the postconditions---that is, proves the the postconditions logically follow from the preconditions and method body in every initial state allowed by the preconditions
23+
* asserts the postconditions---that is, proves that the postconditions logically follow from the preconditions and method body in every initial state allowed by the preconditions
2424

2525
As for the caller, it also follows the same three steps. But how do we represent the call to `callee()`? We could inline the whole callee method, but that would
2626
become unwieldy, would not work for recursion, and is not modular.
@@ -42,7 +42,7 @@ The following code is a simple example of a two-method verification.
4242
```
4343

4444
The output on verifying is given next. Note that the openjml command includes
45-
the `-progress` option, so we receive quite a bit more output.
45+
the `--progress` option, so we receive quite a bit more output.
4646

4747
```
4848
{% include_relative T_CallerCallee.out %}
@@ -70,8 +70,8 @@ is reported as not verified.
7070

7171
A few additional points might be helpful.
7272

73-
Often one is working on the specifications for just one method and so one does not want to try to verify everything. You can specify the one method to run like this:
74-
`openjml --esc --method=caller2 T_CallerCallee.java`
73+
Often one is working on the specifications for just one method and so one does not want to try to verify everything.
74+
You can specify the one method to run like this: `openjml --esc --method=caller2 T_CallerCallee.java`
7575

7676
Secondly, the `--progress` option is useful to see the detail about what verified and what did not; it also puts out information as work is accomplished, so you can see what progress is being made in a long-running job. But you can also reduce the amount of output. For example, the default `--normal` option
7777
```
@@ -85,7 +85,7 @@ which just shows any error messages.
8585

8686
If you want you can hide all the output text and just observe the exit code:
8787
```
88-
openjml -esc T_CallerCallee.java > /tmp/t; echo $?
88+
openjml --esc --quiet T_CallerCallee.java ; echo $?
8989
```
9090
produces just
9191
```

tutorial/MultipleBehaviors.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ There are a few points to note:
2121
* There is no order to the behaviors; they can be written in any order that is understandable.
2222
* Every behavior applies on its own and must hold by itself --- there is no if-then-else among them. If a behavior's preconditions hold,
2323
then its postconditions must hold, independent of what any other behavior says.
24+
* The effective precondition for each behavior is the conjunction (with `&&`) of the preconditions for that behavior. The effective precondition for the combination of multiple behaviors is the disjunction (with `||`) of the effective preconditions of the individual behaviors. Consequently, at the point where such a method is called, at least one, but by no means necessarily all, of the behaviors must have an effective precondition that is true.
2425

2526
In our example, if `a`, `b`, and `c` are all equal, then the precondiition (`requires` clause) of each of the three behaviors is true.
2627
So the postconditions of each of the behaviors must also be true. Fortunately they all agree.
@@ -66,7 +67,7 @@ The normal and exceptional behaviors illustrated in the previous section are ver
6667
The `normal_behavior` heading implies that no exception is allowed (`signals false`); the `exceptional_behavior` heading says that normal termination is not allowed (`ensures false`).
6768
A behavior that is neither of these is a simple `behavior`, which is the default when there is no heading.
6869

69-
One other point: any one of the behavior keywords needs a visibility keyword; almost always, as in the example above, the visibility is the same as the method. The absence of a visibility modifier means `package` visibility, just as the absence of a visibility modifier on the method declaration.
70+
One other point: any one of the behavior keywords needs a visibility keyword; almost always, as in the example above, the visibility is the same as the method. The absence of a visibility modifier means `package` visibility, just as the absence of a visibility modifier on the method declaration. However, if there is no specialized behavior keyword, then there is no place for the visibility keyword; in that cae, the visibility is the same as the visibility of the method.
7071

7172
## Summary of specification cases
7273

tutorial/OldAndOrdering.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ title: JML Tutorial - Method Specifications: old clauses and clause ordering
44

55
We have introduced a few kinds of method specification clauses so far. In fact there are many more, though most are not widely used:
66
* Precondition clauses
7+
* [`recommends`](Recommends)
78
* [`requires`](Preconditions)
89
* [`old`](#old-clause)
910
* Frame conditions
1011
* `reads` (`accessible`)
11-
* [`assignable` (`assigns`)](FrameConditions)
12+
* [`assignable` (`assigns`, `writes`)](FrameConditions)
1213
* `captures`
1314
* `callable`
1415
* Postconditions
@@ -28,15 +29,15 @@ Some of these have been already discussed; others are discussed in later lessons
2829
There is no pre-defined order to the clauses within a single specification case (cf. a later lesson on [multiple specification cases](MultipleBehaviors)].
2930
However, a specification is much more readable if the clauses generally follow the order above, with preconditions first, then frame conditions, followed by postconditions.
3031

31-
There is some meaning to the ordering within the precondition group and within the postcondition group: earlier clauses can set conditions that are needed for later clause to be well-defined. For example,
32+
There is some meaning to the ordering within the precondition group and within the postcondition group: earlier clauses can set conditions that are needed for later clause to be well-defined; but ordering only matters within the kinds of precondition clauses and separately for any `ensures` clauses. For example,
3233
```
3334
{% include_relative T_order1.java %}
3435
```
3536
yields
3637
```
37-
T_order1.old
38+
{% include_relative T_order1.out %}
3839
```
39-
The first requires clause might not be well-defined because `a` might be null. If we reverse the order of the clauses, then JML is content:
40+
The first requires clause might not be well-defined because `a` might be null. If we reverse the order of the clauses, then OpenJML is content:
4041
```
4142
{% include_relative T_order2.java %}
4243
```

tutorial/Postconditions.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,10 @@ This value is referenced as `\result`. Like all JML keywords in expression, `\re
7979
```
8080
{% include_relative T_ensures3.java %}
8181
```
82-
82+
Two final points:
83+
* The order of `ensures` clauses matters. The predicates of a sequence of `ensures` clauses are effectively conjoined together (with `&&`) to produce
84+
a single postcondition predicate. Consequently an earlier predicate can cause a later predicate to be [well-defined](WellDefinedExpressions).
85+
* In thinking about postconditions, be aware of the semantics of the `ensures` clause, namely,
86+
_if the method terminates normally (with an exception), then the given postcondition is true_.
87+
The converse, if the `ensures` predicate is true then the method terminates normally, is not the meaning and is not necessarily true.
8388
## **[Postconditions Problem Set](https://www.openjml.org/tutorial/exercises/PostConEx.html)**

tutorial/SpecifyingExceptions.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ So we could write this trivial example:
1616
```
1717
which verifies successfully. Note that the specification includes a second kind of clause, the `signals_only` clause.
1818
This clause specifies the kinds of exceptions that may be thrown from the method.
19-
JML requires the specification to list `RuntimeException` even though Java does not require declaring `RuntimeException` in a throws clause
19+
JML requires the specification to list `RuntimeException`, even though Java does not require declaring `RuntimeException` in a throws clause,
2020
in order to make it explicitly clear what exceptions might be thrown.
2121

2222
If we omit any exceptions, by saying `signals_only \nothing`, a verification failure results.
@@ -56,4 +56,25 @@ as it should. We can guard against an exception by requiring that the method alw
5656
```
5757
which now verifies again.
5858

59+
Postcondition clauses can be stated in any order; there is no meaning to one being before the other.
60+
Consider this example in which there are two kinds of exceptions thrown.
61+
```
62+
{% include_relative T_Exception4.java %}
63+
```
64+
In the second `signals` clause, the expression `a != null` is required; without it, the later expression
65+
`a[i]` is not [well-defined](WellDefinedExpressions). It is immaterial that there is a test for `a` being null
66+
in the other `signals` clause. Note that if there are no `signals` clauses, then OpenJML complains that
67+
some expected conditions cannot be proved, as shown in this example:
68+
```
69+
{% include_relative T_Exception4a.java %}
70+
```
71+
which gives this result
72+
```
73+
{% include_relative T_Exception4a.out %}
74+
```
75+
The three verification failure messages may occur in any order.
76+
This balance between verification failures and exception specifications is an
77+
advanced topic discussed [here](JavaErrorsAndExceptions).
78+
79+
5980
## **[Specifying Exceptions Problem Set](https://www.openjml.org/tutorial/exercises/SpecifyingExceptionsEx.html)**

tutorial/T_Exception4.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// openjml --esc T_Exception4.java
2+
//@ nullable_by_default
3+
public class T_Exception4 {
4+
5+
public static class V {
6+
public int value;
7+
}
8+
9+
//@ ensures \result == a[i];
10+
//@ signals (NullPointerException e) a == null;
11+
//@ signals (IndexOutOfBoundsException e) a != null && (i < 0 || i >= a.length);
12+
//@ signals_only Exception;
13+
public int value(int[] a, int i) {
14+
return a[i];
15+
}
16+
}

tutorial/T_Exception4a.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// openjml --esc T_Exception4a.java
2+
//@ nullable_by_default
3+
public class T_Exception4a {
4+
5+
public static class V {
6+
public int value;
7+
}
8+
9+
//@ ensures \result == a[i];
10+
public int value(int[] a, int i) {
11+
return a[i];
12+
}
13+
}

tutorial/T_Exception4a.out

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
T_Exception4a.java:11: verify: The prover cannot establish an assertion (PossiblyTooLargeIndex) in method value
2+
return a[i];
3+
^
4+
T_Exception4a.java:11: verify: The prover cannot establish an assertion (PossiblyNegativeIndex) in method value
5+
return a[i];
6+
^
7+
T_Exception4a.java:11: verify: The prover cannot establish an assertion (PossiblyNullDeReference) in method value
8+
return a[i];
9+
^
10+
3 verification failures

0 commit comments

Comments
 (0)