Skip to content

Commit 6a78898

Browse files
committed
another example for eHoare
1 parent a78d1cf commit 6a78898

File tree

1 file changed

+187
-0
lines changed

1 file changed

+187
-0
lines changed
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
require import AllCore Array Real RealExp List.
2+
(*---*) import RField.
3+
require import Distr DBool Xreal.
4+
(*---*) import Biased.
5+
require import StdOrder.
6+
(*---*) import RealOrder.
7+
8+
lemma mul0z (x : int) : 0 * x = 0.
9+
proof. by smt(). qed.
10+
11+
lemma neg0: -0 = 0.
12+
proof. by smt(). qed.
13+
14+
lemma xle_rle:
15+
forall (x y : real),
16+
0%r <= x <= y => x%xr <= y%xr.
17+
proof. by smt(). qed.
18+
19+
lemma Ep_dbiased (p : real) (f : bool -> xreal) :
20+
0%r <= p <= 1%r => Ep (dbiased p) f = p ** f true + (1%r - p) ** f false.
21+
proof.
22+
move => ?.
23+
rewrite (Ep_fin [true; false]) //.
24+
+ by case.
25+
by rewrite /BXA.big /predT /= !dbiased1E /= !clamp_id //.
26+
qed.
27+
28+
(* uniformly sampling a 2-d boolean array of size n x m *)
29+
module M = {
30+
proc sample (n : int, m : int, a : bool array) : (bool array) = {
31+
var i, j : int;
32+
var b : bool;
33+
i <- 0;
34+
while (i < n) {
35+
j <- 0;
36+
while (j < m) {
37+
b <$ dbiased 0.5;
38+
a.[i * m + j] <- b;
39+
j <- j + 1;
40+
}
41+
i <- i + 1;
42+
}
43+
return a;
44+
}
45+
}.
46+
47+
op outer_shape_pred (i n m : int) (a a' : bool array) =
48+
0 <= i <= n
49+
/\ 0 <= m
50+
/\ size a = n * m
51+
/\ size a = size a'.
52+
53+
op shape_pred (i j n m : int) (a a' : bool array) =
54+
0 <= i < n
55+
/\ 0 <= j <= m
56+
/\ size a = n * m
57+
/\ size a = size a'.
58+
59+
op row_eq_upto (i m : int) (a1 a2 : bool array) =
60+
forall (i' j' : int),
61+
0 <= i' < i
62+
=> 0 <= j' < m
63+
=> a1.[i' * m + j'] = a2.[i' * m + j'].
64+
65+
op cell_eq_upto (i j m : int) (a1 a2 : bool array) =
66+
forall (j' : int),
67+
0 <= j' < j
68+
=> a1.[i * m + j'] = a2.[i * m + j'].
69+
70+
lemma row_eq_upto_increase (i m : int) (a1 a2 : bool array):
71+
0 <= i
72+
=> (row_eq_upto i m a1 a2 /\ cell_eq_upto i m m a1 a2
73+
<=> row_eq_upto (i + 1) m a1 a2).
74+
proof. by smt(). qed.
75+
76+
lemma cell_eq_upto_false (i j' j m : int) (a1 a2 : bool array) :
77+
0 <= j' < j
78+
=> a1.[i * m + j'] <> a2.[i * m + j']
79+
=> cell_eq_upto i j m a1 a2 = false.
80+
proof. by smt(). qed.
81+
82+
lemma cell_eq_upto_split (i j m : int) (a1 a2 : bool array) :
83+
0 <= j < m
84+
=> (cell_eq_upto i (j + 1) m a1 a2
85+
<=> (cell_eq_upto i j m a1 a2
86+
/\ a1.[i * m + j] = a2.[i * m + j])
87+
).
88+
proof. by smt(). qed.
89+
90+
lemma mul_add_lt (i j n m : int) :
91+
0 <= i < n => 0 <= j < m => i * m + j < n * m.
92+
proof.
93+
by rewrite (_: n * m = (n - 1) * m + m) /#.
94+
qed.
95+
96+
lemma row_eq_upto_unrelated_set (i m x : int) (v : bool) (a1 a2 : bool array):
97+
i * m <= x < size a1
98+
=> (row_eq_upto i m a1 a2 <=> row_eq_upto i m a1.[x <- v] a2).
99+
proof.
100+
by smt(get_set mul_add_lt).
101+
qed.
102+
103+
lemma cell_eq_upto_unrelated_set (i j m x : int) (v : bool) (a1 a2 : bool array) :
104+
0 <= i /\ 0 <= j < m /\ i * m + j <= x < size a1
105+
=> (cell_eq_upto i j m a1 a2 <=> cell_eq_upto i j m a1.[x <- v] a2).
106+
proof.
107+
by smt(get_set).
108+
qed.
109+
110+
(* The probability of every possible boolean matrix of size n x m is no more than 2 ^ -(n * m) *)
111+
lemma L:
112+
forall (a0 : bool array),
113+
ehoare [M.sample :
114+
(0 <= arg.`1
115+
/\ 0 <= arg.`2
116+
/\ size arg.`3 = arg.`1 * arg.`2
117+
/\ size arg.`3 = size a0)
118+
`|` (1%r / (2%r ^ (n * m)))%xr ==> (res = a0)%xr].
119+
proof.
120+
move => a0.
121+
proc.
122+
while ((0 <= i <= n
123+
/\ 0 <= m
124+
/\ size a = n * m
125+
/\ size a0 = size a)
126+
`|` (2%r ^ ((-(n - i) * m)%r))%xr
127+
* (row_eq_upto i m a a0)%xr).
128+
(* !cond => inv => pos_f <= inv_f *)
129+
+ move => &hr.
130+
rewrite xle_cxr_r => *. (* Bug in EC: the precedent is lost when rewriting xle_cxr_r twice. *)
131+
rewrite xle_cxr_r => *.
132+
have ->: n{hr} - i{hr} = 0 by smt().
133+
rewrite mul0z neg0 rpow0 mul1m_simpl.
134+
apply xle_rle; split => * ;1: by smt().
135+
exact le_b2r.
136+
(* {cond /\ inv | inv_f} c {inv | inv_f} *)
137+
+ wp.
138+
while (( 0 <= i < n
139+
/\ 0 <= j <= m
140+
/\ size a = n * m
141+
/\ size a = size a0)
142+
`|` (2%r ^ ((-((n - i) * m - j))%r))%xr
143+
* (row_eq_upto i m a a0 /\ cell_eq_upto i j m a a0)%xr).
144+
(* !cond => inv => pos_f <= inv_f *)
145+
+ move => &hr />.
146+
rewrite xle_cxr_r => *.
147+
rewrite xle_cxr_l => *.
148+
+ by smt().
149+
+ rewrite (_: - (n{hr} - (i{hr} + 1)) * m{hr}
150+
= - ((n{hr} - i{hr}) * m{hr} - j{hr})) //= 1:/#.
151+
rewrite (_: j{hr} = m{hr}) 1:/#.
152+
rewrite -row_eq_upto_increase 1:/#.
153+
rewrite ler_eqVlt; left; reflexivity.
154+
(* {cond /\ inv | inv_f} c {inv | inv_f} *)
155+
+ wp; skip.
156+
move => &hr.
157+
move => />.
158+
rewrite xle_cxr_r => [#] 5? Hsize *.
159+
rewrite Ep_dbiased /= 1:/#.
160+
rewrite (_: ((0 <= i{hr} < n{hr}) <=> true)) 1:/#.
161+
rewrite (_: ((0 <= j{hr} + 1 <= m{hr}) <=> true)) 1:/#.
162+
rewrite !size_set.
163+
rewrite (_: ((size a{hr} = n{hr} * m{hr}) <=> true)) 1:/#.
164+
rewrite (_: (size a{hr} = size a0) <=> true) /= 1:/#.
165+
rewrite !to_pos_pos 1,2,3,4,5:#smt:(rpow_gt0 b2r_ge0).
166+
rewrite !cell_eq_upto_split 1,2:/#.
167+
rewrite !get_set //= 1,2:#smt:(mul_add_lt).
168+
case (a0.[i{hr} * m{hr} + j{hr}]) => Hcase /=.
169+
+ rewrite -row_eq_upto_unrelated_set 1:#smt:(mul_add_lt).
170+
rewrite -cell_eq_upto_unrelated_set 1:#smt:(mul_add_lt).
171+
by smt(rpow1 rpowN rpowD).
172+
+ rewrite /= -row_eq_upto_unrelated_set 1:#smt:(mul_add_lt).
173+
rewrite -cell_eq_upto_unrelated_set 1:#smt:(mul_add_lt).
174+
by smt(rpow1 rpowN rpowD).
175+
(* pre => inv *)
176+
+ wp; skip.
177+
move => &hr />.
178+
rewrite xle_cxr_r => *.
179+
rewrite xle_cxr_l 1:/#.
180+
rewrite (_: cell_eq_upto i{hr} 0 m{hr} a{hr} a0 = true) //= 1:/#.
181+
wp.
182+
skip => /> &hr.
183+
rewrite xle_cxr_r => *.
184+
rewrite xle_cxr_l 1:/#.
185+
rewrite fromintN rpowN //= rpow_int //=.
186+
rewrite (_: row_eq_upto 0 m{hr} a{hr} a0 = true) //= 1:/#.
187+
qed.

0 commit comments

Comments
 (0)