Skip to content

Commit ed3f840

Browse files
committed
Add doc and examples
1 parent 512dda6 commit ed3f840

File tree

2 files changed

+178
-0
lines changed

2 files changed

+178
-0
lines changed

doc/tactics/async-while.rst

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
========================================================================
2+
Tactic: ``asyncwhile`` Tactic
3+
========================================================================
4+
5+
The ``asyncwhile`` tactic applies to probabilistic relational Hoare Logic
6+
goals where the programs contains a ``while`` loop.
7+
Unlike the ``while`` tactic, the ``asyncwhile`` 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 rulee::
29+
30+
I => (b1 <=> b2 /\ (!L1 /\ !L2 => f1 k1 /\ f2 k2)) \/ (L1 /\ b1) \/ (L2 /\ b2)
31+
equiv[while b1 {c1} ~ while {b2} c2: I /\ b1 <=> b2 /\ !L1 /\ !L2 /\ f1 k1 /\ f2 k2 ==> I]
32+
equiv[while b1 {c1} ~ skip: I /\ b1 /\ L1 /\ ==> I]
33+
equiv[skip ~ while b2 {c2}: I /\ b2 /\ L2 /\ ==> I]
34+
(Pre => I) /\ (I /\ !b1 /\ !b2 => Post)
35+
-------------------------------------------------------------------------------------------
36+
equiv[while b1 {c1} ~ while {b2} c2: Pre ==> Post]
37+
38+
The following example shows ``asynctwhile`` on a prhl goal. The program
39+
increments ``x`` until it reaches ``10``.
40+
41+
.. ecproof::
42+
43+
require import AllCore.
44+
45+
module M = {
46+
proc up_to_10(x : int) : int = {
47+
while (x < 10) {
48+
x <- x + 1;
49+
}
50+
return x;
51+
}
52+
proc up_to_10_by_2(x : int) : int = {
53+
while (x < 10) {
54+
x <- x + 1;
55+
if ( x < 10) x <- x + 1;
56+
}
57+
return x;
58+
}
59+
60+
}.
61+
62+
lemma asynctwhile_example :
63+
equiv[M.up_to_10 ~ M.up_to_10_by_2 : ={x} ==> ={res}].
64+
proof.
65+
proc.
66+
async while
67+
[ (fun r => x <= r + 1), (x{1} ) ]
68+
[ (fun r => x <= r ), (x{2} ) ]
69+
(!(x{1} < 10)) (!(x{2} < 10))
70+
:
71+
(x{1} = x{2}) => //=.
72+
+ move=> &1 &2. smt.
73+
+ move => v1 v2 //=.
74+
unroll {1} 1.
75+
unroll {1} 2.
76+
unroll {2} 1.
77+
rcondt {1} 1. auto.
78+
rcondt {2} 1. auto.
79+
sp 1 1.
80+
if. smt.
81+
sp 1 1.
82+
while (!(x{1} < 10 /\ (x{1} < 10 /\ (x{1} <= v1 + 1))) /\
83+
!(x{2} < 10 /\ (x{2} < 10 /\ (x{2} <= v2 ))) /\ ={x}); auto; smt.
84+
while (!(x{1} < 10 /\ (x{1} < 10 /\ (x{1} <= v1 + 1))) /\
85+
!(x{2} < 10 /\ (x{2} < 10 /\ (x{2} <= v2 ))) /\ ={x}); auto; smt.
86+
+ move => &2. exfalso=> &1 ?. smt.
87+
+ move => &1. exfalso=> &2 ?. smt.
88+
+ exfalso. smt.
89+
+ exfalso. smt.
90+
qed.

examples/async_while.ec

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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+
:
29+
(x{1} = x{2}) => //=.
30+
+ move=> &1 &2. smt.
31+
+ move => v1 v2 //=.
32+
unroll {1} 1.
33+
unroll {1} 2.
34+
unroll {2} 1.
35+
rcondt {1} 1. auto.
36+
rcondt {2} 1. auto.
37+
sp 1 1.
38+
if. smt.
39+
sp 1 1.
40+
while (!(x{1} < 10 /\ (x{1} < 10 /\ (x{1} <= v1 + 1))) /\
41+
!(x{2} < 10 /\ (x{2} < 10 /\ (x{2} <= v2 ))) /\ ={x}); auto; smt.
42+
while (!(x{1} < 10 /\ (x{1} < 10 /\ (x{1} <= v1 + 1))) /\
43+
!(x{2} < 10 /\ (x{2} < 10 /\ (x{2} <= v2 ))) /\ ={x}); auto; smt.
44+
+ move => &2. exfalso=> &1 ?. smt.
45+
+ move => &1. exfalso=> &2 ?. smt.
46+
+ exfalso. smt.
47+
+ exfalso. smt.
48+
qed.
49+
50+
51+
module M1 = {
52+
proc spin_once(i1:bool): bool = {
53+
while (i1) {
54+
i1 <- !i1;
55+
}
56+
return i1;
57+
}
58+
59+
proc spin(i2:bool): bool = {
60+
while (i2) {
61+
}
62+
return i2;
63+
}
64+
}.
65+
66+
op b0:bool.
67+
op b1:bool.
68+
op b2:bool.
69+
op b3:bool.
70+
op b4:bool.
71+
op f1:int -> bool.
72+
op n1:int.
73+
op f2:int -> bool.
74+
op n2:int.
75+
76+
equiv L: M1.spin_once ~ M1.spin:
77+
b0 ==> b4.
78+
proof.
79+
proc.
80+
async while [f1,n1] [f2,n2] (b1) (b2) : (b3).
81+
- admit. (* soundness condition*)
82+
- admit. (*left*)
83+
- admit. (*right*)
84+
- admit. (*lockstep equiv*)
85+
- admit. (*losless left*)
86+
- admit. (*losless right*)
87+
- admit. (*invariant implies post*)
88+
qed.

0 commit comments

Comments
 (0)