https://github.com/EasyCrypt/easycrypt
Raw File
Tip revision: 374dae60b90d55b70e41805c88b33b26faaa455d authored by Pierre-Yves Strub on 12 October 2021, 13:09:21 UTC
parser: fix precedence issue
Tip revision: 374dae6
Mu_mem.ec
(* --------------------------------------------------------------------
 * Copyright (c) - 2012--2016 - IMDEA Software Institute
 * Copyright (c) - 2012--2018 - Inria
 * Copyright (c) - 2012--2018 - Ecole Polytechnique
 *
 * Distributed under the terms of the CeCILL-B-V1 license
 * -------------------------------------------------------------------- *)

(* -------------------------------------------------------------------- *)
require import AllCore List FSet Distr.
require import Ring Number StdRing StdOrder.
(*---*) import RField RealOrder.

lemma mu_mem_le (s:'a fset): forall (d:'a distr) (bd:real),
  (forall (x : 'a), mem s x => mu d (pred1 x) <= bd) =>
  mu d (mem s) <= (card s)%r * bd.
proof.
  elim/fset_ind s=> [d bd mu_bound|x s x_notin_s ih d bd mu_bound].
    by rewrite (mu_eq d _ pred0) 2:mu0 2:fcards0 // => x; rewrite inE.
  rewrite fcardUI_indep 1:fsetP 2:fcard1.
    by move=> x0; rewrite !inE; split=> [[h ->>]|].
  rewrite addzC fromintD mulrDl /=.
  rewrite (mu_eq d _ (predU (pred1 x) (mem s))).
    by move=> z; rewrite !inE orbC.
  rewrite mu_disjoint.
    by rewrite /predI /pred1 /pred0=> z [->].
  rewrite ler_add 1:mu_bound // 1:!inE //.
  by apply ih=> z z_in_s; rewrite mu_bound // !inE; left.
qed.

lemma mu_mem_ge (s:'a fset): forall (d:'a distr) (bd:real),
  (forall (x : 'a), mem s x => mu d (pred1 x) >= bd) =>
  mu d (mem s) >= (card s)%r * bd.
proof.
  elim/fset_ind s=> [d bd mu_bound|x s x_notin_s ih d bd mu_bound].
    by rewrite (mu_eq d _ pred0) 2:mu0 2:fcards0 // => x; rewrite inE.
  rewrite fcardUI_indep 1:fsetP 2:fcard1.
    by move=> x0; rewrite !inE; split=> [[h ->>]|].
  rewrite addzC fromintD mulrDl /=.
  rewrite (mu_eq d _ (predU (pred1 x) (mem s))).
    by move=> z; rewrite !inE orbC.
  rewrite mu_disjoint.
    by rewrite /predI /pred1 /pred0=> z [->].
  rewrite ler_add 1:mu_bound // 1:!inE //.
  by apply ih=> z z_in_s; rewrite mu_bound // !inE; left.
qed.

lemma mu_mem (s:'a fset): forall (d:'a distr) (bd:real),
  (forall (x : 'a), mem s x => mu d (pred1 x) = bd) =>
  mu d (mem s) = (card s)%r * bd.
proof.
  move=> d bd mu_cnst; rewrite eqr_le; split => [|_].
    by apply mu_mem_le=> x h; rewrite mu_cnst.
  by apply mu_mem_ge=> x h; rewrite mu_cnst // -le_ge.
qed.

lemma mu_mem_card (l:'a list) (d:'a distr) (bd:real):
  (forall (x : 'a), mem l x => mu d (pred1 x) = bd) =>
  mu d (mem l) = (card (oflist l))%r * bd.
proof.
  move=> mu_cnst; rewrite (mu_eq _ _ (mem (oflist l))).
    by move=> x; rewrite mem_oflist.
  by apply mu_mem=> x; rewrite mem_oflist=> /mu_cnst.
qed.

lemma mu_mem_le_card (l:'a list) (d:'a distr) (bd:real):
  (forall (x : 'a), mem l x => mu d (pred1 x) <= bd) =>
  mu d (mem l) <= (card (oflist l))%r * bd.
proof.
  move=> mu_bound; rewrite (mu_eq _ _ (mem (oflist l))).
    by move=> x; rewrite mem_oflist.
  by apply mu_mem_le=> x; rewrite mem_oflist=> /mu_bound.
qed.

lemma mu_mem_ge_card (l:'a list) (d:'a distr) (bd:real):
  (forall (x : 'a), mem l x => mu d (pred1 x) >= bd) =>
  mu d (mem l) >= (card (oflist l))%r * bd.
proof.
  move=> mu_bound; rewrite (mu_eq _ _ (mem (oflist l))).
    by move=> x; rewrite mem_oflist.
  by apply mu_mem_ge=> x; rewrite mem_oflist=> /mu_bound.
qed.

lemma mu_mem_le_size (l:'a list) (d:'a distr) (bd:real):
  (forall (x : 'a), mem l x => mu d (pred1 x) <= bd) =>
  mu d (mem l) <= (size l)%r * bd.
proof.
  case l=> [//=|x l mu_bound].
    by rewrite (mu_eq _ _ pred0) // mu0.
  have le0_mu: 0%r <= bd.
    by have := mu_bound x _=> //; smt.
  move: (x::l) mu_bound=> {x l} l mu_bound.
  apply (ler_trans ((card (oflist l))%r * bd)).
    exact/(mu_mem_le_card l d bd mu_bound).
  rewrite cardE -(perm_eq_size (undup l)) 1:oflistK //.
  by rewrite ler_wpmul2r // le_fromint size_undup.
qed.
back to top