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
Copy file name to clipboardExpand all lines: tutorial/Loops.md
+10-12Lines changed: 10 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -50,15 +50,16 @@ It may help to understand what the verifier tries to prove about a loop. It prov
50
50
* and does the update step
51
51
* and the result must satisfy the loop invariants again (with the updated value of the loop index)
52
52
* 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
54
54
55
55
In the example above, the second proof obligation assumes `0 <= i <= a.length` and `\forall int k; 0 <= k < i; a[k] == k;` and
56
56
`(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`.
57
57
58
58
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
59
59
the new value of the expression, namely `a.length-i'`.
60
60
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.
62
63
63
64
## For-each loops
64
65
@@ -84,19 +85,11 @@ A while loop generally follows the same pattern as a traditional for loop. Here
84
85
85
86
## Do-while loops
86
87
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.
88
90
```
89
91
{% include_relative T_dowhile.java %}
90
92
```
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
-
100
93
101
94
## Loop verification errors
102
95
@@ -146,4 +139,9 @@ which produces
146
139
{% include_relative T_LoopNegativeError.out %}
147
140
```
148
141
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
+
149
147
## **[Specifying Loops Problem Set](https://www.openjml.org/tutorial/exercises/SpecifyingLoopsEx.html)**
ArithmeticExample2.java:9: verify: The prover cannot establish an assertion (ArithmeticOperationRange) in method updatePlayerHealth: overflow in int sum
0 commit comments