Skip to content

Commit f1d0d4b

Browse files
1 parent 807e589 commit f1d0d4b

7 files changed

Lines changed: 887 additions & 5 deletions

File tree

refman/_sources/tactics/if.rst.txt

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
========================================================================
2+
Tactic: ``if``
3+
========================================================================
4+
5+
In EasyCrypt, the ``if`` tactic is a way of reasoning about program(s)
6+
that use conditionals. When a program begins with an if statement,
7+
execution will follow one path if the condition is ``true`` and another
8+
path if it is ``false``. The tactic says that to prove the program is
9+
correct, you must consider both cases: you assume the condition holds
10+
and show that the *then* branch establishes the desired result, and you
11+
assume the condition does not hold and show that the *else* branch
12+
establishes the same result. EasyCrypt allows you to apply this rule
13+
only when the program starts with an if, so the proof can split immediately
14+
from the initial state.If the conditional appears deeper in the code, you
15+
can first use the seq tactic (or another tactic such as sp that eliminates
16+
the earlier statements) to separate the preceding statements from the
17+
conditional.
18+
19+
.. contents::
20+
:local:
21+
22+
------------------------------------------------------------------------
23+
Variant: ``if`` (HL)
24+
------------------------------------------------------------------------
25+
26+
.. ecproof::
27+
:title: Hoare logic example
28+
29+
require import AllCore.
30+
31+
module M = {
32+
proc f(x : int) = {
33+
var y : int;
34+
35+
if (x < 0) {
36+
y <- -x;
37+
} else {
38+
y <- x;
39+
}
40+
41+
return y;
42+
}
43+
}.
44+
45+
pred p : glob M.
46+
47+
lemma L : hoare[M.f : p (glob M) ==> 0 <= res].
48+
proof.
49+
proc.
50+
(*$*) if.
51+
(* First goal: (x < 0) holds *)
52+
- wp. skip. smt().
53+
(* Second goal: (x < 0) does not hold *)
54+
- wp. skip. smt().
55+
qed.
56+
57+
------------------------------------------------------------------------
58+
Variant: ``if`` (pRHL)
59+
------------------------------------------------------------------------
60+
61+
In probabilistic relational Hoare logic, the ``if`` tactic is applied
62+
in a lock-step manner, meaning that the two programs being compared must
63+
proceed through the conditional in sync. This requires that their guards
64+
evaluate to the same boolean value in the related states, so that either
65+
both programs take the *then* branch or both take the *else* branch.
66+
67+
As a result, using the ``if`` tactic involves establishing that the two
68+
conditions are equal under the current relational invariant before
69+
splitting into the two synchronized cases.
70+
71+
Although synchronization ensures both guards take the same value, the
72+
implementation splits only on the left guard (rather than explicitly
73+
stating both are true or both are false).
74+
75+
.. ecproof::
76+
:title: Relational Hoare logic example (2-sided)
77+
78+
require import AllCore.
79+
80+
module M = {
81+
proc f(x : int) = {
82+
var y : int;
83+
84+
if (x < 0) {
85+
y <- -x;
86+
} else {
87+
y <- x;
88+
}
89+
90+
return y;
91+
}
92+
}.
93+
94+
lemma L : equiv[M.f ~ M.f: x{1} = x{2} ==> res{1} = res{2}].
95+
proof.
96+
proc.
97+
(*$*) if.
98+
(* First goal: we prove that the guards are in sync. *)
99+
- smt().
100+
(* First goal: (x < 0) holds *)
101+
- wp; skip. smt().
102+
(* Second goal: (x < 0) does not hold *)
103+
- wp; skip. smt().
104+
qed.
105+
106+
107+
------------------------------------------------------------------------
108+
Variant: ``if {side}`` (pRHL)
109+
------------------------------------------------------------------------
110+
111+
In the one-sided ``if`` tactic used in pRHL, the user specifies whether
112+
the conditional reasoning should be applied to the left or the right
113+
program. The tactic then performs a case analysis only on the ``if``
114+
statement at the top of that chosen program, generating separate goals
115+
for the ``true`` and ``false`` branches on that side. Unlike the lock-step
116+
relational ``if`` tactic, no synchronization of guards is required, and
117+
the other program is not constrained to take the same branch or even to
118+
have a similar structure.
119+
120+
.. ecproof::
121+
:title: Relational Hoare logic example (1-sided)
122+
123+
require import AllCore.
124+
125+
module M = {
126+
proc f(x : int) = {
127+
var y : int;
128+
129+
if (x < 0) {
130+
y <- -x;
131+
} else {
132+
y <- x;
133+
}
134+
135+
return y;
136+
}
137+
138+
proc g(x : int) = {
139+
return `|x|;
140+
}
141+
}.
142+
143+
lemma L : equiv[M.f ~ M.g: x{1} = x{2} ==> res{1} = res{2}].
144+
proof.
145+
proc.
146+
(*$*) if{1}.
147+
(* First goal: (x < 0) holds (left program) *)
148+
- wp; skip. smt().
149+
(* Second goal: (x < 0) does not hold (left program) *)
150+
- wp; skip. smt().
151+
qed.
152+
153+
------------------------------------------------------------------------
154+
Variant: ``if`` (pHL)
155+
------------------------------------------------------------------------
156+
157+
In probabilistic Hoare logic, the ``if`` tactic behaves much like in
158+
standard Hoare logic, except that the postcondition is expressed in terms
159+
of a probability bound. Since the if statement is the first command of
160+
the program, its guard is evaluated immediately in the initial state and
161+
therefore deterministically takes either the ``true`` or the ``false``
162+
value, with probability 1. As a result, the program execution splits into
163+
one of the two branches without introducing any additional probabilistic
164+
choice at the level of control flow, and the probability bound is preserved
165+
by reasoning separately about each branch under the corresponding
166+
assumption on the guard.
167+
168+
.. ecproof::
169+
:title: Probabilistic Hoare logic example
170+
171+
require import AllCore.
172+
173+
module M = {
174+
proc f(x : int) = {
175+
var y : int;
176+
177+
if (x < 0) {
178+
y <- -x;
179+
} else {
180+
y <- x;
181+
}
182+
183+
return y;
184+
}
185+
}.
186+
187+
lemma L : phoare[M.f : true ==> 0 <= res] = 1%r.
188+
proof.
189+
proc.
190+
(*$*) if.
191+
(* First goal: (x < 0) holds *)
192+
- wp; skip. smt().
193+
(* Second goal: (x < 0) does not hold *)
194+
- wp; skip. smt().
195+
qed.
196+
197+
------------------------------------------------------------------------
198+
Variant: ``if`` (eHL)
199+
------------------------------------------------------------------------
200+
201+
In expectation Hoare logic, the ``if`` tactic behaves similarly to standard
202+
Hoare logic. Two subgoals are generated, where the pre-expection is additionally
203+
guarded by the branch condition and its negation, respectively. This naturally
204+
splits the goal of proving the upper-bound into two cases along the control
205+
flow.
206+
207+
.. ecproof::
208+
:title: Expectation Hoare logic example
209+
210+
require import AllCore Xreal.
211+
212+
module M = {
213+
proc f(x : int) = {
214+
var y : int;
215+
216+
if (x < 0) {
217+
y <- -x;
218+
} else {
219+
y <- x;
220+
}
221+
222+
return y;
223+
}
224+
}.
225+
226+
lemma L : ehoare[M.f : 0%xr ==> (!(0 <= res))%xr].
227+
proof.
228+
proc.
229+
(*$*) if.
230+
(* First goal: (x < 0) holds *)
231+
- wp; skip. smt().
232+
(* Second goal: (x < 0) does not hold *)
233+
- wp; skip. smt().
234+
qed.

refman/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ <h1>EasyCrypt reference manual<a class="headerlink" href="#easycrypt-reference-m
7878
<div class="toctree-wrapper compound">
7979
<ul>
8080
<li class="toctree-l1"><a class="reference internal" href="tactics.html">Proof tactics reference</a><ul>
81+
<li class="toctree-l2"><a class="reference internal" href="tactics/if.html">Tactic: <code class="docutils literal notranslate"><span class="pre">if</span></code></a></li>
8182
<li class="toctree-l2"><a class="reference internal" href="tactics/skip.html">Tactic: <cite>skip</cite></a></li>
8283
</ul>
8384
</li>

refman/objects.inv

9 Bytes
Binary file not shown.

refman/searchindex.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

refman/tactics.html

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
<script src="_static/js/theme.js"></script>
2424
<link rel="index" title="Index" href="genindex.html" />
2525
<link rel="search" title="Search" href="search.html" />
26-
<link rel="next" title="Tactic: skip" href="tactics/skip.html" />
26+
<link rel="next" title="Tactic: if" href="tactics/if.html" />
2727
<link rel="prev" title="EasyCrypt reference manual" href="index.html" />
2828
</head>
2929

@@ -48,6 +48,7 @@
4848
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
4949
<ul class="current">
5050
<li class="toctree-l1 current"><a class="current reference internal" href="#">Proof tactics reference</a><ul>
51+
<li class="toctree-l2"><a class="reference internal" href="tactics/if.html">Tactic: <code class="docutils literal notranslate"><span class="pre">if</span></code></a></li>
5152
<li class="toctree-l2"><a class="reference internal" href="tactics/skip.html">Tactic: <cite>skip</cite></a></li>
5253
</ul>
5354
</li>
@@ -81,6 +82,7 @@
8182
<h1>Proof tactics reference<a class="headerlink" href="#proof-tactics-reference" title="Link to this heading"></a></h1>
8283
<div class="toctree-wrapper compound">
8384
<ul>
85+
<li class="toctree-l1"><a class="reference internal" href="tactics/if.html">Tactic: <code class="docutils literal notranslate"><span class="pre">if</span></code></a></li>
8486
<li class="toctree-l1"><a class="reference internal" href="tactics/skip.html">Tactic: <cite>skip</cite></a></li>
8587
</ul>
8688
</div>
@@ -91,7 +93,7 @@ <h1>Proof tactics reference<a class="headerlink" href="#proof-tactics-reference"
9193
</div>
9294
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
9395
<a href="index.html" class="btn btn-neutral float-left" title="EasyCrypt reference manual" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
94-
<a href="tactics/skip.html" class="btn btn-neutral float-right" title="Tactic: skip" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
96+
<a href="tactics/if.html" class="btn btn-neutral float-right" title="Tactic: if" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
9597
</div>
9698

9799
<hr/>

0 commit comments

Comments
 (0)