Skip to content

Commit 5fdfc42

Browse files
committed
another example for eHoare
1 parent a78d1cf commit 5fdfc42

File tree

2 files changed

+219
-1
lines changed

2 files changed

+219
-1
lines changed
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
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+
(* uniformly sampling a 2-d boolean array of size n x m *)
9+
module M = {
10+
proc sample (n : int, m : int, a : bool array) : (bool array) = {
11+
var i, j : int;
12+
var b : bool;
13+
i <- 0;
14+
while (i < n) {
15+
j <- 0;
16+
while (j < m) {
17+
b <$ dbiased 0.5;
18+
a.[i * m + j] <- b;
19+
j <- j + 1;
20+
}
21+
i <- i + 1;
22+
}
23+
return a;
24+
}
25+
}.
26+
27+
op outer_shape_pred (i n m : int) (a a' : bool array) =
28+
0 <= i <= n
29+
/\ 0 <= m
30+
/\ size a = n * m
31+
/\ size a = size a'.
32+
33+
op shape_pred (i j n m : int) (a a' : bool array) =
34+
0 <= i < n
35+
/\ 0 <= j <= m
36+
/\ size a = n * m
37+
/\ size a = size a'.
38+
39+
op row_eq_upto (i m : int) (a1 a2 : bool array) =
40+
forall (i' j' : int),
41+
0 <= i' < i
42+
=> 0 <= j' < m
43+
=> a1.[i' * m + j'] = a2.[i' * m + j'].
44+
45+
op cell_eq_upto (i j m : int) (a1 a2 : bool array) =
46+
forall (j' : int),
47+
0 <= j' < j
48+
=> a1.[i * m + j'] = a2.[i * m + j'].
49+
50+
lemma row_eq_upto_increase (i m : int) (a1 a2 : bool array):
51+
0 <= i
52+
=> (row_eq_upto i m a1 a2 /\ cell_eq_upto i m m a1 a2
53+
<=> row_eq_upto (i + 1) m a1 a2).
54+
proof.
55+
move => ? @/row_eq_upto @/cell_eq_upto; split.
56+
- move => ? i' j' *.
57+
by case: (i' < i) => /#.
58+
- move => H; split.
59+
- move => i' j' ??.
60+
have ?: 0 <= i' < i + 1 by smt().
61+
by have := H i' j' _ _ => //.
62+
- by have := H i => /#.
63+
qed.
64+
65+
lemma cell_eq_upto_false (i j' j m : int) (a1 a2 : bool array) :
66+
0 <= j' < j
67+
=> a1.[i * m + j'] <> a2.[i * m + j']
68+
=> cell_eq_upto i j m a1 a2 = false.
69+
proof. by smt(). qed.
70+
71+
lemma cell_eq_upto_split (i j m : int) (a1 a2 : bool array) :
72+
0 <= j < m
73+
=> (cell_eq_upto i (j + 1) m a1 a2
74+
<=> (cell_eq_upto i j m a1 a2
75+
/\ a1.[i * m + j] = a2.[i * m + j])
76+
).
77+
proof.
78+
move => ? @/cell_eq_upto; split.
79+
- move => H; split.
80+
- move => j' ?.
81+
have ?: 0 <= j' < j + 1 by smt().
82+
have := H j' _ => //.
83+
- by smt().
84+
- move => ? j' ?.
85+
by case (j' < j) => /#.
86+
qed.
87+
88+
lemma row_eq_upto_unrelated_set (i m x : int) (v : bool) (a1 a2 : bool array):
89+
i * m <= x < size a1
90+
=> (row_eq_upto i m a1 a2 <=> row_eq_upto i m a1.[x <- v] a2).
91+
proof.
92+
move => ? @/row_eq_upto; split.
93+
- move => ? i' j' ??.
94+
rewrite get_set 1:/#.
95+
have -> /=: !(i' * m + j' = x) by smt().
96+
by smt().
97+
- move => ? i' j' ??.
98+
by rewrite (_: a1.[_] = a1.[x <- v].[i' * m + j']) 1:get_set /#.
99+
qed.
100+
101+
lemma cell_eq_upto_unrelated_set (i j m x : int) (v : bool) (a1 a2 : bool array) :
102+
0 <= i /\ 0 <= j < m /\ i * m + j <= x < size a1
103+
=> (cell_eq_upto i j m a1 a2 <=> cell_eq_upto i j m a1.[x <- v] a2).
104+
proof.
105+
move => [#] ????? @/cell_eq_upto; split.
106+
- move => ? j' ?.
107+
rewrite get_set 1:/#.
108+
have -> /=: !(i * m + j' = x) by smt().
109+
by smt().
110+
- move => ? j' ?.
111+
by rewrite (_: a1.[_] = a1.[x <- v].[i * m + j']) 1:get_set /#.
112+
qed.
113+
114+
(* The probability of every possible boolean matrix of size n x m is no more than 2 ^ -(n * m) *)
115+
lemma L:
116+
forall (a0 : bool array),
117+
ehoare [M.sample :
118+
(0 <= arg.`1
119+
/\ 0 <= arg.`2
120+
/\ size arg.`3 = arg.`1 * arg.`2
121+
/\ size arg.`3 = size a0)
122+
`|` (1%r / (2%r ^ (n * m)))%xr ==> (res = a0)%xr].
123+
proof.
124+
move => a0.
125+
proc.
126+
while ((0 <= i <= n
127+
/\ 0 <= m
128+
/\ size a = n * m
129+
/\ size a0 = size a)
130+
`|` (2%r ^ ((-(n - i) * m)%r))%xr
131+
* (row_eq_upto i m a a0)%xr).
132+
(* !cond => inv => pos_f <= inv_f *)
133+
+ move => &hr.
134+
apply xle_cxr_r => ?.
135+
apply xle_cxr_r => ?.
136+
have ->: n{hr} - i{hr} = 0 by smt().
137+
rewrite Ring.IntID.mul0r Ring.IntID.oppr0 rpow0 mul1m_simpl.
138+
apply xle_rle; split => * ; 1: by smt().
139+
exact le_b2r.
140+
(* {cond /\ inv | inv_f} c {inv | inv_f} *)
141+
+ wp.
142+
while (( 0 <= i < n
143+
/\ 0 <= j <= m
144+
/\ size a = n * m
145+
/\ size a = size a0)
146+
`|` (2%r ^ ((-((n - i) * m - j))%r))%xr
147+
* (row_eq_upto i m a a0 /\ cell_eq_upto i j m a a0)%xr).
148+
(* !cond => inv => pos_f <= inv_f *)
149+
+ move => &hr />.
150+
rewrite xle_cxr_r => *.
151+
rewrite xle_cxr_l => *.
152+
+ by smt().
153+
+ rewrite (_: - _ * m{hr} = - ((n{hr} - i{hr}) * m{hr} - j{hr})) //= 1:/#.
154+
rewrite (_: j{hr} = m{hr}) 1:/#.
155+
rewrite -row_eq_upto_increase 1:/#.
156+
rewrite ler_eqVlt; left; reflexivity.
157+
(* {cond /\ inv | inv_f} c {inv | inv_f} *)
158+
+ wp; skip => /> &hr.
159+
rewrite xle_cxr_r => [#] 5? Hsize *.
160+
rewrite Ep_dbiased /= 1:/#.
161+
have-> /=: 0 <= i{hr} < n{hr} by smt().
162+
have-> /=: 0 <= j{hr} + 1 <= m{hr} by smt().
163+
rewrite !size_set !Hsize /=.
164+
have-> /=: n{hr} * m{hr} = size a0 by smt().
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 //=.
168+
- split; 1: by smt().
169+
move => ?.
170+
by apply (IntOrder.ltr_le_trans ((n{hr} - 1) * m{hr} + m{hr})) => /#.
171+
- split; 1: by smt().
172+
move => ?.
173+
by apply (IntOrder.ltr_le_trans ((n{hr} - 1) * m{hr} + m{hr})) => /#.
174+
case (a0.[i{hr} * m{hr} + j{hr}]) => Hcase /=.
175+
+ rewrite -row_eq_upto_unrelated_set.
176+
- split; 1: by smt().
177+
move => ?.
178+
by apply (IntOrder.ltr_le_trans ((n{hr} - 1) * m{hr} + m{hr})) => /#.
179+
rewrite -cell_eq_upto_unrelated_set.
180+
- do! split; 1,2,3: by smt().
181+
move => ?.
182+
by apply (IntOrder.ltr_le_trans ((n{hr} - 1) * m{hr} + m{hr})) => /#.
183+
rewrite -{2}(rpow1 2%r) // -rpowN // -mulrA.
184+
rewrite (mulrC (b2r _) (2%r ^ - 1%r)).
185+
by rewrite mulrA -rpowD // /#.
186+
+ rewrite /= -row_eq_upto_unrelated_set.
187+
- split; 1: by smt().
188+
move => ?.
189+
by apply (IntOrder.ltr_le_trans ((n{hr} - 1) * m{hr} + m{hr})) => /#.
190+
rewrite -cell_eq_upto_unrelated_set.
191+
- do! split; 1,2,3: by smt().
192+
move => ?.
193+
by apply (IntOrder.ltr_le_trans ((n{hr} - 1) * m{hr} + m{hr})) => /#.
194+
rewrite -{2}(rpow1 2%r) // -rpowN // -mulrA.
195+
rewrite (mulrC (b2r _) (2%r ^ - 1%r)).
196+
by rewrite mulrA -rpowD // /#.
197+
(* pre => inv *)
198+
+ wp; skip => &hr />.
199+
rewrite xle_cxr_r => [#] *.
200+
rewrite xle_cxr_l 1:/#.
201+
have-> //: cell_eq_upto i{hr} 0 m{hr} a{hr} a0 by smt().
202+
auto => /> &hr.
203+
rewrite xle_cxr_r => [#] *.
204+
rewrite xle_cxr_l 1:/#.
205+
rewrite fromintN rpowN //= rpow_int //=.
206+
by have-> //: row_eq_upto 0 m{hr} a{hr} a0 by smt().
207+
qed.

theories/datatypes/Xreal.ec

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
require import AllCore RealSeries List Distr StdBigop DBool DInterval.
22
require import StdOrder.
33
require Subtype Bigop.
4-
import Bigreal Bigint RealOrder.
4+
import Bigreal Bigint RealOrder Biased.
55

66
(* -------------------------------------------------------------------- *)
77
(* Definition of R+ *)
@@ -399,6 +399,9 @@ proof. case: x y => [x|] [y|] //=; smt(@Rp). qed.
399399
lemma xle_add_l x y : x <= y + x.
400400
proof. rewrite addmC xle_add_r. qed.
401401

402+
lemma xle_rle (x y : real) : 0%r <= x <= y => x%xr <= y%xr.
403+
proof. by move => [??] /=; rewrite !to_pos_pos // &(ler_trans x). qed.
404+
402405
lemma xler_add2r (x:realp) (y z : xreal) : y + x%xr <= z + x%xr <=> y <= z.
403406
proof. case: z => // z; case: y => //= y; smt(@Rp). qed.
404407

@@ -963,6 +966,14 @@ proof.
963966
by rewrite big_consT big_seq1 /= !dbool1E.
964967
qed.
965968

969+
lemma Ep_dbiased (p : real) (f : bool -> xreal) :
970+
0%r <= p <= 1%r => Ep (dbiased p) f = p ** f true + (1%r - p) ** f false.
971+
proof.
972+
move => ?.
973+
rewrite (Ep_fin [true; false]) //; 1: by case.
974+
by rewrite /BXA.big /predT /= !dbiased1E /= !clamp_id //.
975+
qed.
976+
966977
(* -------------------------------------------------------------------- *)
967978
lemma Ep_dinterval (f : int -> xreal) i j:
968979
Ep [i..j] f =

0 commit comments

Comments
 (0)