|
1 | 1 | (* -------------------------------------------------------------------- *)
|
2 |
| -require import AllCore List FSet Distr DProd StdBigop. |
| 2 | +require import AllCore List FSet Distr DProd StdOrder StdBigop. |
3 | 3 | (*---*) import Bigreal Bigreal.BRM MUnit.
|
4 | 4 |
|
5 | 5 | 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).
|
202 | 202 | by rewrite -{1}size_rev &(dlist_perm_eq) perm_eq_sym perm_eq_rev.
|
203 | 203 | qed.
|
204 | 204 |
|
| 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 | +
|
205 | 244 | (* 0 <= n could be removed, but applying the lemma is pointless in that case *)
|
206 | 245 | lemma dlist_set2E x0 (d : 'a distr) (p : 'a -> bool) n (I J : int fset) :
|
207 | 246 | is_lossless d => 0 <= n =>
|
|
0 commit comments