Skip to content

Commit cf68b25

Browse files
committed
[stdlib]: more lemmas on distributions over lists
dlist_dlist, dlist_insert
1 parent c54ae97 commit cf68b25

File tree

1 file changed

+40
-1
lines changed

1 file changed

+40
-1
lines changed

theories/distributions/DList.ec

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
(* -------------------------------------------------------------------- *)
2-
require import AllCore List FSet Distr DProd StdBigop.
2+
require import AllCore List FSet Distr DProd StdOrder StdBigop.
33
(*---*) import Bigreal Bigreal.BRM MUnit.
44

55
op dlist (d : 'a distr) (n : int): 'a list distr =
@@ -202,6 +202,45 @@ case (size s = n) => [<-|?]; 2: smt(dlist1E supp_dlist_size size_rev).
202202
by rewrite -{1}size_rev &(dlist_perm_eq) perm_eq_sym perm_eq_rev.
203203
qed.
204204
205+
lemma dlist_dlist ['a] (d : 'a distr) (m n : int) :
206+
0 <= m => 0 <= n =>
207+
dmap (dlist (dlist d m) n) flatten = dlist d (m * n).
208+
proof.
209+
move=> ge0_m; elim: n => /= [|n ge0_n ih].
210+
- by rewrite !dlist0 // dmap_dunit.
211+
rewrite mulrDr /= [dlist d (m * n + m)]dlist_add //.
212+
- by apply: IntOrder.mulr_ge0.
213+
rewrite dlistSr //= dmap_comp !dmap_dprodE /=.
214+
rewrite -ih dlet_dmap /= &(eq_dlet) // => xss /=.
215+
by rewrite &(eq_dmap) /(\o) /= => xs; rewrite flatten_rcons.
216+
qed.
217+
218+
lemma dlist_insert ['a] (x0 : 'a) (i n : int) (d : 'a distr) :
219+
0 <= n => 0 <= i <= n => dlist d (n+1) =
220+
dmap (d `*` dlist d n) (fun x_xs : 'a * 'a list => insert x_xs.`1 x_xs.`2 i).
221+
proof.
222+
move=> ge0_n [ge0_i lti]; apply/eq_sym.
223+
pose f (x_xs : _ * _) := insert x_xs.`1 x_xs.`2 i.
224+
pose g (xs : 'a list) := (nth x0 xs i, take i xs ++ drop (i+1) xs).
225+
have ge0_Sn: 0 <= n + 1 by smt(). apply: (dmap_bij _ _ f g).
226+
- case=> [x xs] /supp_dprod[/=] x_in_d.
227+
case/(supp_dlist _ _ _ ge0_n)=> sz_xs /allP xs_in_d.
228+
move=> @/f /=; apply/supp_dlist; first smt().
229+
rewrite size_insert ?sz_xs //=; apply/allP.
230+
by move=> y /mem_insert[->>//|/xs_in_d].
231+
- move=> xs /(supp_dlist _ _ _ ge0_Sn)[sz_xs /allP xs_in_d] @/g.
232+
rewrite dprod1E !dlist1E ~-1://# sz_xs /=.
233+
rewrite size_cat size_take // size_drop 1:/#.
234+
rewrite iftrue 1:/# -(BRM.big_consT (mu1 d)) &(BRM.eq_big_perm).
235+
by rewrite -cat_cons perm_eq_sym &(perm_eq_nth_take_drop) //#.
236+
- case=> x xs /supp_dprod[/=] _ /(supp_dlist _ _ _ ge0_n)[sz_xs _].
237+
rewrite /g /f /= nth_insert ?sz_xs //= take_insert_le 1:/#.
238+
by rewrite drop_insert_gt 1:/# /= cat_take_drop.
239+
- move=> xs /(supp_dlist _ _ _ ge0_Sn)[/=] sz_xs _ @/f @/g /=.
240+
have sz_take: size (take i xs) = i by rewrite size_take //#.
241+
by apply/insert_nth_take_drop => //#.
242+
qed.
243+
205244
(* 0 <= n could be removed, but applying the lemma is pointless in that case *)
206245
lemma dlist_set2E x0 (d : 'a distr) (p : 'a -> bool) n (I J : int fset) :
207246
is_lossless d => 0 <= n =>

0 commit comments

Comments
 (0)