You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The `openjml` executable is a modified version of the OpenJDK `javac`
7
+
The `openjml` executable is a modified version of the OpenJDK compiler `javac`
8
8
and is correspondingly a classic command-line tool:
9
9
* The command-line arguments are a mix of files and options.
10
10
* Files are given as absolute file paths
11
11
or paths relative to the current working directory
12
12
(not relative to the location of `openjml`).
13
13
* Options inherited from `javac` are unchanged. They are a mix of single-hyphen and double-hyphen spellings.
14
14
* OpenJML-specific options begin with a double hyphen (e.g., `--quiet`) (single hyphens are still accepted for most options).
15
-
Options that take a value either (a) have the value follow the option as the next argument or (b)
15
+
Options that take a value either: (a) have the value follow the option as the next argument or (b)
16
16
(for OpenJML options, but only some Java option) use the syntax `--option=value`.
17
17
For some options, the value may be a comma-separated list; if the value contains
18
18
whitespace, it must be enclosed in quotes.
@@ -23,7 +23,7 @@ The details of all the options are given in the [OpenJML Users' Guide](../docume
23
23
*`--rac`: compile with embedded checks, for runtime-assertion-checking
24
24
*`--progress`: emits more information during processing than the default `--normal`
25
25
26
-
Use `--class-path` or `-cp` just as you would for `javac` to specify the list of folders on which to find files. `openjml` uses a classpath and a sourcepath exactly like `javac` does; in addition `openjml`considers a _specspath_ for finding specification files. For most applications, it is simplest to define a single classpath (using the `-cp` command-line option or the `CLASSPATH` environment variable) giving the jar files and folder roots of package hierarchies for all the class, source and specification files. The details are an advanced topic presented [here](SpecificationFiles).
26
+
Use `--class-path` or `-cp` just as you would for `javac`(i.e., with a path argument after a space, such as `-cp '/home/me/project1:/home/me/prjoject2'`) to specify the list of folders on which to find files. `openjml` uses a classpath and a sourcepath exactly like `javac` does; in addition `openjml`also uses a _specspath_ for finding specification files. For most applications, it is simplest to define a single classpath (using the `-cp` command-line option or the `CLASSPATH` environment variable) giving the jar files and folder roots of package hierarchies for all the class, source and specification files. The details are an advanced topic presented [here](SpecificationFiles).
27
27
28
28
A simple, example command-line is `openjml --esc --progress A.java` .
Copy file name to clipboardExpand all lines: tutorial/FrameConditions.md
+5-5Lines changed: 5 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,7 +20,7 @@ in the pre-state, that is, the state at the beginning of the method's execution.
20
20
`counter1` without the `\old` designator means the value of `counter1` in the
21
21
post-state, the state after the method has completed.
22
22
23
-
Also, why the comparison to `Integer.MAX_VALUE`? That is to avoid warnings about arithmetic overflow. We'll get to that topic [later](ArithmeticModes).
23
+
Also, why the comparison to `Integer.MAX_VALUE` in the preconditions? That is to avoid warnings about arithmetic overflow. We'll get to that topic [later](ArithmeticModes).
24
24
25
25
Now to the point of this lesson. The two increment methods verify, but
26
26
what is happening in the test method?
@@ -36,7 +36,7 @@ that `counter2` is unchanged. One solution would be to add an additional
36
36
ensures clause that states that `counter2 == \old(counter2)`. This specification
37
37
verifies as correct.
38
38
39
-
But this is not a practical solution. We can't add to `increment1()`'s specification a clause stating that every visible variable is unchanged.
39
+
But adding such postconditions is not a practical solution. We can't add to `increment1()`'s specification a clause stating that every visible variable is unchanged.
40
40
Instead we use a *frame condition* whose purpose is to state which memory
41
41
locations a method might have modified. There are a variety of names for
42
42
the frame clause: traditionally it is `assignable`, but `assigns` and `writes` are also permitted.
@@ -70,12 +70,12 @@ program state outside of the method.
70
70
* The formal arguments of the method are in scope for the frame condition,
71
71
just like for the `requires` and `ensures` clauses. The formal arguments
72
72
themselves cannot be changed by a method, but if they are references to objects,
73
-
their fields might be written to by a method. So a method `m(MyType q)`
73
+
then the fields of those objects might be written to by the method. So a method `m(MyType q)`
74
74
might have a frame condition `assigns q.f;` if `f` is a field of `MyType`
75
75
that is written to in the body of `m`.
76
76
* If a method has no external effects other than its return value, you can specify a frame condition `assigns \nothing;`
77
77
*`q.*` for an expression `q` means all fields of q
78
-
*`a[i]` for expression`a` and `i` means that particular array element
78
+
*`a[i]` for expressions`a` and `i` means the particular array element`a[i]` (where the values of `a` and `i` are interpreted in the method's pre-state)
79
79
*`a[*]` for array expression `a` means all elements of that array
80
80
*`a[i..j]` for expressions `a`, `i`, and `j` means the stated range of array elements, from `i` to `j` inclusive.
81
81
@@ -88,7 +88,7 @@ public void m() { ... }
88
88
```
89
89
though there are a few other details to purity --- see the [lesson on pure](MethodsInSpecifications).
90
90
91
-
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.
91
+
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. This allows callers of the method to understand the potential side-effects of the method before calling it.
92
92
93
93
Second, a frame condition is a method specification clause like `requires` and `ensures`. A method specification may contain more than one such clause.
94
94
However, note that each clause is considered individually. That is, each clause
Sometimes it is the case that certain properties must hold at the end of every constructor or every method.
6
-
Then the specifications for each method or constructor have to repeat the same specification clause.
7
-
There is a danger that (a) such a clause will be forgotten for some constructor or method and (b) if the clause needs to be modified, it will not be correctly changed in every place it appears.
5
+
Sometimes certain properties must hold at the end of every constructor or every method.
6
+
Then the specifications for each method or constructor would have to repeat the same specification clause in every constructor or method's specification.
7
+
However, there is a danger that: (a) such a clause will be forgotten for some constructor or method and (b) if the clause needs to be modified, it will not be correctly changed in every place it appears.
8
8
9
-
So JML has a few features to coalesce such replicated clauses. These clauses are part of the _class_ declaration, but apply to every method or constructor as described below.
9
+
So JML has a few features to coalesce such replicated clauses. These clauses are part of the _class_ declaration, but apply to every method or constructor in the class (or interface) as described below.
10
10
11
11
## Initially clauses
12
12
13
-
An `initially` clause at the class level is equivalent to a corresponding `ensures` clause at the end of every constructor, including an unwritten default constructor. For example, suppose we are constructing rectangles and want to ensure that, at least upon construction, every such rectangle has a length larger than its width, which is larger than 0. We might write
13
+
An `initially` clause at the class level is equivalent to a corresponding `ensures` clause at the end of every constructor, including any unwritten default constructor. For example, suppose we are constructing rectangles and want to ensure that, at least upon construction, every such rectangle has a length larger than its width, which is larger than 0. We might write
14
14
```
15
15
{% include_relative T_initially1.java %}
16
16
```
@@ -20,7 +20,7 @@ This yields
20
20
```
21
21
This verification failure is understandable. We did not specify a precondition that `0 < width < length`, so the stated initially clause cannot be fulfilled.
22
22
But why is there no failure for the second constructor? The second constructor calls `this(0,0)`, using the first constructor. Because it is calling that
23
-
constructor, it only uses that constructor's specifications in reasoning about its own implementation. So the second constructor sees
23
+
constructor, it only uses that constructor's specifications in reasoning about its own implementation. So the call of the first constructor by the second constructor sees
@@ -32,13 +32,13 @@ If we insert a precondition to fix the verification of the first constructor, we
32
32
```
33
33
{% include_relative T_initially2.java %}
34
34
```
35
-
which yeilds
35
+
which yields:
36
36
```
37
37
{% include_relative T_initially2.out %}
38
38
```
39
39
Now the first constructor passes verification, but the second one does not. The reason is obvious:
40
-
the size we have given for a default rectangle (0 by 0) does not satisfy our desired `initially` postcondition.
41
-
We'll have a to pick a different size -- 1x2 perhaps.
40
+
the size we have given for a default rectangle (0 by 0) does not satisfy our desired `initially` postcondition, which was enforced by the new precondition on the first constructor.
41
+
To fix this failure, we would have a to pick different sizes -- 1x2 perhaps.
Copy file name to clipboardExpand all lines: tutorial/MethodCalls.md
+6-4Lines changed: 6 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,14 +2,16 @@
2
2
title: JML Tutorial - Method Calls
3
3
---
4
4
5
-
We have seen how to verify methods that have pre- and postconditions to describe
5
+
We have seen how to verify method implementations that have
6
+
pre- and postconditions describing
6
7
the behavior of method bodies that contain if statements and assignments.
7
8
Now let's progress to method calls.
8
9
9
10
The key point to remember is that verification in JML (and other similar
10
11
deductive verification languages and tools) is *modular by method*.
11
12
That is, each method is verified on its own; only when all methods are
12
-
verified with a consistent set of specifications across all of them can the program as a whole be
13
+
verified with a consistent set of specifications
14
+
across all of them can the program as a whole be
13
15
considered verified.
14
16
15
17
Consider two methods, a caller and a callee, as shown in this diagram.
@@ -30,7 +32,7 @@ pre- and post-conditions. We know that the callee's postconditions will be true
30
32
* must prove (assert) that the callee's preconditions hold
31
33
* and then it may assume that the callee's postconditions will hold
32
34
33
-
As long as we keep the callee's specifications the same, we can verify the callee and the caller independently.
35
+
As long as we keep the callee's specifications the same, we can verify the callee and the caller independently. (Thus the callee's specification is a summary of its behavior and is not affected by the callee's implementation details.)
34
36
35
37
It is easy to see that this process works for verifying the methods in a program that do not call anything, to those methods that just call those leaves, all the way up to the top-level methods of the program. It can also be demonstrated that this process is sound when there are recursive calls, as long as it can
36
38
be proved that the program terminates.
@@ -51,7 +53,7 @@ the `--progress` option, so we receive quite a bit more output.
51
53
Looking at this piece by piece:
52
54
* The method `lessThanDouble` requires positive inputs with the first argument
53
55
larger than the second. It returns true if the first argument is less than double the second. The method proves without a problem.
54
-
The output about `lessThanDouble` is near the end of the listing.
56
+
The output about `lessThanDouble` is near the end of the verification listing above.
55
57
* The default constructor `T_CallerCallee()` also verifies without problem.
56
58
* The method `caller1` calls `lessThanDouble` for two test cases and checks
57
59
that the result is what is expected. This method also verifies.
0 commit comments