Skip to content

Commit df376a5

Browse files
author
davidcok
committed
More tutorial example editing
1 parent 93e2689 commit df376a5

14 files changed

+69
-22
lines changed

tutorial/Loops.md

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,16 @@ It may help to understand what the verifier tries to prove about a loop. It prov
5050
* and does the update step
5151
* and the result must satisfy the loop invariants again (with the updated value of the loop index)
5252
* and also the termination expression must have decreased
53-
* Third, it assumes the first two steps above but that the loop condition is false and goes on to reason about any program steps and postconditions that follow the loop.
53+
* Third, it assumes the first two steps above and that the loop condition is false, and then proves that the loop invariants still hold
5454

5555
In the example above, the second proof obligation assumes `0 <= i <= a.length` and `\forall int k; 0 <= k < i; a[k] == k;` and
5656
`(i < a.length)`, and then applies `a[i]=i` and `i++`, and proves `\forall int k; 0 <= k < i'; a[k]==k`, where `i'` is the updated `i`.
5757

5858
It also must prove that `a.length-i` is non-negative at the start of the loop body and that after the loop index update that value is greater than
5959
the new value of the expression, namely `a.length-i'`.
6060

61-
The third proof obligation assumes `0 <= i <= a.length` and `\forall int k; 0 <= k < i; a[k] == k;` and `!(i < a.length)`, from which it can prove the `assert` statement.
61+
The third proof obligation assumes `0 <= i <= a.length` and `\forall int k; 0 <= k < i; a[k] == k;` and `!(i < a.length)`;
62+
the loop invariants are still true, trivailly and they in turn imply the truth of the `assert` statement.
6263

6364
## For-each loops
6465

@@ -84,19 +85,11 @@ A while loop generally follows the same pattern as a traditional for loop. Here
8485

8586
## Do-while loops
8687

87-
Do-while loops can be tricky to specify because they do not follow the same update-at-the-start of a loop pattern. Here is a simple example.
88+
Do-while loops can be tricky to specify because they do not follow the same update-at-the-start of a loop pattern. Also, the loop body is executed at least once, because the
89+
loop condition is not evaluated until the end of the loop body. Here is a simple example.
8890
```
8991
{% include_relative T_dowhile.java %}
9092
```
91-
Here the order of assumptions is this:
92-
* assume the loop invariants
93-
* execute the body
94-
* do the loop test (which in this example incorporates the loop update)
95-
* check that the loop invariants still hold
96-
97-
Because the loop update and test are at the end of the body, the initial loop invariant only reflects the possible values at the start of the loop; the final increment and exit from the loop happen without
98-
checking the loop invariant again. So the loop invariant here is `0 <= i < 10`, not `0 <= i <= 10`.
99-
10093

10194
## Loop verification errors
10295

@@ -146,4 +139,9 @@ which produces
146139
{% include_relative T_LoopNegativeError.out %}
147140
```
148141

142+
## Loop conditions with side effects
143+
144+
Good programming style avoids loop conditions with side effects. Nevertheless, such constructs are legal Java.
145+
However, writing workable specifications for such programs is tricky, reflecting the fact that understanding and writing correct programs using conditions with side-effects is tricky.
146+
149147
## **[Specifying Loops Problem Set](https://www.openjml.org/tutorial/exercises/SpecifyingLoopsEx.html)**

tutorial/SpecStatements.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: Specifications in Method Bodies
2+
title: JML Tutorial - Specifications in Method Bodies
33
---
44

55
The basic unit of specification and verification in JML is the method,

tutorial/T_dowhile.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ public class T_dowhile {
44
//@ requires 20 < a.length;
55
public void test(int[] a) {
66
int i = 0;
7+
//@ maintaining i == \count;
78
//@ maintaining 0 <= i <= 10;
8-
//@ maintaining i == \count && (\count > 0 ==> i < 10);
99
//@ maintaining \forall int k; 0 <= k < i; a[k] == 0;
1010
//@ loop_writes i, a[*];
1111
//@ decreases 10-i;
1212
do {
1313
a[i] = 0;
14-
} while (++i < 10);
14+
++i;
15+
} while (i < 10);
1516
//@ assert \forall int k; 0 <= k < 10; a[k] == 0;
1617
}
1718
}

tutorial/T_foreach.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ public boolean allPositive(int[] a) {
77
//@ maintaining \forall int k; 0 <= k < \count; a[k] > 0;
88
//@ loop_writes \nothing;
99
//@ decreases a.length - \count;
10-
for (int i: a) {
11-
if (i <= 0) return false;
10+
for (int v: a) {
11+
if (v <= 0) return false;
1212
}
1313
return true;
1414
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
ArithmeticExample2.java:9: verify: The prover cannot establish an assertion (ArithmeticOperationRange) in method updatePlayerHealth: overflow in int sum
2+
return (playerHealth + dmg);
3+
^
4+
1 verification failure
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
AssertExample2.java:22: verify: The prover cannot establish an assertion (Postcondition: AssertExample2.java:4:) in method primeChecker
2+
return isPrime;
3+
^
4+
AssertExample2.java:4: verify: Associated declaration: AssertExample2.java:22:
5+
//@ ensures \result <==> !(\exists int i; i >= 2; num % i == 0);
6+
^
7+
2 verification failures
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
CallingMethodsExample1.java:40: verify: The prover cannot establish an assertion (Assert) in method testClass
2+
//@ assert isClassFailing(classGrades);
3+
^
4+
1 verification failure
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CallingMethodsExample2.java:42: warning: A non-pure method is being called where it is not permitted: CallingMethodsExample2.isClassFailing(double[])
2+
//@ assert isClassFailing(classGrades);
3+
^
4+
CallingMethodsExample2.java:42: verify: The prover cannot establish an assertion (Assert) in method testClass
5+
//@ assert isClassFailing(classGrades);
6+
^
7+
1 warning
8+
1 verification failure
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
MethodCallsExample2.java:14: verify: The prover cannot establish an assertion (Assert) in method enoughMaterial
2+
//@ assert (area > materialSqFt);
3+
^
4+
1 verification failure
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
SpecifyingExceptionsExample2.java:10: error: cannot find symbol
2+
@ ensures \result == str.length % tableSize;
3+
^
4+
symbol: variable length
5+
location: variable str of type String
6+
1 error

0 commit comments

Comments
 (0)