Skip to content

Commit 2fe90ee

Browse files
committed
add documentation
1 parent c7af01d commit 2fe90ee

File tree

2 files changed

+196
-0
lines changed

2 files changed

+196
-0
lines changed

doc/tactics/simplify-if.rst

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
========================================================================
2+
Tactic: `simplify if`
3+
========================================================================
4+
5+
The `simplify if` performs an if-conversion on program statement,
6+
i.e it transform if statement into if expression. This transformation preserves the semantics.
7+
This allows to obtain a statement where the weakest precondition does not grow
8+
exponentially in the number of if.
9+
10+
To illustrate the problem here is an example that show how grow the weakest pre-condition:
11+
.. ecproof::
12+
:title: Weakest pre-condition grow exponentially.
13+
14+
require import AllCore.
15+
16+
module M = {
17+
proc f (j:int) : int * int = {
18+
var i, x, y;
19+
x <- 0;
20+
y <- 0;
21+
i <- 0;
22+
while (i < 6) {
23+
if (i = j) x <- i;
24+
else y <- y + i;
25+
i <- i + 1;
26+
}
27+
return (x, y);
28+
}
29+
}.
30+
31+
hoare fP j_: M.f : j = j_ ==> res = if 0 <= j_ < 6 then (j_, 15 - j_) else (0,15).
32+
proof.
33+
proc.
34+
unroll for ^while.
35+
(*$*) time wp. (* The size of the condition grow exponentially in the value of the bound (here 6). *)
36+
skip.
37+
move => />.
38+
smt().
39+
qed.
40+
41+
.. admonition:: Syntax
42+
43+
Since the tactic preserves the semantic it applies to all program logics.
44+
45+
`simplify if side? codepos?`
46+
47+
The `side` argument is required when the goal is a `equiv` judgment, it allows to select
48+
on which side you want to apply the program transformation. The `codepos` argument allows
49+
to specify on which `if` instruction you want to apply the transformation.
50+
51+
52+
.. contents::
53+
:local:
54+
55+
------------------------------------------------------------------------
56+
Variant: Transform at a given code possition
57+
------------------------------------------------------------------------
58+
The tactic applies only if the branches of selected the `if` instruction are only composed of
59+
assignment.
60+
61+
.. exproof::
62+
: title: Hoare logic example selecting where to apply the transformation
63+
require import AllCore.
64+
65+
module M = {
66+
proc f (j:int) : int * int = {
67+
var i, x, y;
68+
x <- 0;
69+
y <- 0;
70+
i <- 0;
71+
while (i < 6) {
72+
if (i = j) x <- i;
73+
else y <- y + i;
74+
i <- i + 1;
75+
}
76+
return (x, y);
77+
}
78+
}.
79+
80+
hoare fP_simplify2 j_: M.f : j = j_ ==> res = if 0 <= j_ < 6 then (j_, 15 - j_) else (0,15).
81+
proof.
82+
proc.
83+
unroll for ^while.
84+
(* You can select a particular occurence of if using codepos *)
85+
(*$*) simplify if ^if. (* Apply the transformation on the first if *)
86+
simplify if ^if{2}. (* Apply the transformation on the second if *)
87+
simplify if ^if{-2}. (* Apply the trnasformation of the penultimate if *)
88+
time wp.
89+
skip.
90+
move => />.
91+
smt().
92+
qed.
93+
94+
------------------------------------------------------------------------
95+
Variant: Transform as much as possible
96+
------------------------------------------------------------------------
97+
98+
.. admonition:: Syntax
99+
100+
`simplify if`
101+
102+
This variant try to find a position where the transformation is possible and applies it.
103+
This is repeated until no position is found.
104+
105+
.. ecproof::
106+
:title: Hoare logic example
107+
108+
require import AllCore.
109+
110+
module M = {
111+
proc f (j:int) : int * int = {
112+
var i, x, y;
113+
x <- 0;
114+
y <- 0;
115+
i <- 0;
116+
while (i < 6) {
117+
if (i = j) x <- i;
118+
else y <- y + i;
119+
i <- i + 1;
120+
}
121+
return (x, y);
122+
}
123+
}.
124+
125+
hoare fP_simplify j_: M.f : j = j_ ==> res = if 0 <= j_ < 6 then (j_, 15 - j_) else (0,15).
126+
proof.
127+
proc.
128+
unroll for ^while.
129+
(*$*)simplify if. (* if instruction are transformed into single assignment *)
130+
time wp. (* The size of the wp is now linear in the number of instruction *)
131+
skip.
132+
move => />.
133+
smt().
134+
qed.

examples/tactics/simplify_if.ec

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
require import AllCore.
2+
3+
module M = {
4+
proc f (j:int) : int * int = {
5+
var i, x, y;
6+
x <- 0;
7+
y <- 0;
8+
i <- 0;
9+
while (i < 6) {
10+
if (i = j) x <- i;
11+
else y <- y + i;
12+
i <- i + 1;
13+
}
14+
return (x, y);
15+
}
16+
}.
17+
18+
hoare fP j_: M.f : j = j_ ==> res = if 0 <= j_ < 6 then (j_, 15 - j_) else (0,15).
19+
proof.
20+
proc.
21+
unroll for ^while.
22+
time wp. (* The size of the condition grow exponentially in the value of the bound (here 6). *)
23+
skip.
24+
move => />.
25+
smt().
26+
qed.
27+
28+
hoare fP_simplify j_: M.f : j = j_ ==> res = if 0 <= j_ < 6 then (j_, 15 - j_) else (0,15).
29+
proof.
30+
proc.
31+
unroll for ^while.
32+
simplify if. (* if instruction are transformed into single assignment *)
33+
time wp. (* The size of the wp is now linear in the number of instruction *)
34+
skip.
35+
move => />.
36+
smt().
37+
qed.
38+
39+
hoare fP_simplify2 j_: M.f : j = j_ ==> res = if 0 <= j_ < 6 then (j_, 15 - j_) else (0,15).
40+
proof.
41+
proc.
42+
unroll for ^while.
43+
(* You can select a particular occurence of if using codepos *)
44+
simplify if ^if. (* Apply the transformation on the first if *)
45+
simplify if ^if{2}. (* Apply the transformation on the second if *)
46+
simplify if ^if{-2}. (* Apply the trnasformation of the penultimate if *)
47+
time wp.
48+
skip.
49+
move => />.
50+
smt().
51+
qed.
52+
53+
54+
55+
56+
57+
58+
59+
60+
61+
62+

0 commit comments

Comments
 (0)