Skip to content

Commit 9dc1dc3

Browse files
committed
[documentation]: document while tactic
1 parent c3a0bf3 commit 9dc1dc3

1 file changed

Lines changed: 132 additions & 0 deletions

File tree

doc/tactics/while.rst

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
========================================================================
2+
Tactic: ``while``
3+
========================================================================
4+
5+
The ``while`` tactic applies to program-logic goals where the next
6+
statement to reason about is a ``while`` loop.
7+
8+
Applying ``while`` replaces the original goal with proof obligations that let
9+
you reason about the loop via an invariant (and, in some variants, a
10+
termination variant). Intuitively, you prove that the invariant is preserved
11+
by one iteration of the loop, and you then use the invariant to justify what
12+
follows once the loop condition becomes false.
13+
14+
.. contents::
15+
:local:
16+
17+
------------------------------------------------------------------------
18+
Variant: Hoare logic
19+
------------------------------------------------------------------------
20+
21+
.. admonition:: Syntax
22+
23+
``while ({formula})``
24+
25+
The formula is a loop invariant. It may reference variables of the program.
26+
27+
Applying this form of ``while`` generates (at least) the following goals:
28+
29+
- **Preservation goal (one iteration):** assuming the invariant holds and the
30+
loop condition is true, executing the loop body re-establishes the invariant.
31+
32+
- **Exit/continuation goal:** you must show that the invariant holds when the
33+
loop is entered, and that when the loop condition becomes false, the
34+
invariant is strong enough to derive the desired postcondition.
35+
36+
.. ecproof::
37+
:title: Hoare logic example
38+
39+
require import AllCore.
40+
41+
module M = {
42+
proc sumsq(n : int) : int = {
43+
var x, i;
44+
x <- 0;
45+
i <- 0;
46+
while (i < n) {
47+
x <- x + (i + 1);
48+
i <- i + 1;
49+
}
50+
return x;
51+
}
52+
}.
53+
54+
lemma ex_while_hl (n : int) :
55+
hoare [M.sumsq : 0 <= n ==> 0 <= res].
56+
proof.
57+
proc.
58+
(*$*) while (0 <= i <= n /\ 0 <= x).
59+
- admit.
60+
- admit.
61+
qed.
62+
63+
------------------------------------------------------------------------
64+
Variant: Probabilistic relational Hoare logic (one-sided)
65+
------------------------------------------------------------------------
66+
67+
.. admonition:: Syntax
68+
69+
``while {side} {formula} {expr}``
70+
71+
Here `{formula}` is a relational invariant, and `{expr}` is an integer-valued
72+
termination variant. This variant applies when the designated program by
73+
``{side}`` ends with a `while` loop.
74+
75+
Applying this form of ``while`` generates two main goals:
76+
77+
- **Loop-body goal (designated side):** assuming the invariant holds and the
78+
loop condition is true, executing the loop body re-establishes the
79+
invariant and decreases the variant.
80+
81+
- **Remaining relational goal:** the loop is removed from the designated
82+
program, and the postcondition is strengthened with the invariant together
83+
with pure logical conditions connecting loop exit to the desired
84+
postcondition.
85+
86+
.. ecproof::
87+
:title: Relational example (shape)
88+
89+
require import AllCore.
90+
91+
module M = {
92+
proc sumsq(n : int) : int = {
93+
var x, i;
94+
x <- 0;
95+
i <- 0;
96+
while (i < n) {
97+
x <- x + (i + 1);
98+
i <- i + 1;
99+
}
100+
return x;
101+
}
102+
}.
103+
104+
lemma ex_while_prhl :
105+
equiv [ M.sumsq ~ M.sumsq : ={n} ==> res{1} = res{2} ].
106+
proof.
107+
proc.
108+
(*$*) while{1} (true) (0).
109+
- admit.
110+
- admit.
111+
qed.
112+
113+
------------------------------------------------------------------------
114+
Variant: Probabilistic Hoare logic
115+
------------------------------------------------------------------------
116+
117+
.. admonition:: Syntax
118+
119+
``while {formula} {expr}``
120+
121+
Here ``{formula}`` is an invariant and ``{expr}`` is an integer termination
122+
variant.
123+
124+
At a high level, this variant generates obligations analogous to the
125+
designated relational case, but for a single program:
126+
127+
- a probabilistic goal for the loop body showing preservation of the
128+
invariant and strict progress of the variant, and
129+
130+
- a remaining goal for the code before the loop, whose postcondition is
131+
strengthened with the invariant plus pure logical conditions that connect
132+
loop exit to the desired postcondition.

0 commit comments

Comments
 (0)