Skip to content

Commit 5d7798f

Browse files
committed
Add doc and examples
1 parent 7209861 commit 5d7798f

2 files changed

Lines changed: 180 additions & 0 deletions

File tree

doc/tactics/async-while.rst

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
========================================================================
2+
Tactic: ``async while`` Tactic
3+
========================================================================
4+
5+
The ``async while`` tactic applies to probabilistic relational Hoare Logic
6+
goals where the programs contains a ``while`` loop.
7+
Unlike the ``while`` tactic, the ``async while`` tactic allows to reason
8+
on loop which are not in lockstep.
9+
10+
------------------------------------------------------------------------
11+
Syntax
12+
------------------------------------------------------------------------
13+
14+
The general form of the tactic is:
15+
16+
.. admonition:: Syntax
17+
18+
``async while [f1,k1] [f2,k2] (L1) (L2) : (I)``
19+
20+
Here:
21+
22+
- ``L1`` and ``L2`` are the left and right condition to control if we
23+
consider the lockstep case, or the oneside case,
24+
- ``k1`` and ``k2`` are natural number
25+
- ``f1`` and ``f2`` are the unrolling condition, initial by the parameter
26+
``k1`` and ``k2``.
27+
28+
Concretely, the tactic implements the following rule::
29+
30+
I => (b1 <=> b2 /\ (!L1 /\ !L2 => f1 k1 /\ f2 k2)) \/ (L1 /\ b1) \/ (L2 /\ b2)
31+
equiv[ while (b1 /\ f k1) {c1} ~ while (b2 /\ f k2) {c2}:
32+
I /\ b1 <=> b2 /\ !L1 /\ !L2 /\ f1 k1 /\ f2 k2 ==> I ]
33+
hoare[ c1: I /\ b1 /\ L1 /\ ==> I ]
34+
hoare[ c2: I /\ b2 /\ L2 /\ ==> I ]
35+
phoare[ while b1 {c1}: I /\ b1 /\ L1 /\ ==> True ]
36+
phoare[ while b2 {c2}: I /\ b2 /\ L2 /\ ==> True ]
37+
(Pre => I) /\ (I /\ !b1 /\ !b2 => Post)
38+
-------------------------------------------------------------------------------------------
39+
equiv[while b1 {c1} ~ while b2 {c2}: Pre ==> Post]
40+
41+
The following example shows ``async while`` on a prhl goal. The program
42+
increments ``x`` until it reaches ``10``.
43+
44+
.. ecproof::
45+
46+
require import AllCore.
47+
48+
module M = {
49+
proc up_to_10(x : int) : int = {
50+
while (x < 10) {
51+
x <- x + 1;
52+
}
53+
return x;
54+
}
55+
proc up_to_10_by_2(x : int) : int = {
56+
while (x < 10) {
57+
x <- x + 1;
58+
if ( x < 10) x <- x + 1;
59+
}
60+
return x;
61+
}
62+
63+
}.
64+
65+
lemma asynctwhile_example :
66+
equiv[M.up_to_10 ~ M.up_to_10_by_2 : ={x} ==> ={res}].
67+
proof.
68+
proc.
69+
async while
70+
[ (fun r => x <= r + 1), (x{1} ) ]
71+
[ (fun r => x <= r ), (x{2} ) ]
72+
(!(x{1} < 10)) (!(x{2} < 10))
73+
: (x{1} = x{2}).
74+
+ move=> &1 &2 => /#.
75+
+ move => v1 v2 //=.
76+
unroll {1} 1.
77+
unroll {1} 2.
78+
unroll {2} 1.
79+
rcondt {1} 1; auto.
80+
rcondt {2} 1; auto.
81+
sp 1 1.
82+
if => //.
83+
sp 1 1.
84+
while (!(x{1} < 10 /\ (x{1} < 10 /\ (x{1} <= v1 + 1))) /\
85+
!(x{2} < 10 /\ (x{2} < 10 /\ (x{2} <= v2 ))) /\ ={x}); auto => /#.
86+
while (!(x{1} < 10 /\ (x{1} < 10 /\ (x{1} <= v1 + 1))) /\
87+
!(x{2} < 10 /\ (x{2} < 10 /\ (x{2} <= v2 ))) /\ ={x}); auto => /#.
88+
+ move => &2; exfalso=> &1 ? /#.
89+
+ move => &1; exfalso=> &2 ? /#.
90+
+ exfalso => /#.
91+
+ exfalso => /#.
92+
+ by auto.
93+
qed.

examples/async_while.ec

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
require import AllCore.
2+
3+
module M = {
4+
proc up_to_10(x : int) : int = {
5+
while (x < 10) {
6+
x <- x + 1;
7+
}
8+
return x;
9+
}
10+
proc up_to_10_by_2(x : int) : int = {
11+
while (x < 10) {
12+
x <- x + 1;
13+
if ( x < 10) x <- x + 1;
14+
}
15+
return x;
16+
}
17+
18+
}.
19+
20+
lemma asynctwhile_example :
21+
equiv[M.up_to_10 ~ M.up_to_10_by_2 : ={x} ==> ={res}].
22+
proof.
23+
proc.
24+
async while
25+
[ (fun r => x <= r + 1), (x{1} ) ]
26+
[ (fun r => x <= r ), (x{2} ) ]
27+
(!(x{1} < 10)) (!(x{2} < 10))
28+
: (x{1} = x{2}).
29+
+ move=> &1 &2 => /#.
30+
+ move => v1 v2 //=.
31+
unroll {1} 1.
32+
unroll {1} 2.
33+
unroll {2} 1.
34+
rcondt {1} 1; auto.
35+
rcondt {2} 1; auto.
36+
sp 1 1.
37+
if => //.
38+
sp 1 1.
39+
while (!(x{1} < 10 /\ (x{1} < 10 /\ (x{1} <= v1 + 1))) /\
40+
!(x{2} < 10 /\ (x{2} < 10 /\ (x{2} <= v2 ))) /\ ={x}); auto => /#.
41+
while (!(x{1} < 10 /\ (x{1} < 10 /\ (x{1} <= v1 + 1))) /\
42+
!(x{2} < 10 /\ (x{2} < 10 /\ (x{2} <= v2 ))) /\ ={x}); auto => /#.
43+
+ move => &2; exfalso=> &1 ? /#.
44+
+ move => &1; exfalso=> &2 ? /#.
45+
+ exfalso => /#.
46+
+ exfalso => /#.
47+
+ by auto.
48+
qed.
49+
50+
module M1 = {
51+
proc spin_once(i1:bool): bool = {
52+
while (i1) {
53+
i1 <- !i1;
54+
}
55+
return i1;
56+
}
57+
58+
proc spin(i2:bool): bool = {
59+
while (i2) {
60+
}
61+
return i2;
62+
}
63+
}.
64+
65+
op b0:bool.
66+
op b1:bool.
67+
op b2:bool.
68+
op b3:bool.
69+
op b4:bool.
70+
op f1:int -> bool.
71+
op n1:int.
72+
op f2:int -> bool.
73+
op n2:int.
74+
75+
equiv L: M1.spin_once ~ M1.spin:
76+
b0 ==> b4.
77+
proof.
78+
proc.
79+
async while [f1,n1] [f2,n2] (b1) (b2) : (b3).
80+
- admit. (* soundness condition*)
81+
- admit. (*left*)
82+
- admit. (*right*)
83+
- admit. (*lockstep equiv*)
84+
- admit. (*losless left*)
85+
- admit. (*losless right*)
86+
- admit. (*invariant implies post*)
87+
qed.

0 commit comments

Comments
 (0)