diff --git a/.github/workflows/docker-action.yml b/.github/workflows/docker-action.yml index 51190dee..fea2e087 100644 --- a/.github/workflows/docker-action.yml +++ b/.github/workflows/docker-action.yml @@ -17,8 +17,10 @@ jobs: strategy: matrix: image: - - 'mathcomp/mathcomp:1.16.0-coq-8.17' - 'mathcomp/mathcomp:1.17.0-coq-8.17' + - 'mathcomp/mathcomp:1.18.0-coq-8.17' + - 'mathcomp/mathcomp:1.17.0-coq-8.18' + - 'mathcomp/mathcomp:1.18.0-coq-8.18' fail-fast: false steps: - uses: actions/checkout@v2 diff --git a/README.md b/README.md index 60dc376d..759c3fb4 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ information theory, and linear error-correcting codes. - [MathComp field](https://math-comp.github.io) - [MathComp analysis](https://github.com/math-comp/analysis) - [Hierarchy Builder](https://github.com/math-comp/hierarchy-builder) + - MathComp algebra tactics - Coq namespace: `infotheo` - Related publication(s): - [Formal Adventures in Convex and Conical Spaces](https://arxiv.org/abs/2004.12713) doi:[10.1007/978-3-030-53518-6_2](https://doi.org/10.1007/978-3-030-53518-6_2) diff --git a/_CoqProject b/_CoqProject index c987e6c1..43670b6d 100644 --- a/_CoqProject +++ b/_CoqProject @@ -6,6 +6,7 @@ lib/ssrZ.v lib/ssrR.v +lib/realType_ext.v lib/Reals_ext.v lib/logb.v lib/Ranalysis_ext.v @@ -23,6 +24,7 @@ lib/euclid.v lib/dft.v lib/vandermonde.v lib/classical_sets_ext.v +lib/Rstruct_ext.v probability/fdist.v probability/proba.v probability/fsdist.v diff --git a/coq-infotheo.opam b/coq-infotheo.opam index 373588e1..778bb677 100644 --- a/coq-infotheo.opam +++ b/coq-infotheo.opam @@ -21,14 +21,15 @@ build: [ ] install: [make "install"] depends: [ - "coq" { (>= "8.17" & < "8.18~") | (= "dev") } - "coq-mathcomp-ssreflect" { (>= "1.16.0" & < "1.18~") | (= "dev") } - "coq-mathcomp-fingroup" { (>= "1.16.0" & < "1.18~") | (= "dev") } - "coq-mathcomp-algebra" { (>= "1.16.0" & < "1.18~") | (= "dev") } - "coq-mathcomp-solvable" { (>= "1.16.0" & < "1.18~") | (= "dev") } - "coq-mathcomp-field" { (>= "1.16.0" & < "1.18~") | (= "dev") } + "coq" { (>= "8.17" & < "8.19~") | (= "dev") } + "coq-mathcomp-ssreflect" { (>= "1.16.0" & < "1.19~") | (= "dev") } + "coq-mathcomp-fingroup" { (>= "1.16.0" & < "1.19~") | (= "dev") } + "coq-mathcomp-algebra" { (>= "1.16.0" & < "1.19~") | (= "dev") } + "coq-mathcomp-solvable" { (>= "1.16.0" & < "1.19~") | (= "dev") } + "coq-mathcomp-field" { (>= "1.16.0" & < "1.19~") | (= "dev") } "coq-mathcomp-analysis" { (>= "0.5.4") & (< "0.7~")} - "coq-hierarchy-builder" { >= "1.3.0" } + "coq-hierarchy-builder" { = "1.5.0" } + "coq-mathcomp-algebra-tactics" { = "1.1.1" } ] tags: [ diff --git a/ecc_classic/decoding.v b/ecc_classic/decoding.v index 7ab8d98d..887a40e4 100644 --- a/ecc_classic/decoding.v +++ b/ecc_classic/decoding.v @@ -1,11 +1,14 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg perm zmodp. -From mathcomp Require Import matrix vector. -Require Import Reals Lra. -From mathcomp Require Import Rstruct. +From mathcomp Require Import all_ssreflect ssralg fingroup finalg perm zmodp ssrnum. +From mathcomp Require Import matrix vector order. +From mathcomp Require Import lra Rstruct reals. +From mathcomp Require ssrnum. +Require Import Reals. Require Import ssrR Reals_ext ssr_ext ssralg_ext Rbigop f2 fdist proba. +Require Import realType_ext. Require Import channel_code channel binary_symmetric_channel hamming pproba. +Require Import Rstruct_ext. (******************************************************************************) (* The variety of decoders *) @@ -32,7 +35,7 @@ Unset Strict Implicit. Import Prenex Implicits. Local Close Scope R_scope. -Import GRing.Theory. +Import GRing.Theory Num.Theory Order.Theory. Local Open Scope ring_scope. Definition repairT (B A : finType) n := {ffun 'rV[B]_n -> option 'rV[A]_n}. @@ -46,7 +49,7 @@ Definition cancel_on n (F : finFieldType) (C : {vspace 'rV[F]_n}) {B} (e : B -> forall c, c \in C -> e (s c) = c. Lemma vspace_not_empty (F : finFieldType) n (C : {vspace 'rV[F]_n}) : - 0 < #| [set cw in C] |. + (0 < #| [set cw in C] |)%nat. Proof. apply/card_gt0P; exists 0; by rewrite inE mem0v. Qed. Section minimum_distance_decoding. @@ -95,7 +98,7 @@ Variables (F : finFieldType) (n : nat) (C : {vspace 'rV[F]_n}). Variable (f : repairT F F n). Definition BD_decoding t := - forall c e, c \in C -> wH e <= t -> f (c + e) = Some c. + forall c e, c \in C -> (wH e <= t)%nat -> f (c + e) = Some c. End bounded_distance_decoding. @@ -105,6 +108,9 @@ Local Open Scope fdist_scope. Local Open Scope proba_scope. Local Open Scope channel_scope. +Local Open Scope reals_ext_scope. +Local Open Scope order_scope. + Section maximum_likelihood_decoding. Variables (A : finFieldType) (B : finType) (W : `Ch(A, B)). @@ -112,23 +118,21 @@ Variables (n : nat) (C : {vspace 'rV[A]_n}). Variable f : decT B [finType of 'rV[A]_n] n. Variable P : {fdist 'rV[A]_n}. -Local Open Scope R_scope. +Local Open Scope reals_ext_scope. Definition ML_decoding := forall y : P.-receivable W, exists x, f y = Some x /\ - W ``(y | x) = \rmax_(x' in C) W ``(y | x'). + W ``(y | x) = \big[Order.max/0]_(x' in C) W ``(y | x'). End maximum_likelihood_decoding. -Local Open Scope R_scope. - Section maximum_likelihood_decoding_prop. Variables (A : finFieldType) (B : finType) (W : `Ch(A, B)). Variables (n : nat) (C : {vspace 'rV[A]_n}). Variable repair : decT B [finType of 'rV[A]_n] n. -Let P := fdist_uniform_supp (vspace_not_empty C). +Let P := fdist_uniform_supp real_realType (vspace_not_empty C). Hypothesis ML_dec : ML_decoding W C repair P. Local Open Scope channel_code_scope. @@ -137,15 +141,13 @@ Lemma ML_err_rate x1 x2 y : repair y = Some x1 -> x2 \in C -> W ``(y | x2) <= W ``(y | x1). Proof. move=> Hx1 Hx2. -case/boolP : (W ``(y | x2) == 0%R) => [/eqP -> //| Hcase]. +case/boolP : (W ``(y | x2) == 0) => [/eqP -> //| Hcase]. have PWy : receivable_prop P W y. apply/existsP; exists x2. by rewrite Hcase andbT fdist_uniform_supp_neq0 inE. case: (ML_dec (mkReceivable PWy)) => x' []. rewrite /= Hx1 => -[<-] ->. -rewrite -big_filter. -apply (leR_bigmaxR (fun i => W ``(y | i))). -by rewrite mem_filter /= mem_index_enum andbT. +by apply: (le_bigmax_cond _ (fun i => W ``(y | i))). Qed. Variable M : finType. @@ -154,28 +156,30 @@ Variable discard : discardT A n M. Variable enc : encT A M n. Hypothesis enc_img : enc @: M \subset C. Hypothesis discard_cancel : forall y x, repair y = Some x -> enc (discard x) = x. +Let dec := [ffun x => omap discard (repair x)]. + +Import ssrnum.Num.Theory. Lemma ML_smallest_err_rate phi : - let dec := [ffun x => omap discard (repair x)] in echa(W, mkCode enc dec) <= echa(W, mkCode enc phi). Proof. -move=> dec. -apply leR_wpmul2l; first by apply/mulR_ge0 => //; exact/invR_ge0/ltR0n. -rewrite /ErrRateCond /= [in X in _ <= X](eq_bigr +apply/RleP/leR_wpmul2l; first by apply/mulR_ge0 => //; exact/invR_ge0/ltR0n. +rewrite /ErrRateCond /=; apply/RleP. +rewrite [leRHS](eq_bigr (fun m => 1 - Pr (W ``(|enc m)) [set tb | phi tb == Some m])); last first. move=> m _; rewrite Pr_to_cplt; congr (_ - Pr _ _). apply/setP => t; by rewrite !inE negbK. -rewrite [in X in X <= _](eq_bigr +rewrite [leLHS](eq_bigr (fun m => 1 - Pr (W ``(|enc m)) [set tb | dec tb == Some m])); last first. move => m _. rewrite [in LHS]Pr_to_cplt; congr (_ - Pr _ _). apply/setP => t; by rewrite !inE negbK. -rewrite 2!big_split /= leR_add2l. -rewrite -2!big_morph_oppR leR_oppr oppRK /Pr (exchange_big_dep xpredT) //=. -rewrite [in X in (_ <= X)%R](exchange_big_dep xpredT) //=. -apply leR_sumR => /= tb _. +rewrite 2!big_split /=; apply: lerD => //. +rewrite -2!big_morph_oppR lerNr opprK /Pr (exchange_big_dep xpredT) //=. +rewrite [leRHS](exchange_big_dep xpredT) //=. +apply ler_sum => /= tb _. rewrite (eq_bigl (fun m => phi tb == Some m)); last by move=> m; rewrite inE. -rewrite [in X in _ <= X](eq_bigl (fun m => dec tb == Some m)); last by move=> m; rewrite inE. +rewrite [leRHS](eq_bigl (fun m => dec tb == Some m)); last by move=> m; rewrite inE. (* show that phi_ML succeeds more often than phi *) have [dectb_None|dectb_Some] := boolP (dec tb == None). case/boolP : (receivable_prop P W tb) => [Hy|Htb]. @@ -187,14 +191,14 @@ have [dectb_None|dectb_Some] := boolP (dec tb == None). rewrite Htb andbT fdist_uniform_supp_neq0 inE. move/subsetP : enc_img; apply; apply/imsetP; by exists m. rewrite (eq_bigr (fun=> 0)); last by move=> m _; rewrite W_tb. - by rewrite big1 //; apply sumR_ge0. + by rewrite big1 //; apply sumr_ge0. case/boolP : (phi tb == None) => [/eqP ->|phi_tb]. - by rewrite big_pred0 //; apply sumR_ge0. + by rewrite big_pred0 //; apply sumr_ge0. have [m1 Hm1] : exists m', dec tb = Some m' by destruct (dec tb) => //; exists s. have [m2 Hm2] : exists m', phi tb = Some m' by destruct (phi tb) => //; exists s. rewrite Hm1 {}Hm2. rewrite (eq_bigl [pred m | m == m2]); last by move=> ?; rewrite eq_sym. -rewrite [in X in _ <= X](eq_bigl [pred m | m == m1]); last by move=> ?; rewrite eq_sym. +rewrite [leRHS](eq_bigl [pred m | m == m1]); last by move=> ?; rewrite eq_sym. rewrite 2!big_pred1_eq; apply ML_err_rate. move: Hm1; rewrite /dec ffunE /omap /obind /oapp. move H : (repair tb) => h. @@ -207,47 +211,7 @@ End maximum_likelihood_decoding_prop. Section MD_ML_decoding. -Variable p : prob. - -(* TODO: move to file on bsc? *) -Lemma bsc_prob_prop n : p < 1 / 2 -> - forall n1 n2 : nat, (n1 <= n2 <= n)%nat -> - ((1 - p) ^ (n - n2) * p ^ n2 <= (1 - p) ^ (n - n1) * p ^ n1)%R. -Proof. -move=> p05 d1 d2 d1d2. -case/boolP : (p == 0%:pr) => [/eqP ->|p0]. - destruct d2 as [|d2]. - destruct d1 as [|d1]; [exact/leRR | by []]. - rewrite !subR0 /= !mul0R !mulR0. - destruct d1 as [|d1] => /=; first by rewrite exp1R mul1R. - rewrite !mul0R !mulR0; exact/leRR. -apply (@leR_pmul2l ((/ (1 - p) ^ (n - d2)) * (/ p ^ d1))%R). - apply mulR_gt0; apply/invR_gt0/pow_lt => //. - rewrite subR_gt0; lra. - by rewrite -prob_gt0. -rewrite (mulRC ((1 - p) ^ (n - d2))) -!mulRA mulRC -!mulRA mulRV; last first. - apply/expR_neq0; rewrite subR_eq0'; apply/gtR_eqF; lra. -rewrite mulR1 -(mulRC (p ^ d1)) [in X in _ <= X]mulRC !mulRA mulVR ?mul1R; last first. - by apply/expR_neq0/gtR_eqF; rewrite -prob_gt0. -rewrite -expRV; last by apply/gtR_eqF; rewrite -prob_gt0. -rewrite -expRV; last by rewrite subR_eq0'; apply/gtR_eqF; lra. -rewrite mulRC expRV; last by apply/gtR_eqF; rewrite -prob_gt0. -rewrite -/(Rdiv _ _) -expRB; last 2 first. - by case/andP : d1d2. - exact/eqP. -rewrite expRV; last first. - rewrite subR_eq0'; apply/eqP => p1. - move: p05; rewrite ltRNge; apply. - lra. -rewrite -/(Rdiv _ _) -expRB; last 2 first. - rewrite leq_sub2l //; by case/andP : d1d2. - rewrite subR_eq0 => ?. - move: p05; rewrite ltRNge; apply. - lra. -suff -> : (n - d1 - (n - d2) = d2 - d1)%nat by apply pow_incr; split => //; lra. -rewrite -subnDA addnC subnDA subKn //. -by case/andP : d1d2. -Qed. +Variable p : {prob R}. Let card_F2 : #| 'F_2 | = 2%nat. Proof. by rewrite card_Fp. Qed. Let W := BSC.c card_F2 p. @@ -261,7 +225,7 @@ Variable enc : encT [finType of 'F_2] M n. Hypothesis compatible : cancel_on C enc discard. Variable P : {fdist 'rV['F_2]_n}. -Lemma MD_implies_ML : p < 1/2 -> MD_decoding [set cw in C] f -> +Lemma MD_implies_ML : p < 1/2 :> R-> MD_decoding [set cw in C] f -> (forall y, f y != None) -> ML_decoding W C f P. Proof. move=> p05 MD f_total y. @@ -278,7 +242,7 @@ case: oc Hoc => [c|] Hc; last first. exists c; split; first by reflexivity. (* replace W ``^ n (y | f c) with a closed formula because it is a BSC *) pose dH_y c := dH y c. -pose g : nat -> R := fun d : nat => (1 - p) ^ (n - d) * p ^ d. +pose g : nat -> R := fun d : nat => ((1 - p) ^ (n - d) * p ^ d)%R. have -> : W ``(y | c) = g (dH_y c). move: (DMC_BSC_prop p enc (discard c) y). set cast_card := eq_ind_r _ _ _. @@ -287,7 +251,7 @@ have -> : W ``(y | c) = g (dH_y c). rewrite -/W compatible //. move/subsetP : f_img; apply. by rewrite inE; apply/existsP; exists (receivable_rV y); apply/eqP. -transitivity (\big[Rmax/R0]_(c in C) (g (dH_y c))); last first. +transitivity (\big[Order.max/0]_(c in C) (g (dH_y c))); last first. apply eq_bigr => /= c' Hc'. move: (DMC_BSC_prop p enc (discard c') y). set cast_card := eq_ind_r _ _ _. @@ -296,10 +260,11 @@ transitivity (\big[Rmax/R0]_(c in C) (g (dH_y c))); last first. (* the function maxed over is decreasing so we may look for its minimizer, which is given by minimum distance decoding *) rewrite (@bigmaxR_bigmin_vec_helper _ _ _ _ _ _ _ _ _ _ codebook_not_empty) //. -- apply eq_bigl => /= i; by rewrite inE. +- by rewrite bigmaxRE; apply eq_bigl => /= i; rewrite inE. - by apply bsc_prob_prop. -- move=> r; rewrite /g. - apply mulR_ge0; apply pow_le => //; lra. +- move=> r; rewrite /g Prob_pE !coqRE. + apply/RleP/mulr_ge0; apply/exprn_ge0; last exact/prob_ge0. + exact/RleP/onem_ge0/RleP/prob_le1. - rewrite inE; move/subsetP: f_img; apply. rewrite inE; apply/existsP; by exists (receivable_rV y); apply/eqP. - by move=> ? _; rewrite /dH_y max_dH. @@ -327,14 +292,14 @@ Variables (A : finFieldType) (B : finType) (W : `Ch(A, B)). Variables (n : nat) (C : {vspace 'rV[A]_n}). Variable dec : decT B [finType of 'rV[A]_n] n. Variable dec_img : oimg dec \subset C. -Let P := fdist_uniform_supp (vspace_not_empty C). +Let P := fdist_uniform_supp real_realType (vspace_not_empty C). Lemma MAP_implies_ML : MAP_decoding W C dec P -> ML_decoding W C dec P. Proof. move=> HMAP. rewrite /ML_decoding => /= tb. -have Hunpos : 1%:R / INR #| [set cw in C] | > 0. - by rewrite div1R; exact/invR_gt0/ltR0n/vspace_not_empty. +have Hunpos : (#| [set cw in C] |%:R)^-1 > 0 :> R. + by rewrite invr_gt0 ltr0n; exact/vspace_not_empty. move: (HMAP tb) => [m [tbm]]. rewrite /fdist_post_prob. unlock. simpl. set tmp := \rmax_(_ <- _ | _) _. @@ -344,9 +309,7 @@ move=> H. evar (h : 'rV[A]_n -> R); rewrite (eq_bigr h) in H; last first. by move=> v vC; rewrite /h; reflexivity. rewrite -bigmaxR_distrl in H; last first. - apply/invR_ge0; rewrite ltR_neqAle; split. - apply/eqP; by rewrite eq_sym -receivable_propE receivableP. - exact/fdist_post_prob_den_ge0. + by apply/RleP; rewrite invr_ge0; exact/fdist_post_prob_den_ge0. rewrite {2 3}/P in H. set r := index_enum _ in H. move: H. @@ -355,16 +318,18 @@ under [in X in _ = X -> _]eq_bigr. rewrite fdist_uniform_supp_in; last by rewrite inE. over. move=> H. -rewrite -bigmaxR_distrr in H; last exact/ltRW/Hunpos. +rewrite -bigmaxR_distrr in H; last exact/RleP/ltW/Hunpos. exists m; split; first exact tbm. rewrite ffunE in H. set x := (X in _ * _ / X) in H. -have x0 : / x <> 0 by apply/eqP/invR_neq0'; rewrite -receivable_propE receivableP. +have x0 : x^-1 <> 0 by apply/eqP/invr_neq0; rewrite -receivable_propE receivableP. move/(eqR_mul2r x0) in H. rewrite /= fdist_uniform_supp_in ?inE // in H; last first. move/subsetP : dec_img; apply. by rewrite inE; apply/existsP; exists (receivable_rV tb); apply/eqP. -by move/eqR_mul2l : H => -> //; exact/eqP/gtR_eqF. +move/lt0r_neq0/eqP: Hunpos. +move/eqR_mul2l : H; move/[apply] ->. +by rewrite bigmaxRE. Qed. End MAP_decoding_prop. diff --git a/ecc_classic/hamming_code.v b/ecc_classic/hamming_code.v index 9b18971d..51c2940a 100644 --- a/ecc_classic/hamming_code.v +++ b/ecc_classic/hamming_code.v @@ -964,7 +964,7 @@ Section hamming_code_error_rate. Variable M : finType. Hypothesis M_not_0 : 0 < #|M|. -Variable p : prob. +Variable p : {prob R}. Let card_F2 : #| 'F_2 | = 2%N. by rewrite card_Fp. Qed. Let W := BSC.c card_F2 p. diff --git a/ecc_modern/degree_profile.v b/ecc_modern/degree_profile.v index dcf3e875..4bbb7d70 100644 --- a/ecc_modern/degree_profile.v +++ b/ecc_modern/degree_profile.v @@ -3,7 +3,7 @@ From mathcomp Require Import all_ssreflect ssralg fingroup zmodp poly ssrnum. From mathcomp Require Import matrix perm. From mathcomp Require boolp. -Require Import ssr_ext ssralg_ext ssrR fdist. +Require Import ssr_ext ssralg_ext fdist. (******************************************************************************) (* Work in progress about LDPC codes *) @@ -101,16 +101,9 @@ Coercion Lambda_of_L : Definition nzdegdist_coerce := NormalizedDegreeDistribution.p. Coercion nzdegdist_coerce : NormalizedDegreeDistribution.L >-> poly_of. -Require Import Reals Rbigop. - Module TreeEnsemble. -Section definition. - -Variable K : numFieldType. -(* lambda, rho: distribution of the number of ports by node arities - (starts at arity 1) *) -Variables lambda rho : NormalizedDegreeDistribution.L K. +Section ensemble. Inductive kind := kv | kf. @@ -459,9 +452,16 @@ Canonical fintree_finType n l := Eval hnf in FinType _ (fintree_finMixin n l). Local Open Scope fdist_scope. -Definition ensemble n l := {fdist (@fintree n l)}. +Definition ensemble {K : numDomainType} n l := @FDist.t K [finType of (@fintree n l)]. +End ensemble. + +Section tree_ensemble. (* maximum branching degree of the graph (root has no parent) *) +Variable K : numFieldType. +(* lambda, rho: distribution of the number of ports by node arities + (starts at arity 1) *) +Variables lambda rho : NormalizedDegreeDistribution.L K. Variable tw : nat. Hypothesis Hlam : (size lambda <= tw)%nat. Hypothesis Hrho : (size rho <= tw)%nat. @@ -698,25 +698,18 @@ apply eq_bigr=> tl _. by rewrite big_cons. Qed. -Variable RofK : K -> R. -Hypothesis RofKpos : forall x : K, (Num.Def.ler 0%:R x) -> (0 <= RofK x)%R. -Hypothesis RofK0 : RofK 0 = 0%R. -Hypothesis RofK1 : RofK 1 = 1%R. -Hypothesis RofKadd : forall x y : K, RofK (x + y) = (RofK x + RofK y)%R. -Hypothesis RofKmul : forall x y : K, RofK (x * y) = (RofK x * RofK y)%R. - -Lemma f0R l t : (0 <= [ffun x => RofK (@fintree_dist l x)] t)%R. -Proof. rewrite ffunE; apply RofKpos, f0. Qed. +Lemma f0R l t : (0 <= [ffun x => (@fintree_dist l x)] t). +Proof. rewrite ffunE; apply f0. Qed. -Lemma f1R l : (\sum_(t : @fintree tw l) [ffun x => RofK (@fintree_dist l x)] t = 1)%R. +Lemma f1R l : (\sum_(t : @fintree tw l) [ffun x => (@fintree_dist l x)] t = 1). Proof. under eq_bigr do rewrite ffunE /=. -by rewrite -(@big_morph _ _ RofK 0%R Rplus 0%:R (@GRing.add K)) // f1 RofK1. +by rewrite f1. Qed. -Definition tree_ensemble l : ensemble tw l := FDist.make (@f0R l) (@f1R l). +Definition tree_ensemble l : ensemble tw l := @FDist.make K _ _ (@f0R l) (@f1R l). -End definition. +End tree_ensemble. End TreeEnsemble. @@ -1054,13 +1047,17 @@ Lemma le_sum_all (P : pred T) (r : K) F G : r <= (\sum_(i in P) F i) / \sum_(i in P) G i. Proof. move=> HG HG' Hall. -rewrite ler_pdivl_mulr // big_distrr /=. +rewrite ler_pdivlMr // big_distrr /=. apply ler_sum => i Hi. -by rewrite -ler_pdivl_mulr // ?Hall // HG'. +by rewrite -ler_pdivlMr // ?Hall // HG'. Qed. Lemma sum_expr_S m l : (\sum_(i < l.+1) m ^ i = 1 + m * \sum_(i < l) m ^ i)%nat. -Proof. by rewrite big_ord_recl big_distrr. Qed. +Proof. +rewrite big_ord_recl/= expn0 big_distrr/=; congr (_ + _)%N. +by apply: eq_bigr => i _ /=; rewrite -expnS. +Qed. + End sum_ops. Require Import subgraph_partition tanner. @@ -2752,9 +2749,9 @@ have HGneq0 : forall i, i \in P -> r2 <= F i / G i -> G i != 0. rewrite pmulr_rgt0 // => /lt0r_neq0 HGi1. by rewrite -(invrK (G i)) invr_neq0. apply (@Order.POrderTheory.le_trans _ K ((\sum_(i in P | r2 <= F i / G i) G i / \sum_(i in P) G i) * (\sum_(i in P | r2 <= F i / G i) F i / \sum_(i in P | r2 <= F i / G i) G i))). - apply ler_pmul; try by assumption || apply ltW. + apply ler_pM; try by assumption || apply ltW. rewrite -big_distrl -(mulr1 r1) -(mulfV (lt0r_neq0 HGp)) mulrA /=. - apply ler_pmul => //. + apply ler_pM => //. by rewrite mulr_ge0 // ltW. by rewrite invr_ge0 ltW. rewrite -big_distrl /=. @@ -2768,14 +2765,14 @@ apply (@Order.POrderTheory.le_trans _ K ((\sum_(i in P | r2 <= F i / G i) G i / by apply mulr_gt0. rewrite -{1}(mulr1 r2) -(mulfV (lt0r_neq0 HGp')). rewrite mulrA big_distrr /=. - apply ler_pmul => //. + apply ler_pM => //. apply sumr_ge0 => i /andP [Hi Hir2]. rewrite mulr_ge0 //; try by apply ltW. by apply HG. by rewrite ltW // invr_gt0. apply ler_sum => i /andP [Hi Hir2]. - apply ler_pmul => //; try by apply ltW. - by apply HG. + apply ler_pM => //; try by apply ltW. + exact: HG. apply (@Order.POrderTheory.le_trans _ K (\sum_(i in P | r2 <= F i / G i) F i / \sum_(i in P) G i)). rewrite -!big_distrl /= mulrC -mulrA (mulrA _ _ (\sum_(i in P) G i)^-1). rewrite mulVf ?mul1r //. @@ -2783,14 +2780,13 @@ apply (@Order.POrderTheory.le_trans _ K (\sum_(i in P | r2 <= F i / G i) F i / \ apply: @Order.POrderTheory.lt_le_trans; try apply Hr1. by apply mulr_gt0. rewrite -big_distrl /=. -apply ler_pmul => //. +apply: ler_pM => //. apply sumr_ge0 => i /andP [Hi Hir2]. - by apply HF. + exact: HF. by rewrite ltW // invr_gt0. rewrite [\sum_(i in P) F i](bigID (fun i => r2 <= F i / G i)) /=. -apply ler_paddr => //. -apply sumr_ge0 => i /andP [Hi Hir2]. -by apply HF. +rewrite ler_wpDr// sumr_ge0// => i /andP[Hi Hir2]. +exact: HF. Qed. Lemma step_dist_it_const c r y : @@ -3034,7 +3030,7 @@ apply (le_sum_all_cond Hr1 Hr2); try by move=> ? _; apply weighted_count_it_ge0. rewrite [X in _ <= X](bigID (fun i : port * {set port} => i.2 \notin conodes c)) /=. (* remove non tree_like case *) -apply ler_paddr; first by apply sumr_ge0 => i _; apply weighted_count_it_ge0. +apply: ler_wpDr; first by apply: sumr_ge0 => i _; exact: weighted_count_it_ge0. (* simplify rhs formula *) set F := BIG_F. apply (@Order.POrderTheory.le_trans _ _ @@ -3044,7 +3040,7 @@ apply (@Order.POrderTheory.le_trans _ _ do 2 (rewrite (sum_weighted_count_it r _ eqb) // ?eqk //; last by move=> ? ?; apply weighted_count_it). rewrite (eq_bigl (mem (dest_port c))); last by move=> ?; rewrite andbT. - rewrite -big_distrl -big_distrr /= mulrC -ler_pdivl_mull; last first. + rewrite -big_distrl -big_distrr /= mulrC -ler_pdivlMl; last first. move: (weight_is_dist Hhead (leq_trans Hmax Hlam')). rewrite /weighted_count big_map big_enum_in -big_distrl /=. by rewrite -big_distrr /= mul1r -mulrA => ->; by rewrite mulr1. @@ -3055,7 +3051,7 @@ apply (@Order.POrderTheory.le_trans _ _ rewrite -3!mulf_div (@mulfV _ r) ?gt_eqF // mulfV; last first. by rewrite invr_neq0 // pnatr_eq0 -lt0n. rewrite mul1r /bnext eqb /= => ->. - by rewrite ler_pmul // ?ler_nat ?leq_subr // ?invr_ge0 ltW // ltr0n. + by rewrite ler_pM // ?ler_nat ?leq_subr // ?invr_ge0 ltW // ltr0n. (* prove this is equal to the original rhs *) rewrite {}/F le_eqVlt. apply /orP /or_introl /eqP. @@ -3098,23 +3094,22 @@ rewrite /weighted_count /step_dist_it eqb /= /(step_dist c r s i). rewrite (enum_step_border eqb Hi) -/r'. apply Order.POrderTheory.le_trans. rewrite /r2 /r1. -apply ler_expn2r. +apply: lerXn2r. by rewrite nnegrE ltW. by rewrite nnegrE divr_ge0 // ler0n. -rewrite ler_pmul // ?invr_ge0 ?ler0n //. +rewrite ler_pM // ?invr_ge0 ?ler0n //. rewrite ler_nat mulnS subnDA leq_sub2r // -subnDA leq_sub2l //. rewrite /known_coports step_coports_ok //. rewrite cardsU addnC leq_subLR addnCA leq_add2l. by rewrite (leq_trans (cards_conode_out Hd Hni)) // leq_addl. -have Hfc: (#|free_coports (step c s i.1 i.2)| > 0)%nat. - rewrite (@leq_ltn_trans (k * maxdeg)%nat) //. - apply (leq_trans Hlam1). +have Hfc : (#|free_coports (step c s i.1 i.2)| > 0)%nat. + rewrite (@leq_ltn_trans (k * maxdeg)%nat) // (leq_trans Hlam1)//. rewrite (cardsCs (~: _)) setCK. by rewrite leq_sub2l // cardsD /= leq_subr. -rewrite lef_pinv // ?posrE ?ltr0n //. +rewrite lef_pV2 // ?posrE ?ltr0n //. rewrite (cardsCs (~: _)) setCK (cardsCs (~: _)) setCK. rewrite ler_nat leq_sub2l // step_codom_ok //. -by apply subset_leq_card, subsetUr. +exact/subset_leq_card/subsetUr. Qed. End prob_tree_like_border. @@ -3563,7 +3558,7 @@ rewrite 2!weighted_count_switch_step le_sum_all_cond //; (* split numerator for tree_like or not *) rewrite [X in _ <= X](bigID(fun i : _ .-tuple _ => tree_like (step_it c i))) /=. (* remove non tree_like case *) -apply ler_paddr; first by apply sumr_ge0 => i _;apply weighted_count_switch_ge0. +apply: ler_wpDr; first by apply: sumr_ge0 => i _; exact: weighted_count_switch_ge0. (* simplify rhs formula *) set F := BIG_F. apply (@Order.POrderTheory.le_trans _ _ (\sum_(i in dest_ports c #|border (nodes c)| @@ -3603,8 +3598,7 @@ apply (@Order.POrderTheory.le_trans _ _ (\sum_(i in dest_ports c #|border (nodes by rewrite mulnS leq_add // leq_mul. rewrite (leq_ltn_trans _ Hlenmax) //. by rewrite sum_expr_S mulnDr addnA (addnC len) -addnA muln1 leq_addr. - rewrite big_mkcondr /=. - rewrite -ler_pdivl_mulr; last first. + rewrite big_mkcondr /= -ler_pdivlMr; last first. move: (weighted_count_it Hlam def_port r (leqnn _) Hb'). by rewrite /weighted_count big_map big_enum_in => ->. move: (tree_like_empty_border Hlam def_port Hpc Htl Hr Hb') => /=. @@ -3624,11 +3618,11 @@ apply (@Order.POrderTheory.le_trans _ _ (\sum_(i in dest_ports c #|border (nodes apply Order.POrderTheory.le_trans. apply (@Order.POrderTheory.le_trans _ K (r0 ^+ len)). rewrite /r1. - apply ler_expn2r. + apply: lerXn2r. by rewrite rpred_div // nnegrE ler0n. by rewrite rpred_div // nnegrE ler0n. - apply ler_pmul. - by apply ler0n. + apply: ler_pM. + exact: ler0n. by rewrite invr_ge0 ler0n. rewrite ler_nat. rewrite -subnDA leq_sub2l //. @@ -3637,22 +3631,21 @@ apply (@Order.POrderTheory.le_trans _ _ (\sum_(i in dest_ports c #|border (nodes apply (@leq_trans len'). by rewrite mulnC leq_mul. by rewrite leq_addr. - rewrite ler_pinv //. + rewrite ler_pV2 //. by rewrite ler_nat max_card. by rewrite inE unitf_gt0 // ltr0n /=; apply/card_gt0P; exists def_port. by rewrite inE unitf_gt0 // ltr0n. rewrite -(subnK Hb) exprD. - rewrite ger_pmull //. - apply exprn_ile1. + rewrite ger_pMl //. + apply: exprn_ile1. by rewrite mulr_ge0 ?ler0n // invr_ge0 ler0n. - rewrite ler_pdivr_mulr ?mul1r. + rewrite ler_pdivrMr ?mul1r. rewrite ler_nat (cardsCs (free_coports _)) setCK -subnDA. - apply leq_sub2l, (@leq_trans #|known_coports c|). + apply/leq_sub2l/(@leq_trans #|known_coports c|). by rewrite cardsD leq_subr. by rewrite leq_addr. by rewrite ltr0n. - apply exprn_gt0. - apply mulr_gt0. + apply/exprn_gt0/mulr_gt0. by rewrite ltr0n ltn_subRL addn0 mulnC. by rewrite invr_gt0 ltr0n. (* prove this is equal to the original rhs *) @@ -3706,10 +3699,10 @@ have Hlenmaxrec: (len' * tree_max l.+1 < #|port|)%nat. by rewrite (leq_ltn_trans _ Hlenmax) // leq_addl. move/(_ Hlen' (border_nodes_step_it Hi) Hd' Hlenmaxrec) => /=. apply Order.POrderTheory.le_trans. -apply ler_expn2r. +apply: lerXn2r. by rewrite rpred_div // nnegrE ler0n. by rewrite rpred_div // nnegrE ler0n. -rewrite ler_pmul//. +rewrite ler_pM ?ler0n//. by rewrite invr_ge0 ler0n. by rewrite subnDA subnAC ler_nat leq_subr. Qed. diff --git a/ecc_modern/ldpc.v b/ecc_modern/ldpc.v index 14f59e79..66c2bed9 100644 --- a/ecc_modern/ldpc.v +++ b/ecc_modern/ldpc.v @@ -1,13 +1,14 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) From mathcomp Require Import all_ssreflect ssralg fingroup finalg perm zmodp. -From mathcomp Require Import matrix vector. +From mathcomp Require Import matrix vector ssrnum. Require Import Reals Lra. From mathcomp Require Import Rstruct. -Require Import ssrR Reals_ext ssr_ext ssralg_ext num_occ bigop_ext Rbigop. +Require Import ssrR Reals_ext realType_ext ssr_ext ssralg_ext num_occ bigop_ext Rbigop. Require Import fdist channel pproba f2 linearcode subgraph_partition tanner. Require Import tanner_partition hamming binary_symmetric_channel decoding. Require Import channel_code summary checksum summary_tanner. +Require Import Rstruct_ext. (******************************************************************************) (* LDPC Codes and Sum-Product Decoding *) @@ -33,6 +34,8 @@ Set Implicit Arguments. Unset Strict Implicit. Import Prenex Implicits. +Import GRing.Theory Num.Theory. + Local Open Scope num_occ_scope. Local Open Scope channel_scope. Local Open Scope R_scope. @@ -82,36 +85,6 @@ Local Open Scope fdist_scope. Local Open Scope proba_scope. Local Open Scope vec_ext_scope. -(* TODO: move to the file on bsc? *) -Section post_proba_bsc_unif. -Variable A : finType. -Hypothesis card_A : #|A| = 2%nat. -Variable p : R. -Hypothesis p_01' : 0 < p < 1. -Let p_01 := Eval hnf in Prob.mk_ (ltR2W p_01'). -Let P := fdist_uniform card_A. -Variable a' : A. -Hypothesis Ha' : receivable_prop (P `^ 1) (BSC.c card_A p_01) (\row_(i < 1) a'). - -Lemma bsc_post (a : A) : - (P `^ 1) `^^ (BSC.c card_A p_01) (\row_(i < 1) a | mkReceivable Ha') = - (if a == a' then 1 - p else p)%R. -Proof. -rewrite fdist_post_probE /= !fdist_rVE DMCE big_ord_recl big_ord0. -rewrite (eq_bigr (fun x : 'M_1 => P a * (BSC.c card_A p_01) ``( (\row__ a') | x))%R); last first. - by move=> i _; rewrite /P !fdist_rVE big_ord_recl big_ord0 !fdist_uniformE mulR1. -rewrite -big_distrr /= (_ : \sum_(_ | _) _ = 1)%R; last first. - transitivity (\sum_(i in 'M_1) fdist_binary card_A p_01 (i ``_ ord0) a')%R. - apply eq_bigr => i _. - by rewrite DMCE big_ord_recl big_ord0 mulR1 /BSC.c mxE. - apply/(@big_rV1_ord0 _ _ _ _ (fdist_binary card_A p_01 ^~ a')). - by rewrite -sum_fdist_binary_swap // FDist.f1. -rewrite mxE mulR1 big_ord_recl big_ord0 /BSC.c fdist_binaryE /= eq_sym !mxE; field. -by rewrite /P fdist_uniformE card_A (_ : 2%:R = 2)%R //; lra. -Qed. - -End post_proba_bsc_unif. - Section DMC_sub_vec_Fnext_Vgraph. Variables (B : finType) (W : `Ch('F_2, B)). Variable n' : nat. @@ -500,8 +473,8 @@ Lemma K949_lemma df n0 : K949 n0 df = marginal_post_prob_den y * post_prob_uniform_cst [set cw in C] y. Proof. rewrite /K949 /marginal_post_prob_den /post_prob_uniform_cst -invRM; last 2 first. - apply/eqP; rewrite FDist.f1 => ?; lra. - by rewrite -not_receivable_prop_uniform receivableP. +- by rewrite FDist.f1; apply: lt0r_neq0. +- by rewrite -not_receivable_prop_uniform receivableP. congr (/ _). transitivity (\sum_(t in 'rV['F_2]_n) if t \in kernel H then W ``(y | t) else 0); last first. @@ -509,24 +482,25 @@ transitivity (\sum_(t in 'rV['F_2]_n) apply eq_bigr => /= t Ht. case: ifP => HtH. rewrite fdist_post_probE fdist_uniform_supp_in ?inE //. - have HH : #|[set cw in kernel H]|%:R <> 0. - apply/INR_eq0/eqP. + have HH : (#|[set cw in kernel H]|%:R)%mcR != 0. + (* the following three lines amount to INR_eq0 *) + have->: 0 = GRing.natmul 1 0 by []. + apply/eqP => /mulrIn /eqP. + rewrite -unitfE unitr1 => /(_ erefl); apply/negP. rewrite cards_eq0. by apply/set0Pn; exists t; rewrite inE. - rewrite -(mulRC (W ``(y | t))) -[X in X = _]mulR1. - rewrite -!mulRA. + rewrite -(mulrC (W ``(y | t))) -[X in X = _]mulr1. + rewrite !coqRE -!mulrA. congr (_ * _). - rewrite mul1R fdist_uniform_supp_restrict /= fdist_uniform_supp_distrr /=; last first. - rewrite invRM; last 2 first. - exact/eqP/invR_neq0. + rewrite fdist_uniform_supp_restrict /= fdist_uniform_supp_distrr /=; last first. + rewrite invrM; last 2 first. + exact/invr_neq0. rewrite (eq_bigl (fun x => x \in [set cw in C])); last by move=> i; rewrite inE. - by rewrite -not_receivable_prop_uniform receivableP. - rewrite invRK -mulRA mulRC mulVR ?mulR1 ?mulRV //; first by exact/eqP. - set tmp1 := \sum_(_ | _) _. - rewrite /tmp1 (eq_bigl (fun x => x \in [set cw in C])); last by move=> i; rewrite inE. - by rewrite -not_receivable_prop_uniform receivableP. + by rewrite unitfE -not_receivable_prop_uniform receivableP. + rewrite invrK [X in _ = _ * X]mulrAC mulVr ?mul1r ?coqRE ?mulVr //. + by rewrite unitfE -not_receivable_prop_uniform receivableP. rewrite fdist_post_probE fdist_uniform_supp_notin; last by rewrite inE; exact/negbT. - by rewrite !(mul0R,div0R). + by rewrite !coqRE !mul0r. rewrite -big_mkcond /=. rewrite /alpha. transitivity (W Zp0 (y ``_ n0) * @@ -877,7 +851,7 @@ Fixpoint sumproduct_loop (lmax : nat) (beta0 beta1 : 'M_(m, n)) : option ('rV['F let estimation x n0 alpha := (W x (y \_ n0) * \prod_(m1 in 'F n0) alpha m1 n0)%R in let gamma0 n0 := estimation Zp0 n0 alpha0 in let gamma1 n0 := estimation Zp1 n0 alpha1 in - let chat := \matrix_(i < 1, n0 < n) if gamma0 n0 >b= gamma1 n0 then 0 else 1 in + let chat := \matrix_(i < 1, n0 < n) if (gamma0 n0 >= gamma1 n0)%mcR then 0 else 1 in if H *m chat^T == 0 then Some chat else diff --git a/information_theory/aep.v b/information_theory/aep.v index c721e474..7852dd9f 100644 --- a/information_theory/aep.v +++ b/information_theory/aep.v @@ -1,10 +1,10 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg matrix. +From mathcomp Require Import all_ssreflect ssralg ssrnum matrix. From mathcomp Require boolp. Require Import Reals. From mathcomp Require Import Rstruct. -Require Import ssrR Reals_ext ssr_ext ssralg_ext logb Rbigop fdist proba. +Require Import ssrR Reals_ext realType_ext ssr_ext ssralg_ext logb Rbigop fdist proba. Require Import entropy. (******************************************************************************) @@ -20,7 +20,6 @@ Set Implicit Arguments. Unset Strict Implicit. Import Prenex Implicits. -Local Open Scope R_scope. Local Open Scope fdist_scope. Local Open Scope proba_scope. Local Open Scope entropy_scope. @@ -28,7 +27,7 @@ Local Open Scope ring_scope. Local Open Scope vec_ext_scope. Section mlog_prop. -Variables (A : finType) (P : fdist A). +Variables (A : finType) (P : {fdist A}). Local Open Scope R_scope. Definition aep_sigma2 := `E ((`-- (`log P)) `^2) - (`H P)^2. @@ -58,7 +57,8 @@ rewrite (_ : \sum_(a in A) - _ = - (2 * `H P ^ 2))%R; last first. by rewrite -/(entropy P) -mulRA /= mulR1. set s := ((\sum_(a in A ) _)%R in LHS). rewrite (_ : \sum_(a in A) _ = s)%R; last by apply eq_bigr => a _; field. -by field. +rewrite RpowE GRing.expr2 -!RmultE mulR1. +field. Qed. Lemma aep_sigma2_ge0 : 0 <= aep_sigma2. @@ -66,12 +66,12 @@ Proof. rewrite -V_mlog /Var; apply Ex_ge0 => ?; exact: pow_even_ge0. Qed. End mlog_prop. -Definition sum_mlog_prod A (P : fdist A) n : {RV (P `^ n) -> R} := +Definition sum_mlog_prod (A : finType) (P : {fdist A}) n : {RV (P `^ n) -> R} := (fun t => \sum_(i < n) - log (P t ``_ i))%R. Arguments sum_mlog_prod {A} _ _. -Lemma sum_mlog_prod_sum_map_mlog A (P : fdist A) n : +Lemma sum_mlog_prod_sum_map_mlog (A : finType) (P : {fdist A}) n : sum_mlog_prod P n.+1 \=sum (\row_(i < n.+1) `-- (`log P)). Proof. elim : n => [|n IH]. @@ -93,7 +93,7 @@ elim : n => [|n IH]. Qed. Section aep_k0_constant. - +Local Open Scope R_scope. Variables (A : finType) (P : {fdist A}). Definition aep_bound epsilon := (aep_sigma2 P / epsilon ^ 3)%R. @@ -111,14 +111,15 @@ Qed. End aep_k0_constant. -Section AEP. +Section AEP. +Local Open Scope R_scope. Variables (A : finType) (P : {fdist A}) (n : nat) (epsilon : R). Hypothesis Hepsilon : 0 < epsilon. Lemma aep : aep_bound P epsilon <= n.+1%:R -> - Pr (P `^ n.+1) [set t | (0 b= epsilon) ] <= epsilon. + Pr (P `^ n.+1) [set t | (0 < P `^ n.+1 t)%mcR && + (`| (`-- (`log (P `^ n.+1)) `/ n.+1) t - `H P | >= epsilon)%mcR ] <= epsilon. Proof. move=> Hbound. apply (@leR_trans (aep_sigma2 P / (n.+1%:R * epsilon ^ 2))); last first. @@ -137,9 +138,14 @@ have {H1 H2} := (wlln (H1 n) (H2 n) Hsum Hepsilon). move/(leR_trans _); apply. apply/Pr_incl/subsetP => ta; rewrite 2!inE => /andP[H1]. rewrite /sum_mlog_prod [`-- (`log _)]lock /= -lock /= /scalel_RV /log_RV /neg_RV. -rewrite fdist_rVE log_prodR_sumR_mlog //. -apply: (prodR_gt0_inv (FDist.ge0 P)). -by move: H1; rewrite fdist_rVE => /ltRP. +rewrite fdist_rVE. +rewrite log_prodR_sumR_mlog //. +have : forall x, 0 <= P x. + move=> x. + apply/RleP. + exact: FDist.ge0. +move/prodR_gt0_inv; apply. +by move: H1; rewrite fdist_rVE => /RltP. Qed. End AEP. diff --git a/information_theory/binary_symmetric_channel.v b/information_theory/binary_symmetric_channel.v index 3d9f0b13..4f8ebc30 100644 --- a/information_theory/binary_symmetric_channel.v +++ b/information_theory/binary_symmetric_channel.v @@ -1,11 +1,11 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg finset fingroup finalg perm. -From mathcomp Require Import zmodp matrix. -From mathcomp Require Import Rstruct classical_sets. +From mathcomp Require Import all_ssreflect ssralg ssrnum zmodp matrix lra. +From mathcomp Require Import mathcomp_extra Rstruct classical_sets. Require Import Reals Lra. -Require Import ssrR Reals_ext logb ssr_ext ssralg_ext bigop_ext Rbigop fdist. +Require Import ssrR Reals_ext realType_ext logb ssr_ext ssralg_ext bigop_ext Rbigop fdist. Require Import entropy binary_entropy_function channel hamming channel_code. +Require Import pproba Rstruct_ext. (******************************************************************************) (* Capacity of the binary symmetric channel *) @@ -28,7 +28,7 @@ Module BSC. Section BSC_sect. Variable A : finType. Hypothesis card_A : #|A| = 2%nat. -Variable p : prob. +Variable p : {prob R}. Definition c : `Ch(A, A) := fdist_binary card_A p. @@ -37,13 +37,19 @@ End BSC. Local Open Scope entropy_scope. +Import Order.TTheory GRing.Theory Num.Def Num.Theory. + Section bsc_capacity_proof. Variable A : finType. Hypothesis card_A : #|A| = 2%nat. -Variables (P : fdist A) (p : R). -Hypothesis p_01' : (0 < p < 1)%R. +Variables (P : {fdist A}) (p : R). +Hypothesis p_01' : (0 < p < 1)%mcR. + +Let p_01'_ : (0 <= p <= 1)%mcR. +by move: p_01' => /andP[/ltW -> /ltW ->]. +Qed. -Let p_01 : prob := Eval hnf in Prob.mk_ (ltR2W p_01'). +Let p_01 : {prob R} := Eval hnf in Prob.mk_ p_01'_. Lemma HP_HPW : `H P - `H(P, BSC.c card_A p_01) = - H2 p. Proof. @@ -62,28 +68,66 @@ set a := Set2.a _. set b := Set2.b _. case: (Req_EM_T (P a) 0) => H1. rewrite H1 !(mul0R, mulR0, addR0, add0R). move: (FDist.f1 P); rewrite Set2sumE /= -/a -/b. - rewrite H1 add0R => ->. - rewrite /log Log_1 !(mul0R, mulR0, addR0, add0R, mul1R, mulR1); field. + rewrite H1 add0r => ->. + rewrite /log Log_1 -!RmultE !(mul0R, mulR0, addR0, add0R, mul1R, mulR1). + rewrite /onem -RminusE (_ : 1%mcR = 1)//. + field. rewrite /log LogM; last 2 first. - rewrite -fdist_gt0; exact/eqP. - case: p_01' => ? ?; lra. + move/eqP in H1. + have [+ _] := fdist_gt0 P a. + by move/(_ H1) => /RltP. + case/andP: p_01' => ? ?. + apply/Reals_ext.onem_gt0. + by apply/RltP. rewrite /log LogM; last 2 first. - rewrite -fdist_gt0; exact/eqP. - by case: p_01'. + move/eqP in H1. + have [+ _] := fdist_gt0 P a. + by move/(_ H1) => /RltP. + case/andP: p_01' => ? ?. + by apply/RltP. case: (Req_EM_T (P b) 0) => H2. rewrite H2 !(mul0R, mulR0, addR0, add0R). move: (FDist.f1 P); rewrite Set2sumE /= -/a -/b. - rewrite H2 addR0 => ->. - rewrite /log Log_1 !(mul0R, mulR0, addR0, add0R, mul1R, mulR1); field. + rewrite H2 addr0 => ->. + rewrite /log Log_1 -!RmultE !(mul0R, mulR0, addR0, add0R, mul1R, mulR1). + rewrite /onem -RminusE (_ : 1%mcR = 1)//. + field. rewrite /log LogM; last 2 first. - rewrite -fdist_gt0; exact/eqP. - by case: p_01'. + move/eqP in H2. + have [+ _] := fdist_gt0 P b. + by move/(_ H2) => /RltP. + case/andP: p_01' => ? ?. + by apply/RltP. rewrite /log LogM; last 2 first. - rewrite -fdist_gt0; exact/eqP. - rewrite subR_gt0; by case: p_01'. + move/eqP in H2. + have [+ _] := fdist_gt0 P b. + by move/(_ H2) => /RltP. + case/andP: p_01' => ? ?. + apply/Reals_ext.onem_gt0. + by apply/RltP. +rewrite /log. +rewrite -!RmultE. +rewrite /onem -RminusE (_ : 1%mcR = 1)//. transitivity (p * (P a + P b) * log p + (1 - p) * (P a + P b) * log (1 - p) ). - rewrite /log; by field. -by move: (FDist.f1 P); rewrite Set2sumE /= -/a -/b => ->; rewrite /log; field. + rewrite /log. + set l2Pa := Log 2 (P a). + set l2Pb := Log 2 (P b). + set l21p := Log 2 (1 - p). + set l2p := Log 2 p. + ring_simplify. (* TODO *) + congr (_ + _). + rewrite [RHS]addRC !addRA; congr (_ + _). + rewrite [RHS]addRC !addRA; congr (_ + _). + rewrite [RHS]addRC !addRA; congr (_ + _ + _). + rewrite !mulNR; congr (- _). + by rewrite [RHS]mulRC mulRA. + by rewrite [RHS]mulRC mulRA. + by rewrite mulRC. +move: (FDist.f1 P). +rewrite Set2sumE /= -/a -/b. +rewrite -RplusE => ->. +rewrite !mulR1. +rewrite /log; field. Qed. Lemma IPW : `I(P, BSC.c card_A p_01) = `H(P `o BSC.c card_A p_01) - H2 p. @@ -101,33 +145,46 @@ set a := Set2.a _. set b := Set2.b _. rewrite /BSC.c !fdist_binaryxx !fdist_binaryE /= !(eq_sym _ a). rewrite (negbTE (Set2.a_neq_b card_A)). move: (FDist.f1 P); rewrite Set2sumE /= -/a -/b => P1. +rewrite -!(RmultE,RplusE). have -> : p * P a + (1 - p) * P b = 1 - ((1 - p) * P a + p * P b). - rewrite -{2}P1; by field. + rewrite -RplusE (_ : 1%mcR = 1)// in P1. + rewrite -{2}P1. + ring_simplify. + congr (_ + _). + by rewrite subRK. +case/andP: p_01' => /RltP Hp1 /RltP Hp2. +rewrite (_ : 0%mcR = 0%coqR)// in Hp1. +rewrite (_ : 1%mcR = 1%coqR)// in Hp2, P1. have H01 : 0 < ((1 - p) * P a + p * P b) < 1. - move: (FDist.ge0 P a) => H1. + move: (FDist.ge0 P a) => /RleP H1. move: (FDist.le1 P b) => H4. move: (FDist.le1 P a) => H3. - case: p_01' => Hp1 Hp2. split. - case/Rle_lt_or_eq_dec : H1 => H1. - - apply addR_gt0wl; by [apply mulR_gt0; lra | apply mulR_ge0; lra]. - - by rewrite -H1 mulR0 add0R (_ : P b = 1) ?mulR1 // -P1 -H1 add0R. + case/Rle_lt_or_eq_dec : H1 => H1; rewrite (_ : 0%mcR = 0)// in H1. + - apply addR_gt0wl. + apply: mulR_gt0 => //. + by rewrite subR_gt0. + apply: mulR_ge0 => //. + exact: ltRW. + - by rewrite -H1 mulR0 add0R (_ : P b = 1) ?mulR1 // -P1 -H1 add0r. rewrite -{2}P1. case: (Req_EM_T (P a) 0) => Hi. rewrite Hi mulR0 !add0R. - rewrite Hi add0R in P1. - by rewrite P1 mulR1. + rewrite Hi add0r in P1. + by rewrite P1 mulR1 add0r. case: (Req_EM_T (P b) 0) => Hj. - rewrite Hj addR0 in P1. + rewrite Hj addr0 in P1. rewrite Hj mulR0 !addR0 P1 mulR1. - lra. + rewrite addr0. + by rewrite ltR_subl_addr ltR_addl. case/Rle_lt_or_eq_dec : H1 => H1. - apply leR_lt_add. - + rewrite -{2}(mul1R (P a)); apply leR_wpmul2r; lra. + + rewrite -{2}(mul1R (P a)); apply leR_wpmul2r => //. + by rewrite leR_subl_addr leR_addl; exact: ltRW. + rewrite -{2}(mul1R (P b)); apply ltR_pmul2r => //. - apply/ltRP; rewrite lt0R; apply/andP; split; [exact/eqP|exact/leRP]. - - rewrite -H1 mulR0 2!add0R. - have -> : P b = 1 by rewrite -P1 -H1 add0R. + by apply/RltP; rewrite lt0r; apply/andP; split; [exact/eqP|by []]. + - rewrite -H1 mulR0 add0R add0r. + have -> : P b = 1 by rewrite -P1 -H1 add0r. by rewrite mulR1. rewrite (_ : forall a b, - (a + b) = - a - b); last by move=> *; field. rewrite -mulNR. @@ -137,17 +194,33 @@ by rewrite /H2 !mulNR; apply Req_le; field. Qed. Lemma bsc_out_H_half' : 0 < 1%:R / 2%:R < 1. -Proof. by rewrite /= (_ : 1%:R = 1) // (_ : 2%:R = 2) //; lra. Qed. +Proof. +rewrite /= (_ : 1%:R = 1) // (_ : 2%:R = 2) //. +split => //. +apply: divR_gt0 => //. +apply/ltR_pdivr_mulr => //. +by rewrite mul1R. +Qed. Lemma H_out_binary_uniform : `H(fdist_uniform card_A `o BSC.c card_A p_01) = 1. Proof. rewrite {1}/entropy !Set2sumE /= !fdist_outE !Set2sumE /=. rewrite /BSC.c !fdist_binaryxx !fdist_binaryE (eq_sym _ (Set2.a _)) !fdist_uniformE. rewrite (negbTE (Set2.a_neq_b card_A)). -rewrite -!mulRDl (_ : 1 - p + p = 1); last by field. -rewrite mul1R (_ : p + (1 - p) = 1); last by field. -rewrite mul1R -!mulRDl card_A /= (_ : INR 2 = 2) // /log LogV; last lra. -by rewrite Log_n //=; field. +rewrite -!mulrDl. +rewrite /onem subrK. +rewrite !mul1r. +rewrite addrC subrK. +have ? : 2%mcR != 0%mcR :> R. + rewrite (_ : 2%mcR = 2)//. + rewrite (_ : 0%mcR = 0)//. + by apply/eqP. +rewrite -RdivE// ?card_A//. +rewrite div1R -RinvE//. +rewrite -!mulRDl /log LogV//. +rewrite Log_n //=. +rewrite (_ : 2%mcR = 2)//. +field. Qed. End bsc_capacity_proof. @@ -156,40 +229,61 @@ Section bsc_capacity_theorem. Variable A : finType. Hypothesis card_A : #|A| = 2%nat. Variable p : R. -Hypothesis p_01' : 0 < p < 1. -Let p_01 := Eval hnf in Prob.mk_ (ltR2W p_01'). +Hypothesis p_01' : (0 < p < 1)%mcR. +Let p_01'_ : (0 <= p <= 1)%mcR. +by move: p_01' => /andP[/ltW -> /ltW ->]. +Qed. +Let p_01 : {prob R} := Eval hnf in Prob.mk_ p_01'_. Theorem BSC_capacity : capacity (BSC.c card_A p_01) = 1 - H2 p. Proof. rewrite /capacity /image. set E := (fun y : R => _). -set p' := Prob.mk_ (ltR2W p_01'). +set p' := Prob.mk_ p_01'_. have has_sup_E : has_sup E. split. set d := fdist_binary card_A p' (Set2.a card_A). by exists (`I(d, BSC.c card_A p')), d. exists 1 => y [P _ <-{y}]. - rewrite IPW; apply/RleP/leR_subl_addr/(leR_trans (H_out_max card_A P p_01')). + have := IPW card_A P p_01'. + set tmp := (X in `I(_, BSC.c _ X)). + rewrite (_ : tmp = p_01)//; last first. + by apply/val_inj => //. + move=> ->. + apply/RleP/leR_subl_addr/(leR_trans (H_out_max card_A P p_01')). rewrite addRC -leR_subl_addr subRR. - by rewrite (entropy_H2 card_A (Prob.mk_ (ltR2W p_01'))); exact/entropy_ge0. + by rewrite (entropy_H2 card_A (Prob.mk_ (p_01'_))); exact/entropy_ge0. apply eqR_le; split. apply/RleP. have [_ /(_ (1 - H2 p))] := Rsup_isLub (0 : R) has_sup_E. apply => x [d _ dx]; apply/RleP. suff : `H(d `o BSC.c card_A p_01) <= 1. - move: (@IPW _ card_A d _ p_01') => ?. - by unfold p_01 in *; lra. - exact: H_out_max. + have := IPW card_A d p_01'. + set tmp := (X in `I(_, BSC.c _ X)). + rewrite (_ : tmp = p_01)//; last first. + by apply/val_inj => //. + set tmp' := (X in _ = `H(d `o (BSC.c card_A X)) - _ -> _). + rewrite (_ : tmp' = p_01)//; last first. + by apply/val_inj => //. + rewrite dx => -> ?. + by rewrite leR_subl_addr subRK. + have := H_out_max card_A d p_01'. + set tmp' := (X in `H(d `o (BSC.c card_A X)) <= _ -> _). + rewrite (_ : tmp' = p_01)//. + by apply/val_inj. move: (@IPW _ card_A (fdist_uniform card_A) _ p_01'). rewrite H_out_binary_uniform => <-. -by apply/RleP/Rsup_ub => //=; exists (fdist_uniform card_A). +apply/RleP/Rsup_ub => //=. +exists (fdist_uniform card_A) => //. +do 2 f_equal. +exact: val_inj. Qed. End bsc_capacity_theorem. Section dH_BSC. -Variable p : prob. +Variable p : {prob R}. Let card_F2 : #| 'F_2 | = 2%nat. by rewrite card_Fp. Qed. Let W := BSC.c card_F2 p. Variables (M : finType) (n : nat) (f : encT [finType of 'F_2] M n). @@ -211,3 +305,95 @@ by rewrite big_const /= iter_mulR /= card_dH_vec. Qed. End dH_BSC. + +(* moved from decoder.v; TODO: rename *) +Section bsc_prob_prop. +Local Open Scope reals_ext_scope. +Local Open Scope ring_scope. +Local Open Scope order_scope. + +(* This lemma is more or less stating that + (log q <|n2 / n|> log r) <= (log q <|n1 / n|> log r) *) +Lemma expr_conv_mono n n1 n2 q r : + 0 < q :> R -> q <= r -> (n1 <= n2 <= n)%nat -> + r ^+ (n - n2) * q ^+ n2 <= r ^+ (n - n1) * q ^+ n1. +Proof. +move=> /[dup] /ltW q0 q1 qr /andP [] n12 n2n. +have r1 := lt_le_trans q1 qr. +have r0 := ltW r1. +rewrite [leLHS](_ : _ = q ^+ n1 * q ^+ (n2 - n1)%nat * r ^+ (n - n2)%nat); + last by rewrite -exprD subnKC // mulrC. +rewrite [leRHS](_ : _ = q ^+ n1 * r ^+ (n2 - n1)%nat * r ^+ (n - n2)%nat); + last by rewrite -mulrA -exprD addnBAC // subnKC // mulrC. +apply: ler_pM => //; [by apply/mulr_ge0; apply/exprn_ge0 | by apply/exprn_ge0 | ]. +apply: ler_pM => //; [by apply/exprn_ge0 | by apply/exprn_ge0 |]. +rewrite -[leLHS]mul1r -ler_pdivlMr ?exprn_gt0 // -expr_div_n. +apply: exprn_ege1. +by rewrite ler_pdivlMr // mul1r. +Qed. + +Lemma bsc_prob_prop p n : p%:pp < 1 / 2 -> + forall n1 n2 : nat, (n1 <= n2 <= n)%nat -> + ((1 - p) ^ (n - n2) * p ^ n2 <= (1 - p) ^ (n - n1) * p ^ n1)%R. +Proof. +rewrite Prob_pE. +move=> p05 d1 d2 d1d2. +case/boolP: (p == R0%:pr). + move/eqP->; rewrite !coqRE; apply/RleP. + rewrite probpK subr0 !expr1n !mul1r !expr0n. + move: d1d2; case: d2; first by rewrite leqn0 => /andP [] ->. + case: (d1 == 0%nat) => //=. + move=> ? ?; exact:ler01. +move/prob_gt0 => p1. +rewrite !coqRE. +apply/RleP/expr_conv_mono => //. +lra. +Qed. +End bsc_prob_prop. + +(* moved from ldpc.v *) +Section post_proba_bsc_unif. +Local Open Scope reals_ext_scope. +Local Open Scope ring_scope. +Local Open Scope order_scope. +Local Open Scope proba_scope. +Local Open Scope vec_ext_scope. + +Variable A : finType. +Hypothesis card_A : #|A| = 2%nat. +Variable p : R. +Hypothesis p_01' : 0 < p < 1. + +Let p_01'_ : 0 <= p <= 1. +by move: p_01' => /andP [/ltW -> /ltW ->]. +Qed. + +Let p_01 : {prob R} := Eval hnf in Prob.mk_ p_01'_. +(* +Let p_01 := Eval hnf in Prob.mk_ (ltR2W p_01'). +*) + +Let P := fdist_uniform (R:=R_numFieldType) card_A. +Variable a' : A. +Hypothesis Ha' : receivable_prop (P `^ 1) (BSC.c card_A p_01) (\row_(i < 1) a'). + +Lemma bsc_post (a : A) : + (P `^ 1) `^^ (BSC.c card_A p_01) (\row_(i < 1) a | mkReceivable Ha') = + (if a == a' then 1 - p else p)%R. +Proof. +rewrite fdist_post_probE /= !fdist_rVE DMCE big_ord_recl big_ord0. +rewrite (eq_bigr (fun x : 'M_1 => P a * (BSC.c card_A p_01) ``( (\row__ a') | x))%R); last first. + by move=> i _; rewrite /P !fdist_rVE big_ord_recl big_ord0 !fdist_uniformE mulr1. +rewrite -big_distrr /= (_ : \sum_(_ | _) _ = 1)%R; last first. + transitivity (\sum_(i in 'M_1) fdist_binary card_A p_01 (i ``_ ord0) a')%R. + apply eq_bigr => i _. + by rewrite DMCE big_ord_recl big_ord0 mulR1 /BSC.c mxE. + apply/(@big_rV1_ord0 _ _ _ _ (fdist_binary card_A p_01 ^~ a')). + by rewrite -sum_fdist_binary_swap // FDist.f1. +rewrite mxE mulr1 big_ord_recl big_ord0 /BSC.c fdist_binaryE /= eq_sym !mxE. +rewrite !coqRE mulr1 onemE. +rewrite mulrAC mulfV ?mul1r // fdist_uniformE card_A invr_neq0 //. +by apply: lt0r_neq0; lra. +Qed. + +End post_proba_bsc_unif. diff --git a/information_theory/channel.v b/information_theory/channel.v index 80fbb742..506d3226 100644 --- a/information_theory/channel.v +++ b/information_theory/channel.v @@ -1,6 +1,6 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg matrix. +From mathcomp Require Import all_ssreflect all_algebra. Require Import Reals. From mathcomp Require Import Rstruct. Require Import ssrR Reals_ext logb ssr_ext ssralg_ext bigop_ext Rbigop fdist. @@ -54,12 +54,13 @@ Reserved Notation "`H( W | P )" (at level 10, W, P at next level). Reserved Notation "`I( P , W )" (at level 50, format "`I( P , W )"). Local Open Scope R_scope. +Local Open Scope fdist_scope. Module Channel1. Section channel1. Variables A B : finType. -Local Notation "'`Ch'" := (A -> fdist B) (only parsing). +Local Notation "'`Ch'" := (A -> {fdist B}) (only parsing). Record chan_star := mkChan { c :> `Ch ; @@ -97,7 +98,7 @@ Variables (A B : finType) (W : `Ch(A, B)) (n : nat). Definition f (x : 'rV[A]_n) := [ffun y : 'rV[B]_n => (\prod_(i < n) W `(y ``_ i | x ``_ i))]. -Lemma f0 x y : 0 <= f x y. Proof. rewrite ffunE; exact: prodR_ge0. Qed. +Lemma f0 x y : (0 <= f x y). Proof. rewrite ffunE; apply/RleP; exact: prodR_ge0. Qed. Lemma f1 x : (\sum_(y in 'rV_n) f x y = 1)%R. Proof. @@ -160,21 +161,22 @@ Proof. by rewrite DMCE -rprod_sub_vec. Qed. End DMC_sub_vec. Section fdist_out. -Variables (A B : finType) (P : fdist A) (W : A -> fdist B). +Variables (A B : finType) (P : {fdist A}) (W : A -> {fdist B}). +Local Open Scope ring_scope. Definition f := [ffun b : B => \sum_(a in A) W a b * P a]. -Let f0 (b : B) : 0 <= f b. -Proof. by rewrite ffunE; apply: sumR_ge0 => a _; exact: mulR_ge0. Qed. +Let f0 (b : B) : (0 <= f b). +Proof. by rewrite ffunE; apply/RleP; apply: sumR_ge0 => a _; exact: mulR_ge0. Qed. Let f1 : \sum_(b in B) f b = 1. Proof. under eq_bigr do rewrite ffunE /=. -rewrite exchange_big /= -(FDist.f1 P). -by apply eq_bigr => a _; rewrite -big_distrl /= (FDist.f1 (W a)) mul1R. +rewrite exchange_big /= -[RHS](FDist.f1 P). +by apply eq_bigr => a _; rewrite -big_distrl /= (FDist.f1 (W a)) -RmultE mul1R. Qed. -Definition fdist_out : fdist B := locked (FDist.make f0 f1). +Definition fdist_out : {fdist B} := locked (FDist.make f0 f1). Lemma fdist_outE b : fdist_out b = \sum_(a in A) W a b * P a. Proof. by rewrite /fdist_out; unlock; rewrite ffunE. Qed. @@ -189,7 +191,7 @@ Section fdist_out_prop. Variables A B : finType. Local Open Scope ring_scope. -Lemma fdist_rV_out (W : `Ch(A, B)) (P : fdist A) n (b : 'rV_n): +Lemma fdist_rV_out (W : `Ch(A, B)) (P : {fdist A}) n (b : 'rV_n): `O(P, W) `^ _ b = \sum_(j : 'rV[A]_n) (\prod_(i < n) W j ``_ i b ``_ i) * P `^ _ j. Proof. @@ -208,16 +210,16 @@ apply: eq_big. Qed. Local Close Scope ring_scope. -Lemma fdistX_prod_out (W : `Ch(A, B)) (P : fdist A) : (fdistX (P `X W))`1 = `O(P, W). +Lemma fdistX_prod_out (W : `Ch(A, B)) (P : {fdist A}) : (fdistX (P `X W))`1 = `O(P, W). Proof. rewrite fdistX1; apply/fdist_ext => b; rewrite fdist_outE fdist_sndE. -by under eq_bigr do rewrite fdist_prodE mulRC. +by under eq_bigr do rewrite fdist_prodE -RmultE mulRC. Qed. End fdist_out_prop. Section Pr_fdist_prod. -Variables (A B : finType) (P : fdist A) (W : `Ch(A, B)) (n : nat). +Variables (A B : finType) (P : {fdist A}) (W : `Ch(A, B)) (n : nat). Lemma Pr_DMC_rV_prod (Q : 'rV_n * 'rV_n -> bool) : Pr (((P `^ n) `X (W ``^ n))) [set x | Q x] = @@ -270,13 +272,13 @@ apply: eq_big => ta. by rewrite inE; apply/esym/eqP/rowP => a; rewrite mxE ffunE. move=> Hta. rewrite fdist_rVE /=; apply eq_bigr => l _. -by rewrite fdist_prodE -fst_tnth_prod_rV -snd_tnth_prod_rV ffunE mulRC. +by rewrite fdist_prodE -fst_tnth_prod_rV -snd_tnth_prod_rV ffunE -RmultE mulRC. Qed. Local Close Scope ring_scope. End Pr_fdist_prod. -Lemma channel_jcPr (A B : finType) (W : `Ch(A, B)) (P : fdist A) a b : +Lemma channel_jcPr (A B : finType) (W : `Ch(A, B)) (P : {fdist A}) a b : P a != 0 -> W a b = \Pr_(fdistX (P `X W))[ [set b] | [set a] ]. Proof. by move=> Pa0; rewrite jcPr_fdistX_prod//; exact/eqP. Qed. @@ -284,7 +286,7 @@ Proof. by move=> Pa0; rewrite jcPr_fdistX_prod//; exact/eqP. Qed. Notation "`H( P , W )" := (`H (P `X W)) : channel_scope. Section conditional_entropy_chan. -Variables (A B : finType) (W : `Ch(A, B)) (P : fdist A). +Variables (A B : finType) (W : `Ch(A, B)) (P : {fdist A}). Definition cond_entropy_chan := `H(P, W) - `H P. End conditional_entropy_chan. @@ -292,7 +294,7 @@ End conditional_entropy_chan. Notation "`H( W | P )" := (cond_entropy_chan W P) : channel_scope. Section condentropychan_prop. -Variables (A B : finType) (W : `Ch(A, B)) (P : fdist A). +Variables (A B : finType) (W : `Ch(A, B)) (P : {fdist A}). Lemma cond_entropy_chanE : `H(W | P) = cond_entropy (fdistX (P `X W)). Proof. @@ -306,7 +308,7 @@ Proof. rewrite cond_entropy_chanE cond_entropyE big_morph_oppR; apply: eq_bigr => a _. rewrite big_morph_oppR /entropy mulRN -mulNR big_distrr/=; apply: eq_bigr => b _. rewrite fdistXI fdist_prodE /= mulNR mulRA; congr (- _). -have [->|Pa0] := eqVneq (P a) 0; first by rewrite !(mulR0,mul0R). +have [->|Pa0] := eqVneq (P a) 0; first by rewrite -RmultE !(mulR0,mul0R). by rewrite -channel_jcPr. Qed. @@ -325,7 +327,7 @@ End mutual_info_chan. Notation "`I( P , W )" := (mutual_info_chan P W) : channel_scope. Section mutual_info_chan_prop. -Variables (A B : finType) (W : `Ch(A, B)) (P : fdist A). +Variables (A B : finType) (W : `Ch(A, B)) (P : {fdist A}). Lemma mutual_info_chanE : `I(P, W) = mutual_info (fdistX (P `X W)). Proof. @@ -339,4 +341,4 @@ From mathcomp Require Import classical_sets. Local Open Scope classical_set_scope. Definition capacity (A B : finType) (W : `Ch(A, B)) := - reals.sup [set `I(P, W) | P in [set: fdist A]]. + reals.sup [set `I(P, W) | P in [set: {fdist A}]]. diff --git a/information_theory/channel_code.v b/information_theory/channel_code.v index 8ab0c92b..60d6ce74 100644 --- a/information_theory/channel_code.v +++ b/information_theory/channel_code.v @@ -1,6 +1,6 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg matrix. +From mathcomp Require Import all_ssreflect ssralg matrix. Require Import Reals. From mathcomp Require Import Rstruct. Require Import Reals_ext ssrR logb Rbigop fdist proba channel. diff --git a/information_theory/channel_coding_converse.v b/information_theory/channel_coding_converse.v index 7d42f404..34b117b2 100644 --- a/information_theory/channel_coding_converse.v +++ b/information_theory/channel_coding_converse.v @@ -1,6 +1,6 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg matrix. +From mathcomp Require Import all_ssreflect ssralg matrix. Require Import Reals. From mathcomp Require Import Rstruct. Require Import ssrR Reals_ext ssr_ext ssralg_ext logb ln_facts Rbigop num_occ. @@ -126,10 +126,10 @@ apply (@leR_trans ((n.+1%:R / n%:R) ^ K * aux)); last first. + apply (@leR_pmul2r n%:R) => //. rewrite -mulRA mulVR // ?mulR1 ?INR_eq0' ?gtn_eqF // (_ : 2 = 2%:R) //. rewrite -natRM; apply/le_INR/leP; by rewrite -{1}(mul1n n) ltn_pmul2r. - - exact/leRR. + - by apply/RleP; rewrite Order.POrderTheory.lexx. rewrite expRM -mulRA; apply leR_pmul => //. - exact/expR_ge0/ltRW/ltR0n. -- exact/leRR. +- by apply/RleP; rewrite Order.POrderTheory.lexx. - apply invR_le => //. + apply mulR_gt0; last exact aux_gt0. rewrite expRV ?INR_eq0' //; exact/invR_gt0/expR_gt0. diff --git a/information_theory/channel_coding_direct.v b/information_theory/channel_coding_direct.v index 964e7085..1c0a1556 100644 --- a/information_theory/channel_coding_direct.v +++ b/information_theory/channel_coding_direct.v @@ -1,9 +1,9 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg matrix perm. +From mathcomp Require Import all_ssreflect ssralg ssrnum matrix perm. Require Import Reals Lra Classical. From mathcomp Require Import Rstruct classical_sets. -Require Import ssrZ ssrR Reals_ext logb ssr_ext ssralg_ext bigop_ext Rbigop. +Require Import ssrZ ssrR Reals_ext realType_ext logb ssr_ext ssralg_ext bigop_ext Rbigop. Require Import fdist proba entropy aep typ_seq joint_typ_seq channel. Require Import channel_code. @@ -36,11 +36,11 @@ Local Open Scope vec_ext_scope. Module Wght. Section wght. -Variables (A M : finType) (P : fdist A) (n : nat). +Variables (A M : finType) (P : {fdist A}) (n : nat). Definition f := [ffun g : encT A M n => \prod_(m in M) P `^ n (g m)]. -Lemma f0 g : 0 <= f g. Proof. rewrite ffunE; exact: prodR_ge0. Qed. +Lemma f0 g : (0 <= f g)%mcR. Proof. rewrite ffunE; apply/RleP; exact: prodR_ge0. Qed. Lemma f1 : \sum_(g in {ffun M -> 'rV[A]_n}) f g = 1. Proof. @@ -66,7 +66,7 @@ Definition jtdec P W epsilon (f : encT A M n) : decT B M n := (prod_rV (f m, tb) \in `JTS P W n epsilon) && [forall m', (m' != m) ==> (prod_rV (f m', tb) \notin `JTS P W n epsilon)]]]. -Lemma jtdec_map epsilon (P : fdist A) (W : `Ch(A, B)) (f : encT A M n) tb m0 m1 : +Lemma jtdec_map epsilon (P : {fdist A}) (W : `Ch(A, B)) (f : encT A M n) tb m0 m1 : (prod_rV (f m0, tb) \in `JTS P W n epsilon) && [forall m', (m' != m0) ==> (prod_rV (f m', tb) \notin `JTS P W n epsilon)] -> (prod_rV (f m1, tb) \in `JTS P W n epsilon) && @@ -98,7 +98,8 @@ have : \sum_(f : encT A M n) Wght.d P f * epsilon <= x. - by apply leR_wpmul2l => //; exact/Rnot_lt_le/abs. - by apply mulR_ge0 => //; exact/echa_ge0. apply/Rlt_not_le/(@ltR_leR_trans epsilon) => //. -by rewrite -big_distrl /= (FDist.f1 (Wght.d P)) mul1R; exact/leRR. +rewrite -big_distrl /= (FDist.f1 (Wght.d P)) mul1R. +by apply/RleP; rewrite Order.POrderTheory.lexx. Qed. Definition o_PI (m m' : M) := fun g : encT A M n => [ffun x => g (tperm m m' x)]. @@ -248,7 +249,7 @@ End sum_rV_ffun. Section random_coding_good_code_existence. -Variables (B A : finType) (W : `Ch(A, B)) (P : fdist A). +Variables (B A : finType) (W : `Ch(A, B)) (P : {fdist A}). Definition epsilon0_condition r epsilon epsilon0 := 0 < epsilon0 /\ epsilon0 < epsilon / 2 /\ epsilon0 < (`I(P, W) - r) / 4. @@ -284,7 +285,7 @@ congr P2; rewrite /tbehead tupleE /behead_tuple; exact: val_inj. Qed. (* TODO: move? *) -Lemma rsum_rmul_tuple_pmf_tnth {C : finType} n k (Q : fdist C) : +Lemma rsum_rmul_tuple_pmf_tnth {C : finType} n k (Q : {fdist C}) : \sum_(t : {:k.-tuple ('rV[C]_n)}) \prod_(m < k) (Q `^ n) t \_ m = 1. Proof. transitivity (\sum_(j : {ffun 'I_k -> 'rV[_]_n}) \prod_(m < k) Q `^ _ (j m)). @@ -301,7 +302,7 @@ by rewrite FDist.f1 iter_mulR exp1R. Qed. (* TODO: move? *) -Lemma rsum_rmul_tuple_pmf {C} n k (Q : fdist C) : +Lemma rsum_rmul_tuple_pmf {C : finType} n k (Q : {fdist C}) : \sum_(t in {:k.-tuple ('rV[C]_n)}) \prod_(x <- t) (Q `^ n) x = 1. Proof. rewrite -[X in _ = X](rsum_rmul_tuple_pmf_tnth n k Q). @@ -419,7 +420,8 @@ transitivity (\sum_(v in 'rV[A]_n) apply eq_bigr => // w _. rewrite DMCE 2!fdist_rVE -big_split /=. apply eq_bigr => /= i _. - by rewrite fdist_prodE -fst_tnth_prod_rV -snd_tnth_prod_rV /= mulRC. + rewrite fdist_prodE -fst_tnth_prod_rV -snd_tnth_prod_rV /= mulRC. + by rewrite RmultE GRing.mulrC. rewrite /Pr big_rV_prod pair_big_dep /=. by apply eq_bigl; case=> /= ? ?; rewrite !inE. Qed. @@ -716,6 +718,7 @@ rewrite [X in X < _](_ : _ = (\sum_(f : encT A M n) Wght.d P f * (e(W, mkCode f rewrite exchange_big /= big_const /= iter_addR div1R mulRA mulVR ?mul1R //. by rewrite INR_eq0' card_ord. set Cal_E := @cal_E M n epsilon0. +apply/RltP. apply (@leR_ltR_trans (\sum_(f : encT A M n) Wght.d P f * Pr (W ``(| f ord0)) (~: Cal_E f ord0) + \sum_(i | i != ord0) @@ -723,8 +726,8 @@ apply (@leR_ltR_trans rewrite exchange_big /= -big_split /=. apply leR_sumR => /= i _. rewrite -big_distrr /= -mulRDr. - apply leR_wpmul2l; first exact: FDist.ge0. - rewrite [X in X <= _](_ : _ = Pr (W ``(| i ord0)) + apply leR_wpmul2l; first exact/RleP/FDist.ge0. + rewrite [X in (X <= _)%coqR](_ : _ = Pr (W ``(| i ord0)) (~: Cal_E i ord0 :|: \bigcup_(i0 : M | i0 != ord0) Cal_E i i0)); last first. congr Pr; apply/setP => /= tb. move: (preimC_Cal_E epsilon0 i tb); by rewrite inE. @@ -783,7 +786,8 @@ apply (@ltR_leR_trans (exp2 (- (- (log epsilon0) / epsilon0) * epsilon0))). - rewrite ltR_oppr oppRK; by case: Hn => _ [Hn2 _]. rewrite !mulNR -mulRA mulVR ?mulR1 ?oppRK; last first. by apply/gtR_eqF; case: Hepsilon0. - by rewrite logK; [exact/leRR | case: Hepsilon0]. + rewrite logK; [| by case: Hepsilon0]. + by apply/RleP; rewrite Order.POrderTheory.lexx. Qed. End random_coding_good_code_existence. @@ -800,17 +804,17 @@ Theorem channel_coding (r : CodeRateType) : r < capacity W -> exists n M (c : code A B M n), CodeRate c = r /\ echa(W, c) < epsilon. Proof. move=> r_I epsilon Hepsilon. -have [P HP] : exists P : fdist A, r < `I(P, W). +have [P HP] : exists P : {fdist A}, r < `I(P, W). apply NNPP => abs. - have {}abs : forall P : fdist A, `I(P, W) <= r. + have {}abs : forall P : {fdist A}, `I(P, W) <= r. move/not_ex_all_not in abs. move=> P; exact/Rnot_lt_le/abs. have ? : capacity W <= r. apply/RleP. - have : has_sup [set `I(P, W) | P in [set: fdist A]]. + have : has_sup [set `I(P, W) | P in [set: {fdist A}]]. case: set_of_I_nonempty => [x [P H1]]; split; first by exists x, P. by exists (rate r) => _ [Q _ <-]; exact/Rstruct.RleP/abs. - move=> /(@Rsup_isLub 0 [set `I(P, W) | P in [set: fdist A]])[_]. + move=> /(@Rsup_isLub 0 [set `I(P, W) | P in [set: {fdist A}]])[_]. apply. by move=> x [P _ <-{x}]; exact/RleP/abs. lra. @@ -847,7 +851,8 @@ have [n Hn] : exists n, n_condition W P r epsilon0 n. apply (@leR_trans (INR '| up (- log epsilon0 / epsilon0) |)). case: (Z_lt_le_dec (up (- log epsilon0 / epsilon0)) 0) => H1. by apply (@leR_trans 0); [exact/IZR_le/ltZW | exact: leR0n]. - by rewrite INR_Zabs_nat //; exact/leRR. + rewrite INR_Zabs_nat //. + by apply/RleP; rewrite Order.POrderTheory.lexx. apply le_INR. rewrite /supermax maxnA. apply/leP. @@ -864,8 +869,12 @@ have [n Hn] : exists n, n_condition W P r epsilon0 n. split. by apply (@ltR_leR_trans (INR n1)); [tauto | exact/le_INR/leP]. by apply leq_trans with n1 => //; tauto. -case: (random_coding_good_code (ltRW Hepsilon) Hepsilon0 Hn) => +have He : (0 <= epsilon)%mcR. + apply/RleP. + by apply/ltRW. +case: (random_coding_good_code He Hepsilon0 Hn) => M [HM [M_k H]]. +move/RltP in H. case: (good_code_sufficient_condition HM H) => f Hf. exists n, M, (mkCode f (jtdec P W epsilon0 f)); split => //. rewrite /CodeRate M_k INR_Zabs_nat; last exact/Int_part_ge0. diff --git a/information_theory/chap2.v b/information_theory/chap2.v index 1936c9d3..2b5fa46c 100644 --- a/information_theory/chap2.v +++ b/information_theory/chap2.v @@ -1,7 +1,6 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup perm finalg. -From mathcomp Require Import matrix. +From mathcomp Require Import all_ssreflect ssralg perm matrix. From mathcomp Require boolp. Require Import Reals Lra. From mathcomp Require Import Rstruct. @@ -43,5 +42,3 @@ Local Open Scope fdist_scope. Local Open Scope proba_scope. Local Open Scope entropy_scope. Local Open Scope vec_ext_scope. - - diff --git a/information_theory/conditional_divergence.v b/information_theory/conditional_divergence.v index 7b073c83..dc7b6a0e 100644 --- a/information_theory/conditional_divergence.v +++ b/information_theory/conditional_divergence.v @@ -1,6 +1,6 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg finset fingroup finalg matrix. +From mathcomp Require Import all_ssreflect ssralg finset matrix. Require Import Reals. From mathcomp Require Import Rstruct. Require Import ssrR Reals_ext ssr_ext ssralg_ext logb Rbigop ln_facts. @@ -30,7 +30,7 @@ Local Open Scope num_occ_scope. Local Open Scope types_scope. Section conditional_dominance. -Variables (A B : finType) (V W : `Ch(A, B)) (P : fdist A). +Variables (A B : finType) (V W : `Ch(A, B)) (P : {fdist A}). Definition cdom_by := forall a, P a != 0 -> V a `<< W a. @@ -39,12 +39,12 @@ Proof. split; [move/dominatesP => H | move=> H; apply/dominatesP]. - move=> a p_not_0; apply/dominatesP => b; move: (H (a, b)). rewrite fdist_prodE /= => H0 H1. - move: H0; rewrite H1 mulR0 => /(_ erefl)/eqP. + move: H0; rewrite H1 -RmultE mulR0 => /(_ erefl)/eqP. by rewrite fdist_prodE mulR_eq0' /= (negbTE p_not_0) orFb => /eqP. - case=> a p_not_0 b; move: {H}(H a) => H. rewrite fdist_prodE /=. - have [->|H1] := eqVneq (P a) 0; first by rewrite mul0R. - move: {H}(H H1) => /dominatesP ->; first by rewrite mulR0. + have [->|H1] := eqVneq (P a) 0; first by rewrite -RmultE mul0R. + move: {H}(H H1) => /dominatesP ->; first by rewrite -RmultE mulR0. move/eqP : b; by rewrite fdist_prodE mulR_eq0' /= (negbTE H1) orFb => /eqP. Qed. @@ -55,16 +55,16 @@ Notation "P '|-' V '< V a `< (P `X V) `<< (P `X W). Proof. move=> V_dom_by_W /=; apply/dominatesP => ab Hab. -case/leR_eqVlt : (FDist.ge0 P ab.1) => [/esym|] Hab1. -- by rewrite fdist_prodE Hab1 mul0R. +case/RleP/leR_eqVlt : (FDist.ge0 P ab.1) => [/esym|] Hab1. +- by rewrite fdist_prodE Hab1 -RmultE mul0R. - rewrite fdist_prodE in Hab. - rewrite fdist_prodE (dominatesE (V_dom_by_W _ _)) ?mulR0 //. + rewrite fdist_prodE (dominatesE (V_dom_by_W _ _)) -?RmultE ?mulR0 //. + exact/gtR_eqF. + move: Hab; rewrite mulR_eq0 => -[|//]. by move: (gtR_eqF _ _ Hab1) => /eqP. @@ -73,14 +73,14 @@ Qed. End joint_dom. Section conditional_divergence. -Variables (A B : finType) (V W : `Ch(A, B)) (P : fdist A). +Variables (A B : finType) (V W : `Ch(A, B)) (P : {fdist A}). Definition cdiv := \sum_(a : A) P a * D(V a || W a). End conditional_divergence. Notation "'D(' V '||' W '|' P ')'" := (cdiv V W P) : divergence_scope. Section conditional_divergence_prop. -Variables (A B : finType) (V W : `Ch(A, B)) (P : fdist A). +Variables (A B : finType) (V W : `Ch(A, B)) (P : {fdist A}). Hypothesis V_dom_by_W : P |- V << W. @@ -92,13 +92,13 @@ rewrite (_ : D(V || W | P) = \sum_(a in A) (\sum_(b in B) by rewrite -(big_morph _ (morph_mulRDl _) (mul0R _)) mulRC. rewrite pair_bigA big_mkcond /=. apply eq_bigr => -[a b] /= _. -rewrite fdist_prodE /= (mulRC (P a)) [in RHS]mulRAC. +rewrite fdist_prodE /= -RmultE (mulRC (P a)) [in RHS]mulRAC. case/boolP : (P a == 0) => [/eqP -> | Pa0]; first by rewrite !mulR0. congr (_ * _). case/boolP : (V a b == 0) => [/eqP -> | Vab0]; first by rewrite !mul0R. congr (_ * _). have Wab0 : W a b != 0 := dominatesEN (V_dom_by_W Pa0) Vab0. -rewrite fdist_prodE /= {2}/Rdiv (mulRC _ (W a b)) (invRM (W a b)) //. +rewrite fdist_prodE /= {2}/Rdiv -RmultE (mulRC _ (W a b)) (invRM (W a b)) //. by rewrite -mulRA (mulRCA (P a)) mulRV // mulR1. Qed. @@ -113,7 +113,7 @@ End conditional_divergence_prop. Section conditional_divergence_vs_conditional_relative_entropy. Local Open Scope divergence_scope. Local Open Scope reals_ext_scope. -Variables (A B : finType) (P Q : A -> {fdist B}) (R : fdist A). +Variables (A B : finType) (P Q : A -> {fdist B}) (R : {fdist A}). Lemma cond_relative_entropy_compat : R `X P `<< R `X Q -> cond_relative_entropy (R, P) (R, Q) = D(P || Q | R). @@ -129,7 +129,7 @@ rewrite mulRA. rewrite {1}/jcPr. rewrite fdistX2 fdist_prod1 Pr_set1. have [H|H] := eqVneq (R a) 0. - by rewrite H 2!mul0R fdist_prodE H !mul0R. + by rewrite H mul0R fdist_prodE H -RmultE !mul0R/=. congr (_ * log _). by rewrite setX1 Pr_set1 fdistXE fdist_prodE /=; field; exact/eqP. rewrite /jcPr !setX1 !Pr_set1 !fdistXE !fdistX2. @@ -137,6 +137,7 @@ have [H'|H'] := eqVneq ((R `X Q) (a, b)) 0. have : (R `X P) (a, b) = 0 by move/dominatesP : PQ => ->. rewrite fdist_prodE /= mulR_eq0 => -[| -> ]. by move/eqP : H; tauto. + rewrite -RmultE. by rewrite !(mulR0,mul0R,div0R). by rewrite 2!fdist_prod1 /=; field; split; exact/eqP. Qed. @@ -207,7 +208,7 @@ rewrite /div /= -mulRDr mulRA -big_split /=. rewrite (big_morph _ (morph_mulRDr _) (mulR0 _)). rewrite (big_morph _ morph_exp2_plus exp2_0). apply eq_bigr => b _. -case/boolP : (P a == 0) => [/eqP|] Pa0. +case/boolP : (type.d P a == 0) => [/eqP|] Pa0. move: Hy; rewrite in_set => /forallP/(_ a)/forallP/(_ b)/eqP => ->. move: (HV); rewrite in_set => /cond_type_equiv/(_ _ Hx a). move: Hx; rewrite in_set => /forallP/(_ a)/eqP; rewrite {}Pa0 => HPa sumB. @@ -221,7 +222,9 @@ case/boolP : (W a b == 0) => [/eqP |] Wab0. by rewrite nullV 2!mul0R oppR0 addR0 mulR0 exp2_0. move: Hy; rewrite in_set => /forallP/(_ a)/forallP/(_ b)/eqP => ->. by rewrite jtype_0_jtypef. -rewrite -{1}(@logK (W a b)); last by rewrite -fdist_gt0. +rewrite -{1}(@logK (W a b)); last first. + apply/RltP. + by rewrite -fdist_gt0. case/boolP : (V a b == 0) => [/eqP|] Vab0. suff -> : N( a, b | [seq x ``_ i | i <- enum 'I_n], [seq y ``_ i | i <- enum 'I_n]) = O. by rewrite pow_O Vab0 !(mulR0,mul0R,addR0,add0R,oppR0,exp2_0). @@ -229,9 +232,16 @@ case/boolP : (V a b == 0) => [/eqP|] Vab0. by rewrite jtype_0_jtypef. rewrite -exp2_pow; congr exp2. rewrite -mulRN -mulRDr mulRA addR_opp -logDiv; last 2 first. - by apply/divR_gt0; rewrite -fdist_gt0. - by rewrite -fdist_gt0. -rewrite /Rdiv (mulRAC _ (/ _)) mulRV // mul1R logV -?fdist_gt0 //. + apply/divR_gt0. + apply/RltP. + by rewrite -fdist_gt0//. + apply/RltP. + by rewrite -fdist_gt0//. + apply/RltP. + by rewrite -fdist_gt0//. +rewrite /Rdiv (mulRAC _ (/ _)) mulRV // mul1R logV -?fdist_gt0 //; last first. + apply/RltP. + by rewrite -fdist_gt0//. rewrite mulRN 3!mulNR oppRK; congr (_ * log _). move: Hy; rewrite in_set => /forallP/(_ a)/forallP/(_ b)/eqP => ->. move: (HV); rewrite in_set => /cond_type_equiv => /(_ _ Hx a) sumB. @@ -254,14 +264,14 @@ Variable V : P_ n ( A , B ). Variable W : `Ch*(A, B). Definition exp_cdiv := - if P |- V < ->. +suff : (type.d P) |- V < ->. apply/forallP => a; apply/implyP => Pa0. apply/forall_inP => b /eqP Wab; by rewrite (dominatesE (H _ Pa0)). Qed. diff --git a/information_theory/entropy.v b/information_theory/entropy.v index 6a1c3313..018eeee9 100644 --- a/information_theory/entropy.v +++ b/information_theory/entropy.v @@ -1,6 +1,6 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect fingroup perm matrix. +From mathcomp Require Import all_ssreflect all_algebra fingroup perm matrix. Require Import Reals. From mathcomp Require Import Rstruct. Require Import ssrR Reals_ext ssr_ext ssralg_ext Rbigop bigop_ext logb ln_facts. @@ -58,8 +58,10 @@ Local Open Scope fdist_scope. Local Open Scope proba_scope. Local Open Scope vec_ext_scope. +Import Order.POrderTheory GRing.Theory Num.Theory. + Section entropy_definition. -Variables (A : finType) (P : fdist A). +Variables (A : finType) (P : {fdist A}). Definition entropy := - \sum_(a in A) P a * log (P a). Local Notation "'`H'" := (entropy). @@ -67,11 +69,11 @@ Local Notation "'`H'" := (entropy). Lemma entropy_ge0 : 0 <= `H. Proof. rewrite /entropy big_morph_oppR; apply sumR_ge0 => i _. -have [->|Hi] := eqVneq (P i) 0; first by rewrite mul0R oppR0; exact/leRR. +have [->|Hi] := eqVneq (P i) 0; first by rewrite mul0R oppR0. (* NB: this step in a standard textbook would be handled as a consequence of lim x->0 x log x = 0 *) rewrite mulRC -mulNR; apply mulR_ge0 => //; apply: oppR_ge0. -rewrite -log1; apply Log_increasing_le => //. -by apply/ltRP; rewrite lt0R Hi; exact/leRP. +rewrite -log1; apply: Log_increasing_le => //. +by apply/RltP; rewrite lt0r Hi/=. Qed. End entropy_definition. @@ -84,17 +86,17 @@ Local Open Scope fdist_scope. Local Open Scope proba_scope. Context (A : finType). -Lemma entropy_Ex (P : fdist A) : `H P = `E (`-- (`log P)). +Lemma entropy_Ex (P : {fdist A}) : `H P = `E (`-- (`log P)). Proof. rewrite /entropy /log_RV /= big_morph_oppR. by apply eq_bigr => a _; rewrite mulRC -mulNR. Qed. -Lemma xlnx_entropy (P : fdist A) : `H P = / ln 2 * - \sum_(a : A) xlnx (P a). +Lemma xlnx_entropy (P : {fdist A}) : `H P = / ln 2 * - \sum_(a : A) xlnx (P a). Proof. rewrite /entropy mulRN; congr (- _); rewrite big_distrr/=. apply: eq_bigr => a _; rewrite /log /Rdiv mulRA mulRC; congr (_ * _). -rewrite /xlnx; case : ifP => // /ltRP Hcase. +rewrite /xlnx; case : ifP => // /RltP Hcase. have -> : P a = 0 by case (Rle_lt_or_eq_dec 0 (P a)). by rewrite mul0R. Qed. @@ -104,18 +106,21 @@ Lemma entropy_uniform n (An1 : #|A| = n.+1) : Proof. rewrite /entropy. under eq_bigr do rewrite fdist_uniformE. -rewrite big_const iter_addR mulRA mulRV; last by rewrite INR_eq0' An1. -by rewrite mul1R logV ?oppRK//; rewrite An1; apply/ltR0n. +rewrite big_const iter_addR mulRA RmultE -RinvE; last first. + by rewrite An1 -INRE INR_eq0'. +rewrite INRE mulRV; last by rewrite An1 -INRE INR_eq0'. +rewrite -RmultE mul1R logV ?oppRK//; rewrite An1. +by rewrite -INRE; apply/ltR0n. Qed. -Lemma entropy_H2 (card_A : #|A| = 2%nat) (p : prob) : +Lemma entropy_H2 (card_A : #|A| = 2%nat) (p : {prob R}) : H2 p = entropy (fdist_binary card_A p (Set2.a card_A)). Proof. rewrite /H2 /entropy Set2sumE /= fdist_binaryxx !fdist_binaryE. by rewrite eq_sym (negbTE (Set2.a_neq_b _)) oppRD addRC. Qed. -Lemma entropy_max (P : fdist A) : `H P <= log #|A|%:R. +Lemma entropy_max (P : {fdist A}) : `H P <= log #|A|%:R. Proof. have [n An1] : exists n, #|A| = n.+1. by exists #|A|.-1; rewrite prednK //; exact: (fdist_card_neq0 P). @@ -126,11 +131,16 @@ transitivity (\sum_(a|a \in A) P a * log (P a) + rewrite -big_split /=; apply eq_bigr => a _; rewrite -mulRDr. case/boolP : (P a == 0) => [/eqP ->|H0]; first by rewrite !mul0R. congr (_ * _); rewrite logDiv ?addR_opp //. - by rewrite -fdist_gt0. - by rewrite fdist_uniformE; apply/invR_gt0; rewrite An1; exact/ltR0n. + by apply/RltP; rewrite -fdist_gt0. + rewrite fdist_uniformE. + rewrite -RinvE; last by rewrite An1 -INRE INR_eq0'. + apply/invR_gt0; rewrite An1 -INRE. + exact/ltR0n. under [in X in _ + X]eq_bigr do rewrite fdist_uniformE. rewrite -[in X in _ + X = _]big_distrl /= FDist.f1 mul1R. -by rewrite addRC /entropy /log LogV ?oppRK ?subR_opp // An1; exact/ltR0n. +rewrite addRC /entropy /log. + rewrite -RinvE; last by rewrite An1 -INRE INR_eq0'. +by rewrite LogV ?oppRK ?subR_opp // An1 ?INRE// -INRE; exact/ltR0n. Qed. Lemma entropy_fdist_rV_of_prod n (P : {fdist A * 'rV[A]_n}) : @@ -252,7 +262,7 @@ Lemma cond_entropy1_ge0 a : 0 <= cond_entropy1 a. Proof. rewrite /cond_entropy1 big_morph_oppR; apply sumR_ge0 => b _; rewrite -mulRN. have [->|H0] := eqVneq (\Pr_QP[[set b]|[set a]]) 0. - by rewrite mul0R; exact/leRR. + by rewrite mul0R. apply mulR_ge0; [exact: jcPr_ge0|]. rewrite -oppR0 -(Log_1 2) /log leR_oppr oppRK. by apply Log_increasing_le => //; [rewrite jcPr_gt0 | exact: jcPr_le1]. @@ -328,8 +338,8 @@ transitivity ( apply eq_bigr => a _; rewrite -big_split /=; apply eq_bigr => b _. have [->|H0] := eqVneq (PQ (a, b)) 0; first by rewrite !mul0R addR0. rewrite -mulRDr; congr (_ * _); rewrite mulRC logM //. - by rewrite -Pr_jcPr_gt0 setX1 Pr_set1 fdistXE -fdist_gt0. - by rewrite -fdist_gt0; exact: dom_by_fdist_fstN H0. + by rewrite -Pr_jcPr_gt0 setX1 Pr_set1 fdistXE; apply/RltP; rewrite -fdist_gt0. + by apply/RltP; rewrite -fdist_gt0; exact: dom_by_fdist_fstN H0. rewrite [in X in _ + X = _]big_morph_oppR; congr (_ + _). - rewrite /entropy; congr (- _); apply eq_bigr => a _. by rewrite -big_distrl /= -fdist_fstE. @@ -563,7 +573,7 @@ transitivity (- (\sum_(a in A) \sum_(b in B) PQ (a, b) * log (P a)) + have [->|H0] := eqVneq (PQ (a, b)) 0; first by rewrite !mul0R. congr (_ * _); rewrite logDiv //. - by rewrite -Pr_jcPr_gt0 Pr_gt0 setX1 Pr_set1. - - by rewrite -fdist_gt0; exact: dom_by_fdist_fstN H0. + - by apply/RltP; rewrite -fdist_gt0; exact: dom_by_fdist_fstN H0. rewrite -subR_opp; congr (_ - _). - rewrite /entropy; congr (- _); apply/eq_bigr => a _. by rewrite -big_distrl /= -fdist_fstE. @@ -615,7 +625,7 @@ Lemma mutual_info_sym (A B : finType) (PQ : {fdist A * B}) : Proof. by rewrite !mutual_infoE entropyB fdistX1. Qed. (* eqn 2.47 *) -Lemma mutual_info_self (A : finType) (P : fdist A) : +Lemma mutual_info_self (A : finType) (P : {fdist A}) : mutual_info (fdist_self P) = `H P. Proof. by rewrite mutual_infoE cond_entropy_self subR0 fdist_self1. Qed. @@ -680,8 +690,7 @@ Lemma cdiv1_ge0 z : 0 <= cdiv1 z. Proof. have [z0|z0] := eqVneq (PQR`2 z) 0. apply sumR_ge0 => -[a b] _. - rewrite {1}/jcPr setX1 Pr_set1 (dom_by_fdist_snd _ z0) div0R mul0R. - exact: leRR. + by rewrite {1}/jcPr setX1 Pr_set1 (dom_by_fdist_snd _ z0) div0R mul0R. have Hc : (fdistX PQR)`1 z != 0 by rewrite fdistX1. have Hc1 : (fdistX (fdist_proj13 PQR))`1 z != 0. by rewrite fdistX1 fdist_proj13_snd. @@ -791,8 +800,8 @@ rewrite cond_mutual_infoE2; apply sumR_ge0 => c _; apply mulR_ge0 => //. exact: cdiv1_ge0. Qed. -Let P : fdist A := (fdistA PQR)`1. -Let Q : fdist B := (PQR`1)`2. +Let P : {fdist A} := (fdistA PQR)`1. +Let Q : {fdist B} := (PQR`1)`2. Lemma chain_rule_mutual_info : mutual_info PQR = mutual_info (fdist_proj13 PQR) + cond_mutual_info (fdistX (fdistA PQR)). @@ -823,7 +832,7 @@ End conditional_mutual_information. Section conditional_relative_entropy. Section def. -Variables (A B : finType) (P Q : (fdist A * (A -> fdist B))). +Variables (A B : finType) (P Q : ({fdist A} * (A -> {fdist B}))). Let Pj : {fdist B * A} := fdistX (P.1 `X P.2). Let Qj : {fdist B * A} := fdistX (Q.1 `X Q.2). Let P1 : {fdist A} := P.1. @@ -837,7 +846,7 @@ End def. Section prop. Local Open Scope divergence_scope. Local Open Scope reals_ext_scope. -Variables (A B : finType) (P Q : (fdist A * (A -> fdist B))). +Variables (A B : finType) (P Q : ({fdist A} * (A -> {fdist B}))). Let Pj : {fdist B * A} := fdistX (P.1 `X P.2). Let Qj : {fdist B * A} := fdistX (Q.1 `X Q.2). Let P1 : {fdist A} := P.1. @@ -857,7 +866,8 @@ rewrite fdist_sndE big_distrl /= big_distrr /= -big_split /=; apply eq_bigr => b rewrite mulRA (_ : P1 a * _ = Pj (b, a)); last first. rewrite /jcPr Pr_set1 -/P1 mulRCA setX1 Pr_set1 {1}/Pj fdistX2 fdist_prod1. have [P2a0|P2a0] := eqVneq (P1 a) 0. - have Pba0 : Pj (b, a) = 0 by rewrite /P fdistXE fdist_prodE P2a0 mul0R. + have Pba0 : Pj (b, a) = 0. + by rewrite /P fdistXE fdist_prodE P2a0 -RmultE mul0R. by rewrite Pba0 mul0R. by rewrite mulRV // ?mulR1. rewrite -mulRDr. @@ -865,13 +875,13 @@ have [->|H0] := eqVneq (Pj (b, a)) 0; first by rewrite !mul0R. congr (_ * _). have P1a0 : P1 a != 0. apply: contra H0 => /eqP. - by rewrite /P fdistXE fdist_prodE => ->; rewrite mul0R. + by rewrite /P fdistXE fdist_prodE => ->; rewrite -RmultE mul0R. have Qba0 := dominatesEN PQ H0. have Q2a0 : Q1 a != 0. - apply: contra Qba0; rewrite /Q fdistXE fdist_prodE => /eqP ->; by rewrite mul0R. + apply: contra Qba0; rewrite /Q fdistXE fdist_prodE => /eqP ->; by rewrite -RmultE mul0R. rewrite -logM; last 2 first. - by apply/divR_gt0; rewrite -fdist_gt0. - apply/divR_gt0; by rewrite -Pr_jcPr_gt0 setX1 Pr_set1 -fdist_gt0. + by apply/divR_gt0; apply/RltP; rewrite -fdist_gt0. + by apply/divR_gt0; by rewrite -Pr_jcPr_gt0 setX1 Pr_set1; apply/RltP; rewrite -fdist_gt0. congr (log _). rewrite /jcPr !setX1 !Pr_set1. rewrite !fdistXE !fdistX2 !fdist_prod1 !fdist_prodE /=. @@ -879,7 +889,7 @@ rewrite -/P1 -/Q1; field. split; first exact/eqP. split; first exact/eqP. apply/eqP. -by apply: contra Qba0; rewrite /Qj fdistXE fdist_prodE /= => /eqP ->; rewrite mulR0. +by apply: contra Qba0; rewrite /Qj fdistXE fdist_prodE /= => /eqP ->. Qed. End prop. @@ -1127,8 +1137,8 @@ End prop. Section prop2. Variables (A B C : finType) (PQR : {fdist A * B * C}). -Let P : fdist A := (fdistA PQR)`1. -Let Q : fdist B := (PQR`1)`2. +Let P : {fdist A} := (fdistA PQR)`1. +Let Q : {fdist B} := (PQR`1)`2. Let R := PQR`2. Lemma mi_bound : PQR`1 = P `x Q (* P and Q independent *) -> mutual_info (fdist_proj13 PQR) + @@ -1168,9 +1178,11 @@ Proof. rewrite chain_rule_rV; apply leR_sumR => /= i _. case: ifPn => [/eqP|] i0. rewrite (_ : i = ord0); last exact/val_inj. - by rewrite head_of_fdist_rV_fdist_nth; exact/leRR. + rewrite head_of_fdist_rV_fdist_nth. + by apply/RleP; rewrite lexx. apply: leR_trans; first exact: information_cant_hurt. -by rewrite fdistX1 fdist_take_nth; exact/leRR. +rewrite fdistX1 fdist_take_nth. +by apply/RleP; rewrite lexx. Qed. End independence_bound_on_entropy. @@ -1303,6 +1315,7 @@ Lemma information_cant_hurt_cond (A : finType) (n' : nat) (n := n'.+1 : nat) cond_entropy (fdist_prod_of_rV P) <= cond_entropy (fdist_prod_of_rV (fdist_take P (lift ord0 i))). Proof. +apply/RleP. rewrite -subR_ge0. set Q : {fdist A * 'rV[A]_i * 'rV[A]_(n' - i)} := fdist_take_drop P i. have H1 : fdist_proj13 (fdistAC Q) = fdist_prod_of_rV (fdist_take P (lift ord0 i)). @@ -1452,16 +1465,19 @@ Variable P : {fdist 'rV[A]_n}. Lemma han : n.-1%:R * `H P <= \sum_(i < n) `H (fdist_col' P i). Proof. -rewrite -subn1 natRB // mulRBl mul1R leR_subl_addr {2}(chain_rule_rV P). -rewrite -big_split /= -{1}(card_ord n) -sum1_card big_morph_natRD big_distrl /=. +rewrite -subn1 natrB // -RmultE mulRBl mul1R. +apply/RleP; rewrite leR_subl_addr {2}(chain_rule_rV P). +rewrite -big_split /= -{1}(card_ord n) -sum1_card. +rewrite -INRE big_morph_natRD big_distrl /=. apply leR_sumR => i _; rewrite mul1R. case: ifPn => [/eqP|] i0. rewrite (_ : i = ord0); last exact/val_inj. rewrite -tail_of_fdist_rV_fdist_col' /tail_of_fdist_rV /head_of_fdist_rV. rewrite -{1}(fdist_rV_of_prodK P) entropy_fdist_rV_of_prod. move: (chain_rule (fdist_prod_of_rV P)); rewrite /joint_entropy => ->. - by rewrite [in X in _ <= X]addRC leR_add2l -fdistX1; exact: information_cant_hurt. -by rewrite (chain_rule_multivar _ i0) leR_add2l; exact/han_helper. + by rewrite [in X in (_ <= X)%R]addRC leR_add2l -fdistX1; exact: information_cant_hurt. +rewrite (chain_rule_multivar _ i0) leR_add2l. +by apply/RleP; exact/han_helper. Qed. End Han_inequality. diff --git a/information_theory/entropy_convex.v b/information_theory/entropy_convex.v index 798ad5c2..61a5441d 100644 --- a/information_theory/entropy_convex.v +++ b/information_theory/entropy_convex.v @@ -1,13 +1,13 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) From HB Require Import structures. -From mathcomp Require Import all_ssreflect ssralg fingroup finalg matrix. +From mathcomp Require Import all_ssreflect ssralg ssrnum matrix. From mathcomp Require boolp. -From mathcomp Require Import Rstruct. +From mathcomp Require Import mathcomp_extra Rstruct. Require Import Reals Ranalysis_ext Lra. -Require Import ssrR Reals_ext logb ssr_ext ssralg_ext bigop_ext Rbigop fdist. -Require Import jfdist_cond entropy convex binary_entropy_function log_sum. -Require Import divergence. +Require Import ssrR Reals_ext realType_ext logb ssr_ext ssralg_ext bigop_ext. +Require Import Rbigop fdist jfdist_cond entropy convex binary_entropy_function. +Require Import log_sum divergence. (******************************************************************************) (* Section 2.7 of Elements of Information Theory *) @@ -46,9 +46,11 @@ Local Open Scope fdist_scope. Local Open Scope convex_scope. Local Open Scope entropy_scope. +Import Order.POrderTheory GRing.Theory Num.Theory. + Section entropy_log_div. -Variables (A : finType) (p : fdist A) (n : nat) (An1 : #|A| = n.+1). -Let u := fdist_uniform An1. +Variables (A : finType) (p : {fdist A}) (n : nat) (An1 : #|A| = n.+1). +Let u := @fdist_uniform R_numFieldType _ _ An1. Local Open Scope divergence_scope. @@ -57,12 +59,17 @@ Proof. rewrite /entropy /div. evar (RHS : A -> R). have H a : p a * log (p a / u a) = RHS a. - case : (nneg_finfun_ge0 p a) => H. + have /RleP[H|H] := FDist.ge0 p a. - rewrite fdist_uniformE. change (p a * log (p a / / #|A|%:R)) with (p a * log (p a * / / #|A|%:R)). have H0 : 0 < #|A|%:R by rewrite An1 ltR0n. have /eqP H1 : #|A|%:R <> 0 by apply/eqP/gtR_eqF. - rewrite invRK // logM // mulRDr. + rewrite -RinvE ?An1; last first. + by rewrite -INRE// INR_eq0'. + rewrite /Rdiv invRK// logM //; last first. + by rewrite -INRE ltR0n. + rewrite mulRDr -INRE. + rewrite -An1. by instantiate (RHS := fun a => p a * log (p a) + p a * log #|A|%:R). - by rewrite /RHS -H /= 3!mul0R add0R. have -> : \sum_(a in A) p a * log (p a / u a) = \sum_(a in A) RHS a. @@ -74,18 +81,19 @@ End entropy_log_div. Section dominated_pair. Variable A : finType. -Implicit Types p q : prob. +Implicit Types p q : {prob R}. -Definition dom_pair := {d : fdist A * fdist A | d.1 `<< d.2}. +Definition dom_pair := {d : {fdist A} * {fdist A} | d.1 `<< d.2}. -Lemma dom_conv p (x y u v : fdist A) : +Lemma dom_conv p (x y u v : {fdist A}) : x `<< y -> u `<< v -> x <| p |> u `<< y <| p |> v. Proof. -rewrite !dominatesP => xy uv a; rewrite !fdist_convE. +move=> /dominatesP xy /dominatesP uv; apply/dominatesP => a. +rewrite !fdist_convE. rewrite paddR_eq0; [|exact/mulR_ge0 |exact/mulR_ge0]. rewrite !mulR_eq0 => -[[->|/xy ->]]; last first. - by rewrite mulR0 add0R => -[->|/uv ->]; rewrite !(mul0R,mulR0). -by rewrite mul0R add0R => -[|/uv ->]; + by rewrite -RplusE -!RmultE mulR0 add0R => -[->|/uv ->]; rewrite !(mul0R,mulR0). +by rewrite -RplusE -!RmultE mul0R add0R => -[|/uv ->]; [rewrite onem0 => /R1_neq_R0 | rewrite mulR0]. Qed. @@ -96,18 +104,18 @@ Definition avg_dom_pair p (x y : dom_pair) : dom_pair := let d_dom_c := proj2_sig y in exist _ (ab <| p |> cd) (dom_conv p b_dom_a d_dom_c). -Definition uncurry_dom_pair U (f : fdist A -> fdist A -> U) (x : dom_pair) := +Definition uncurry_dom_pair U (f : {fdist A} -> {fdist A} -> U) (x : dom_pair) := f (sval x).1 (sval x).2. Let avg := avg_dom_pair. -Let avg1 x y : avg 1%:pr x y = x. +Let avg1 x y : avg 1%coqR%:pr x y = x. Proof. by rewrite /avg; case x => x0 H /=; exact/boolp.eq_exist/conv1. Qed. Let avgI p x : avg p x x = x. Proof. by rewrite /avg; case x => x0 H /=; exact/boolp.eq_exist/convmm. Qed. -Let avgC p x y : avg p x y = avg p.~%:pr y x. +Let avgC p x y : avg p x y = avg (Prob.p p).~%:pr y x. Proof. by rewrite /avg; exact/boolp.eq_exist/convC. Qed. Let avgA p q x y z : @@ -132,41 +140,52 @@ have [y2a0|y2a0] := eqVneq (y.2 a) 0. rewrite y2a0 (_ : y.1 a = 0) ?(mulR0,addR0,mul0R); last first. by move/dominatesP : Hy; exact. have [x2a0|x2a0] := eqVneq (x.2 a) 0. - by rewrite (_ : x.1 a = 0) ?(mul0R,mulR0); - [exact/leRR|exact/((dominatesP _ _).1 Hx)]. - have [p0|p0] := eqVneq p 0%:pr; first by rewrite p0 ?mul0R; exact/leRR. - apply/Req_le; rewrite mulRA; congr (_ * _ * log _). + rewrite (_ : x.1 a = 0). + by rewrite -!RmultE -!RplusE ?(mul0R,mulR0,addR0). + exact/((dominatesP _ _).1 Hx). + have [p0|p0] := eqVneq p 0%coqR%:pr. + by rewrite p0 -!RmultE -!RplusE ?(mul0R,mulR0,addR0). + apply/Req_le; rewrite -!RmultE -!RplusE mulRA ?(mulR0,addR0); congr (_ * _ * log _). + simpl. by field; split; exact/eqP. have [x2a0|x2a0] := eqVneq (x.2 a) 0. - rewrite x2a0 (_ : x.1 a = 0) ?(mulR0,add0R,mul0R); last first. + rewrite x2a0 (_ : x.1 a = 0)// -?RplusE -?RmultE ?(mulR0,add0R,mul0R); last first. by move/dominatesP : Hx; exact. - have [->|t0] := eqVneq p.~ 0; first by rewrite !mul0R; exact/leRR. + have [->|t0] := eqVneq (Prob.p p).~ 0; first by rewrite !mul0R. apply/Req_le; rewrite mulRA; congr (_ * _ * log _). + simpl. by field; split; exact/eqP. -set h : fdist A -> fdist A -> {ffun 'I_2 -> R} := fun p1 p2 => [ffun i => - [eta (fun=> 0) with ord0 |-> p * p1 a, lift ord0 ord0 |-> p.~ * p2 a] i]. +set h : {fdist A} -> {fdist A} -> {ffun 'I_2 -> R} := fun p1 p2 => [ffun i => + [eta (fun=> 0) with ord0 |-> p * p1 a, lift ord0 ord0 |-> (Prob.p p).~ * p2 a] i]. have hdom : h x.1 y.1 `<< h x.2 y.2. apply/dominatesP => i; rewrite /h /= !ffunE; case: ifPn => _. by rewrite mulR_eq0 => -[->|/eqP]; [rewrite mul0R | rewrite (negbTE x2a0)]. case: ifPn => // _. by rewrite mulR_eq0 => -[->|/eqP]; [rewrite mul0R | rewrite (negbTE y2a0)]. -have h0 p1 p2 : [forall i, 0 ?; rewrite /h /= ffunE. +have h0 p1 p2 : [forall i, (0 <= h p1 p2 i)%mcR]. + apply/forallPP; first by move=> ?; exact/RleP. + move=> ?; rewrite /h /= ffunE. case: ifPn => [_ | _]; first exact/mulR_ge0. - case: ifPn => [_ | _]; last exact/leRR. + case: ifPn => [_ |//]. by apply/mulR_ge0 => //; exact/onem_ge0/prob_le1. -have := log_sum setT (mkNNFinfun (h0 x.1 y.1)) (mkNNFinfun (h0 x.2 y.2)) hdom. +have h01 (x0 : 'I_2) : 0 <= mkNNFinfun (h0 x.1 y.1) x0. + rewrite /= /h ffunE/=; case: ifPn => _; first exact: mulR_ge0. + by case: ifPn => // _; exact: mulR_ge0. +have h02 (x0 : 'I_2) : 0 <= mkNNFinfun (h0 x.2 y.2) x0. + rewrite /= /h ffunE/=; case: ifPn => _; first exact: mulR_ge0. + by case: ifPn => // _; exact: mulR_ge0. +have := log_sum setT (mkNNFinfun (h0 x.1 y.1)) (mkNNFinfun (h0 x.2 y.2)) h01 h02 hdom. rewrite /= -!sumR_ord_setT !big_ord_recl !big_ord0 !addR0. rewrite /h /= !ffunE => /leR_trans; apply. rewrite !eqxx eq_sym (negbTE (neq_lift ord0 ord0)) -!mulRA; apply/Req_le. congr (_ + _ ). - have [->|t0] := eqVneq p 0%:pr; first by rewrite !mul0R. + have [->|t0] := eqVneq p 0%coqR%:pr; first by rewrite !mul0R. by congr (_ * (_ * log _)); field; split; exact/eqP. -have [->|t1] := eqVneq p.~ 0; first by rewrite !mul0R. +have [->|t1] := eqVneq (Prob.p p).~ 0; first by rewrite !mul0R. by congr (_ * (_ * log _)); field; split; exact/eqP. Qed. -Lemma convex_relative_entropy (p1 p2 q1 q2 : fdist A) (r : prob) : +Lemma convex_relative_entropy (p1 p2 q1 q2 : {fdist A}) (r : {prob R}) : p1 `<< q1 -> p2 `<< q2 -> D(p1 <| r |> p2 || q1 <| r |> q2) <= D(p1 || q1) <| r |> D(p2 || q2). Proof. @@ -184,12 +203,13 @@ Hypothesis cardA_gt0 : (0 < #|A|)%nat. Let cardApredS : #|A| = #|A|.-1.+1. Proof. by rewrite prednK. Qed. -Lemma entropy_concave : concave_function (fun P : fdist A => `H P). +Lemma entropy_concave : concave_function (fun P : choice_of_Type {fdist A} => `H P). Proof. apply RNconcave_function => p q t; rewrite /convex_function_at. rewrite !(entropy_log_div _ cardApredS) /= /leconv /= [in X in _ <= X]avgRE. rewrite oppRD oppRK 2!mulRN mulRDr mulRN mulRDr mulRN oppRD oppRK oppRD oppRK. -rewrite addRCA !addRA -2!mulRN -mulRDl (addRC _ t) onemKC mul1R -addRA leR_add2l. +rewrite addRCA !addRA -2!mulRN -mulRDl (addRC _ t). +rewrite !RplusE onemKC mul1R -!RplusE -addRA leR_add2l. have := convex_relative_entropy t (dom_by_uniform p cardApredS) (dom_by_uniform q cardApredS). by rewrite convmm. @@ -243,7 +263,7 @@ move=> ? ? ? x [? ?]; split; [exact/ltRW/(@leR_ltR_trans b)|exact/ltRW/(@ltR_leR_trans c)]. Qed. -Lemma concavity_of_entropy_x_le_y x y (t : prob) : +Lemma concavity_of_entropy_x_le_y x y (t : {prob R}) : x \in open_unit_interval -> y \in open_unit_interval -> x < y -> concave_function_at H2 x y t. Proof. @@ -329,14 +349,14 @@ End entropy_concave_alternative_proof_binary_case. Section mutual_information_concave. Local Open Scope fdist_scope. -Variables (A B : finType) (W : A -> fdist B). +Variables (A B : finType) (W : A -> {fdist B}). Hypothesis B_not_empty : (0 < #|B|)%nat. Lemma mutual_information_concave : - concave_function (fun P => mutual_info (P `X W)). + concave_function (fun P : choice_of_Type {fdist A} => mutual_info (P `X W)). Proof. suff : concave_function - (fun P => let PQ := fdistX (P `X W) in `H PQ`1 - cond_entropy PQ). + (fun P : choice_of_Type {fdist A} => let PQ := fdistX (P `X W) in `H PQ`1 - cond_entropy PQ). set f := fun _ => _. set g := fun _ => _. suff -> : f = g by []. by rewrite boolp.funeqE => d; rewrite {}/f {}/g /= -mutual_infoE -mutual_info_sym. @@ -346,8 +366,8 @@ apply: R_concave_functionB. rewrite /convex_function_at 3!fdistX1. apply: leR_trans (concave_H (p `X W)`2 (q `X W)`2 t). under eq_bigr do rewrite fdist_prod2_conv. - exact/leRR. -suff : affine (fun x => cond_entropy (fdistX (x `X W))). + by apply/RleP; rewrite lexx. +suff : affine (fun x : choice_of_Type {fdist A} => cond_entropy (fdistX (x `X W))). by move=> /affine_functionP[]. move=> t p q. rewrite /= avgRE /cond_entropy /cond_entropy1. @@ -355,21 +375,28 @@ rewrite 2!big_distrr -big_split /=; apply eq_bigr => a _. rewrite !fdistX2 !fdist_fstE !mulRN -oppRD; congr (- _). rewrite !big_distrr -big_split /=; apply eq_bigr => b _. rewrite !big_distrl !big_distrr -big_split /=; apply eq_bigr => b0 _. -rewrite !fdist_prodE /= fdist_convE /= !(mulRA t) !(mulRA t.~). +rewrite !fdist_prodE /= fdist_convE /= !(mulRA t) !(mulRA (Prob.p t).~). +rewrite -!(RmultE,RplusE). have [Hp|/eqP Hp] := eqVneq (t * p a) 0. - rewrite Hp. - have [->|/eqP Hq] := eqVneq (t.~ * q a) 0; first by field. - rewrite !(mul0R,add0R) jcPr_fdistX_prod /=; last by rewrite fdist_convE Hp add0R. + rewrite Hp ?(add0R,mul0R). + have [->|/eqP Hq] := eqVneq ((Prob.p t).~ * q a) 0. + by rewrite ?(mul0R). + rewrite jcPr_fdistX_prod /=; last first. + by rewrite fdist_convE -RplusE -!RmultE Hp add0R. by rewrite jcPr_fdistX_prod //=; move: Hq; rewrite mulR_neq0 => -[]. -have [Hq|Hq] := eqVneq (t.~ * q a) 0. +have [Hq|Hq] := eqVneq ((Prob.p t).~ * q a) 0. rewrite Hq !(mul0R,addR0). - rewrite jcPr_fdistX_prod; last by rewrite fdist_convE Hq addR0. + rewrite jcPr_fdistX_prod; last first. + by rewrite fdist_convE -RplusE -!RmultE Hq addR0. by rewrite jcPr_fdistX_prod //=; move: Hp; rewrite mulR_neq0 => -[]. rewrite jcPr_fdistX_prod; last first. by rewrite /= fdist_convE paddR_eq0; [tauto|exact/mulR_ge0|exact/mulR_ge0]. rewrite jcPr_fdistX_prod; last by move: Hp; rewrite mulR_neq0 => -[]. rewrite jcPr_fdistX_prod //=; last by move/eqP: Hq; rewrite mulR_neq0 => -[]. -by field. +move/eqP in Hq. +rewrite /onem -RminusE (_ : 1%mcR = 1)//. +rewrite /onem -RminusE (_ : 1%mcR = 1)// in Hq. +by rewrite -!mulRDl. Qed. End mutual_information_concave. @@ -377,10 +404,10 @@ End mutual_information_concave. Section mutual_information_convex. Local Open Scope divergence_scope. Local Open Scope fdist_scope. -Variables (A B : finType) (P : fdist A). +Variables (A B : finType) (P : {fdist A}). Lemma mutual_information_convex : - convex_function (fun W : A -> fdist B => mutual_info (P `X W)). + convex_function (fun W : A -> {fdist B} => mutual_info (P `X W)). Proof. move=> /= p1yx p2yx t. pose p1xy := P `X p1yx. @@ -402,10 +429,14 @@ have -> : qlambdaxy = q1xy <| t |> q2xy. apply/fdist_ext => -[a b]. rewrite !fdist_prodE !fdist_convE /= /q1xy /q2xy !fdist_prodE /= /p1 /plambday. rewrite !fdist_sndE !big_distrr /= -big_split /=; apply eq_bigr => a0 _. - by rewrite /plambdaxy /= !fdist_prodE /= /p1xy /plambdayx fdist_convE /=; field. + rewrite /plambdaxy /= !fdist_prodE /= /p1xy /plambdayx fdist_convE /=. + rewrite -!(RmultE,RplusE). + field. have -> : plambdaxy = p1xy <| t |> p2xy. apply/fdist_ext => -[a b]. - by rewrite !fdist_prodE !fdist_convE /= /p1xy /p2xy !fdist_prodE /=; field. + rewrite !fdist_prodE !fdist_convE /= /p1xy /p2xy !fdist_prodE /=. + rewrite -!(RmultE,RplusE). + field. have -> : mutual_info (P `X p1yx) = D(p1xy || q1xy). rewrite mutual_infoE0 /div pair_big /=; apply: eq_bigr => -[a b] _ /=. congr (_ * log (_ / _)). @@ -416,13 +447,13 @@ have -> : mutual_info (P `X p2yx) = D(p2xy || q2xy). apply: convex_relative_entropy. - apply/dominatesP => -[a b]. rewrite /q1xy /p1xy fdist_prodE /= mulR_eq0 /p1 /p1xy => -[|]. - by rewrite fdist_prodE => ->; rewrite mul0R. - by rewrite fdist_sndE => /psumR_eq0P ->. + by rewrite fdist_prodE => ->; rewrite /= mul0r. + by rewrite fdist_sndE => /psumr_eq0P ->. - apply/dominatesP => -[a b]. rewrite /q1xy /p1xy fdist_prodE /= mulR_eq0. rewrite /p1 /p1xy => -[|]. - by rewrite fdist_prodE => ->; rewrite mul0R. - by rewrite fdist_sndE => /psumR_eq0P /= ->. + by rewrite fdist_prodE => ->; rewrite mul0r. + by rewrite fdist_sndE => /psumr_eq0P /= ->. Qed. End mutual_information_convex. diff --git a/information_theory/erasure_channel.v b/information_theory/erasure_channel.v index 0e730f54..69f42943 100644 --- a/information_theory/erasure_channel.v +++ b/information_theory/erasure_channel.v @@ -1,10 +1,9 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg perm zmodp. -From mathcomp Require Import matrix. +From mathcomp Require Import all_ssreflect all_algebra matrix. Require Import Reals. From mathcomp Require Import Rstruct. -Require Import ssrR Reals_ext ssr_ext ssralg_ext logb Rbigop fdist entropy. +Require Import ssrR Reals_ext realType_ext ssr_ext ssralg_ext logb Rbigop fdist entropy. Require Import binary_entropy_function channel hamming channel_code. (******************************************************************************) @@ -22,11 +21,14 @@ Local Open Scope channel_scope. Local Open Scope R_scope. Local Open Scope reals_ext_scope. +Import Num.Theory. + Module EC. Section EC_sect. Variables (A : finType) (p : R). Hypothesis p_01 : 0 <= p <= 1. +Local Open Scope ring_scope. Definition f (a : A) := [ffun b => if b is Some a' then @@ -36,22 +38,27 @@ Definition f (a : A) := [ffun b => Lemma f0 a b : 0 <= f a b. Proof. rewrite /f ffunE. -case: b => [a'|]; last by case: p_01. -case: ifP => _. -case: p_01 => ? ?; exact/onem_ge0. -exact/leRR. +case: b => [a'|]; last first. + by case: p_01 => /RleP. +case: ifP => _ //. +case: p_01 => ? ?//. +by apply/RleP/onem_ge0. Qed. Lemma f1 (a : A) : \sum_(a' : {:option A}) f a a' = 1. Proof. -rewrite (bigD1 None) //= (bigD1 (Some a)) //= !ffunE eqxx /= (proj2 (psumR_eq0P _)). -- by rewrite addR0 onemKC. -- rewrite /f; case => [a'|]; last by case: p_01. +rewrite (bigD1 None) //= (bigD1 (Some a)) //= !ffunE eqxx /=. +rewrite [X in _ + (_ + X)](_ : _ = 0). + by rewrite GRing.addr0 onemKC. +apply/eqP; rewrite psumr_eq0/=; last first. + - rewrite /f; case => [a'|]; last by case: p_01. rewrite ffunE. - case: ifPn => [_ |*]; last exact/leRR. - case: p_01 => ? ? _; exact/onem_ge0. -- case => //= a' aa'; rewrite ffunE; case: ifPn => // /eqP ?; subst a'. - move: aa'; by rewrite eqxx. + case: ifPn => [_ _|//]. + by case: p_01 => ? ?; apply/RleP/onem_ge0. +- apply/allP; case => //= a' aa'; rewrite ffunE; case: ifPn => // /eqP ?. + subst a'. + move: aa'; by rewrite eqxx. + by rewrite eqxx implybT. Qed. Definition c : `Ch(A, [finType of option A]) := @@ -60,10 +67,10 @@ Definition c : `Ch(A, [finType of option A]) := End EC_sect. Section EC_prob. - +Local Open Scope fdist_scope. Variable X : finType. Hypothesis card_X : #|X| = 2%nat. -Variables (P : fdist X) (p : R) (* erasure probability *). +Variables (P : {fdist X}) (p : R) (* erasure probability *). Hypothesis p_01 : 0 <= p <= 1. Let BEC := @EC.c X p p_01. diff --git a/information_theory/error_exponent.v b/information_theory/error_exponent.v index 53072f86..9b8bba9b 100644 --- a/information_theory/error_exponent.v +++ b/information_theory/error_exponent.v @@ -1,9 +1,11 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg matrix. +From mathcomp Require Import all_ssreflect ssralg ssrnum. Require Import Reals Lra. From mathcomp Require Import Rstruct. Require Import ssrR Reals_ext Ranalysis_ext logb ln_facts Rbigop fdist entropy. +From mathcomp Require Import reals. +Require Import realType_ext Rstruct_ext. Require Import channel_code channel divergence conditional_divergence. Require Import variation_dist pinsker. @@ -36,9 +38,11 @@ Local Open Scope channel_scope. Local Open Scope reals_ext_scope. Local Open Scope R_scope. +Import Order.TTheory GRing.Theory Num.Theory. + Section mutinfo_distance_bound. -Variables (A B : finType) (V W : `Ch(A, B)) (P : fdist A). +Variables (A B : finType) (V W : `Ch(A, B)) (P : {fdist A}). Hypothesis V_dom_by_W : P |- V << W. Hypothesis cdiv_ub : D(V || W | P) <= (exp(-2)) ^ 2 * / 2. @@ -48,8 +52,12 @@ split; first exact: sqrt_pos. apply pow2_Rle_inv; [ exact: sqrt_pos | exact/ltRW/exp_pos | ]. rewrite [in X in X <= _]/= mulR1 sqrt_sqrt; last first. apply mulR_ge0; [lra | exact: cdiv_ge0]. -apply/leRP; rewrite -(leR_pmul2r' (/ 2)); last exact/ltRP/invR_gt0. -by rewrite -mulRA mulRCA mulRV ?mulR1; [exact/leRP | exact/gtR_eqF]. +apply/RleP; rewrite -(@ler_pM2r _ (/ 2)); last first. + by rewrite RinvE' invr_gt0// (_ : 2%coqR = 2%:R)// INRE ltr0n. +rewrite RmultE -mulrA mulrCA RinvE' (_ : 2%coqR = 2%:R)// INRE. +rewrite mulfV ?mulr1 ?gt_eqF//. + by apply/RleP; rewrite -RdivE'. +exact/RltP. Qed. Local Open Scope variation_distance_scope. @@ -72,7 +80,7 @@ apply: (@leR_trans (d((P `X V), (P `X W)))). by apply Req_le; rewrite pair_bigA /=; apply eq_bigr => -[]. apply: leR_sumR => a _. rewrite (bigD1 b) //= distRC -[X in X <= _]addR0. - rewrite 2!fdist_prodE /= !(mulRC (P a)) addR_opp. + rewrite 2!fdist_prodE /= !(mulrC (P a)) addR_opp. by apply/leR_add2l/sumR_ge0 => ? _; exact/normR_ge0. - rewrite cdiv_is_div_joint_dist => //. exact/Pinsker_inequality_weak/joint_dominates. @@ -120,7 +128,7 @@ Hypothesis set_of_I_has_ubound : classical_sets.has_ubound (fun y => exists P, `I(P, W) = y). Lemma error_exponent_bound : exists Delta, 0 < Delta /\ - forall P : fdist A, forall V : `Ch(A, B), + forall P : {fdist A}, forall V : `Ch(A, B), P |- V << W -> Delta <= D(V || W | P) + +| minRate - `I(P, V) |. Proof. @@ -140,7 +148,7 @@ have /mu_cond : D_x no_cond 0 x /\ R_dist x 0 < mu. - rewrite /R_dist subR0 gtR0_norm // /x. apply (@leR_ltR_trans (mu * / 2)); first exact/geR_minl. by rewrite ltR_pdivr_mulr //; lra. -rewrite /R_dist {2}/xlnx ltRR' subR0 ltR0_norm; last first. +rewrite /R_dist {2}/xlnx ltxx subR0 ltR0_norm; last first. apply xlnx_neg; split => //; rewrite /x. exact: leR_ltR_trans (geR_minr _ _) ltRinve21. move=> Hx. @@ -150,7 +158,7 @@ exists Delta; split. - by apply mulR_gt0; [exact/subR_gt0 | exact/invR_gt0]. - by apply mulR_gt0; [exact: expR_gt0 | exact: invR_gt0]. move=> P V v_dom_by_w. -case/boolP : (Delta [/leRP| /leRP/ltRNge] Hcase. +case/boolP : (Delta <= D(V || W | P))%mcR => [/RleP| /RleP/ltRNge] Hcase. apply (@leR_trans (D(V || W | P))) => //. by rewrite -{1}(addR0 (D(V || W | P))); exact/leR_add2l/leR_maxl. suff HminRate : (minRate - capacity W) / 2 <= minRate - (`I(P, V)). diff --git a/information_theory/joint_typ_seq.v b/information_theory/joint_typ_seq.v index 47f93000..00f8b2a0 100644 --- a/information_theory/joint_typ_seq.v +++ b/information_theory/joint_typ_seq.v @@ -1,6 +1,6 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg matrix. +From mathcomp Require Import all_ssreflect ssralg matrix. Require Import Reals Lra. From mathcomp Require Import Rstruct. Require Import ssrZ ssrR Reals_ext ssr_ext logb ssralg_ext bigop_ext Rbigop. @@ -48,7 +48,7 @@ Local Open Scope R_scope. Section joint_typ_seq_definition. Variables A B : finType. -Variable P : fdist A. +Variable P : {fdist A}. Variable W : `Ch(A, B). Variable n : nat. Variable epsilon : R. @@ -65,7 +65,7 @@ Local Notation "'`JTS'" := (set_jtyp_seq). Lemma typical_sequence1_JTS x : prod_rV x \in `JTS -> exp2 (- INR n * (`H P + epsilon)) <= P `^ n x.1 <= exp2 (- INR n * (`H P - epsilon)). Proof. -rewrite inE => /and3P[/andP[/leRP JTS11 /leRP JTS12] _ _]. +rewrite inE => /and3P[/andP[/RleP JTS11 /RleP JTS12] _ _]. by rewrite prod_rVK in JTS11, JTS12. Qed. @@ -73,7 +73,7 @@ Lemma typical_sequence1_JTS' x : prod_rV x \in `JTS -> exp2 (- INR n * (`H (`O( P , W)) + epsilon)) <= (`O( P , W)) `^ n x.2 <= exp2 (- INR n * (`H (`O( P , W)) - epsilon)). Proof. -rewrite inE => /and3P[_ /andP[/leRP JTS11 /leRP JTS12] _]. +rewrite inE => /and3P[_ /andP[/RleP JTS11 /RleP JTS12] _]. by rewrite prod_rVK in JTS11, JTS12. Qed. @@ -84,7 +84,7 @@ Local Open Scope jtyp_seq_scope. Section jtyp_seq_upper. -Variables (A B : finType) (P : fdist A) (W : `Ch(A, B)). +Variables (A B : finType) (P : {fdist A}) (W : `Ch(A, B)). Variable n : nat. Variable epsilon : R. @@ -101,7 +101,7 @@ Qed. End jtyp_seq_upper. Section jtyp_seq_transmitted. -Variables (A B : finType) (P : fdist A) (W : `Ch(A, B)). +Variables (A B : finType) (P : {fdist A}) (W : `Ch(A, B)). Variable epsilon : R. Local Open Scope zarith_ext_scope. @@ -151,7 +151,8 @@ have : (JTS_1_bound <= n)%nat -> apply divR_gt0 => //; lra. exact/ltRW/(proj1 (archimed _ )). rewrite leR_subl_addr addRC -leR_subl_addr; apply: leR_trans. - by rewrite Pr_to_cplt setCK; exact/leRR. + rewrite Pr_to_cplt setCK. + by apply/RleP; rewrite Order.POrderTheory.lexx. have H1 m : Pr ((P `X W) `^ m) [set x | (rV_prod x).2 \notin `TS ( `O(P , W) ) m epsilon ] <= Pr ( (`O( P , W) ) `^ m) (~: `TS ( `O( P , W) ) m (epsilon / 3)). @@ -180,7 +181,8 @@ have : (JTS_1_bound <= n)%nat -> apply/ltZW/up_pos/aep_bound_ge0; lra. exact/ltRW/(proj1 (archimed _ )). rewrite leR_subl_addr addRC -leR_subl_addr; apply: leR_trans. - by rewrite Pr_to_cplt setCK; exact/leRR. + rewrite Pr_to_cplt setCK. + by apply/RleP; rewrite Order.POrderTheory.lexx. have H1 m : Pr ((P `X W) `^ m) (~: `TS ((P `X W)) m epsilon) <= Pr (((P `X W) ) `^ m) (~: `TS ((P `X W)) m (epsilon / 3)). have : 1 <= 3 by lra. @@ -204,7 +206,8 @@ have : (JTS_1_bound <= n)%nat -> apply/ltZW/up_pos/aep_bound_ge0; lra. exact/Rlt_le/(proj1 (archimed _ )). rewrite leR_subl_addr addRC -leR_subl_addr; apply: leR_trans. - by rewrite Pr_to_cplt setCK; exact/leRR. + rewrite Pr_to_cplt setCK. + by apply/RleP; rewrite Order.POrderTheory.lexx. move=> Hn. rewrite [in X in _ <= X](_ : epsilon = epsilon / 3 + epsilon / 3 + epsilon / 3)%R; last by field. move: Hn; rewrite 2!geq_max => /andP[Hn1 /andP[Hn2 Hn3]]. @@ -234,7 +237,7 @@ Qed. End jtyp_seq_transmitted. Section non_typicality. -Variables (A B : finType) (P : fdist A) (W : `Ch(A, B)) (n : nat) (epsilon : R). +Variables (A B : finType) (P : {fdist A}) (W : `Ch(A, B)) (n : nat) (epsilon : R). Lemma non_typical_sequences : Pr ((P `^ n) `x ((`O(P , W)) `^ n)) [set x | prod_rV x \in `JTS P W n epsilon] <= exp2 (- n%:R * (`I(P, W) - 3 * epsilon)). diff --git a/information_theory/jtypes.v b/information_theory/jtypes.v index 2b323086..d4d06dd9 100644 --- a/information_theory/jtypes.v +++ b/information_theory/jtypes.v @@ -1,10 +1,10 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect fingroup perm. +From mathcomp Require Import all_ssreflect ssralg ssrnum fingroup perm. From mathcomp Require boolp. Require Import Reals. From mathcomp Require Import Rstruct. -Require Import ssrR Reals_ext ssr_ext ssralg_ext logb Rbigop fdist entropy. +Require Import ssrR Reals_ext realType_ext ssr_ext ssralg_ext logb Rbigop fdist entropy. Require Import num_occ channel types. (******************************************************************************) @@ -39,6 +39,8 @@ Import Prenex Implicits. Local Open Scope R_scope. Local Open Scope channel_scope. +Import Num.Theory. + Module JType. Section def. Variables (A B : finType) (n : nat). @@ -99,12 +101,14 @@ pose pf := fun a => [ffun b : B => then / #|B|%:R else (f a b)%:R / ln%:R]. move=> a. -refine (@mkNNFinfun _ (pf a) _); apply/forallP_leRP => b. -rewrite /pf ffunE. -case: ifP => [_ | Hcase]. +refine (@mkNNFinfun _ (pf a) _); apply/forallPP; first by move=> ?; exact/RleP. +move=> b; rewrite /pf ffunE. +case: ifPn => [_ | Hcase]. - exact/invR_ge0/ltR0n. - apply divR_ge0; first exact/leR0n. - by apply/ltRP; rewrite lt0R INR_eq0' Hcase /= leR0n'. + apply/RltP; rewrite lt0r; apply/andP; split. + by apply: contra Hcase; rewrite INR_eq0'. + exact/RleP/leR0n. Defined. Definition chan_of_jtype (A B : finType) (Anot0 : (0 < #|A|)%nat) (Bnot0 : (0 < #|B|)%nat) @@ -115,11 +119,29 @@ set pf := fun a b => then / #|B|%:R else (f a b)%:R / ln%:R. refine (@Channel1.mkChan A B _ Anot0) => a. -apply: (@FDist.mk _ (@nneg_fun_of_pre_jtype _ _ Bnot0 n f a)). -under eq_bigr do rewrite ffunE /=. +apply: (@FDist.make _ _ (@nneg_fun_of_pre_jtype _ _ Bnot0 n f a)). + move=> b. + rewrite /nneg_fun_of_pre_jtype/= ffunE. + case: ifPn => // ?. + by apply/RleP/invR_ge0/ltR0n. + apply/RleP/divR_ge0. + exact/leR0n. + rewrite ltR_neqAle; split. + apply/eqP. + by rewrite eq_sym INR_eq0'. + exact: leR0n. +rewrite /=. +under eq_bigr do rewrite ffunE. case/boolP : (\sum_(b1 in B) (f a b1) == O)%nat => Hcase. - by rewrite /Rle big_const iter_addR mulRV // INR_eq0' -lt0n. -- rewrite big_morph_natRD /Rdiv -big_distrl /= mulRV //. +- under eq_bigr. + move=> b bB. + rewrite RdivE//; last first. + by rewrite INR_eq0'. + over. + rewrite big_morph_natRD /Rdiv. + rewrite -big_distrl /=. + rewrite GRing.mulfV//. by rewrite -big_morph_natRD // INR_eq0'. Defined. @@ -643,8 +665,9 @@ Local Open Scope nat_scope. Definition type_of_row (a : A) (Ha : N(a | ta) != 0) : P_ N(a | ta) ( B ). pose f := [ffun b => Ordinal (ctyp_element_ub Hrow_num_occ Hta a b)]. pose d := [ffun b => ((f b)%:R / N(a | ta)%:R)%R]. -have d0 : forall b, (0 <= d b)%R. +have d0 : forall b, (0 <= d b)%mcR. move=> b. + apply/RleP. rewrite /d /= ffunE. apply mulR_ge0; first exact/leR0n. apply/invR_ge0/ltR0n; by rewrite lt0n. @@ -1085,6 +1108,8 @@ Qed. End cond_type_equiv_sect. +Local Open Scope fdist_scope. + Module OutType. Section OutType_sect. @@ -1098,8 +1123,8 @@ Variable V : P_ n ( A , B ). Definition f := [ffun b => ((\sum_(a in A) (JType.f V) a b)%:R / n%:R)%R]. -Lemma f0 (b : B) : (0 <= f b)%R. -Proof. rewrite ffunE; apply divR_ge0; [exact/leR0n | exact/ltR0n]. Qed. +Lemma f0 (b : B) : (0 <= f b)%mcR. +Proof. rewrite ffunE; apply/RleP/ divR_ge0; [exact/leR0n | exact/ltR0n]. Qed. Lemma f1 : (\sum_(b in B) f b = 1)%R. Proof. @@ -1108,7 +1133,7 @@ rewrite -big_distrl /= -big_morph_natRD exchange_big /=. by move/eqP : (JType.sum_f V) => ->; rewrite mulRV // INR_eq0'. Qed. -Definition d : fdist B := FDist.make f0 f1. +Definition d : {fdist B} := FDist.make f0 f1. Definition P : P_ n ( B ). refine (@type.mkType _ _ (FDist.make f0 f1) [ffun b => Ordinal (jtype_entry_ub V b)] _). @@ -1145,7 +1170,7 @@ Qed. Hypothesis Bnot0 : (0 < #|B|)%nat. Hypothesis Vctyp : V \in \nu^{B}(P). -Lemma output_type_out_fdist : forall b, (`tO( V )) b = `O( P , V ) b. +Lemma output_type_out_fdist : forall b, type.d (`tO( V )) b = `O( P , V ) b. Proof. rewrite /fdist_of_ffun /= /OutType.d /OutType.f => b /=. rewrite ffunE big_morph_natRD /Rdiv (big_morph _ (morph_mulRDl _) (mul0R _)). @@ -1160,13 +1185,13 @@ case: ifP => [/eqP |] Hcase. rewrite in_set in Hta. move/forallP/(_ a) : Hta. rewrite -sum_V div0R. - move/eqP => ->; rewrite mulR0. + move/eqP => ->; rewrite -RmultE mulR0. move/eqP in Hcase. rewrite sum_nat_eq0 in Hcase. move/forallP/(_ b) : Hcase. move/implyP/(_ Logic.eq_refl)/eqP => ->. by rewrite mul0R. -- rewrite -mulRA sum_V; congr (_ * _). +- rewrite -RmultE -mulRA sum_V; congr (_ * _). move: Hta; rewrite in_set => /forallP/(_ a)/eqP ->. by rewrite mulRA -{1}(mul1R (/ n%:R)) mulVR // INR_eq0' -sum_V Hcase. Qed. @@ -1213,13 +1238,11 @@ Qed. End card_perm_shell. Section shell_partition. - -Local Open Scope fun_scope. -Local Open Scope nat_scope. - Variables A B : finType. Variable n' : nat. Let n := n'.+1. +Local Open Scope fun_scope. +Local Open Scope nat_scope. (** The stochastic matrix with entries N(a, b | ta, tb): *) @@ -1261,10 +1284,8 @@ Definition shell_partition : {set set_of_finType [finType of n.-tuple B]} := Lemma cover_shell : cover shell_partition = [set: n.-tuple B]. Proof. -rewrite /cover /cond_type. -apply/setP => tb. -rewrite in_set. -apply/bigcupP. +rewrite /cover /cond_type; apply/setP => tb. +rewrite in_set; apply/bigcupP. exists (num_co_occ_jtype ta tb).-shell ta. - apply/imsetP; exists (num_co_occ_jtype ta tb) => //. rewrite inE. @@ -1283,7 +1304,8 @@ exists (num_co_occ_jtype ta tb).-shell ta. by rewrite /num_co_occ_jtype /= 2!ffunE. Qed. -Lemma trivIset_shell' tb tb' V : tb \in V.-shell ta -> tb' \in V.-shell ta = relYn ta tb' tb. +Lemma trivIset_shell' tb tb' V : tb \in V.-shell ta -> + tb' \in V.-shell ta = relYn ta tb' tb. Proof. rewrite 2!in_set => H. rewrite /relYn. @@ -1299,10 +1321,11 @@ rewrite /disjoint. apply/pred0P => tb /=. apply/negP/negP. move: tb. -apply/forallP; rewrite -negb_exists; apply/negP; case/existsP => tb /andP [H1 H2]; contradict HS12. +apply/forallP; rewrite -negb_exists; apply/negP; + case/existsP => tb /andP [H1 H2]; contradict HS12. apply/negP/negPn/eqP/setP => ?. rewrite 2!(@trivIset_shell' tb) //. -apply reflexive_relYn. +exact: reflexive_relYn. Qed. End shell_partition. @@ -1335,9 +1358,8 @@ Let sum_tuples_ctypes' f : \sum_ (tb : _ ) f tb = Proof. transitivity (\sum_ (tb in [set: n.-tuple B]) f tb). by apply eq_bigl => tb; rewrite in_set. -rewrite -(cover_shell Anot0 Bnot0 Hta). -rewrite -sum_tuples_ctypes'' // big_trivIset //. -apply trivIset_shell. +rewrite -(cover_shell Anot0 Bnot0 Hta) -sum_tuples_ctypes''// big_trivIset//. +exact: trivIset_shell. Qed. Lemma sum_tuples_ctypes f F : @@ -1345,8 +1367,9 @@ Lemma sum_tuples_ctypes f F : \sum_(V | V \in \nu^{B}(P)) \sum_ (tb in V.-shell ta | F tb) f tb. Proof. rewrite big_mkcond /=. -transitivity (\sum_(V | V \in \nu^{B}(P)) \sum_(tb in V.-shell ta) if F tb then f tb else 0). - by apply sum_tuples_ctypes'. +transitivity (\sum_(V | V \in \nu^{B}(P)) \sum_(tb in V.-shell ta) + if F tb then f tb else 0). + exact: sum_tuples_ctypes'. apply eq_bigr => s _. rewrite [in LHS]big_mkcond /= [in RHS]big_mkcond /=. apply/esym/eq_bigr => tb _. diff --git a/information_theory/kraft.v b/information_theory/kraft.v index 1f291084..9428de7f 100644 --- a/information_theory/kraft.v +++ b/information_theory/kraft.v @@ -1,7 +1,6 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect path ssralg fingroup zmodp poly. -From mathcomp Require Import ssrnum. +From mathcomp Require Import all_ssreflect path ssralg ssrnum. Require FunctionalExtensionality. Require Import ssr_ext. @@ -574,7 +573,7 @@ Lemma prefix_implies_kraft_cond : prefix_code C -> Proof. move=> prefixC T_gt0; rewrite /kraft_cond size_map -/n. (*\color{comment}{\framebox{at this point, the goal is $\sum_{i < n} |T|^{-\ell_i} \leq 1$}} *) -have /ler_pmul2l <- : ((0 : R) < #|T|%:R ^+ lmax)%R. +have /ler_pM2l <- : ((0 : R) < #|T|%:R ^+ lmax)%R. by rewrite exprn_gt0 // ltr0n. rewrite mulr1 big_distrr /=. (*\color{comment}{\framebox{the goal is now $\sum_{i < n}\frac{|T|^{\ell_{\mathrm{max}}}}{#|T|^{\ell(i)}} \leq |T|^{\ell_{\mathrm{max}}}$}} *) rewrite (eq_bigr (fun i : 'I_n => #|suffixes C``_i|%:R)%R); last first. @@ -619,7 +618,7 @@ Lemma w_ub (H : kraft_cond R T l) j : w j <= #|T|^(nth O l j) - 1. Proof. have H' : (\sum_(i < n) #|T|%:R^-(nth O l i) <= (1 : R))%R. move: H; by rewrite /kraft_cond (_ : size l = n). -rewrite -(@ler_nat R) -(@ler_pmul2l _ (#|T|%:R ^- nth O l j))%R; last first. +rewrite -(@ler_nat R) -(@ler_pM2l _ (#|T|%:R ^- nth O l j))%R; last first. by rewrite -exprVn exprn_gt0 // invr_gt0 ltr0n card_ord. case/boolP : (j == ord0) => [/eqP ->|i0]. by rewrite wE0 mulr0 mulr_ge0 // -exprVn exprn_ge0 // invr_ge0 ler0n. @@ -632,11 +631,11 @@ rewrite (eq_bigr (fun j : 'I__ => #|T|%:R ^-nth O l j))%R; last first. by rewrite (leq_trans (ltn_ord i)) // ltnW. by rewrite unitfE pnatr_eq0. by rewrite mulrA mulVr ?unitfE -?natrX ?pnatr_eq0 ?expn_eq0 // mul1r. -rewrite ler_subr_addr natrX (le_trans _ H') //. +rewrite lerBrDr natrX (le_trans _ H') //. rewrite [X in (X <= _)%R](_ : _ = \sum_(k < j.+1) #|T|%:R^-nth O l k)%R; last first. by rewrite big_ord_recr /= card_ord. rewrite (@big_ord_widen _ _ _ j.+1 n (fun i => #|T|%:R ^- nth O l i))%R //. -rewrite [in X in (_ <= X)%R](bigID (fun k : 'I_n => k < j.+1)) /= ler_addl. +rewrite [in X in (_ <= X)%R](bigID (fun k : 'I_n => k < j.+1)) /= lerDl. rewrite sumr_ge0 // => k _; by rewrite invr_ge0 exprn_ge0 // ler0n. Qed. @@ -728,12 +727,12 @@ have H1 : (r >= (w j)%:R + (1 : R))%R. (*\color{comment}{\framebox{here we prove by rewrite (leq_trans (ltn_ord i)) // ltnW. by rewrite unitfE pnatr_eq0 card_ord. by rewrite -(big_mkord xpredT f)%R -big_cat_nat //= ltnW. - rewrite ler_add //. + rewrite lerD //. (*\color{comment}{\framebox{at this point, the subgoal is $1 \leq u$, for the step (\ref{eqn:kraft_converse2})-(\ref{eqn:kraft_converse3})}} *) rewrite /u -(@prednK k); last by rewrite (leq_ltn_trans _ jk). rewrite big_nat_recl; last by move/(leq_sub2r 1) : jk; rewrite !subn1. rewrite divrr ?unitfE -?natrX ?pnatr_eq0 ?expn_eq0 ?card_ord //. - rewrite ler_addl sumr_ge0 // => i _. + rewrite lerDl sumr_ge0 // => i _. by rewrite natrX divr_ge0 // exprn_ge0 // ?card_ord ?ler0n. have H2 : (r - 1 < (w j)%:R)%R. (* \color{comment}{\framebox{here we prove $r - 1 < w_j$}} *) have /(congr1 (fun x => x%:R : R)%R) : w k = @@ -750,10 +749,10 @@ have H2 : (r - 1 < (w j)%:R)%R. (* \color{comment}{\framebox{here we prove $r - have : ((w k %% #|T| ^ (l``_k - l``_j))%:R / #|T|%:R ^+ (l``_k - l``_j) < (1 : R))%R. (*\color{comment}{\framebox{here we prove $(w_k \bmod |T|^{\ell_k-\ell_j}) / |T|^{\ell_k - \ell_j} < 1$, leading to (\ref{eqn:kraft_converse6})}} *) - rewrite ltr_pdivr_mulr; [|by rewrite -natrX ltr0n expn_gt0 card_ord]. + rewrite ltr_pdivrMr; [|by rewrite -natrX ltr0n expn_gt0 card_ord]. by rewrite mul1r -natrX ltr_nat ltn_mod expn_gt0 card_ord. - by rewrite {}wkE ltr_sub_addl addrC ltr_add2r. -by rewrite ltr_subl_addl addrC ltNge H1 in H2. + by rewrite {}wkE ltrBDl addrC ltrD2r. +by rewrite ltrBlDl addrC ltNge H1 in H2. Qed. End kraft_cond_implies_prefix. diff --git a/information_theory/pproba.v b/information_theory/pproba.v index 13ddf66b..1c3cc6e4 100644 --- a/information_theory/pproba.v +++ b/information_theory/pproba.v @@ -1,6 +1,6 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg zmodp matrix. +From mathcomp Require Import all_ssreflect all_algebra zmodp matrix. Require Import Reals. From mathcomp Require Import Rstruct. Require Import ssrR Reals_ext ssr_ext ssralg_ext bigop_ext Rbigop fdist proba. @@ -35,6 +35,8 @@ Local Open Scope proba_scope. Local Open Scope channel_scope. Local Open Scope R_scope. +Import Num.Theory. + Section receivable. Variables (A B : finType) (n : nat) (P : {fdist 'rV[A]_n}) (W : `Ch(A, B)). @@ -57,9 +59,9 @@ Lemma receivable_propE (y : P.-receivable W) : Proof. apply/idP/idP => [|H]. - case/existsP => /= x /andP[Px0]. - apply: contra => /eqP/psumR_eq0P => /= H. + apply: contra => /eqP /psumr_eq0P => /= H. apply/eqP; rewrite -(@eqR_mul2l (P x)); last exact/eqP. - by rewrite mulR0 H // => /= x' _; exact: mulR_ge0. + by rewrite mulR0 H // => /= x' _; rewrite RmultE mulr_ge0//. - have /= : \sum_(x in setT) P x * W ``(y | x) != 0. apply: contra H => /eqP H; apply/eqP. rewrite -[RHS]H; apply/eq_bigl => /= x; by rewrite !inE. @@ -87,8 +89,8 @@ apply/idP/idP => [|/eqP]. move: (H i). rewrite negb_and !negbK => /orP[|/eqP //]. by rewrite -(negbK (_ == _)) fdist_uniform_supp_neq0 iC. -- have : forall i : 'rV_n, i \in C -> (0 <= W ``(y | i))%R by []. - move/psumR_eq0P => H /H {}H. +- have : forall i : 'rV_n, i \in C -> (0 <= W ``(y | i))%mcR by []. + move/psumr_eq0P => H /H {}H. rewrite /receivable_prop; apply/negP. case/existsP => z /andP[]. by rewrite fdist_uniform_supp_neq0 => /H ->; rewrite eqxx. @@ -99,24 +101,30 @@ End receivable_uniform. Section fdist_posterior_probability. Variables (A B : finType) (W : `Ch(A, B)) (n : nat) (P : {fdist 'rV[A]_n}). Variable y : P.-receivable W. +Local Open Scope ring_scope. Let den := \sum_(x in 'rV_n) P x * W ``(y | x). Let f := [ffun x => P x * W ``(y | x) / den]. Definition fdist_post_prob_den_ge0 : 0 <= den. -Proof. by apply sumR_ge0 => x _; exact: mulR_ge0. Qed. +Proof. by apply/RleP/sumR_ge0 => x _; exact: mulR_ge0. Qed. Let f0 x : 0 <= f x. Proof. -rewrite ffunE; apply divR_ge0; first exact: mulR_ge0. -apply/ltRP; rewrite lt0R {1}/den -receivable_propE receivableP. -exact/leRP/fdist_post_prob_den_ge0. +rewrite ffunE; apply/RleP; rewrite -RdivE//; last first. + by rewrite /den -receivable_propE receivableP. +apply: divR_ge0; first exact: mulR_ge0. +apply/RltP; rewrite lt0r {1}/den -receivable_propE receivableP. +exact/fdist_post_prob_den_ge0. Qed. Let f1 : \sum_(x in 'rV_n) f x = 1. Proof. under eq_bigr do rewrite ffunE /=. -by rewrite -big_distrl /= mulRC mulVR // -receivable_propE receivableP. +rewrite -big_distrl /= -RmultE mulRC. +rewrite -RinvE; last first. + by rewrite -receivable_propE receivableP. +by rewrite mulVR // -receivable_propE receivableP. Qed. Definition fdist_post_prob : {fdist 'rV[A]_n} := locked (FDist.make f0 f1). @@ -134,8 +142,12 @@ Variables (A B : finType) (W : `Ch(A, B)) (n : nat) (P : {fdist 'rV[A]_n}). Lemma post_probE (x : 'rV[A]_n) (y : P.-receivable W) : P `^^ W (x | y) = \Pr_(P `X (W ``^ n))[ [set x] | [set receivable_rV y]]. Proof. -rewrite fdist_post_probE /jcPr setX1 2!Pr_set1 fdist_prodE /=; congr (_ / _). -by rewrite fdist_sndE /=; apply eq_bigr => x' _; rewrite fdist_prodE /= mulRC. +rewrite fdist_post_probE /jcPr setX1 2!Pr_set1 fdist_prodE /=. +rewrite -RdivE; last first. + rewrite -receivable_propE. + by case: y. +congr (_ / _). +by rewrite fdist_sndE /=; apply eq_bigr => x' _; rewrite fdist_prodE /= -RmultE mulRC. Qed. End posterior_probabilityE. @@ -145,6 +157,7 @@ Variables (A B : finType) (W : `Ch(A, B)) (n : nat). Variable (C : {set 'rV[A]_n}). Hypothesis HC : (0 < #| C |)%nat. Variable y : (`U HC).-receivable W. +Local Open Scope ring_scope. Definition post_prob_uniform_cst := / \sum_(c in C) W ``(y | c). @@ -153,22 +166,38 @@ Let K := post_prob_uniform_cst. Lemma post_prob_uniformF (x : 'rV[A]_n) : x \notin C -> (`U HC) `^^ W (x | y) = 0. Proof. -by move=> xC; rewrite fdist_post_probE fdist_uniform_supp_notin // /Rdiv !mul0R. +move=> xC; rewrite fdist_post_probE fdist_uniform_supp_notin //. +by rewrite -!RmultE !mul0R. Qed. Lemma post_prob_uniformT (x : 'rV[A]_n) : x \in C -> (`U HC) `^^ W (x | y) = K * W ``(y | x). Proof. move=> Ht. -rewrite fdist_post_probE fdist_uniform_supp_in // mulRC {1}/Rdiv -mulRA [in RHS]mulRC; congr (_ * _). -rewrite /den fdist_uniform_supp_restrict. have C0 : INR #|C| != 0 by rewrite INR_eq0' -lt0n. -rewrite div1R -invRM //. - rewrite /K; congr Rinv; rewrite big_distrr /=; apply eq_bigr => i iC. - by rewrite fdist_uniform_supp_in // div1R mulRA mulRV // mul1R. +rewrite fdist_post_probE fdist_uniform_supp_in //. +rewrite -RinvE; last first. + by rewrite -INRE. +rewrite -!RmultE mulRC. +rewrite -RinvE; last first. + rewrite -receivable_propE. + by case: y. +rewrite mulRA. +congr (_ * _). +rewrite /den fdist_uniform_supp_restrict. +rewrite -invRM//. +3: by rewrite -INRE. + rewrite /K /post_prob_uniform_cst; congr Rinv. + rewrite !RmultE -INRE. + rewrite big_distrl /=. + apply eq_bigr => i iC. + rewrite fdist_uniform_supp_in //. + rewrite GRing.mulrAC INRE GRing.mulVr ?GRing.mul1r//. + by rewrite GRing.unitfE -INRE. rewrite (eq_bigr (fun t => 1 / INR #|C| * W ``(y | t))); last first. - by move=> *; rewrite fdist_uniform_supp_in. + move=> *; rewrite fdist_uniform_supp_in//. + by rewrite GRing.div1r INRE. apply/eqP; rewrite -big_distrr /= mulR_eq0 => -[]. - by rewrite div1R; exact/invR_neq0/eqP. + by rewrite -RdivE// div1R; apply/invR_neq0/eqP. by apply/eqP; rewrite -not_receivable_prop_uniform receivableP. Qed. @@ -188,6 +217,7 @@ Local Open Scope vec_ext_scope. Section marginal_post_prob. Variables (A B : finType) (W : `Ch(A, B)) (n : nat) (P : {fdist 'rV[A]_n}). Variable y : P.-receivable W. +Local Open Scope ring_scope. Let f' := fun x : 'rV_n => P `^^ W (x | y). @@ -198,6 +228,9 @@ Proof. under eq_bigr do rewrite /f' fdist_post_probE /Rdiv. rewrite -big_distrl /= mulR_eq0 => -[/eqP|]. - by apply/negP; rewrite -receivable_propE receivableP. +- rewrite -RinvE//; last first. + rewrite -receivable_propE. + by case: y. - by apply/invR_neq0/eqP; rewrite -receivable_propE receivableP. Qed. @@ -205,12 +238,12 @@ Let f (i : 'I_n) := [ffun a => marginal_post_prob_den * \sum_(t in 'rV_n | t `` Let f0 i a : 0 <= f i a. Proof. -rewrite ffunE; apply mulR_ge0. +rewrite ffunE; apply/RleP/mulR_ge0. - rewrite / marginal_post_prob_den. - apply/invR_ge0/ltRP; rewrite lt0R; apply/andP; split; [apply/eqP |apply/leRP]; last first. - by apply sumR_ge0 => /= ? _; exact: FDist.ge0. + apply/invR_ge0/RltP; rewrite lt0r/=; apply/andP; split; [apply/eqP |apply/RleP]; last first. + exact: sumR_ge0. exact/f'_neq0. -- by apply sumR_ge0 => /= ? _; exact: FDist.ge0. +- exact: sumR_ge0. Qed. Let f1 i : \sum_(a in A) f i a = 1. @@ -220,14 +253,16 @@ rewrite -big_distrr /= /marginal_post_prob_den. set tmp1 := \sum_( _ | _ ) _. set tmp2 := \sum_( _ | _ ) _. suff : tmp1 = tmp2. - move=> tp12; rewrite -tp12 mulVR //; exact/eqP/f'_neq0. + move=> tp12; rewrite -tp12. + by rewrite -RmultE mulVR //; exact/eqP/f'_neq0. by rewrite {}/tmp1 {}/tmp2 (partition_big (fun x : 'rV_n => x ``_ i) xpredT). Qed. -Definition fdist_marginal_post_prob i : fdist A := FDist.make (f0 i) (f1 i). +Definition fdist_marginal_post_prob i : {fdist A} := FDist.make (f0 i) (f1 i). End marginal_post_prob. -Notation "P ''_' n0 '`^^' W '(' a '|' y ')'" := (@fdist_marginal_post_prob _ _ W _ P y n0 a) : proba_scope. +Notation "P ''_' n0 '`^^' W '(' a '|' y ')'" := + (@fdist_marginal_post_prob _ _ W _ P y n0 a) : proba_scope. Section marginal_post_prob_prop. Variables (A B : finType) (W : `Ch(A, B)) (n : nat) (C : {set 'rV[A]_n}). diff --git a/information_theory/shannon_fano.v b/information_theory/shannon_fano.v index b74f0a88..9854fce4 100644 --- a/information_theory/shannon_fano.v +++ b/information_theory/shannon_fano.v @@ -1,9 +1,10 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup zmodp poly ssrnum. +From mathcomp Require Import all_ssreflect ssralg ssrnum. Require Import Reals. From mathcomp Require Import Rstruct. -Require Import ssrZ ssrR logb Reals_ext Rbigop ssr_ext fdist entropy kraft. +Require Import ssrZ ssrR logb Reals_ext realType_ext Rbigop ssr_ext fdist. +Require Import entropy kraft. (******************************************************************************) (* Shannon-Fano codes *) @@ -20,6 +21,8 @@ Unset Printing Implicit Defensive. Local Open Scope R_scope. +Import Order.POrderTheory Num.Theory. + Definition kraft_condR (T : finType) (sizes : seq nat) := let n := size sizes in (\sum_(i < n) #|T|%:R^-(nth O sizes i) <= (1 : R))%R. @@ -61,7 +64,9 @@ Let sizes := [seq (size \o f) a| a in A]. Lemma shannon_fano_is_kraft : is_shannon_fano P f -> kraft_condR T sizes. Proof. move=> H. -rewrite /kraft_condR -(FDist.f1 P) /sizes size_map. +rewrite /kraft_condR. +rewrite (_ : 1 = 1%mcR)//. +rewrite -(FDist.f1 P) /sizes size_map. rewrite (eq_bigr (fun i:'I_(size(enum A)) => #|'I_t|%:R ^- size (f (nth a (enum A) i)))); last first. move=> i _; by rewrite /= (nth_map a). rewrite -(big_mkord xpredT (fun i => #|T|%:R ^- size (f (nth a (enum A) i)))). @@ -69,10 +74,9 @@ rewrite -(big_nth a xpredT (fun i => #|'I_t|%:R ^- size (f i))). rewrite enumT. apply leR_sumR => i _. rewrite H. -have Pi0 : 0 < P i by apply/ltRP; rewrite lt0R Pr0; exact/leRP. +have Pi0 : 0 < P i by apply/RltP; rewrite lt0r Pr0/=. apply (@leR_trans (Exp #|T|%:R (- Log #|T|%:R (1 / P i)))); last first. - rewrite div1R LogV //. - rewrite oppRK LogK //; first exact/leRR. + rewrite div1R LogV// oppRK LogK //; first by apply/RleP; rewrite lexx. by rewrite (_ : 1 = 1%:R) // ltR_nat card_ord. rewrite pow_Exp; last by apply ltR0n; rewrite card_ord. rewrite Exp_Ropp. @@ -80,7 +84,7 @@ apply/leR_inv/Exp_le_increasing => //. by rewrite (_ : 1 = 1%:R) // ltR_nat card_ord. rewrite INR_Zabs_nat; last first. case/boolP : (P i == 1) => [/eqP ->|Pj1]. - by rewrite divR1 Log_1 /ceil fp_R0 eqxx /=; apply/Int_part_ge0/leRR. + by rewrite divR1 Log_1 /ceil fp_R0 eqxx /=; apply/Int_part_ge0. apply/leR0ceil/ltRW/ltR0Log. by rewrite (_ : 1 = 1%:R) // ltR_nat card_ord. rewrite div1R invR_gt1 // ltR_neqAle; split => //; exact/eqP. @@ -113,13 +117,15 @@ Lemma shannon_fano_average_entropy : is_shannon_fano P f -> Proof. move=> H; rewrite /average. apply (@ltR_leR_trans (\sum_(x in A) P x * (- Log #|T|%:R (P x) + 1))). - apply ltR_sumR; [exact: fdist_card_neq0|move=> i]. - apply ltR_pmul2l. - apply/ltRP; rewrite lt0R Pr_pos /=; exact/leRP. + apply: ltR_sumR. + apply: fdist_card_neq0. + exact: P. + move=> i. + apply ltR_pmul2l; first by apply/RltP; rewrite lt0r Pr_pos /=. rewrite H. rewrite (_ : #|T|%:R = 2) // ?card_ord // -!/(log _). set x := log _; case: (ceilP x) => _ Hx. - have Pi0 : 0 < P i by apply/ltRP; rewrite lt0R Pr_pos /=; exact/leRP. + have Pi0 : 0 < P i by apply/RltP; rewrite lt0r Pr_pos /=. rewrite INR_Zabs_nat; last first. apply/leR0ceil. rewrite /x div1R /log LogV //. diff --git a/information_theory/source_code.v b/information_theory/source_code.v index 65adb6f6..e167c2b1 100644 --- a/information_theory/source_code.v +++ b/information_theory/source_code.v @@ -1,6 +1,6 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg matrix. +From mathcomp Require Import all_ssreflect ssralg matrix. Require Import Reals. From mathcomp Require Import Rstruct. Require Import ssrR Reals_ext logb fdist proba. @@ -40,7 +40,7 @@ Variables (A : finType) (k n : nat). Definition scode_vl := scode A (seq bool) k. -Variables (P : fdist A) (f : {RV (P `^ n) -> seq bool}). +Variables (P : {fdist A}) (f : {RV (P `^ n) -> seq bool}). Definition E_leng_cw := `E ((INR \o size) `o f). @@ -56,7 +56,7 @@ Definition SrcRate (sc : scode_fl) := n%:R / k%:R. End scode_fl_definition. Section code_error_rate. -Variables (A : finType) (B : Type) (P : fdist A). +Variables (A : finType) (B : Type) (P : {fdist A}). Variables (k : nat) (sc : scode A B k). Definition SrcErrRate := Pr (P `^ k) [set ta | dec sc (enc sc ta) != ta]. diff --git a/information_theory/source_coding_fl_converse.v b/information_theory/source_coding_fl_converse.v index fbbae23f..a089b1b1 100644 --- a/information_theory/source_coding_fl_converse.v +++ b/information_theory/source_coding_fl_converse.v @@ -1,10 +1,10 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg matrix. +From mathcomp Require Import all_ssreflect ssralg ssrnum matrix. Require Import Reals Lra. From mathcomp Require Import Rstruct. -Require Import ssrR Reals_ext logb Rbigop fdist proba entropy aep typ_seq. -Require Import source_code. +Require Import ssrR Reals_ext realType_ext logb Rbigop fdist proba entropy aep. +Require Import typ_seq source_code. (******************************************************************************) (* Source coding theorem (fixed length, converse part) *) @@ -24,10 +24,13 @@ Local Open Scope source_code_scope. Local Open Scope entropy_scope. Local Open Scope reals_ext_scope. Local Open Scope R_scope. +Local Open Scope fdist_scope. + +Import Order.POrderTheory GRing.Theory Num.Theory. Section source_coding_converse'. -Variables (A : finType) (P : fdist A). +Variables (A : finType) (P : {fdist A}). Variables num den : nat. Let r := num%:R / den.+1%:R. Hypothesis Hr : 0 < r < `H P. @@ -104,13 +107,14 @@ apply (@leR_trans (exp2 n%:R)). by apply/le_INR/leP/subset_leqif_cards/imsetS/subsetP => x Hx; rewrite inE. apply (@leR_trans #| [set: 'rV[bool]_n] |%:R). exact/le_INR/leP/leq_imset_card. - by rewrite cardsT card_mx /= card_bool natRexp2 mul1n; exact/leRR. + rewrite cardsT card_mx /= card_bool natRexp2 mul1n. + by apply/RleP; rewrite lexx. apply Exp_le_increasing => //. rewrite /e0 [X in _ <= _ * X](_ : _ = r); last by field. apply (@leR_pmul2r (1 / r)) => //. by apply divR_gt0; [lra | tauto]. rewrite -mulRA div1R mulRV ?mulR1; last first. - by case: Hr => /ltRP; rewrite lt0R => /andP[]. + by case: Hr => /RltP; rewrite lt0r => /andP[]. by case/leR_max : Hk. Qed. @@ -125,6 +129,7 @@ suff : 1 = a + b by move=> ->; field. rewrite /a {a}. have -> : b = \sum_(i in [set i | dec sc (enc sc i) == i]) P `^ k.+1 i. apply eq_big => // i /=; by rewrite inE. +rewrite (_ : 1 = 1%mcR)//. rewrite -(FDist.f1 (P `^ k.+1)). rewrite (bigID [pred a | a \in [set i0 | dec sc (enc sc i0) == i0]]) /= addRC. by congr (_ + _); apply eq_bigl => t /=; rewrite !inE. @@ -147,7 +152,7 @@ Lemma step3 : 1 - (esrc(P , sc)) <= \sum_(x in 'rV[A]_k.+1 | x \in no_failure :&: `TS P k.+1 delta) P `^ k.+1 x. Proof. rewrite step2; apply/leR_add2r/leR_sumRl => //= i Hi. -exact/leRR. + by apply/RleP; rewrite lexx. by move: Hi; rewrite in_setI => /andP[]. Qed. @@ -155,11 +160,12 @@ Lemma step4 : 1 - (esrc(P , sc)) <= delta + #| no_failure :&: `TS P k.+1 delta|%:R * exp2 (- k.+1%:R * (`H P - delta)). Proof. apply/(leR_trans step3)/leR_add. -- move/leRP : Hk; rewrite 2!leR_max' -andbA => /andP[/leRP]. - move/(Pr_TS_1 Hdelta) => Hdelta _. +- move: Hk => /leR_max[] /leR_max[]. + move/(Pr_TS_1 Hdelta) => Hdelta _ _. rewrite -[in X in _ <= X](oppRK delta) leR_oppr -(@leR_add2l 1) 2!addR_opp. move/leR_trans : Hdelta; apply. - rewrite Pr_to_cplt; exact/leRR. + rewrite Pr_to_cplt. + by apply/RleP; rewrite lexx. - apply (@leR_trans (\sum_(x in 'rV[A]_k.+1 | x \in no_failure :&: `TS P k.+1 delta) exp2 (- k.+1%:R * (`H P - delta)))). @@ -168,12 +174,13 @@ apply/(leR_trans step3)/leR_add. move: (typ_seq_definition_equiv2 i_TS) => [H1 _]. apply (@Log_le_inv 2) => //. + move: i_TS. - rewrite /`TS inE /typ_seq => /andP[/leRP i_TS _]. + rewrite /`TS inE /typ_seq => /andP[/RleP i_TS _]. exact: (ltR_leR_trans (exp2_gt0 _) i_TS). + rewrite /exp2 ExpK //. rewrite mulRC mulRN -mulNR -leR_pdivr_mulr; last exact/ltR0n. rewrite leR_oppr /Rdiv mulRC; by rewrite div1R mulNR in H1. - by rewrite big_const iter_addR; exact/leRR. + rewrite big_const iter_addR. + by apply/RleP; rewrite lexx. Qed. Lemma step5 : 1 - (esrc(P , sc)) <= delta + exp2 (- k.+1%:R * (e0 - delta)). @@ -201,11 +208,11 @@ have H : exp2 (- k.+1%:R * (e0 - delta)) <= delta. have H1 : (`H P - r) / 2 < `H P - r. rewrite -[X in _ < X]mulR1. apply ltR_pmul2l; last lra. - apply/ltRP; rewrite ltR_subRL' addR0; apply/ltRP; by case: Hr. + by apply/RltP; rewrite RminusE subr_gt0; apply/RltP; case: Hr. apply Rmin_case_strong => H2 //; exact: (leR_ltR_trans H2 H1). + rewrite -mulRA div1R mulRV; last by rewrite subR_eq0'; exact/eqP/e0_delta. rewrite mulNR mulR1 leR_oppl. - by move/leRP : Hk; rewrite 2!leR_max' => /andP[/andP[_ /leRP]]. + by move: Hk => /leR_max[] /leR_max[]. suff : 1 - (esrc(P , sc)) <= delta + delta by move=> *; lra. exact/(leR_trans step5)/leR_add2l. Qed. @@ -227,7 +234,7 @@ End source_coding_converse'. Section source_coding_converse. -Variables (A : finType) (P : fdist A). +Variables (A : finType) (P : {fdist A}). Theorem source_coding_converse : forall epsilon, 0 < epsilon < 1 -> forall r : Qplus, 0 < r < `H P -> diff --git a/information_theory/source_coding_fl_direct.v b/information_theory/source_coding_fl_direct.v index f9409995..53bae9f5 100644 --- a/information_theory/source_coding_fl_direct.v +++ b/information_theory/source_coding_fl_direct.v @@ -1,6 +1,6 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg matrix. +From mathcomp Require Import all_ssreflect ssralg matrix. Require Import Reals Lra. From mathcomp Require Import Rstruct. Require Import ssrZ ssrR Reals_ext ssr_ext ssralg_ext logb natbin Rbigop fdist. @@ -21,9 +21,10 @@ Unset Strict Implicit. Import Prenex Implicits. Local Open Scope ring_scope. +Local Open Scope fdist_scope. Section encoder_and_decoder. -Variables (A : finType) (P : fdist A) (n k : nat). +Variables (A : finType) (P : {fdist A}) (n k : nat). Variable S : {set 'rV[A]_k.+1}. @@ -105,7 +106,7 @@ Local Open Scope entropy_scope. Local Open Scope reals_ext_scope. Section source_coding_direct'. -Variables (A : finType) (P : fdist A) (num den : nat). +Variables (A : finType) (P : {fdist A}) (num den : nat). Let r := (num%:R / den.+1%:R)%R. Hypothesis Hr : `H P < r. Variable epsilon : R. @@ -193,7 +194,7 @@ rewrite inE /=; apply/negPn/negPn. apply (@leR_trans (exp2 (k%:R * (lambda / 2) + k%:R * (`H P + lambda / 2)))); last first. rewrite -mulRDr addRC -addRA. rewrite (_ : forall a, a / 2 + a / 2 = a)%R; last by move=> ?; field. - exact/leRR. + by apply/RleP; rewrite Order.POrderTheory.lexx. apply (@leR_trans (exp2 (1 + INR k * (`H P + lambda / 2)))); last first. apply Exp_le_increasing => //; apply leR_add2r. move/leR_max : Hdelta => [_ Hlambda]. @@ -208,13 +209,14 @@ rewrite inE /=; apply/negPn/negPn. apply mulR_ge0; first exact: leR0n. apply addR_ge0; first exact: entropy_ge0. apply Rlt_le; exact: lambda2_gt0. - + by rewrite addRR -{1}(logK Rlt_0_2) -ExpD {1}/log Log_n //; exact/leRR. + + rewrite addRR -{1}(logK Rlt_0_2) -ExpD {1}/log Log_n //. + by apply/RleP; rewrite Order.POrderTheory.lexx. Qed. End source_coding_direct'. Section source_coding_direct. -Variables (A : finType) (P : fdist A). +Variables (A : finType) (P : {fdist A}). Theorem source_coding_direct epsilon : 0 < epsilon < 1 -> forall r : Qplus, `H P < r -> diff --git a/information_theory/source_coding_vl_converse.v b/information_theory/source_coding_vl_converse.v index 64118c8a..ddb19721 100644 --- a/information_theory/source_coding_vl_converse.v +++ b/information_theory/source_coding_vl_converse.v @@ -1,9 +1,9 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg matrix. +From mathcomp Require Import all_ssreflect ssralg ssrnum matrix. Require Import Reals. From mathcomp Require Import Rstruct. -Require Import ssrR Reals_ext logb ssr_ext ssralg_ext bigop_ext. +Require Import ssrR Reals_ext realType_ext logb ssr_ext ssralg_ext bigop_ext. Require Import Rbigop fdist proba entropy divergence log_sum source_code. (******************************************************************************) @@ -29,6 +29,8 @@ Local Open Scope entropy_scope. Local Open Scope divergence_scope. Local Open Scope R_scope. +Import Order.POrderTheory Num.Theory. + Section log_sum_ord. Variable n : nat. Variable f g : nat ->R^+. @@ -41,10 +43,12 @@ Lemma log_sum_inequality_ord_add1 : Proof. have Rle0f_1 : forall x : 'I_n, 0 <= f x.+1 by move=> ?; apply nneg_f_ge0. have Rle0g_1 : forall x : 'I_n, 0 <= g x.+1 by move=> ?; apply nneg_f_ge0. -have newRle0f_1: [forall x : 'I_n, 0 f x.+1] x]. - by apply/forallP_leRP => ?; rewrite ffunE. -have newRle0g_1: [forall x : 'I_n, 0 g x.+1] x]. - by apply/forallP_leRP => ?; rewrite ffunE. +have newRle0f_1 : [forall x : 'I_n, (0 <= [ffun x : 'I_n => f x.+1] x)%mcR]. + apply/forallPP; first by move=> x; apply/RleP. + by move=> ?/=; rewrite ffunE. +have newRle0g_1: [forall x : 'I_n, (0 <= [ffun x : 'I_n => g x.+1] x)%mcR]. + apply/forallPP; first by move=> x; apply/RleP. + by move=> ?/=; rewrite ffunE. have f_dom_by_g1 : mkNNFinfun newRle0f_1 `<< mkNNFinfun newRle0g_1. apply/dominatesP => a; move/dominatesP : f_dom_by_g. by rewrite /= !ffunE; exact. @@ -52,7 +56,11 @@ have H : forall h, \sum_(a | a \in [set: 'I_n]) h a.+1 = \sum_(a | a \in 'I_n) h a.+1. by move=> ?; under eq_bigl do rewrite in_setT. rewrite -!H -(H (fun i => f i * log (f i / g i))). -move: (log_sum [set: 'I_n] (mkNNFinfun newRle0f_1) (mkNNFinfun newRle0g_1) f_dom_by_g1). +have H1 : (forall x : 'I_n, 0 <= mkNNFinfun newRle0f_1 x). + by move=> x//=; rewrite ffunE. +have H2 : (forall x : 'I_n, 0 <= mkNNFinfun newRle0g_1 x). + by move=> x//=; rewrite ffunE. +have := (log_sum [set: 'I_n] (mkNNFinfun newRle0f_1) (mkNNFinfun newRle0g_1) H1 H2 f_dom_by_g1). rewrite /=. under eq_bigr do rewrite ffunE. under [in X in _ * log (_ / X) <= _ -> _]eq_bigr do rewrite ffunE. @@ -82,9 +90,12 @@ rewrite [X in _ <= X] have Rle0g_add1 : forall x : 'I_n, 0 <= g x.+1 by move=> ?; apply nneg_f_ge0. move=> H. have eq_g_0 : forall i : 'I_n, 0 = g i.+1. - by move/esym/psumR_eq0P : H => H i; rewrite H. + move/esym/psumr_eq0P : H => H i; rewrite H//. + by move=> /= j _; exact/RleP. have : 0 = \sum_(i < n) f i.+1. - apply/esym/psumR_eq0P => i _; [exact: nneg_f_ge0|]. + apply/esym/eqP; rewrite psumr_eq0 /=; last first. + move=> i _. exact/RleP/nneg_f_ge0. + apply/allP => i _; apply/eqP. by move/dominatesP : f_dom_by_g; apply; rewrite -eq_g_0. by move => tmp; move: Hf; rewrite -tmp; move/Rlt_not_eq. apply: eq_bigr => i _. @@ -181,7 +192,7 @@ End Bigop_Lemma. Local Open Scope vec_ext_scope. Section Entropy_lemma. -Variables (A : finType) (P : fdist A) (n : nat). +Variables (A : finType) (P : {fdist A}) (n : nat). Lemma entropy_TupleFDist : `H (P `^ n) = n%:R * `H P. Proof. @@ -202,7 +213,7 @@ rewrite [LHS](_ :_ = \sum_(i | i \in A) P i * log (P i) * rewrite big_ord_recl (_ : _ ``_ ord0 = i); last first. by rewrite mxE; case: splitP => // j Hj; rewrite mxE. rewrite -mulRA. - case: (FDist.ge0 P i) => [pi_pos| <-]; last by rewrite !mul0R. + case/RleP : (FDist.ge0 P i) => [pi_pos| <-]; last by rewrite !mul0R. congr (P i * _). rewrite -mulRDr. rewrite (@eq_bigr _ _ _ _ _ _ @@ -216,11 +227,11 @@ rewrite [LHS](_ :_ = \sum_(i | i \in A) P i * log (P i) * by rewrite !mul0R. have rmul_pos : 0 < \prod_(i1 ?. - exact: FDist.ge0. + apply/RltP; rewrite lt0r eq_sym rmul_non0; apply/RleP/prodR_ge0 => ?. + exact/RleP/FDist.ge0. by rewrite /log LogM // !mulRDr mulRA mulRA. rewrite (_ : \sum_(j in 'rV_n0) _ = 1); last first. - by rewrite -(FDist.f1 (P `^ n0)); apply eq_bigr => i _; rewrite fdist_rVE. + by rewrite (_ : 1 = 1%mcR)// -(FDist.f1 (P `^ n0)); apply eq_bigr => i _; rewrite fdist_rVE. rewrite -big_distrl /= mulR1 [in RHS]addRC; congr (_ + _). rewrite -big_distrl /= FDist.f1 mul1R; apply eq_bigr => i _. by rewrite fdist_rVE. @@ -230,7 +241,7 @@ End Entropy_lemma. Section le_entroPN_logeEX. -Variable (A : finType) (P : fdist A) (f : A -> seq bool). +Variable (A : finType) (P : {fdist A}) (f : A -> seq bool). Let X : {RV P -> R} := INR \o size \o f. Definition Nmax := \max_(a in A) size (f a). Hypothesis f_uniq : uniquely_decodable f. @@ -250,11 +261,11 @@ move/nesym/INR_not_0 : (@Xnon0 a) => H. by rewrite ltR0n ltn_neqAle /= leq0n andbT; apply/eqP/nesym. Qed. -Let PN_ge0 : forall i : 'I_Nmax.+1, 0 <= [ffun x : 'I__ => `Pr[ X = x%:R]] i. -Proof. by move => a; rewrite ffunE. Qed. +Let PN_ge0 : (forall i : 'I_Nmax.+1, 0 <= [ffun x : 'I__ => `Pr[ X = x%:R]] i)%mcR. +Proof. by move => a; rewrite ffunE; apply/RleP. Qed. Lemma PN_sum1 : - \sum_(i < Nmax.+1) [ffun x : 'I__ => `Pr[ X = x%:R] ] i = 1. + (\sum_(i < Nmax.+1) [ffun x : 'I__ => `Pr[ X = x%:R] ] i = 1)%mcR. Proof. rewrite -(FDist.f1 P). rewrite [in RHS](partition_big (inordf (size \o f)) (fun i => i \in 'I_Nmax.+1)) //=. @@ -262,9 +273,10 @@ apply: eq_bigr => i _; rewrite ffunE. rewrite /pr_eq; unlock. apply: eq_bigl => i0. rewrite /= inE. -apply/eqP/eqP=>[/INR_eq H|<-]; last by rewrite inordfE. -apply: ord_inj. -by rewrite -H inordfE. +apply/eqP/eqP=> [|<-]; last first. + by rewrite inordfE /X /= FDist.f1 INRE. +rewrite FDist.f1 /X /= -INRE => /INR_eq H. +by apply/val_inj => /=; rewrite -H inordfE. Qed. Definition PN := FDist.make PN_ge0 PN_sum1. @@ -277,15 +289,17 @@ rewrite /pr_eq; unlock. rewrite /Pr ffunE mulRC big_distrl /=. under eq_bigr do rewrite mulRC. apply: congr_big=>[//| x| x]; last by move/eqP<-; rewrite inordfE. -rewrite inE; apply/eqP/eqP; first by move<-; rewrite inordfE. -by move/INR_eq => H; apply: ord_inj; rewrite -H inordfE. +rewrite inE; apply/eqP/eqP=> [<-|]. + by rewrite inordfE /X/= INRE. +rewrite /X /= -INRE => /INR_eq H. +by apply: ord_inj; rewrite -H inordfE. Qed. Lemma le_1_EX : 1 <= `E X. Proof. -rewrite -(FDist.f1 P); apply: leR_sumR => i _. +rewrite (_ : 1 = 1%mcR)// -(FDist.f1 P); apply: leR_sumR => i _. rewrite -{1}(mul1R (P i)). -apply leR_wpmul2r; first exact: FDist.ge0. +apply leR_wpmul2r; first exact/RleP/FDist.ge0. by move: (Xpos i); rewrite (_ : 1 = 1%:R) //= (_ : 0 = 0%:R) // ltR_nat leR_nat. Qed. @@ -296,10 +310,10 @@ Proof. move => EX_1. have eq_0_P : forall a, X a <> 1 -> 0 = P a. move: EX_1. - rewrite -{1}(FDist.f1 P) => EX1 a Xnon1. + rewrite (_ : 1 = 1%mcR)// -{1}(FDist.f1 P) => EX1 a Xnon1. have /leR_sumR_eq H : forall i : A, i \in A -> P i <= (size (f i))%:R * P i. move=> i _; rewrite -{1}(mul1R ( P i)). - apply/leR_wpmul2r; first exact: FDist.ge0. + apply/leR_wpmul2r; first exact/RleP/FDist.ge0. by move: (Xpos i); rewrite (_ : 1 = 1%:R) //= (_ : 0 = 0%:R) // ltR_nat leR_nat. case: (Req_dec (P a) 0) => //. have : (size (f a))%:R * P a = P a by rewrite (H EX1 a). @@ -309,8 +323,10 @@ rewrite /entropy Ropp_eq_0_compat //. rewrite (eq_bigr (fun=> 0)) ?big_const ?iter_addR ?mulR0 //= => i _. rewrite /pr_eq; unlock. rewrite /Pr ffunE. -case (Req_dec i%:R 1)=>[->| neq0]. +rewrite -INRE. +case: (Req_dec i%:R 1)=>[->| neq0]. rewrite [X in _ * log X = _](_ : _ = 1); first by rewrite /log Log_1 mulR0. + rewrite (_ : 1 = 1%mcR)//. rewrite -{2}(FDist.f1 P). rewrite [in RHS](bigID (fun a => a \in [set x | (size (f x))%:R == 1])) /=. rewrite [X in _ = _ + X](_ : _ = 0); first by rewrite addR0. @@ -327,7 +343,7 @@ Lemma le_entroPN_logeEX' : Proof. move/Rle_lt_or_eq_dec:le_1_EX=>[lt_EX_1| eq_E_0]; last first. rewrite -eq_E_0 /Rminus Rplus_opp_r mul0R Ropp_0 addR0 mul1R /log Log_1. - by move/esym/entroPN_0 : eq_E_0 ->; exact: leRR. + by move/esym/entroPN_0 : eq_E_0 ->. have lt_0_EX_1 : 0 < `E X - 1 by rewrite subR_gt0. pose alp := (`E X - 1) / `E X . have gt_alp_1 : alp < 1. @@ -373,7 +389,8 @@ rewrite EX_ord -big_pow1; last exact/eqP/ltR_eqF. rewrite mulRC (big_morph _ (morph_mulRDl _) (mul0R _)). rewrite -(@leR_add2r (\sum_(i < Nmax.+1) i%:R * `Pr[ X = i%:R ] * log alp)). rewrite -addRA (_ : - _ + _ = 0) ?addR0; last first. - by rewrite addRC addR_opp subR_eq0; apply eq_bigr => i _; rewrite ffunE. + rewrite addRC addR_opp subR_eq0; apply eq_bigr => i _; rewrite ffunE. + by rewrite -INRE. rewrite (@eq_bigr _ _ _ 'I_Nmax.+1 _ _ _ (fun i => `Pr[ X = i%:R ] * log (alp ^ i)))=>[|i _]; last first. by rewrite log_pow // [in RHS]mulRC -mulRA (mulRC _ (log alp)) mulRA. rewrite /entropy addRC; move: oppRB; rewrite/Rminus; move<-. @@ -381,12 +398,18 @@ rewrite -(oppRK (log _)) leR_oppl oppRK big_morph_oppR -big_split /=. rewrite [X in _ <= X](_ : _ = \sum_(i < Nmax.+1) `Pr[ X = i%:R] * (log (`Pr[ X = i%:R ]) - log (alp ^ i))); last first. - by apply: eq_bigr => i _; rewrite ffunE addR_opp -mulRBr. + by apply: eq_bigr => i _; rewrite ffunE addR_opp -INRE -mulRBr. rewrite -sub0R -(mul1R (0 - _)). have pmf1' : \sum_(i < Nmax) `Pr[X = i.+1%:R] = 1. - rewrite -PN_sum1 /=. + rewrite (_ : 1 = 1%mcR)// -PN_sum1 /=. under [in RHS]eq_bigr do rewrite ffunE. - rewrite big_ord_recl -subR_eq subRR; apply/esym. + rewrite big_ord_recl. + rewrite -RplusE. + rewrite -subR_eq. + rewrite [LHS](_ : _ = 0); last first. + apply/eqP; rewrite GRing.subr_eq0; apply/eqP/eq_bigr => i _ /=. + by rewrite INRE. + apply/esym. rewrite /pr_eq; unlock. rewrite /Pr big1 // => i. rewrite inE; move/eqP => Xi_0. @@ -432,7 +455,7 @@ End le_entroPN_logeEX. Section v_scode_converse'_1tuple. -Variables (A : finType) (P : fdist A). +Variables (A : finType) (P : {fdist A}). Variable f : A -> seq bool. Local Notation "'Nmax'" := (Nmax f). Let X : {RV P -> R} := (INR \o size \o f). @@ -444,13 +467,13 @@ Definition Pf (i : seq bool) := if [ pick x | f x == i ] is Some x then P x else Lemma Rle0Pf i : 0 <= Pf i. Proof. rewrite /Pf. -case: pickP => [x _ | _ ]; [exact: FDist.ge0|exact: leRR]. +by case: pickP => [x _ | _ ]; [exact/RleP/FDist.ge0|]. Qed. Lemma pmf1_Pf : \sum_(m < Nmax.+1) \sum_(a in {: m.-tuple bool}) Pf a = 1. Proof. move: (uniq_dec_inj f_uniq) => f_inj. -rewrite -(FDist.f1 P). +rewrite (_ : 1 = 1%mcR)// -(FDist.f1 P). rewrite (partition_big (inordf (size \o f)) (fun i => i \in 'I_Nmax.+1)) //=. apply: eq_bigr => i _. rewrite (big_seq_tuple i f_inj (fdist_card_neq0 P)) /Pf=>[|x]. @@ -465,14 +488,15 @@ Qed. Definition Pf' (m : 'I_Nmax.+1) := [ffun a : m.-tuple bool => Pf a / (PN m)]. Lemma Rle0Pf' (m : 'I_Nmax.+1) : - PN m <> 0 -> [forall a : m.-tuple bool, 0 0 -> [forall a : m.-tuple bool, (0 <= Pf' m a)%mcR]. Proof. -move=> PNnon0; apply/forallP_leRP => a; rewrite /Pf'. +move=> PNnon0; apply/forallPP; first by move=> ?; exact/RleP. +move=> a; rewrite /Pf'. apply: (Rmult_le_reg_r (PN m)). move/eqP in PNnon0. - by apply/ltRP; rewrite lt0R PNnon0 ffunE; exact/leRP. + by apply/RltP; rewrite lt0r PNnon0 ffunE; exact/RleP. rewrite mul0R ffunE /Rdiv -mulRA -Rinv_l_sym // mulR1 /Pf. -by case: pickP => [? _ // | _ ]; exact: leRR. +by case: pickP. Qed. Lemma pmf1_Pf' m : PN m <> 0 -> \sum_(a in {: m.-tuple bool}) Pf' m a = 1. @@ -490,7 +514,7 @@ rewrite /Pr (eq_bigr (fun x => Pf (f x))) => [|a ain]; last first. case:pickP; first by move =>x /eqP/ f_inj ->. by move/(_ a); rewrite eqxx. rewrite (eq_bigl (fun x => size (f x) == m) _) => [|a]; last first. - rewrite inE /X /=. + rewrite inE /X /= -INRE. by apply/eqP/eqP => [/INR_eq | ->]. rewrite (big_seq_tuple m f_inj (fdist_card_neq0 P)) /Pf => [//|i0]. case: pickP => // ?; first by move/eqP <-; rewrite codom_f. @@ -536,9 +560,13 @@ rewrite (eq_bigl (fun m => m \in [set : 'I_Nmax.+1]) _) => [|?]; last first. rewrite rsum_disjoints_set [Y in Y + _ = _]big1 ?add0R; last first. move=> /= i; rewrite inE. rewrite /pr_eq; unlock. - rewrite /Pr ffunE /= => /eqP/psumR_eq0P => H. + rewrite /Pr ffunE /= => /eqP/psumr_eq0P => H. have {}H : forall j : A, j \in [set x | (size (f x))%:R == i%:R] -> P j = 0. - by apply: H => ? ?; exact: FDist.ge0. + move=> a Ha. + apply: H => //. + rewrite inE/=. + rewrite inE in Ha. + by rewrite (eqP Ha) INRE. rewrite big1 // => i0 _. rewrite {1}/Pf. case: pickP => [a /eqP fai0|]; last by rewrite mul0R. @@ -558,10 +586,10 @@ rewrite {2}/PN. rewrite [in X in _ = _ * (_ * / X)]/= [in X in _ = _ * (_ * / X)]ffunE. rewrite mulRV ?mulR1; last by rewrite /PN /= ffunE in Pr_non0. rewrite /log LogM; last 2 first. - apply/ltRP; rewrite lt0R eq_sym Pfi0_non0; apply/leRP. - rewrite /Pf; case:pickP=>[? _ | ? ]; [exact: FDist.ge0 | exact/leRR]. - by apply/invR_gt0; rewrite -fdist_gt0. -rewrite LogV; last by rewrite -fdist_gt0. + apply/RltP; rewrite lt0r eq_sym Pfi0_non0; apply/RleP. + rewrite /Pf; case:pickP=>[? _ | ? ]; [exact/RleP/FDist.ge0 | by []]. + by apply/invR_gt0/RltP; rewrite -fdist_gt0. +rewrite LogV; last by apply/RltP; rewrite -fdist_gt0. by rewrite /PN /= ffunE -addRA Rplus_opp_l addR0. Qed. @@ -596,7 +624,13 @@ rewrite [Y in _ <= Y + _ ](_ :_ = 0). rewrite mulRC inE; move/eqP => H. apply/leR_wpmul2r; first by rewrite /PN /= ffunE. pose pmf_Pf' := mkNNFinfun (Rle0Pf' H). - have pmf1'_Pf' : \sum_(a in {: i.-tuple bool}) pmf_Pf' a == 1 :> R. + have pmf1'_Pf' : ([forall a, (0 <= pmf_Pf' a)%mcR] && ((\sum_(a in {: i.-tuple bool}) pmf_Pf' a)%mcR == 1%mcR)). + apply/andP; split. + apply/forallP => x. + rewrite /pmf_Pf'/= /Pf'; rewrite ffunE. + apply/RleP/divR_ge0 => //. + exact: Rle0Pf. + by apply/RltP/fdist_gt0/eqP. by apply/eqP; apply: (pmf1_Pf' H). pose distPf := FDist.mk pmf1'_Pf'. move: (entropy_max distPf). @@ -619,7 +653,7 @@ Section v_scode_converse'_ntuple. Variables (A : finType) (n : nat). Variable f : encT A (seq bool) n. -Variable P : fdist A. +Variable P : {fdist A}. Hypothesis f_uniq : uniquely_decodable f. Lemma converse_case1 : @E_leng_cw _ _ P f < n%:R * log #|A|%:R -> @@ -645,7 +679,7 @@ Section Extend_encoder. Variables (A : finType) (n m : nat). Variable f : encT A (seq bool) n. -Variable P : fdist A. +Variable P : {fdist A}. Hypothesis f_uniq : uniquely_decodable f. Hypothesis m_non0 : 0 <> m%:R. Let fm (x : 'rV['rV[A]_n]_m) := extension f (tuple_of_row x). @@ -721,7 +755,7 @@ End Extend_encoder. Section v_scode_converse'. -Variables (A : finType) (P : fdist A). +Variables (A : finType) (P : {fdist A}). Variable n : nat. Variable f : encT A (seq bool) n. Hypothesis f_uniq : uniquely_decodable f. @@ -768,7 +802,8 @@ have le_1_alp : 1 <= alp. rewrite mulR1; apply: (@leR_trans 2); last exact: leR2e. by rewrite (_ : 1 = 1%:R) // (_ : 2 = 2%:R) // leR_nat. rewrite card_mx -natRexp mul1n log_pow //. - by rewrite (_ : 0 = INR 0) //; apply/lt_INR/ltP/fdist_card_neq0. + rewrite (_ : 0 = INR 0) //; apply/lt_INR/ltP/fdist_card_neq0. + exact: P. have alppos : 0 < alp by exact: (@ltR_leR_trans 1). have Ypos : 0 < Y by apply/mulR_gt0 => //; apply/mulR_gt0. apply: (Rmult_le_reg_r (INR (m eps) * INR n)). @@ -816,7 +851,7 @@ apply: (@leR_trans (m'' eps)%:R); last exact/le_INR/leP/leq_maxr. apply: (@leR_trans (m''' eps)%:R); last exact/le_INR/leP/leq_maxl. rewrite INR_Zabs_nat. apply: (@leR_trans ((4 * / (INR n * eps * ln 2)))); last exact: proj1 (ceilP _). - by rewrite (mulRC n%:R); exact/leRR. + by rewrite (mulRC n%:R); apply/RleP; rewrite lexx. apply: le_IZR. apply: (@leR_trans ((4 * / (INR n * eps * ln 2)))); last exact: proj1 (ceilP _). apply: Rle_mult_inv_pos; first exact: ltRW (@mulR_gt0 2 2 _ _). @@ -856,7 +891,7 @@ rewrite mulRA (mulRC (exp 1)) -(mulRA (m eps)%:R). apply le_eps => //. move:case2. rewrite ELC_TupleFDist mulRC (mulRC (m eps)%:R) card_mx mul1n -natRexp log_pow; last first. - by rewrite (_ : 0 = INR 0) //; apply/lt_INR/ltP/fdist_card_neq0. + by rewrite (_ : 0 = INR 0) //; apply/lt_INR/ltP/fdist_card_neq0; exact: P. move/(ltR_pmul2r (mpos eps nnon0)) => /ltRW. by apply: leR_trans; exact/le_1_EX. Qed. @@ -865,7 +900,7 @@ End v_scode_converse'. Section v_scode_converse. -Variables (A : finType) (P : fdist A) (n : nat). +Variables (A : finType) (P : {fdist A}) (n : nat). Variable f : encT A (seq bool) n. Hypothesis f_uniq : uniquely_decodable f. diff --git a/information_theory/source_coding_vl_direct.v b/information_theory/source_coding_vl_direct.v index 27757fea..f4ba05c3 100644 --- a/information_theory/source_coding_vl_direct.v +++ b/information_theory/source_coding_vl_direct.v @@ -1,9 +1,9 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg matrix. +From mathcomp Require Import all_ssreflect ssralg matrix. Require Import Reals Lra. From mathcomp Require Import Rstruct. -Require Import ssrR Reals_ext logb ssr_ext ssralg_ext bigop_ext. +Require Import ssrR Reals_ext realType_ext logb ssr_ext ssralg_ext bigop_ext. Require Import Rbigop fdist proba entropy aep typ_seq natbin source_code. (******************************************************************************) @@ -67,12 +67,12 @@ End R_lemma. Section Length. Variable (X : finType) (n' : nat). Let n := n'.+1. -Variable P : fdist X. +Variable P : {fdist X}. Variable epsilon : R. Hypothesis eps_pos : 0 < epsilon. Lemma fdist_support_LB : 1 <= INR #|X|. -Proof. by rewrite (_ : 1 = INR 1) //; exact/le_INR/leP/fdist_card_neq0. Qed. +Proof. rewrite (_ : 1 = INR 1) //; apply/le_INR/leP/fdist_card_neq0; exact: P. Qed. Lemma fdist_supp_lg_add_1_neq_0 : 1 + log (INR #|X|) <> 0. Proof. @@ -133,7 +133,7 @@ End Length. Section Enc_Dec. Variable (X : finType) (n' : nat). Let n := n'.+1. -Variable P : fdist X. +Variable P : {fdist X}. Variable epsilon : R. Hypothesis eps_pos : 0 < epsilon. @@ -222,7 +222,7 @@ Section E_Leng_Cw_Lemma. Variables (X : finType). Variable (n' : nat). Let n := n'.+1. -Variable P : fdist X. +Variable P : {fdist X}. Variable epsilon : R. Hypothesis eps_pos : 0 < epsilon. Hypothesis aepbound_UB : aep_bound P epsilon <= INR n. @@ -263,11 +263,12 @@ rewrite (rsum_split _ (`TS P n'.+1 epsilon)). rewrite eq_sizef_Lnt eq_sizef_Lt -!(big_morph _ (morph_mulRDl _) (mul0R _)) mulRC. rewrite (_ : \sum_(i | i \in ~: `TS P n epsilon) P `^ n i = 1 - \sum_(i | i \in `TS P n epsilon) P `^ n i); last first. -- by rewrite -(FDist.f1 P`^n) (rsum_split _ (`TS P n epsilon)) addRC addRK. +- by rewrite (_ : 1 = 1%mcR)// -(FDist.f1 P`^n) (rsum_split _ (`TS P n epsilon)) addRC addRK. - apply leR_add. + rewrite -[X in _ <= X]mulR1; apply: leR_wpmul2l => //. * by apply: addR_ge0 => //; exact/ltRW/Lt_pos. - * by rewrite -(FDist.f1 (P `^ n)); apply: leR_sumRl => // *; exact/leRR. + * rewrite (_ : 1 = 1%mcR)// -(FDist.f1 (P `^ n)); apply: leR_sumRl => // *. + by apply/RleP; rewrite Order.POrderTheory.lexx. + apply: leR_wpmul2r => //. * by apply addR_ge0 => //; exact (Lnt_nonneg _ P). * by rewrite leR_subl_addr addRC -leR_subl_addr; exact: Pr_TS_1. @@ -278,7 +279,7 @@ End E_Leng_Cw_Lemma. Section v_scode. Variable (X : finType) (n' : nat). Let n := n'.+1. -Variable P : fdist X. +Variable P : {fdist X}. Variable epsilon : R. Hypothesis eps_pos : 0 < epsilon . Definition epsilon':= epsilon / (3 + (3 * log (INR #|X|))). @@ -367,7 +368,7 @@ apply: (Rle_lt_trans _ (INR n'.+1 * (`H P + epsilon') + 1 + 1 + + by apply: Rplus_le_compat; [apply: ltRW; apply: (proj2 (ceilP _)) | apply: Rle_refl]. + apply: Rmult_le_compat_l; first by apply: Rlt_le; apply: eps'_pos. by apply: Rplus_le_compat; [apply: ltRW; apply: (proj2 (ceilP _)) | apply: Rle_refl]. -- rewrite cardsT card_tuple log_pow_INR; last exact: fdist_card_neq0. +- rewrite cardsT card_tuple log_pow_INR; last by apply: fdist_card_neq0; exact: P. rewrite -addRA -addRA -addRA addRC addRA addRC addRA -(Rinv_r_simpl_l (INR n) (1 + 1)); last first. by apply/eqP; rewrite INR_eq0'. rewrite (mulRC 2 _) -{1}mulRA -mulRDr -mulRA -mulRDr (mulRC epsilon' _) -mulRA. @@ -405,7 +406,7 @@ End v_scode. Section variable_length_source_coding. -Variables (X : finType) (P : fdist X). +Variables (X : finType) (P : {fdist X}). Variable epsilon : R. Hypothesis eps_pos : 0 < epsilon . Local Notation "'n0'" := (n0 P epsilon). diff --git a/information_theory/string_entropy.v b/information_theory/string_entropy.v index 795b54c3..020b624e 100644 --- a/information_theory/string_entropy.v +++ b/information_theory/string_entropy.v @@ -1,10 +1,10 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg matrix. +From mathcomp Require Import all_ssreflect ssralg ssrnum. Require Import Reals. From mathcomp Require Import Rstruct. -Require Import ssrR Reals_ext ssr_ext ssralg_ext logb Rbigop. -Require Import fdist entropy convex ln_facts jensen num_occ. +Require Import ssrR Reals_ext Rstruct_ext realType_ext ssr_ext ssralg_ext logb. +Require Import Rbigop fdist entropy convex ln_facts jensen num_occ. (******************************************************************************) (* String entropy *) @@ -28,9 +28,11 @@ Local Open Scope num_occ_scope. Local Open Scope entropy_scope. Local Coercion INR : nat >-> R. +Import Num.Theory. + Definition simplR := (add0R, addR0, subR0, mul0R, mulR0, mul1R, mulR1). -Local Hint Resolve leRR : core. +Local Hint Resolve Rle_refl : core. Local Hint Resolve leR0n : core. Section seq_nat_fdist. @@ -42,9 +44,9 @@ Hypothesis total_gt0 : total != O. Let f_div_total := [ffun a : A => f a / total]. -Lemma f_div_total_pos c : 0 <= f_div_total c. +Lemma f_div_total_pos c : (0 <= f_div_total c)%mcR. Proof. -rewrite ffunE; apply mulR_ge0 => //. +rewrite ffunE; apply/RleP/mulR_ge0 => //. apply /Rlt_le /invR_gt0 /ltR0n. by rewrite lt0n. Qed. @@ -190,7 +192,7 @@ apply (@leR_trans ((\sum_(i <- ss') N(a|i))%:R * have Htotal := esym (num_occ_flatten a ss'). rewrite big_tnth in Htotal. have Hnum2 : N(a|flatten ss') != O. - rewrite -lt0n -ltR0n'; exact/ltRP. + rewrite -lt0n; exact/ltR0n. set d := seq_nat_fdist Htotal Hnum2. set r := fun i => (size (tnth (in_tuple ss') i)) @@ -263,8 +265,8 @@ Definition hoH (k : nat) := / n%:R * Lemma hoH_decr (k : nat) : hoH k.+1 <= hoH k. Proof. -rewrite /hoH; apply/leRP; rewrite leR_pmul2l'; last first. - by apply/ltRP/invR_gt0/ltRP; rewrite ltR0n' lt0n. +rewrite /hoH; apply/RleP; rewrite ler_pM2l//; last first. + by rewrite INRE RinvE' invr_gt0// ltr0n lt0n. (* TODO *) Abort. diff --git a/information_theory/success_decode_bound.v b/information_theory/success_decode_bound.v index 84bd400b..e1c37d0f 100644 --- a/information_theory/success_decode_bound.v +++ b/information_theory/success_decode_bound.v @@ -1,9 +1,9 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg matrix. +From mathcomp Require Import all_ssreflect ssralg ssrnum matrix. Require Import Reals. From mathcomp Require Import Rstruct. -Require Import ssrR Reals_ext ssr_ext ssralg_ext logb Rbigop fdist entropy. +Require Import ssrR Rstruct_ext Reals_ext ssr_ext ssralg_ext logb Rbigop fdist entropy. Require Import ln_facts num_occ types jtypes divergence conditional_divergence. Require Import entropy channel_code channel. @@ -40,6 +40,8 @@ Local Open Scope types_scope. Local Open Scope divergence_scope. Local Open Scope set_scope. +Import Order.POrderTheory Num.Theory. + Section typed_success_decomp_sect. Variables A B M : finType. @@ -116,9 +118,12 @@ Hypothesis Vctyp : V \in \nu^{B}(P). Lemma success_factor_bound_part1 : success_factor tc V <= 1. Proof. -apply/leRP; rewrite -(leR_pmul2l' #|M|%:R) ?ltR0n' //; apply/leRP. -rewrite /success_factor /Rdiv -(mulRC (/ #|M|%:R)) 2!mulRA. -rewrite mulRV ?INR_eq0' -?lt0n // mul1R. +apply/RleP; rewrite -(@ler_pM2l _ #|M|%:R)//; last by rewrite ltr0n. +apply/RleP. +rewrite /success_factor /Rdiv -(mulRC (/ #|M|%:R)%coqR) -!RmultE 2!mulRA. +rewrite INRE mulRV; last first. + by rewrite -INRE INR_eq0' -?lt0n. +rewrite mul1R -INRE. rewrite -iter_addR -big_const /=. rewrite (_ : \sum_(m | m \in M ) 1 = \sum_(m : M) 1); last exact/eq_bigl. rewrite big_distrr /=. @@ -183,7 +188,9 @@ Proof. rewrite /success_factor -mulRA (mulRC (/ #|M|%:R)) !mulRA. apply leR_wpmul2r; first exact/invR_ge0/ltR0n. rewrite /mutual_info_chan -addR_opp addRC addRA. -rewrite (_ : - `H(P , V) + `H P = - `H( V | P )); last by rewrite /cond_entropy_chan; field. +rewrite (_ : - `H(type.d P , V) + `H P = - `H( V | P )); last first. + rewrite /cond_entropy_chan. + by rewrite oppRD oppRK. rewrite mulRDr mulRN -mulNR /exp2 ExpD; apply leR_wpmul2l => //. rewrite -big_morph_natRD; apply (@leR_trans #| T_{`tO( V )} |%:R); last first. by rewrite -output_type_out_entropy //; exact: card_typed_tuples. @@ -271,16 +278,16 @@ apply (@leR_trans ( \sum_(V|V \in \nu^{B}(P)) exp_cdiv P V W * exp2 (- n%:R * +| log #|M|%:R * / n%:R - `I(P, V) |))). apply: leR_sumR => V Vnu. rewrite -mulRA; apply leR_wpmul2l. - by rewrite /exp_cdiv; case : ifP => _ //; exact/leRR. + by rewrite /exp_cdiv; case : ifP. by rewrite /success_factor mulRA; exact: success_factor_ub. apply (@leR_trans (\sum_(V | V \in \nu^{B}(P)) exp_cdiv P Vmax W * exp2 (- n%:R * +| log #|M|%:R * / n%:R - `I(P, Vmax)|))). apply leR_sumR => V HV. - by move/leRP: (@arg_rmax2 [finType of (P_ n (A, B))] V0 + by move/RleP: (@arg_rmax2 [finType of (P_ n (A, B))] V0 (fun V => exp_cdiv P V W * success_factor_bound M V P) V). rewrite big_const iter_addR /success_factor_bound; apply leR_wpmul2r. - apply mulR_ge0; last exact/exp2_ge0. - by rewrite /exp_cdiv; case: ifP => _ //; exact/leRR. + by rewrite /exp_cdiv; case: ifP. - by rewrite natRexp; exact/le_INR/leP/card_nu. Qed. @@ -318,7 +325,7 @@ apply (@leR_trans (\sum_(P : P_ n ( A )) scha W (P.-typed_code c))); last first. \sum_(P : P_ n ( A )) scha W (Pmax.-typed_code c)); last first. by rewrite big_const iter_addR. apply leR_sumR => P _. - by move/leRP : (arg_rmax2 P0 (fun P1 : P_ n (A) => scha(W, P1.-typed_code c)) P). + by move/RleP : (arg_rmax2 P0 (fun P1 : P_ n (A) => scha(W, P1.-typed_code c)) P). rewrite schaE // -(sum_messages_types c). rewrite div1R (big_morph _ (morph_mulRDr _) (mulR0 _)). apply leR_sumR => P _. @@ -327,11 +334,12 @@ rewrite schaE // div1R -mulRA mulRCA mulVR ?INR_eq0' -?lt0n // mulR1. apply/(@leR_trans (\sum_(m | m \in enc_pre_img c P) \sum_(y | (dec (P.-typed_code c)) y == Some m) (W ``(|(enc (P.-typed_code c)) m)) y)). - apply leR_sumR => m Hm. - apply Req_le, eq_big => tb // _. + apply: leR_sumR => m Hm. + apply/Req_le/eq_big => tb // _. rewrite inE in Hm. by rewrite /tcode /= ffunE Hm. -- by apply leR_sumRl => //= i ?; [exact/leRR | exact: sumR_ge0]. +- apply leR_sumRl => //= i ?; [| exact: sumR_ge0]. + by apply/RleP; rewrite lexx. Qed. End success_bound_sect. diff --git a/information_theory/typ_seq.v b/information_theory/typ_seq.v index e1a3aabb..c151f6a1 100644 --- a/information_theory/typ_seq.v +++ b/information_theory/typ_seq.v @@ -1,9 +1,9 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg matrix. +From mathcomp Require Import all_ssreflect ssralg ssrnum matrix. Require Import Reals Lra. From mathcomp Require Import Rstruct. -Require Import ssrR Reals_ext logb Rbigop. +Require Import ssrR Reals_ext realType_ext logb Rbigop. Require Import fdist proba entropy aep. (******************************************************************************) @@ -40,12 +40,14 @@ Local Open Scope fdist_scope. Local Open Scope proba_scope. Local Open Scope entropy_scope. +Import Order.TTheory GRing.Theory Num.Theory. + Section typical_sequence_definition. -Variables (A : finType) (P : fdist A) (n : nat) (epsilon : R). +Variables (A : finType) (P : {fdist A}) (n : nat) (epsilon : R). Definition typ_seq (t : 'rV[A]_n) := - exp2 (- n%:R * (`H P + epsilon)) forall r, 1 <= r -> +Lemma set_typ_seq_incl (A : finType) (P : {fdist A}) n epsilon : 0 <= epsilon -> forall r, 1 <= r -> `TS P n (epsilon / 3) \subset `TS P n epsilon. Proof. move=> e0 r r1. apply/subsetP => /= x. -rewrite !inE /typ_seq => /andP[/leRP H2 /leRP H3] [:Htmp]. -apply/andP; split; apply/leRP. +rewrite !inE /typ_seq => /andP[/RleP H2 /RleP H3] [:Htmp]. +apply/andP; split; apply/RleP. - apply/(leR_trans _ H2)/Exp_le_increasing => //. rewrite !mulNR leR_oppr oppRK; apply leR_wpmul2l; first exact/leR0n. apply/leR_add2l. @@ -74,44 +76,51 @@ Qed. Section typ_seq_prop. -Variables (A : finType) (P : fdist A) (epsilon : R) (n : nat). +Variables (A : finType) (P : {fdist A}) (epsilon : R) (n : nat). Lemma TS_sup : #| `TS P n epsilon |%:R <= exp2 (n%:R * (`H P + epsilon)). Proof. suff Htmp : #| `TS P n epsilon |%:R * exp2 (- n%:R * (`H P + epsilon)) <= 1. by rewrite -(mulR1 (exp2 _)) mulRC -leR_pdivr_mulr // /Rdiv -exp2_Ropp -mulNR. -rewrite -(FDist.f1 (P `^ n)). +rewrite (_ : 1 = 1%mcR)// -(FDist.f1 (P `^ n)). rewrite (_ : _ * _ = \sum_(x in `TS P n epsilon) (exp2 (- n%:R * (`H P + epsilon)))); last first. by rewrite big_const iter_addR. -by apply/leR_sumRl => //= i; rewrite inE; case/andP => /leRP. +by apply/leR_sumRl => //= i; rewrite inE; case/andP => /RleP. Qed. Lemma typ_seq_definition_equiv x : x \in `TS P n epsilon -> exp2 (- n%:R * (`H P + epsilon)) <= P `^ n x <= exp2 (- n%:R * (`H P - epsilon)). -Proof. by rewrite inE /typ_seq => /andP[? ?]; split; apply/leRP. Qed. +Proof. by rewrite inE /typ_seq => /andP[? ?]; split; apply/RleP. Qed. Lemma typ_seq_definition_equiv2 x : x \in `TS P n.+1 epsilon -> `H P - epsilon <= - (1 / n.+1%:R) * log (P `^ n.+1 x) <= `H P + epsilon. Proof. rewrite inE /typ_seq. case/andP => H1 H2; split; - apply/leRP; rewrite -(leR_pmul2l' n.+1%:R) ?ltR0n' //; - rewrite div1R mulRA mulRN mulRV ?INR_eq0' // mulN1R; apply/leRP. -- rewrite leR_oppr. + apply/RleP; rewrite -(@ler_pM2r _ n.+1%:R) ?ltr0n//. +- rewrite div1R -[in leRHS]RmultE mulRAC mulNR INRE mulVR; last first. + by rewrite mulrn_eq0/= oner_eq0. + rewrite mulN1R; apply/RleP. + rewrite leR_oppr. apply/(@Exp_le_inv 2) => //. - rewrite LogK //; last by apply/(ltR_leR_trans (exp2_gt0 _)); apply/leRP: H1. - apply/leRP; by rewrite -mulNR. -- rewrite leR_oppl. + rewrite LogK //; last by apply/(ltR_leR_trans (exp2_gt0 _)); apply/RleP: H1. + rewrite mulrC -mulNR -INRE. + exact/RleP. +- rewrite div1R -[in leLHS]RmultE mulRAC mulNR INRE mulVR; last first. + by rewrite mulrn_eq0/= oner_eq0. + rewrite mulN1R; apply/RleP. + rewrite leR_oppl. apply/(@Exp_le_inv 2) => //. - rewrite LogK //; last by apply/(ltR_leR_trans (exp2_gt0 _)); apply/leRP: H1. - apply/leRP; by rewrite -mulNR. + rewrite LogK //; last by apply/(ltR_leR_trans (exp2_gt0 _)); apply/RleP: H1. + rewrite mulrC -mulNR -INRE. + exact/RleP. Qed. End typ_seq_prop. Section typ_seq_more_prop. -Variables (A : finType) (P : fdist A) (epsilon : R) (n : nat). +Variables (A : finType) (P : {fdist A}) (epsilon : R) (n : nat). Hypothesis He : 0 < epsilon. @@ -120,66 +129,83 @@ Lemma Pr_TS_1 : aep_bound P epsilon <= n.+1%:R -> Proof. move=> k0_k. have -> : Pr P `^ n.+1 (`TS P n.+1 epsilon) = - Pr P `^ n.+1 [set i | (i \in `TS P n.+1 epsilon) && (0 /= t; rewrite !inE. apply/idP/andP => [H|]; [split => // | by case]. - case/andP : H => /leRP H _; exact/ltRP/(ltR_leR_trans (exp2_gt0 _) H). + case/andP : H => /RleP H _; exact/RltP/(ltR_leR_trans (exp2_gt0 _) H). set p := [set _ | _]. rewrite Pr_to_cplt leR_add2l leR_oppl oppRK. have -> : Pr P `^ n.+1 (~: p) = Pr P `^ n.+1 [set x | P `^ n.+1 x == 0] + - Pr P `^ n.+1 [set x | (0 b epsilon)]. + Pr P `^ n.+1 [set x | (0 < P `^ n.+1 x)%mcR && + (`| - (1 / n.+1%:R) * log (P `^ n.+1 x) - `H P | > epsilon)%mcR]. have -> : ~: p = [set x | P `^ n.+1 x == 0 ] :|: - [set x | (0 b epsilon)]. + [set x | (0 < P `^ n.+1 x)%mcR && + (`| - (1 / n.+1%:R) * log (P `^ n.+1 x) - `H P | > epsilon)%mcR]. apply/setP => /= i; rewrite !inE negb_and orbC. - apply/idP/idP => [/orP[/ltRP|]|]. - - by rewrite -fdist_gt0 => /negP; rewrite negbK => ->. + apply/idP/idP => [/orP[/RltP|]|]. + - move/RltP => H. + have {}H : P `^ n.+1 i = 0. + apply/eqP. + apply/negPn. + apply: contra H. + by have [+ _] := fdist_gt0 (P `^ n.+1) i. + by rewrite H eqxx. - rewrite /typ_seq negb_and => /orP[|] LHS. - + case/boolP : (P `^ n.+1 i == 0) => /= H1; first by []. - have {}H1 : 0 < P `^ n.+1 i. - apply/ltRP; rewrite ltR_neqAle' eq_sym H1; exact/leRP. - apply/andP; split; first exact/ltRP. - move: LHS; rewrite -ltRNge' => /ltRP/(@Log_increasing 2 _ _ Rlt_1_2 H1). + + have [//|H1] := eqVneq (P `^ n.+1 i) 0. + have {}H1 : 0 < P `^ n.+1 i by apply/RltP; rewrite lt0r H1/=. + apply/andP; split; first exact/RltP. + move/RleP: LHS => /ltRNge/(@Log_increasing 2 _ _ Rlt_1_2 H1). rewrite /exp2 ExpK // mulRC mulRN -mulNR -ltR_pdivr_mulr; last exact/ltR0n. - rewrite /Rdiv mulRC ltR_oppr => /ltRP; rewrite mulNR -ltR_subRL' => LHS. - rewrite mul1R geR0_norm //; by move/ltRP : LHS; move/(ltR_trans He)/ltRW. - + move: LHS; rewrite leRNgt' negbK => /ltRP LHS. - apply/orP; right; apply/andP; split; first exact/ltRP/(ltR_trans (exp2_gt0 _) LHS). + rewrite /Rdiv mulRC ltR_oppr => /RltP; rewrite -ltrBrDl => LHS. + rewrite div1r// mulNr -RinvE//; last by rewrite gt_eqF// ltr0n. + rewrite ger0_norm// -INRE//. + by move/RltP : LHS; move/(ltR_trans He)/ltRW/RleP. + + move: LHS; rewrite leNgt negbK => LHS. + apply/orP; right; apply/andP; split. + exact/(lt_trans _ LHS)/RltP/exp2_gt0. + move/RltP in LHS. move/(@Log_increasing 2 _ _ Rlt_1_2 (exp2_gt0 _)) : LHS. rewrite /exp2 ExpK // mulRC mulRN -mulNR -ltR_pdivl_mulr; last exact/ltR0n. rewrite oppRD oppRK => LHS. have H2 : forall a b c, - a + b < c -> - c - a < - b by move=> *; lra. move/H2 in LHS. - rewrite div1R mulRC mulRN -/(Rdiv _ _) leR0_norm. - * apply/ltRP; by rewrite ltR_oppr. - * apply: (leR_trans (ltRW LHS)); lra. + rewrite div1r mulrC mulrN ler0_norm//. + * rewrite ltrNr//; apply/RltP; rewrite -RminusE -RoppE. + by rewrite -RdivE ?gt_eqF// ?ltr0n// -INRE. + * apply/RleP; rewrite -RminusE -RoppE. + rewrite -RdivE ?gt_eqF// ?ltr0n// -INRE//. + apply: (leR_trans (ltRW LHS)). + by apply/RleP; rewrite lerNl oppr0// ltW//; apply/RltP. - rewrite -negb_and; apply: contraTN. - rewrite negb_or /typ_seq => /andP[H1 /andP[/leRP H2 /leRP H3]]. - apply/andP; split; first exact/gtR_eqF/ltRP. - rewrite negb_and H1 /= -leRNgt'. + rewrite negb_or /typ_seq => /andP[H1 /andP[/RleP H2 /RleP H3]]. + apply/andP; split; first exact/gtR_eqF/RltP. + rewrite negb_and H1 /= -leNgt. move/(@Log_increasing_le 2 _ _ Rlt_1_2 (exp2_gt0 _)) : H2. rewrite /exp2 ExpK // mulRC mulRN -mulNR -leR_pdivl_mulr ?oppRD; last exact/ltR0n. move => H2. have /(_ _ _ _ H2) {}H2 : forall a b c, - a + - b <= c -> - c - a <= b. by move=> *; lra. - move/ltRP in H1. + move/RltP in H1. move/(@Log_increasing_le 2 _ _ Rlt_1_2 H1) : H3. rewrite /exp2 ExpK //. rewrite mulRC mulRN -mulNR -leR_pdivr_mulr; last exact/ltR0n. - rewrite oppRD oppRK div1R mulRC mulRN => H3. + rewrite oppRD oppRK div1r mulrC mulrN => H3. have /(_ _ _ _ H3) {}H3 : forall a b c, a <= - c + b -> - b <= - a - c. by move=> *; lra. - rewrite leR_Rabsl; apply/andP; split; exact/leRP. + by rewrite ler_norml; apply/andP; split; + apply/RleP; rewrite -RminusE -RoppE; + rewrite -RdivE ?gt_eqF// ?ltr0n// -INRE//. rewrite Pr_union_disj // disjoints_subset; apply/subsetP => /= i. - rewrite !inE /= => /eqP Hi; by rewrite negb_and Hi ltRR'. + by rewrite !inE /= => /eqP Hi; rewrite negb_and Hi ltxx. rewrite {1}/Pr (eq_bigr (fun=> 0)); last by move=> /= v; rewrite inE => /eqP. rewrite big_const iter_addR mulR0 add0R. apply/(leR_trans _ (aep He k0_k))/Pr_incl/subsetP => /= t. -rewrite !inE /= => /andP[-> /= H3]; apply/ltRW'. -by rewrite /log_RV /= /scalel_RV /= mulRN -mulNR. +rewrite !inE /= => /andP[-> H3]. +rewrite /log_RV /= /scalel_RV /= mulRN -mulNR. +apply/ltW. +by rewrite RmultE RoppE// RdivE ?gt_eqF ?INRE ?ltr0n. Qed. Variable He1 : epsilon < 1. @@ -211,13 +237,19 @@ Lemma TS_inf : aep_bound P epsilon <= n.+1%:R -> (1 - epsilon) * exp2 (n.+1%:R * (`H P - epsilon)) <= #| `TS P n.+1 epsilon |%:R. Proof. move=> k0_k. -have H1 : 1 - epsilon <= Pr (P `^ n.+1) (`TS P n.+1 epsilon) <= 1. - split; by [apply Pr_TS_1 | apply Pr_1]. +have H1 : (1 - epsilon <= Pr (P `^ n.+1) (`TS P n.+1 epsilon) <= 1)%mcR. + by apply/andP; split; apply/RleP; [exact: Pr_TS_1 | exact: Pr_1]. have H2 : (forall x, x \in `TS P n.+1 epsilon -> - exp2 (- n.+1%:R * (`H P + epsilon)) <= P `^ n.+1 x <= exp2 (- n.+1%:R * (`H P - epsilon))). - by move=> x; rewrite inE /typ_seq => /andP[/leRP ? /leRP]. -move: (wolfowitz (exp2_gt0 _) (exp2_gt0 _) H1 H2). -by rewrite mulNR exp2_Ropp {1}/Rdiv invRK ?gtR_eqF //; case. + exp2 (- n.+1%:R * (`H P + epsilon)) <= + P `^ n.+1 x <= exp2 (- n.+1%:R * (`H P - epsilon)))%mcR. + by move=> x; rewrite inE /typ_seq => /andP[-> ->]. +have /RltP H3 := exp2_gt0 (- n.+1%:R * (`H P + epsilon)). +have /RltP H5 := exp2_gt0 (- n.+1%:R * (`H P - epsilon)). +have := wolfowitz H3 H5 H1 H2. +rewrite mulNR exp2_Ropp. +rewrite RinvE ?gtR_eqF// invrK => /andP[] /RleP. +by rewrite -!RmultE -RminusE -INRE. +(* TODO: clean *) Qed. End typ_seq_more_prop. diff --git a/information_theory/types.v b/information_theory/types.v index 451d9eb0..4cd545af 100644 --- a/information_theory/types.v +++ b/information_theory/types.v @@ -1,11 +1,11 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg perm zmodp. +From mathcomp Require Import all_ssreflect ssralg ssrnum perm. From mathcomp Require Import matrix. From mathcomp Require boolp. From mathcomp Require Import Rstruct. Require Import Reals. -Require Import ssrR Reals_ext ssr_ext ssralg_ext logb Rbigop. +Require Import ssrR Reals_ext realType_ext ssr_ext ssralg_ext logb Rbigop. Require Import fdist proba entropy num_occ channel_code channel typ_seq. (******************************************************************************) @@ -35,6 +35,7 @@ Import Prenex Implicits. Local Open Scope entropy_scope. Local Open Scope num_occ_scope. Local Open Scope R_scope. +Local Open Scope fdist_scope. Module type. @@ -44,7 +45,7 @@ Variable A : finType. Variable n : nat. Record type : predArgType := mkType { - d :> fdist A ; + d :> {fdist A} ; f : {ffun A -> 'I_n.+1} ; d_f : forall a, d a = INR (f a) / INR n }. @@ -52,7 +53,8 @@ End type_def. End type. -Coercion type_coercion := type.d. +Definition type_coercion := type.d. +Coercion type_coercion : type.type >-> fdist_of. Notation "'P_' n '(' A ')'" := (type.type A n) : types_scope. @@ -61,18 +63,19 @@ Local Open Scope types_scope. Definition ffun_of_type A n (P : P_ n ( A )) := let: type.mkType _ f _ := P in f. Lemma type_fun_type A n (_ : n != O) (P : P_ n ( A )) a : - ((type.f P) a)%:R = n%:R * P a. + ((type.f P) a)%:R = n%:R * type.d P a. Proof. case: P => /= d f d_f; by rewrite d_f mulRCA mulRV ?INR_eq0' // mulR1. Qed. -Lemma INR_type_fun A n (P : P_ n ( A )) a : ((type.f P) a)%:R / n%:R = P a. +Lemma INR_type_fun A n (P : P_ n ( A )) a : ((type.f P) a)%:R / n%:R = type.d(*TODO: fix coercion *)P a. Proof. destruct P as [d f d_f] => /=. by rewrite d_f. Qed. -Lemma no_0_type A (d : fdist A) (t : {ffun A -> 'I_1}) : +Lemma no_0_type (A : finType) (d : {fdist A}) (t : {ffun A -> 'I_1}) : (forall a, d a = (t a)%:R / 0%:R) -> False. Proof. move=> H; apply R1_neq_R0. +rewrite (_ : 1 = 1%mcR)//. rewrite -(FDist.f1 d). transitivity (\sum_(a | a \in A) INR (t a) / 0); first exact/eq_bigr. rewrite -big_distrl /= -big_morph_natRD. @@ -83,8 +86,8 @@ Qed. Definition type_of_tuple (A : finType) n (ta : n.+1.-tuple A) : P_ n.+1 ( A ). set f := [ffun a => N(a | ta)%:R / n.+1%:R]. -assert (H1 : forall a, (0 <= f a)%R). - move=> a; rewrite ffunE; apply divR_ge0; by [apply leR0n | apply ltR0n]. +assert (H1 : forall a, (0%mcR <= f a)%mcR). + move=> a; rewrite ffunE; apply/RleP/divR_ge0; by [apply leR0n | apply ltR0n]. have H2 : \sum_(a in A) f a = 1%R. under eq_bigr do rewrite ffunE /=. by rewrite -big_distrl /= -big_morph_natRD sum_num_occ_alt mulRV // INR_eq0'. @@ -121,7 +124,7 @@ Definition type_eqMixin A n := EqMixin (@type_eqP A n). Canonical type_eqType A n := Eval hnf in EqType _ (@type_eqMixin A n). Lemma type_ffunP A n (P Q : P_ n.+1 ( A )) : - (forall c, P c = Q c) -> P = Q. + (forall c, type.d P c = type.d Q c) -> P = Q. Proof. move=> H. destruct P as [d1 f1 H1]. @@ -134,20 +137,25 @@ move: {H}(H a); rewrite H1 H2 eqR_mul2r //. apply/invR_neq0; by rewrite INR_eq0. Qed. -Definition nneg_fun_of_ffun (A : finType) n (f : {ffun A -> 'I_n.+2}) : nneg_finfun A. -set d := [ffun a : A => INR (f a) / INR n.+1]. -refine (@mkNNFinfun _ d _); apply/forallP_leRP => a. -by rewrite ffunE; apply divR_ge0; [apply leR0n | apply ltR0n]. -Defined. - Definition fdist_of_ffun (A : finType) n (f : {ffun A -> 'I_n.+2}) - (Hf : (\sum_(a in A) f a)%nat == n.+1) : fdist A. -set pf := nneg_fun_of_ffun f. -have H : \sum_(a in A) pf a == 1 :> R. + (Hf : (\sum_(a in A) f a)%nat == n.+1) : {fdist A}. +set pf := [ffun a : A => INR (f a) / INR n.+1]. +have H : (\sum_(a in A) pf a)%mcR = 1 :> R. rewrite /pf; under eq_bigr do rewrite ffunE /=. rewrite /Rdiv -big_distrl /= -big_morph_natRD. - by move/eqP : Hf => ->; rewrite mulRV // INR_eq0'. -exact:(FDist.mk H). + move/eqP : Hf => ->. + rewrite -RmultE. + by rewrite mulRV// INR_eq0'. +apply: (FDist.make _ H). +move=> a. +apply/RleP. +rewrite /pf/= ffunE; apply: divR_ge0 => //. + apply/RleP. + rewrite INRE. + by rewrite Num.Theory.ler0n. +apply/RltP. +rewrite INRE. +by rewrite Num.Theory.ltr0n. Defined. Lemma fdist_of_ffun_prop (A : finType) n (f : {ffun A -> 'I_n.+2}) @@ -163,7 +171,7 @@ refine (match Sumbool.sumbool_of_bool (\sum_(a in A) f a == n.+1)%nat with end). Defined. -Lemma ffun_of_fdist A n (d : fdist A) (t : {ffun A -> 'I_n.+2}) +Lemma ffun_of_fdist (A : finType) n (d : {fdist A}) (t : {ffun A -> 'I_n.+2}) (H : forall a : A, d a = INR (t a) / INR n.+1) : (\sum_(a in A) t a)%nat == n.+1. Proof. suff : INR (\sum_(a in A) t a) == INR n.+1 * \sum_(a | a \in A) d a. @@ -312,7 +320,7 @@ Variables (A : finType) (n : nat) (P : P_ n ( A )). Local Open Scope nat_scope. Definition typed_tuples := - [set t : n.-tuple A | [forall a, P a == (INR N(a | t) / INR n)%R] ]. + [set t : n.-tuple A | [forall a, type.d P a == (INR N(a | t) / INR n)%R] ]. End typed_tuples. @@ -389,12 +397,12 @@ Local Open Scope tuple_ext_scope. Local Open Scope vec_ext_scope. Lemma tuple_dist_type t : tuple_of_row t \in T_{P} -> - P `^ n t = \prod_(a : A) P a ^ (type.f P a). + (type.d P) `^ n t = \prod_(a : A) type.d P a ^ (type.f P a). Proof. move=> Hx. rewrite fdist_rVE. -rewrite (_ : \prod_(i < n) P (t ``_ i) = - \prod_(a : A) (\prod_(i < n) (if a == t ``_ i then P t ``_ i else 1))); last first. +rewrite (_ : \prod_(i < n) type.d P (t ``_ i) = + \prod_(a : A) (\prod_(i < n) (if a == t ``_ i then type.d P t ``_ i else 1))); last first. rewrite exchange_big; apply eq_big ; first by []. move=> i _. rewrite (bigID (fun y => y == t ``_ i)) /=. @@ -420,16 +428,18 @@ Qed. Local Close Scope tuple_ext_scope. Lemma tuple_dist_type_entropy t : tuple_of_row t \in T_{P} -> - P `^ n t = exp2 (- INR n * `H P). + (type.d P) `^ n t = exp2 (- INR n * `H P). Proof. move/(@tuple_dist_type t) => ->. -rewrite (_ : \prod_(a : A) P a ^ (type.f P) a = - \prod_(a : A) exp2 (P a * log (P a) * INR n)); last first. +rewrite (_ : \prod_(a : A) type.d P a ^ (type.f P) a = + \prod_(a : A) exp2 (type.d P a * log (type.d P a) * INR n)); last first. apply eq_bigr => a _. - case/boolP : (0 == P a) => H; last first. - have {}H : 0 < P a. - have := FDist.ge0 P a. + case/boolP : (0 == type.d P a) => H; last first. + have {}H : 0 < type.d P a. + have := FDist.ge0 (type.d P) a. + move/RleP. case/Rle_lt_or_eq_dec => // abs. + rewrite (_ : 0%mcR = 0)// in abs. by rewrite abs eqxx in H. rewrite -{1}(logK H) -exp2_pow. congr exp2. @@ -448,13 +458,15 @@ Qed. Local Open Scope typ_seq_scope. +Import Order.POrderTheory. + Lemma typed_tuples_are_typ_seq : (@row_of_tuple A n @: T_{ P }) \subset `TS P n 0. Proof. apply/subsetP => t Ht. rewrite /set_typ_seq inE /typ_seq tuple_dist_type_entropy; last first. case/imsetP : Ht => x Hx ->. by rewrite row_of_tupleK. -by rewrite addR0 subR0 !leRR'. +by rewrite addR0 subR0 lexx. Qed. Lemma card_typed_tuples : INR #| T_{ P } | <= exp2 (INR n * `H P). @@ -466,7 +478,7 @@ case/boolP : [exists x, x \in T_{P}] => x_T_P. - case/existsP : x_T_P => ta Hta. rewrite -(row_of_tupleK ta) in Hta. rewrite -(tuple_dist_type_entropy Hta). - rewrite [X in X <= _](_ : _ = Pr P `^ n (@row_of_tuple A n @: T_{P})). + rewrite [X in X <= _](_ : _ = Pr (type.d P) `^ n (@row_of_tuple A n @: T_{P})). by apply Pr_1. symmetry. rewrite /Pr. @@ -491,7 +503,8 @@ apply (@leR_trans (INR #| `TS P n 0 |)). apply: leq_trans; last first. by apply subset_leq_card; exact: typed_tuples_are_typ_seq. by rewrite card_imset //; exact: row_of_tuple_inj. -by apply: (leR_trans (TS_sup _ _ _)); rewrite addR0; exact/leRR. +apply: (leR_trans (TS_sup _ _ _)); rewrite addR0. +by apply/RleP; rewrite Order.POrderTheory.lexx. Qed. Lemma perm_tuple_in_Ttuples ta (s : 'S_n) : @@ -512,7 +525,7 @@ Definition enc_pre_img (P : P_ n ( A )) := [set m | tuple_of_row (enc c m) \in T Lemma enc_pre_img_injective (P Q : P_ n ( A )) : enc_pre_img P != set0 -> enc_pre_img P = enc_pre_img Q -> - forall a, P a = Q a. + forall a, type.d P a = type.d Q a. Proof. rewrite /enc_pre_img. case/set0Pn => m. @@ -582,7 +595,7 @@ Lemma sum_messages_types' f : \sum_ (S | S \in enc_pre_img_partition c) \sum_(m in S) f m. Proof. rewrite (bigID (fun P => [exists m, m \in enc_pre_img c P] )). -rewrite (_ : forall a b, addR_comoid a b = a + b) //. +rewrite (_ : forall a b, Radd_comoid a b = a + b) //. rewrite Rplus_comm big1 ; last first. move=> P ; rewrite andTb negb_exists => HP. apply big_pred0 => m /=. diff --git a/lib/Rbigop.v b/lib/Rbigop.v index 93b88c9a..3eb2f943 100644 --- a/lib/Rbigop.v +++ b/lib/Rbigop.v @@ -1,6 +1,6 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg matrix. +From mathcomp Require Import all_ssreflect ssralg ssrnum matrix. From mathcomp Require Import Rstruct. Require Import Reals Lra. Require Import ssrR Reals_ext logb ssr_ext ssralg_ext. @@ -117,16 +117,11 @@ Set Implicit Arguments. Unset Strict Implicit. Import Prenex Implicits. +Import Order.POrderTheory GRing.Theory Num.Theory. + Local Open Scope R_scope. Local Open Scope reals_ext_scope. -Canonical addR_monoid := Monoid.Law addRA add0R addR0. -Canonical addR_comoid := Monoid.ComLaw addRC. -Canonical mulR_monoid := Monoid.Law mulRA mul1R mulR1. -Canonical mulR_muloid := Monoid.MulLaw mul0R mulR0. -Canonical mulR_comoid := Monoid.ComLaw mulRC. -Canonical addR_addoid := Monoid.AddLaw mulRDl mulRDr. - Lemma morph_oppR : {morph [eta Ropp] : x y / x + y}. Proof. by move=> x y /=; field. Qed. @@ -160,12 +155,10 @@ Lemma sumR_ord_setT (n : nat) (f : 'I_n -> R) : \sum_(i < n) f i = \sum_(i in [set: 'I_n]) f i. Proof. by apply eq_bigl => i; rewrite inE. Qed. +(* TODO: rm? *) Lemma sumR_ge0 (A : eqType) (d : seq A) (P : pred A) f (H : forall i, P i -> 0 <= f i) : 0 <= \sum_(i <- d | P i) f i. -Proof. -elim: d => [|h t IH]; first by rewrite big_nil; exact/leRR. -rewrite big_cons; case: ifPn => // Ph; apply/addR_ge0 => //; exact: H. -Qed. +Proof. by apply/RleP/sumr_ge0 => i Pi; exact/RleP/H. Qed. Lemma sumR_neq0 (U : eqType) (P : U -> R) (s : seq.seq U) : (forall i, 0 <= P i) -> @@ -191,40 +184,18 @@ apply/nesym/eqP/sumR_neq0; last by move/card_gt0P : HA => [a _]; exists a. by move=> a; apply/ltRW/f0. Qed. -Lemma psumR_seq_eq0P (A : eqType) (l : seq A) f : - uniq l -> - (forall a, a \in l -> 0 <= f a) -> - \sum_(a <- l) f a = 0 <-> (forall a, a \in l -> f a = 0). -Proof. -move=> ul Hf; split=> [H a al|h]; last first. - by rewrite (eq_big_seq (fun=> 0)) ?big1. -suff : f a = 0 /\ \sum_(i <- l|i != a) f i = 0 by case. -apply: Rplus_eq_R0. -- exact/Hf. -- by rewrite big_seq_cond; apply: sumR_ge0 => ? /andP[? ?]; apply Hf. -- by rewrite -bigD1_seq. -Qed. - -Lemma psumR_eq0P (A : finType) (P : pred A) f : - (forall a, P a -> 0 <= f a) -> - \sum_(a | P a) f a = 0 <-> (forall a, P a -> f a = 0). -Proof. -move=> Hf; split=> [H a Ha|h]; last first. - by rewrite (eq_bigr (fun=> 0)) // big_const iter_addR mulR0. -suff : f a = 0 /\ \sum_(i | P i && (i != a)) f i = 0 by case. -apply: Rplus_eq_R0. -- exact/Hf/Ha. -- apply: sumR_ge0 => ? /andP[? ?]; by apply Hf. -- rewrite -bigD1 /=; [exact H | exact Ha]. -Qed. - Section leR_ltR_sumR. Variable A : Type. Implicit Types (f g : A -> R) (P Q : pred A). Lemma leR_sumR r P f g : (forall i, P i -> f i <= g i) -> \sum_(i <- r | P i) f i <= \sum_(i <- r | P i) g i. -Proof. move=> leE12. elim/big_ind2: _ => // m1 m2 n1 n2. lra. Qed. +Proof. +move=> leE12. +elim/big_ind2: _ => //. + exact: Rle_refl. +by move=> m1 m2 n1 n2; lra. +Qed. End leR_ltR_sumR. @@ -235,7 +206,9 @@ Lemma leR_sumR_support (X : {set A}) : (forall i, i \in X -> P i -> f i <= g i) -> \sum_(i in X | P i) f i <= \sum_(i in X | P i) g i. Proof. -move=> H; elim/big_rec2 : _ => // a x y /andP[aX Pa] yx. +move=> H; elim/big_rec2 : _ => //. + exact: Rle_refl. +move=> a x y /andP[aX Pa] yx. by apply leR_add => //; apply: H. Qed. @@ -244,7 +217,8 @@ Lemma leR_sumRl : (forall i, P i -> f i <= g i) -> \sum_(i | P i) f i <= \sum_(i | Q i) g i. Proof. move=> f_g Qg H; elim: (index_enum _) => [| h t IH]. -- by rewrite !big_nil; exact/leRR. +- rewrite !big_nil. + by apply/RleP; rewrite lexx. - rewrite !big_cons /=; case: ifP => [Ph|Ph]. by rewrite (H _ Ph); apply leR_add => //; exact: f_g. case: ifP => // Qh; apply: (leR_trans IH). @@ -256,7 +230,7 @@ Lemma leR_sumRl_support (U : pred A) : \sum_(i in U | P i) f i <= \sum_(i in U | Q i) f i. Proof. move=> Hf P_Q; elim: (index_enum _) => [|h t IH]. -- by rewrite !big_nil; exact/leRR. +- by rewrite !big_nil; apply/RleP; rewrite lexx. - rewrite !big_cons; case: (h \in U) => //=; case: ifP => // Ph. + by case: ifP => [Qh|]; [rewrite leR_add2l | rewrite (P_Q _ Ph)]. + by case: ifP => // Qh; rewrite -[X in X <= _]add0R; exact/leR_add. @@ -295,7 +269,7 @@ End leR_ltR_sumR_finType. Lemma leR_sumR_Rabs (A : finType) f : `| \sum_a f a | <= \sum_(a : A) `| f a |. Proof. elim: (index_enum _) => [|h t IH]. - rewrite 2!big_nil Rabs_R0; exact/leRR. + by rewrite 2!big_nil Rabs_R0. rewrite 2!big_cons. apply (@leR_trans (`| f h | + `| \sum_(j <- t) f j |)); [exact/Rabs_triang |exact/leR_add2l]. @@ -348,9 +322,9 @@ Lemma leR_sumR_eq (A : finType) (f g : A -> R) (P : pred A) : \sum_(a | P a) g a = \sum_(a | P a) f a -> (forall a, P a -> g a = f a). Proof. -move=> H1 H2 i Hi; rewrite -subR_eq0; move: i Hi; apply psumR_eq0P. -- move=> i Hi; rewrite leR_subr_addr add0R; exact: H1. -- by rewrite big_split /= -big_morph_oppR subR_eq0 H2. +move=> H1 H2 i Hi; rewrite -subR_eq0; move: i Hi; apply: psumr_eq0P. + by move=> i Pi; rewrite RminusE subr_ge0; apply/RleP/H1. +by rewrite big_split/= -big_morph_oppR; apply/eqP; rewrite subr_eq0 H2. Qed. Section pascal. @@ -375,10 +349,6 @@ End pascal. Section leR_ltR_rprod. -Lemma prodR_gt0 (A : finType) F : (forall a, 0 < F a) -> - 0 < \prod_(a : A) F a. -Proof. by move=> F0; elim/big_ind : _ => // x y ? ?; exact: mulR_gt0. Qed. - Lemma prodR_ge0 (A : finType) F : (forall a, 0 <= F a) -> 0 <= \prod_(a : A) F a. Proof. by move=> F0; elim/big_ind : _ => // x y ? ?; exact: mulR_ge0. Qed. @@ -397,7 +367,8 @@ Qed. Lemma prodR_ge1 (A : finType) f : (forall a, 1 <= f a) -> 1 <= \prod_(a : A) f a. Proof. -elim/big_ind : _ => // [|x y Hx Hy *]; first by move=> _; exact/leRR. +elim/big_ind : _ => // [|x y Hx Hy *]. + by move=> _; apply/RleP; rewrite lexx. by rewrite -{1}(mulR1 1); apply/leR_pmul => //; [exact: Hx | exact: Hy]. Qed. @@ -419,9 +390,9 @@ Qed. Local Open Scope vec_ext_scope. Local Open Scope ring_scope. -Lemma prodR_gt0_inv (B : finType) F (HF: forall a, 0 <= F a) : +Lemma prodR_gt0_inv (B : finType) F (HF: forall a, (0 <= F a)%coqR) : forall n (x : 'rV[B]_n.+1), - 0 < \prod_(i < n.+1) F (x ``_ i) -> forall i, 0 < F (x ``_ i). + (0 < \prod_(i < n.+1) F (x ``_ i) -> forall i, 0 < F (x ``_ i))%coqR. Proof. elim => [x | n IH]. rewrite big_ord_recr /= big_ord0 mul1R => Hi i. @@ -435,7 +406,7 @@ move: (HF (x ``_ ord0)); rewrite leR_eqVlt => -[<-|H]. rewrite mulRC (pmulR_lgt0 H) => H'. case; case => [i0|i Hi]. rewrite (_ : Ordinal _ = ord0) //; exact/val_inj. -have : 0 < \prod_(i0 < n.+1) F (t ``_ i0). +have : (0 < \prod_(i0 < n.+1) F (t ``_ i0))%coqR. suff : (\prod_(i < n.+1) F (x ``_ (lift ord0 i)) = \prod_(i < n.+1) F (t ``_ i))%R by move=> <-. apply eq_bigr => ? _; by rewrite mxE. @@ -458,9 +429,9 @@ have [/forallP Hf|] := boolP [forall i, f i != 0%R]; last first. rewrite (bigD1 i0) //= fi0 mul0R; apply prodR_ge0. by move=> i ; move: (fg i) => [Hi1 Hi2]; exact: (leR_trans Hi1 Hi2). have Hprodf : 0 < \prod_(i : A) f i. - apply prodR_gt0 => a. + apply/RltP. apply prodr_gt0 => a _. apply/RltP. move: (Hf a) (fg a) => {}Hf {fg}[Hf2 _]. - apply/ltRP; rewrite lt0R Hf /=; exact/leRP. + by apply/RltP; rewrite lt0r Hf/=; exact/RleP. apply (@leR_pmul2r (1 * / \prod_(i : A) f i) _ _). apply divR_gt0 => //; lra. rewrite mul1R mulRV; last exact/gtR_eqF. @@ -486,7 +457,7 @@ move/negbTE in Hf; rewrite Hf; move/negbT in Hf. rewrite -(mulRV (f a)) //. apply leR_wpmul2r => //. rewrite -(mul1R (/ f a)). -apply divR_ge0; [lra | apply/ltRP; rewrite lt0R Hf; exact/leRP]. +by apply divR_ge0; [lra |by apply/RltP; rewrite lt0r Hf; exact/RleP]. Qed. End leR_ltR_rprod. @@ -494,18 +465,21 @@ End leR_ltR_rprod. Local Open Scope vec_ext_scope. Local Open Scope ring_scope. -Lemma log_prodR_sumR_mlog {A : finType} k (f : A ->R+) : forall n (ta : 'rV[A]_n.+1), - (forall i, 0 < f ta ``_ i) -> +Lemma log_prodR_sumR_mlog {A : finType} k (f : A -> R) : + (forall a, 0 <= f a)%coqR -> + forall n (ta : 'rV[A]_n.+1), + (forall i, 0 < f ta ``_ i)%coqR -> (- Log k (\prod_(i < n.+1) f ta ``_ i) = \sum_(i < n.+1) - Log k (f ta ``_ i))%R. Proof. +move=> f0. elim => [i Hi | n IH]. by rewrite big_ord_recl big_ord0 mulR1 big_ord_recl big_ord0 addR0. move=> ta Hi. rewrite big_ord_recl /= LogM; last 2 first. exact/Hi. - by apply prodR_gt0 => ?; exact/Hi. + by apply/RltP; apply prodr_gt0 => ? _; exact/RltP/Hi. set tl := \row_(i < n.+1) ta ``_ (lift ord0 i). -have : forall i0 : 'I_n.+1, 0 < f tl ``_ i0. +have : forall i0 : 'I_n.+1, (0 < f tl ``_ i0)%coqR. move=> i; rewrite mxE; exact/Hi. move/IH => {}IH. have -> : (\prod_(i < n.+1) f ta ``_ (lift ord0 i) = \prod_(i < n.+1) f tl ``_ i)%R. @@ -532,7 +506,7 @@ Qed. Lemma bigmaxR_ge0 : (forall r, r \in s -> 0 <= F r) -> 0 <= \rmax_(m <- s) (F m). Proof. case: s => [_ | hd tl Hr]. -- rewrite big_nil; exact/leRR. +- by rewrite big_nil. - apply (@leR_trans (F hd)); last by rewrite big_cons; exact: leR_maxl. apply Hr; by rewrite in_cons eqxx. Qed. diff --git a/lib/Reals_ext.v b/lib/Reals_ext.v index 8f8c0380..afd95b3b 100644 --- a/lib/Reals_ext.v +++ b/lib/Reals_ext.v @@ -1,10 +1,12 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) From mathcomp Require Import all_ssreflect. +From mathcomp Require Import all_algebra vector reals normedtype. +From mathcomp Require Import mathcomp_extra boolp. From mathcomp Require Import Rstruct. -From mathcomp Require boolp. +Require Import ssrR realType_ext. Require Import Reals Lra. -Require Import ssrR. +From mathcomp Require Import lra. (******************************************************************************) (* Additional lemmas and definitions about Coq reals *) @@ -12,7 +14,6 @@ Require Import ssrR. (* Section reals_ext. *) (* various lemmas about up, Int_part, frac_part, Rabs define ceil and floor *) (* *) -(* T ->R+ == finite functions that return non-negative reals. *) (* T ->R^+ == functions that return non-negative reals. *) (* *) (* p.~ == 1 - p *) @@ -32,16 +33,12 @@ Require Import ssrR. (******************************************************************************) Declare Scope reals_ext_scope. +Delimit Scope R_scope with coqR. Reserved Notation "T '->R^+' " (at level 10, format "'[' T ->R^+ ']'"). -Reserved Notation "T '->R+' " (at level 10, format "'[' T ->R+ ']'"). Reserved Notation "+| r |" (at level 0, r at level 99, format "+| r |"). Reserved Notation "P '`<<' Q" (at level 51). Reserved Notation "P '`< + solve [exact/RleP/onem_ge0] : core. + Local Open Scope R_scope. Local Open Scope reals_ext_scope. -Lemma Rlt_1_2 : 1 < 2. Proof. lra. Qed. +Lemma Rlt_1_2 : 1 < 2. Proof. Lra.lra. Qed. Global Hint Resolve Rlt_1_2 : core. Section reals_ext. -Lemma forallP_leRP (A : finType) (f : A -> R) : reflect (forall a, 0 <= f a) [forall a, 0 [/forallP H a|H]; [exact/leRP/H|apply/forallP => a; exact/leRP]. -Qed. - Lemma iter_mulR x (n : nat) : ssrnat.iter n (Rmult x) 1 = x ^ n. Proof. elim : n => // n Hn ; by rewrite iterS Hn. Qed. -Lemma iter_addR x (n : nat) : ssrnat.iter n (Rplus x) 0 = INR n * x. -Proof. -elim : n ; first by rewrite mul0R. -move=> n Hn; by rewrite iterS Hn -{1}(mul1R x) -mulRDl addRC -S_INR. -Qed. +Lemma iter_addR x (n : nat) : ssrnat.iter n (Rplus x) 0 = n%:R * x. +Proof. by rewrite iter_addr addr0 -mulr_natr mulrC RmultE INRE. Qed. (* TODO: see Rplus_lt_reg_pos_r in the standard library *) (*Lemma Rplus_le_lt_reg_pos_r r1 r2 r3 : 0 < r2 -> r1 + r2 <= r3 -> r1 < r3. @@ -116,16 +110,10 @@ Proof. field. Qed. Lemma x_x2_max q : q * (1 - q) <= / 4. Proof. rewrite x_x2_eq. -have : forall a b, 0 <= b -> a - b <= a. move=> *; lra. -apply; apply mulR_ge0; [lra | exact: pow_even_ge0]. +have : forall a b, 0 <= b -> a - b <= a. move=> *; Lra.lra. +apply; apply mulR_ge0; [Lra.lra | exact: pow_even_ge0]. Qed. -(*Lemma pow0_inv : forall (n : nat) x, x ^ n = 0 -> x = 0. -Proof. -elim => [x /= H | n IH x /= /eqP]; first lra. -by rewrite mulR_eq0 => /orP[/eqP //|/eqP/IH]. -Qed.*) - End about_the_pow_function. Lemma up_pos r : 0 <= r -> (0 < up r)%Z. @@ -143,20 +131,20 @@ rewrite Z.abs_eq; last first. apply up_pos in Hr. by apply Z.lt_le_incl. case: (base_Int_part r). -rewrite /Int_part minus_IZR => _ ?; lra. +rewrite /Int_part minus_IZR => _ ?; Lra.lra. Qed. Lemma Rle_up a : a <= IZR (Z.abs (up a)). Proof. case: (Rlt_le_dec a 0) => Ha; last by apply Rle_up_pos. -apply (@leR_trans 0); first lra. +apply (@leR_trans 0); first Lra.lra. exact/IZR_le/Zabs_pos. Qed. Lemma up_Int_part r : (up r = Int_part r + 1)%Z. Proof. case: (base_Int_part r) => H1 H2. -rewrite -(up_tech r (Int_part r)) // plus_IZR //; lra. +rewrite -(up_tech r (Int_part r)) // plus_IZR //; Lra.lra. Qed. Lemma Int_part_ge0 a : 0 <= a -> (0 <= Int_part a)%Z. @@ -168,10 +156,11 @@ Qed. Lemma frac_part_INR m : frac_part (INR m) = 0. Proof. rewrite /frac_part /Int_part -(up_tech _ (Z_of_nat m)). -rewrite minus_IZR plus_IZR /= -INR_IZR_INZ; by field. -rewrite -INR_IZR_INZ; exact/leRR. -rewrite {1}INR_IZR_INZ; apply IZR_lt. -by apply Z.lt_add_pos_r. +- by rewrite minus_IZR plus_IZR /= -INR_IZR_INZ; by field. +- rewrite -INR_IZR_INZ. + by apply/RleP; rewrite Order.POrderTheory.lexx. +- rewrite {1}INR_IZR_INZ; apply IZR_lt. + by apply Z.lt_add_pos_r. Qed. Lemma frac_Int_part x : frac_part x = 0 -> IZR (Int_part x) = x. @@ -205,11 +194,11 @@ rewrite -(tech_up _ ((up a - 1) * (up b - 1) + 1)). rewrite ?plus_IZR ?minus_IZR ?mult_IZR ?minus_IZR // Ha Hb. rewrite (_ : forall a, a + 1 - 1 = a); last by move=> *; field. rewrite (_ : forall a, a + 1 - 1 = a); last by move=> *; field. - lra. + Lra.lra. rewrite ?plus_IZR ?minus_IZR ?mult_IZR ?minus_IZR // Ha Hb. rewrite (_ : forall a, a + 1 - 1 = a); last by move=> *; field. rewrite (_ : forall a, a + 1 - 1 = a); last by move=> *; field. - exact/leRR. + by apply/RleP; rewrite Order.POrderTheory.lexx. Qed. Lemma frac_part_pow a : frac_part a = 0 -> forall n : nat, frac_part (a ^ n) = 0. @@ -224,34 +213,20 @@ Definition ceil (r : R) : Z := if frac_part r == 0 then Int_part r else up r. Definition floor : R -> Z := Int_part. Lemma floorP (r : R) : r - 1 < IZR (floor r) <= r. -Proof. rewrite /floor; case: (base_Int_part r) => ? ?; split=> //; lra. Qed. +Proof. rewrite /floor; case: (base_Int_part r) => ? ?; split=> //; Lra.lra. Qed. Lemma ceilP (r : R) : r <= IZR (ceil r) < r + 1. Proof. rewrite /ceil; case: ifPn => [|] /eqP r0. - rewrite frac_Int_part //; lra. + rewrite frac_Int_part //; Lra.lra. case: (floorP r); rewrite /floor => H1 /Rle_lt_or_eq_dec[] H2. - rewrite up_Int_part plus_IZR; lra. + rewrite up_Int_part plus_IZR; Lra.lra. by exfalso; apply/r0; rewrite subR_eq0. Qed. Lemma leR0ceil x : 0 <= x -> (0 <= ceil x)%Z. Proof. move=> ?; case: (ceilP x) => K _; exact/le_IZR/(leR_trans _ K). Qed. -Lemma ltR_Rabsl a b : `| a | [/ltRP/Rabs_def2[? ?]|/ltR2P[? ?]]; first exact/ltR2P. -exact/ltRP/Rabs_def1. -Qed. - -Lemma leR_Rabsl a b : `| a | [/leRP|]; last by move=> /leR2P[? ?]; exact/leRP/Rabs_le. -case: (Rlt_le_dec a 0) => h; [ - by rewrite ltR0_norm // => ?; apply/leR2P; lra | - by rewrite geR0_norm // => ?; apply/leR2P; lra ]. -Qed. - Lemma factE n0 : fact n0 = n0 `!. Proof. by elim: n0 => // n0 IH /=; rewrite IH factS mulSn -multE. Qed. @@ -272,11 +247,11 @@ Lemma normR_max a b c c' : 0 <= a <= c -> 0 <= b <= c' -> Proof. move=> [H1 H2] [H H3]; case: (Rtotal_order a b) => [H0|[H0|H0]]. - rewrite distRC gtR0_norm ?subR_gt0 //. - apply: (@leR_trans b); [lra | apply/(leR_trans H3)/leR_maxr; lra]. + apply: (@leR_trans b); [Lra.lra | apply/(leR_trans H3)/leR_maxr; lra]. - subst b; rewrite subRR normR0. exact/(leR_trans H1)/(leR_trans H2)/leR_maxl. -- rewrite geR0_norm; last lra. - apply: (@leR_trans a); [lra|exact/(leR_trans H2)/leR_maxl]. +- rewrite geR0_norm; last Lra.lra. + apply: (@leR_trans a); [Lra.lra|exact/(leR_trans H2)/leR_maxl]. Qed. End reals_ext. @@ -297,118 +272,108 @@ Variable (T : finType). Record nneg_finfun := mkNNFinfun { nneg_ff :> {ffun T -> R} ; - _ : [forall a, 0 R+' " := (nneg_finfun T) : reals_ext_scope. - -Lemma nneg_finfun_ge0 (T : finType) (f : T ->R+) : forall a, 0 <= f a. -Proof. by case: f => f /= /forallP H a; apply/leRP/H. Qed. - Record nneg_fun (T : Type) := mkNNFun { nneg_f :> T -> R ; nneg_f_ge0 : forall a, 0 <= nneg_f a }. Notation "T '->R^+' " := (nneg_fun T) : reals_ext_scope. -Lemma nneg_fun_eq {C : Type} (f g : C ->R^+) : nneg_f f = nneg_f g -> f = g. -Proof. -destruct f as [f Hf]. -destruct g as [g Hg]. -move=> /= ?; subst. -suff : Hf = Hg by move=> ->. -exact/boolp.Prop_irrelevance. -Qed. - Section onem. Implicit Types r s p q : R. -Definition onem r := 1 - r. -Local Notation "p '.~'" := (onem p). +Lemma onem0 : 0.~ = 1. Proof. by rewrite onem0. Qed. -Lemma onem0 : 0.~ = 1. Proof. by rewrite /onem subR0. Qed. +Lemma onem1 : 1.~ = 0. Proof. by rewrite onem1. Qed. -Lemma onem1 : 1.~ = 0. Proof. by rewrite /onem subRR. Qed. +Lemma onem_ge0 r : r <= 1 -> 0 <= r.~. +Proof. by move=> /RleP r1; apply/RleP/onem_ge0. Qed. -Lemma onem_ge0 r : r <= 1 -> 0 <= r.~. Proof. move=> ?; rewrite /onem; lra. Qed. +Lemma onem_le1 r : 0 <= r -> r.~ <= 1. +Proof. by move=> /RleP r0; apply/RleP/onem_le1. Qed. -Lemma onem_le1 r : 0 <= r -> r.~ <= 1. Proof. move=> ?; rewrite /onem; lra. Qed. +Lemma onem_le r s : r <= s <-> s.~ <= r.~. +Proof. +split. + by move=> /RleP rs; apply/RleP; rewrite -onem_le. +by move=> /RleP rs; apply/RleP; rewrite onem_le. +Qed. -Lemma onem_le r s : r <= s <-> s.~ <= r.~. -Proof. by rewrite /onem; split=> ?; lra. Qed. +Lemma onemE x : x.~ = 1 - x. Proof. by []. Qed. -Lemma onem_lt r s : r < s <-> s.~ < r.~. -Proof. by rewrite /onem; split=> ?; lra. Qed. +Lemma onem_lt r s : r < s <-> s.~ < r.~. Proof. by rewrite !onemE; Lra.lra. Qed. -Lemma onemKC r : r + r.~ = 1. Proof. rewrite /onem; by field. Qed. +Lemma onemKC r : r + r.~ = 1. Proof. by rewrite !onemE; Lra.lra. Qed. Lemma onemK r : r.~.~ = r. -Proof. by rewrite /onem subRBA addRC addRK. Qed. +Proof. by rewrite !onemE subRBA addRC addRK. Qed. Lemma onemD p q : (p + q).~ = p.~ + q.~ - 1. -Proof. rewrite /onem; field. Qed. +Proof. rewrite !onemE /GRing.add /=; Lra.lra. Qed. Lemma onemM p q : (p * q).~ = p.~ + q.~ - p.~ * q.~. -Proof. rewrite /onem; field. Qed. +Proof. rewrite !onemE /GRing.mul /=; Lra.lra. Qed. -Lemma onem_div p q : q != 0 -> (p / q).~ = (q - p) /q. -Proof. -by move=> Hq; rewrite /onem -(divRR q) // /Rdiv /Rminus -mulNR -mulRDl. -Qed. +Lemma onem_div p q : q != 0 -> (p / q)%coqR.~ = (q - p) / q. +Proof. by move=> q0; rewrite !onemE /Rdiv mulRDl mulNR -!divRE divRR. Qed. -Lemma onem_prob r : R0 R0 (R0 <= r.~ <= R1)%mcR. Proof. -by case/leR2P=> ? ?; apply/leR2P; split; - [rewrite leR_subr_addr add0R | rewrite leR_subl_addr -(addR0 1) leR_add2l]. +Proof. +by case/andP => /RleP ? /RleP ?; apply/andP; split; + [ apply/RleP; rewrite onemE leR_subr_addr add0R + | apply/RleP; rewrite onemE leR_subl_addr -(addR0 1) leR_add2l]. Qed. -Lemma onem_oprob r : R0 R0 (R0 < r.~ < R1)%mcR. Proof. -by case/ltR2P=> ? ?; apply/ltR2P; split; - [rewrite ltR_subr_addr add0R | rewrite ltR_subl_addr -(addR0 1) ltR_add2l]. +by case/andP=> /RltP ? /RltP ?; apply/andP; split; + [ apply/RltP; rewrite onemE ltR_subr_addr add0R + | apply/RltP; rewrite onemE ltR_subl_addr -(addR0 1) ltR_add2l]. Qed. -Lemma onem_eq0 r : r.~ = 0 <-> r = 1. Proof. rewrite /onem; lra. Qed. +Lemma onem_eq0 r : r.~ = 0 <-> r = 1. Proof. rewrite onemE; Lra.lra. Qed. -Lemma onem_eq1 r : r.~ = 1 <-> r = 0. Proof. rewrite /onem; lra. Qed. +Lemma onem_eq1 r : r.~ = 1 <-> r = 0. Proof. rewrite onemE; Lra.lra. Qed. Lemma onem_neq0 r : r.~ != 0 <-> r != 1. Proof. by split; apply: contra => /eqP/onem_eq0/eqP. Qed. -Lemma onem_gt0 r : r < 1 -> 0 < r.~. Proof. rewrite /onem; lra. Qed. +Lemma onem_gt0 r : r < 1 -> 0 < r.~. Proof. rewrite onemE; Lra.lra. Qed. -Lemma onem_lt1 r : 0 < r -> r.~ < 1. Proof. rewrite /onem; lra. Qed. +Lemma onem_lt1 r : 0 < r -> r.~ < 1. Proof. rewrite onemE; Lra.lra. Qed. Lemma subR_onem r s : r - s.~ = r + s - 1. -Proof. by rewrite /onem -addR_opp oppRB addRA. Qed. +Proof. by rewrite onemE -addR_opp oppRB addRA. Qed. End onem. +(*Definition Ronem (p: R) := (@onem real_realType p).*) +(*Notation "p '.~'" := (Ronem p) : reals_ext_scope.*) -Notation "p '.~'" := (onem p) : reals_ext_scope. +Module ProbR. +Definition mk_ (q : R) (Oq1 : 0 <= q <= 1) : {prob R}. +apply: (@Prob.mk _ q). +case: Oq1 => q0 q1. +apply/andP; split; exact/RleP. +Qed. (* TODO: shoud be cleaner *) +End ProbR. -Module Prob. -Record t := mk { - p :> R ; - Op1 : (0 -> R. +(*Definition prob := prob real_realType.*) +(*Definition prob_coercion : @prob [realType of R] -> R := @Prob.p real_realType. +Coercion prob_coercion : prob >-> R. -Lemma probpK p H : Prob.p (@Prob.mk p H) = p. Proof. by []. Qed. +#[global] Hint Extern 0 (Rle (IZR Z0) _) => + solve [apply/RleP/prob_ge0] : core. +#[global] Hint Extern 0 (Rle _ (IZR (Zpos xH))) => + solve [apply/RleP/prob_le1] : core.*) + +(*Lemma probpK p H : Prob.p (@Prob.mk p H) = p. Proof. by []. Qed. Lemma OO1 : R0 p /= /leR2P[]. Qed. -Global Hint Resolve prob_le1 : core. +Global Hint Resolve prob_le1 : core.*) + +(*Reserved Notation "{ 'prob' T }" (at level 0, format "{ 'prob' T }"). +Definition prob_of (R : realType) := fun phT : phant (Num.NumDomain.sort (*Real.sort*)R) => @prob R.*) + +Section ad_hoc_coercion_from_prob_to_R. +(* +Prob_p compensates a missing coercion from real_realType to R. +Without Prob_p, (p : {prob R}) fails to typecheck as (p : R) as follows: + +Variable p : {prob R}. +Check p. +Fail Check p : R. +Check Prob.p p. + +This problem may be solved by using HB in the definition of realType in mca, +and then Prob_p should be removed. + +Prob_p in a goal blocks uses of some lemmas and must be removed manually by +`rewrite Prob_pE`. +The notation `%:pp` is for indicating where a user should do this. +*) +Definition Prob_p : Prob.t (real_realType) -> R. +exact: Prob.p. +Defined. +Lemma Prob_pE p : Prob_p p = @Prob.p real_realType p. +Proof. by []. Qed. +End ad_hoc_coercion_from_prob_to_R. +Coercion Prob_p : prob >-> R. +Notation "p %:pp" := (Prob_p p) (at level 1, format "p %:pp"). + +Notation "{ 'prob' T }" := (@prob_of _ (Phant T)). +Definition probR_coercion (p : {prob R}) : R := Prob.p p. +Local Coercion probR_coercion : prob_of >-> R. + +Lemma probR_ge0 (p : {prob R}) : 0 <= p. Proof. exact/RleP/prob_ge0. Qed. +Lemma probR_le1 (p : {prob R}) : p <= 1. Proof. exact/RleP/prob_le1. Qed. +#[global] Hint Extern 0 (Rle (IZR Z0) _) => solve [exact/probR_ge0] : core. +#[global] Hint Extern 0 (Rle _ (IZR (Zpos xH))) => solve [exact/probR_le1] : core. Section prob_lemmas. -Implicit Types p q : prob. +Implicit Types p q : {prob R}. + +Canonical probR0 := Eval hnf in (@Prob.mk real_realType R0 (@OO1 _)). +Canonical probR1 := Eval hnf in (@Prob.mk real_realType R1 (@O11 _)). -Lemma prob_gt0 p : p != 0%:pr <-> 0 < p. +Lemma probR_gt0 p : p != 0%:pr <-> 0 < p. Proof. rewrite ltR_neqAle; split=> [H|[/eqP p0 _]]. split => //; exact/nesym/eqP. by case: p p0 => p ?; apply: contra => /eqP[/= ->]. Qed. -Lemma prob_gt0' p : p != 0 :> R <-> 0 < p. -Proof. exact: prob_gt0. Qed. +Lemma probR_gt0' p : p != 0 :> R <-> 0 < p. +Proof. exact: probR_gt0. Qed. -Lemma prob_lt1 p : p != 1%:pr <-> p < 1. +Lemma probR_lt1 p : p != 1%:pr <-> p < 1. Proof. rewrite ltR_neqAle; split=> [H|[/eqP p1 _]]. by split => //; exact/eqP. by case: p p1 => p ?; apply: contra => /eqP[/= ->]. Qed. -Lemma prob_lt1' p : p != 1 :> R <-> p < 1. -Proof. exact: prob_lt1. Qed. +Lemma probR_lt1' p : p != 1 :> R <-> p < 1. +Proof. exact: probR_lt1. Qed. -Lemma prob_trichotomy p : p = 0%:pr \/ p = 1%:pr \/ 0 < p < 1. +Lemma probR_trichotomy p : p = 0%:pr \/ p = 1%:pr \/ 0 < p < 1. Proof. have [/eqP ->|pneq0]:= boolP (p == 0%:pr); first by left. right. have [/eqP ->|pneq1] := boolP (p == 1%:pr); first by left. -by right; split; [apply prob_gt0 | apply prob_lt1]. +by right; split; [apply probR_gt0 | apply probR_lt1]. Qed. -Lemma probK p : p = (p.~).~%:pr. +Lemma probRK p : p = ((Prob.p p).~).~%:pr. Proof. by apply val_inj => /=; rewrite onemK. Qed. -Lemma probKC (p : prob) : p + p.~ = 1 :> R. -Proof. by rewrite onemKC. Qed. +Lemma probRKC (p : {prob R}) : p + (Prob.p p).~ = 1 :> R. +Proof. exact: onemKC. Qed. -Lemma probadd_eq0 p q : p + q = 0%:pr <-> p = 0%:pr /\ q = 0%:pr. +Lemma probadd_eq0 p q : p + q = 0 <-> p = 0%:pr /\ q = 0%:pr. Proof. split => [/paddR_eq0 | ]. -- by move=> /(_ _)[] // /val_inj-> /val_inj->. +- by move=> /(_ _)[] // p0 q0; split; exact/val_inj. - by case => -> ->; rewrite addR0. Qed. -Lemma probadd_neq0 p q : p + q != 0%:pr <-> p != 0%:pr \/ q != 0%:pr. +Lemma probadd_neq0 p q : p + q != 0 <-> p != 0%:pr \/ q != 0%:pr. Proof. split => [/paddR_neq0| ]; first by move=> /(_ _ _); apply. by case; apply: contra => /eqP/probadd_eq0 [] /eqP ? /eqP. Qed. -Lemma probmul_eq1 p q : p * q = 1%:pr <-> p = 1%:pr /\ q = 1%:pr. +Lemma probmul_eq1 p q : p * q = 1 <-> p = 1%:pr /\ q = 1%:pr. Proof. split => [/= pq1|[-> ->]]; last by rewrite mulR1. move: R1_neq_R0; rewrite -{1}pq1 => /eqP; rewrite mulR_neq0' => /andP[]. -rewrite 2!prob_gt0'=> p0 q0. -have /leR_eqVlt[p1|] := prob_le1 p; last first. +rewrite 2!probR_gt0'=> p0 q0. +have /leR_eqVlt[p1|] := probR_le1 p; last first. by move/(ltR_pmul2r q0); rewrite mul1R => /(ltR_leR_trans); - move/(_ _ (prob_le1 q))/ltR_neqAle => []. -have /leR_eqVlt[q1|] := prob_le1 q; last first. + move/(_ _ (probR_le1 q))/ltR_neqAle => []. +have /leR_eqVlt[q1|] := probR_le1 q; last first. by move/(ltR_pmul2r p0); rewrite mul1R mulRC => /(ltR_leR_trans); - move/(_ _ (prob_le1 p)) /ltR_neqAle => []. + move/(_ _ (probR_le1 p)) /ltR_neqAle => []. by split; apply val_inj. Qed. End prob_lemmas. -Lemma prob_IZR (p : positive) : R0 //. +split; first exact/Rlt_le/Rinv_0_lt_compat/IZR_lt/Pos2Z.is_pos. +rewrite -[X in (_ <= X)%coqR]Rinv_1; apply Rle_Rinv => //. - exact/IZR_lt/Pos2Z.is_pos. - exact/IZR_le/Pos2Z.pos_le_pos/Pos.le_1_l. Qed. -Canonical probIZR (p : positive) := Eval hnf in Prob.mk (prob_IZR p). +Lemma prob_IZR' (p : positive) : (0 <= / IZR (Zpos p) <= 1)%O. +Proof. +have [/RleP ? /RleP ?] := prob_IZR p. +exact/andP. +Qed. + +Canonical probIZR (p : positive) := Eval hnf in Prob.mk (prob_IZR' p). Definition divRnnm n m := INR n / INR (n + m). -Lemma prob_divRnnm n m : R0 |n0] := boolP (n == O); first by rewrite div0R; apply/leR2P/OO1. +rewrite /divRnnm. +have [/eqP ->|n0] := boolP (n == O). + rewrite div0R. + by have /andP[/RleP ? /RleP ?]:= (@OO1 real_realType). split; first by apply divR_ge0; [exact: leR0n | rewrite ltR0n addn_gt0 lt0n n0]. by rewrite leR_pdivr_mulr ?mul1R ?leR_nat ?leq_addr // ltR0n addn_gt0 lt0n n0. Qed. +Lemma prob_divRnnm' n m : (R0 <= divRnnm n m <= R1)%O. +Proof. +have [/RleP ? /RleP ?] := prob_divRnnm n m. exact/andP. +Qed. + Canonical probdivRnnm (n m : nat) := - Eval hnf in @Prob.mk (divRnnm n m) (prob_divRnnm n m). + Eval hnf in @Prob.mk _ (divRnnm n m) (prob_divRnnm' n m). -Lemma prob_invn (m : nat) : (R0 /RleP ->] := prob_divRnnm 1 m. Qed. Canonical probinvn (n : nat) := - Eval hnf in @Prob.mk (/ INR (1 + n)) (prob_invn n). + Eval hnf in @Prob.mk _ (/ INR (1 + n)) (prob_invn n). -Lemma prob_invp (p : prob) : (0 //; exact: addR_gt0wl. - rewrite leR_pdivr_mulr ?mul1R; last exact: addR_gt0wl. by rewrite addRC -leR_subl_addr subRR. Qed. -Definition Prob_invp (p : prob) := Prob.mk (prob_invp p). +Lemma prob_invp' (p : {prob R}) : (0 <= 1 / (1 + p) <= 1)%O. +Proof. +have [/RleP ? /RleP ?] := prob_invp p. exact/andP. +Qed. + +Definition Prob_invp (p : {prob R}) := Prob.mk (prob_invp' p). + +Lemma prob_mulR (p q : {prob R}) : (0 <= p * q <= 1)%coqR. +Proof. +by split; [exact/mulR_ge0 |rewrite -(mulR1 1%coqR); apply leR_pmul]. +Qed. -Lemma prob_mulR (p q : prob) : (0 prob ; - Op1 : (0 {prob R}; + Op1 : (0 -> prob. -Canonical oprobcplt (p : oprob) := Eval hnf in OProb.mk (onem_oprob (OProb.O1 p)). +Canonical oprobcplt (p : oprob) := Eval hnf in OProb.mk (onem_oprob (OProb.O1 p)). *) +Coercion OProb.p : oprob >-> prob_of. Section oprob_lemmas. -Implicit Types p q : oprob. +Implicit Types p q : {oprob R}. Lemma oprob_gt0 p : 0 < p. -Proof. by case: p => p /= /andP [] /ltRP. Qed. +Proof. by case: p => p /= /andP [] /RltP. Qed. Lemma oprob_lt1 p : p < 1. -Proof. by case: p => p /= /andP [] _ /ltRP. Qed. +Proof. by case: p => p /= /andP [] _ /RltP. Qed. Lemma oprob_ge0 p : 0 <= p. Proof. exact/ltRW/oprob_gt0. Qed. @@ -581,26 +612,26 @@ Proof. by move:(oprob_gt0 p); rewrite ltR_neqAle=> -[] /nesym /eqP. Qed. Lemma oprob_neq1 p : p != 1 :> R. Proof. by move:(oprob_lt1 p); rewrite ltR_neqAle=> -[] /eqP. Qed. -Lemma oprobK p : p = (p.~).~%:opr. +Lemma oprobK (p : {oprob R}) : p = ((Prob.p (OProb.p p)).~).~%:opr. Proof. by apply/val_inj/val_inj=> /=; rewrite onemK. Qed. -Lemma prob_trichotomy' (p : prob) (P : prob -> Prop) : - P 0%:pr -> P 1%:pr -> (forall o : oprob, P o) -> P p. +Lemma prob_trichotomy' (p : {prob R}) (P : {prob R} -> Prop) : + P 0%:pr -> P 1%:pr -> (forall o : {oprob R}, P o) -> P p. Proof. move=> p0 p1 po. -have [-> //|[->//|/ltR2P p01]] := prob_trichotomy p. -exact: po (OProb.mk p01). +have [-> //|[->//| p01]] := prob_trichotomy p. +exact (po (OProb.mk p01)). Qed. Lemma oprobadd_gt0 p q : 0 < p + q. Proof. exact/addR_gt0/oprob_gt0/oprob_gt0. Qed. -Lemma oprobadd_neq0 p q : p + q != 0%R. +Lemma oprobadd_neq0 p q : p + q != 0%coqR. Proof. by move: (oprobadd_gt0 p q); rewrite ltR_neqAle => -[] /nesym /eqP. Qed. End oprob_lemmas. -Lemma oprob_divRnnm n m : (0 < n)%nat -> (0 < m)%nat -> (0 < divRnnm n m < 1)%R. +Lemma oprob_divRnnm n m : (0 < n)%nat -> (0 < m)%nat -> (0 < divRnnm n m < 1)%coqR. Proof. rewrite /divRnnm. split; first by apply divR_gt0; [rewrite ltR0n | rewrite ltR0n addn_gt0 H orTb]. @@ -608,15 +639,18 @@ rewrite ltR_pdivr_mulr ?mul1R ?ltR_nat // ?ltR0n ?addn_gt0 ?H ?orTb //. by rewrite -[X in (X < _)%nat](addn0 n) ltn_add2l. Qed. -Lemma oprob_mulR (p q : oprob) : (0 /RltP ->] := oprob_mulR p q. Qed. + +Canonical oprobmulR (p q : {oprob R}) := + Eval hnf in @OProb.mk _ (Prob.p (OProb.p p) * q)%:pr (oprob_mulR' p q). Record Qplus := mkRrat { num : nat ; den : nat }. @@ -670,7 +704,7 @@ Notation "P '`<b 0 }. + H : (v > 0)%mcR }. Definition K (r : t) := H r. Arguments K : simpl never. Module Exports. @@ -687,57 +721,83 @@ Canonical Rpos_eqType := Eval hnf in EqType Rpos Rpos_eqMixin. Definition Rpos_choiceMixin := Eval hnf in [choiceMixin of Rpos by <:]. Canonical Rpos_choiceType := Eval hnf in ChoiceType Rpos Rpos_choiceMixin. -Definition mkRpos x H := @Rpos.mk x (introT (ltRP _ _) H). +Definition rpos_coercion (p : Rpos) : Real.sort real_realType := Rpos.v p. +Coercion rpos_coercion : Rpos >-> Real.sort. + +Definition mkRpos x H := @Rpos.mk x (introT (RltP _ _) H). Canonical Rpos1 := @mkRpos 1 Rlt_0_1. -Lemma Rpos_gt0 (x : Rpos) : 0 < x. Proof. by case: x => p /= /ltRP. Qed. +Lemma Rpos_gt0 (x : Rpos) : 0 < x. Proof. by case: x => p /= /RltP. Qed. Global Hint Resolve Rpos_gt0 : core. Lemma Rpos_neq0 (x : Rpos) : val x != 0. -Proof. by case: x => p /=; rewrite /gtRb lt0R => /andP[]. Qed. +Proof. by case: x => p /=; rewrite /RltP lt0r => /andP[]. Qed. -Lemma addRpos_gt0 (x y : Rpos) : x + y >b 0. Proof. exact/ltRP/addR_gt0. Qed. +Lemma addRpos_gt0 (x y : Rpos) : ((x + y)%coqR > 0)%mcR. +Proof. exact/RltP/addR_gt0. Qed. Canonical addRpos x y := Rpos.mk (addRpos_gt0 x y). -Lemma mulRpos_gt0 (x y : Rpos) : x * y >b 0. Proof. exact/ltRP/mulR_gt0. Qed. +Lemma mulRpos_gt0 (x y : Rpos) : ((x * y)%coqR > 0)%mcR. +Proof. exact/RltP/mulR_gt0. Qed. Canonical mulRpos x y := Rpos.mk (mulRpos_gt0 x y). -Lemma divRpos_gt0 (x y : Rpos) : x / y >b 0. Proof. exact/ltRP/divR_gt0. Qed. +Lemma divRpos_gt0 (x y : Rpos) : (((x : R) / (y : R))%coqR > 0)%mcR. +Proof. exact/RltP/divR_gt0. Qed. Canonical divRpos x y := Rpos.mk (divRpos_gt0 x y). -Canonical oprob_Rpos (p : oprob) := @mkRpos p (oprob_gt0 p). +(* TODO: Canonical oprob_Rpos (p : oprob) := @mkRpos p (oprob_gt0 p). *) -Lemma oprob_divRposxxy (x y : Rpos) : (0 ?. +move/RltP/Order.POrderTheory.ltW/RleP => ?. +by []. +Qed. + +Lemma prob_divRposxxy' (x y : Rpos) : (0 <= x / (x + y) <= 1)%O. +Proof. +have [/RleP ? /RleP ?] := prob_divRposxxy x y. exact/andP. +Qed. -Canonical divRposxxy_oprob (x y : Rpos) := - Eval hnf in OProb.mk (oprob_divRposxxy x y). +Canonical divRposxxy (x y : Rpos) := + Eval hnf in Prob.mk (prob_divRposxxy' x y). -Lemma divRposxxyC r q : divRposxxy q r = (divRposxxy r q).~%:pr. +Lemma divRposxxyC r q : divRposxxy q r = (Prob.p (divRposxxy r q)).~%:pr. Proof. apply val_inj => /=; rewrite [in RHS]addRC onem_div ?addRK //. exact: Rpos_neq0. Qed. -Lemma onem_divRxxy (r q : Rpos) : (r / (r + q)).~ = q / (q + r). -Proof. by rewrite /onem subR_eq (addRC r) -mulRDl mulRV // ?gtR_eqF. Qed. +Import GRing.Theory. + +Lemma onem_divRxxy (r q : Rpos) : (rpos_coercion r / (rpos_coercion r + q)).~ = q / (q + r). +Proof. +rewrite /onem; apply/eqP; rewrite subr_eq. +rewrite !RplusE (addrC (r : R)) RdivE; last first. + by rewrite gtR_eqF//; apply: addR_gt0. +rewrite -mulrDl divff//. +by rewrite gtR_eqF//; apply: addR_gt0. +Qed. Module Rnng. Local Open Scope R_scope. Record t := mk { v : R ; - H : 0 p /= /leRP. Qed. +Proof. by case: x => p /= /RleP. Qed. Local Hint Resolve Rnng_ge0 : core. -Canonical Rnng0 := Eval hnf in @mkRnng 0 (leRR 0). +Canonical Rnng0 := Eval hnf in @mkRnng 0 (Rle_refl 0). Canonical Rnng1 := Eval hnf in @mkRnng R1 Rle_0_1. -Lemma addRnng_ge0 (x y : Rnng) : 0 R. +Lemma s_of_pqE (p q : {prob R}) : Prob.p [s_of p, q] = ((Prob.p p).~ * (Prob.p q).~)%coqR.~ :> R. Proof. by rewrite /s_of_pq; unlock. Qed. -Lemma s_of_pq_oprob (p q : oprob) : 0 : x = ((p : R).~ * (q : R).~).~%:opr :> R by []. +set y := (X in _ < oprob_to_real X < _). +have := OProb.O1 y. +by move/andP => -[/RltP ? /RltP]. Qed. -Canonical oprob_of_s_of_pq (p q : oprob) := Eval hnf in OProb.mk (s_of_pq_oprob p q). +Lemma s_of_pq_oprob' (p q : {oprob R}) : (0 < Prob.p [s_of p, q] < 1)%O. +Proof. by have [/RltP -> /RltP ->] := s_of_pq_oprob p q. Qed. +Canonical oprob_of_s_of_pq (p q : {oprob R}) := Eval hnf in OProb.mk (s_of_pq_oprob' p q). -Lemma s_of_p0 (p : prob) : [s_of p, 0%:pr] = p. + +Lemma s_of_p0 (p : {prob R}) : [s_of p, 0%:pr] = p. Proof. by apply/val_inj; rewrite /= s_of_pqE onem0 mulR1 onemK. Qed. -Lemma s_of_0q (q : prob) : [s_of 0%:pr, q] = q. +Lemma s_of_0q (q : {prob R}) : [s_of 0%:pr, q] = q. Proof. by apply/val_inj; rewrite /= s_of_pqE onem0 mul1R onemK. Qed. -Lemma s_of_p1 (p : prob) : [s_of p, 1%:pr] = 1%:pr. +Lemma s_of_p1 (p : {prob R}) : [s_of p, 1%:pr] = 1%:pr. Proof. by apply/val_inj; rewrite /= s_of_pqE onem1 mulR0 onem0. Qed. -Lemma s_of_1q (q : prob) : [s_of 1%:pr, q] = 1%:pr. +Lemma s_of_1q (q : {prob R}) : [s_of 1%:pr, q] = 1%:pr. Proof. by apply/val_inj; rewrite /= s_of_pqE onem1 mul0R onem0. Qed. -Lemma s_of_pqE' (p q : prob) : [s_of p, q] = p + p.~ * q :> R. -Proof. rewrite s_of_pqE /= /onem; field. Qed. +Lemma s_of_pqE' (p q : {prob R}) : Prob.p [s_of p, q] = Prob.p p + (Prob.p p).~ * Prob.p q :> R. +Proof. +rewrite s_of_pqE. +rewrite !RmultE !RplusE. +rewrite /onem/=. +lra. +Qed. -Lemma s_of_gt0 p q : p != 0%:pr -> 0 < [s_of p, q]. +Lemma s_of_gt0 p q : p != 0%:pr -> 0 < Prob.p [s_of p, q]. Proof. -move=> ?; rewrite s_of_pqE'; - apply addR_gt0wl; [exact/prob_gt0 | exact: mulR_ge0]. +move=> ?; rewrite s_of_pqE'; apply: addR_gt0wl => //; first exact/probR_gt0. +by apply: mulR_ge0 => //; exact: onem_ge0. Qed. -Lemma s_of_gt0_oprob (p : oprob) (q : prob) : 0 < [s_of p, q]. +Lemma s_of_gt0_oprob (p : {oprob R}) (q : {prob R}) : 0 < [s_of p, q]. Proof. by apply/s_of_gt0/oprob_neq0. Qed. -Lemma ge_s_of (p q : prob) : p <= [s_of p, q]. -Proof. rewrite s_of_pqE' addRC -leR_subl_addr subRR; exact/mulR_ge0. Qed. +Lemma ge_s_of (p q : {prob R}) : Prob.p p <= Prob.p [s_of p, q]. +Proof. +rewrite s_of_pqE' addRC -leR_subl_addr subRR. +by apply/mulR_ge0 => //; exact: onem_ge0. +Qed. -Lemma r_of_pq_prob (p q : prob) : 0 prob) => p0. - rewrite (eqP p0) div0R; apply/andP; split; apply/leRP => //; exact/leRR. -case/boolP : (q == 0%:pr :> prob) => q0. - rewrite (eqP q0) (s_of_p0 p) divRR //; apply/andP; split; apply/leRP=> //; exact/leRR. -apply/andP; split; apply/leRP. -- apply divR_ge0 => //; exact/s_of_gt0. -- rewrite leR_pdivr_mulr ?mul1R; [exact: ge_s_of | exact: s_of_gt0]. +have [->|p0] := eqVneq p 0%:pr; first by rewrite div0R. +have [->|a0] := eqVneq q 0%:pr; first by rewrite (s_of_p0 p) divRR. +split. +- by apply divR_ge0 => //; exact/s_of_gt0. +- by rewrite leR_pdivr_mulr ?mul1R; [exact: ge_s_of | exact: s_of_gt0]. Qed. -Definition r_of_pq (p q : prob) : prob := locked (Prob.mk (r_of_pq_prob p q)). +Lemma r_of_pq_prob' (p q : {prob R}) : + (0%coqR <= (p / [s_of p, q])%coqR <= 1%coqR)%mcR. +Proof. by have [/RleP -> /RleP ->] := r_of_pq_prob p q. Qed. + +Definition r_of_pq (p q : {prob R}) : {prob R} := locked (Prob.mk (r_of_pq_prob' p q)). Notation "[ 'r_of' p , q ]" := (r_of_pq p q) : reals_ext_scope. -Lemma r_of_pqE (p q : prob) : [r_of p, q] = p / [s_of p, q] :> R. +Lemma r_of_pqE (p q : {prob R}) : Prob.p [r_of p, q] = Prob.p p / Prob.p [s_of p, q] :> R. Proof. by rewrite /r_of_pq; unlock. Qed. -Lemma r_of_pq_oprob (p q : oprob) : 0 //. + by apply: oprob_gt0. + rewrite s_of_pqE//. + have := (OProb.O1 (((oprob_to_real p).~ * (oprob_to_real q).~).~)%:opr). + move/andP=> [] /RltP /=. + by rewrite RmultE. rewrite ltR_pdivr_mulr ?mul1R; last by apply/(oprob_gt0). rewrite ltR_neqAle; split; last by apply/ge_s_of. rewrite s_of_pqE'; apply/eqP/ltR_eqF/ltR_addl. -by apply/oprob_gt0. +by have := oprob_gt0 ((oprob_to_real p).~ * oprob_to_real q)%:opr. Qed. -Canonical oprob_of_r_of_pq (p q : oprob) := Eval hnf in OProb.mk (r_of_pq_oprob p q). -Lemma r_of_p0 (p : prob) : p != 0%:pr -> [r_of p, 0%:pr] = 1%:pr. +Lemma r_of_pq_oprob' (p q : {oprob R}) : (0 < Prob.p [r_of OProb.p p, OProb.p q] < 1)%O. +Proof. by have [/RltP -> /RltP ->] := r_of_pq_oprob p q. Qed. +Canonical oprob_of_r_of_pq (p q : {oprob R}) := Eval hnf in OProb.mk (r_of_pq_oprob' p q). + +Lemma r_of_p0 (p : {prob R}) : p != 0%:pr -> [r_of p, 0%:pr] = 1%:pr. Proof. by move=> p0; apply val_inj; rewrite /= r_of_pqE s_of_p0 divRR. Qed. -Lemma r_of_p0_oprob (p : oprob) : [r_of p, 0%:pr] = 1%:pr. +Lemma r_of_p0_oprob (p : {oprob R}) : [r_of OProb.p p, 0%:pr] = 1%:pr. Proof. by apply/r_of_p0/oprob_neq0. Qed. -Lemma r_of_0q (q : prob) : [r_of 0%:pr, q] = 0%:pr. +Lemma r_of_0q (q : {prob R}) : [r_of 0%:pr, q] = 0%:pr. Proof. by apply/val_inj; rewrite /= r_of_pqE div0R. Qed. -Lemma r_of_p1 (p : prob) : [r_of p, 1%:pr] = p. +Lemma r_of_p1 (p : {prob R}) : [r_of p, 1%:pr] = p. Proof. by apply/val_inj; rewrite /= r_of_pqE s_of_p1 divR1. Qed. -Lemma r_of_1q (q : prob) : [r_of 1%:pr, q] = 1%:pr. +Lemma r_of_1q (q : {prob R}) : [r_of 1%:pr, q] = 1%:pr. Proof. by apply/val_inj; rewrite /= r_of_pqE s_of_1q divR1. Qed. -Lemma p_is_rs (p q : prob) : p = [r_of p, q] * [s_of p, q] :> R. +Lemma p_is_rs (p q : {prob R}) : Prob.p p = [r_of p, q] * [s_of p, q] :> R. Proof. -case/boolP : (p == 0%:pr :> prob) => p0; first by rewrite (eqP p0) r_of_0q mul0R. -case/boolP : (q == 0%:pr :> prob) => q0. +case/boolP : (p == 0%:pr :> {prob R}) => p0; first by rewrite (eqP p0) r_of_0q mul0R. +case/boolP : (q == 0%:pr :> {prob R}) => q0. by rewrite (eqP q0) s_of_p0 r_of_p0 // mul1R. +rewrite /probR_coercion. rewrite r_of_pqE /Rdiv -mulRA mulVR ?mulR1 //. -suff : [s_of p, q] != 0 :> R by []. -by rewrite prob_gt0; apply s_of_gt0. +suff : Prob.p [s_of p, q] != 0 :> R by []. +by rewrite prob_gt0; apply/RltP/s_of_gt0. Qed. -Lemma r_of_pq_is_r (p q r s : prob) : r != 0%:pr -> s != 0%:pr -> - p = r * s :> R -> s.~ = p.~ * q.~ -> [r_of p, q] = r. +Lemma r_of_pq_is_r (p q r s : {prob R}) : r != 0%:pr -> s != 0%:pr -> + Prob.p p = Prob.p r * Prob.p s :> R -> (Prob.p s).~ = (Prob.p p).~ * (Prob.p q).~ -> [r_of p, q] = r. Proof. move=> r0 s0 H1 H2; apply val_inj => /=. rewrite r_of_pqE eqR_divr_mulr; last by rewrite s_of_pqE -H2 onemK. -rewrite (p_is_rs _ q) /= {1}s_of_pqE -H2 onemK r_of_pqE s_of_pqE. +rewrite (p_is_rs _ q) /=. +rewrite /probR_coercion. +rewrite {1}s_of_pqE -H2 onemK r_of_pqE s_of_pqE. by rewrite -H2 onemK /Rdiv -mulRA mulVR ?mulR1. Qed. -Lemma r_of_pq_is_r_oprob (p q : prob) (r s : oprob) : +(*Lemma r_of_pq_is_r_oprob (p q : prob) (r s : oprob) : p = r * s :> R -> s.~ = p.~ * q.~ -> [r_of p, q] = r. -Proof. apply/r_of_pq_is_r/oprob_neq0/oprob_neq0. Qed. +Proof. apply/r_of_pq_is_r/oprob_neq0/oprob_neq0. Qed.*) -Lemma p_of_rs_prob (r s : prob) : 0 -[] r /andP [] /leRP r0 /leRP r1 -[] s /= /andP [] /leRP s0 /leRP s1. -apply/andP; split; apply/leRP; [exact/mulR_ge0 | rewrite -(mulR1 1); exact: leR_pmul]. +move: r s => -[] r /andP [] /RleP r0 /RleP r1 -[] s /= /andP [] /RleP s0 /RleP s1. +apply/andP; split; apply/RleP; [exact/mulR_ge0 | rewrite -(mulR1 1); exact: leR_pmul]. Qed. -Definition p_of_rs (r s : prob) : prob := locked (Prob.mk (p_of_rs_prob r s)). +Definition p_of_rs (r s : {prob R}) : {prob R} := locked (Prob.mk (p_of_rs_prob r s)). Notation "[ 'p_of' r , s ]" := (p_of_rs r s) : reals_ext_scope. - -Lemma p_of_rsE (r s : prob) : [p_of r, s] = r * s :> R. +Lemma p_of_rsE (r s : {prob R}) : Prob.p [p_of r, s] = Prob.p r * Prob.p s :> R. Proof. by rewrite /p_of_rs; unlock. Qed. -Lemma p_of_rs_oprob (r s : oprob) : 0 [p_of q, p] != 1%:pr. +Lemma p_of_neq1 (p q : {prob R}) : 0 < Prob.p p < 1 -> [p_of q, p] != 1%:pr. Proof. case=> p0 p1; apply/eqP => pq1; move: (p1). rewrite [X in _ < X -> _](_ : _ = Prob.p 1%:pr) //. -rewrite -pq1 p_of_rsE -ltR_pdivr_mulr // divRR ?prob_gt0 //. +rewrite -pq1 p_of_rsE -ltR_pdivr_mulr // divRR; last first. + apply/prob_gt0. + by apply/RltP. by rewrite ltRNge; exact. Qed. -Lemma p_of_rs1 (r s : prob) : - ([p_of r, s] == 1%:pr :> prob) = ((r == 1%:pr) && (s == 1%:pr)). +Lemma p_of_rs1 (r s : {prob R}) : + ([p_of r, s] == 1%:pr :> {prob R}) = ((r == 1%:pr) && (s == 1%:pr)). Proof. apply/idP/idP; last by case/andP => /eqP -> /eqP ->; rewrite p_of_r1. -move/eqP/(congr1 Prob.p); rewrite /= p_of_rsE => /eqP. +move/eqP/(congr1 probR_coercion). +rewrite /probR_coercion. +rewrite /= p_of_rsE => /eqP. apply contraLR => /nandP. wlog : r s / r != 1%:pr by move=> H [|] ?; [|rewrite mulRC]; rewrite H //; left. move=> r1 _. -have [/eqP->|/prob_gt0/ltR_neqAle[/nesym r0 _]] := boolP (r == 0%:pr :> prob). - by rewrite mul0R eq_sym; apply/eqP. +have [/eqP->|] := boolP (r == 0%:pr :> {prob R}). + by rewrite mul0R eq_sym oner_eq0. +move/prob_gt0/RltP/ltR_neqAle => [/nesym r0 _]. apply/eqP => /(@eqR_mul2r (/ r)). move/(_ (invR_neq0 _ r0)). rewrite mulRAC mulRV ?mul1R; last exact/eqP. -move/eqP/prob_gt0 in r0. +move/eqP/prob_gt0/RltP in r0. move=> srV; move: (prob_le1 s); rewrite {}srV. -rewrite invR_le1 // => r_le1. +move/RleP. +rewrite (invR_le1 _ r0) => r_le1. move: (prob_le1 r) => le_r1. -by move/eqP : r1; apply; apply/val_inj; apply eqR_le. +move/eqP : r1; apply; apply/val_inj; apply eqR_le; split => //=. +exact/RleP. Qed. Lemma p_of_rs1P r s : reflect (r = 1%:pr /\ s = 1%:pr) ([p_of r, s] == 1%:pr). @@ -952,30 +1049,51 @@ apply: (iffP idP); [by case/andP => /eqP -> /eqP -> | by case => -> ->; rewrite eqxx]. Qed. -Lemma q_of_rs_prob (r s : prob) : 0 {prob R}) => r1. + by rewrite (eqP r1) onem1 mul0R div0R; split. +case/boolP : (s == 1%:pr :> {prob R}) => s1. + by rewrite (eqP s1) mulR1 p_of_r1 divRR ?onem_neq0 //. +split. + apply/divR_ge0. + by apply/mulR_ge0 => //; exact: onem_ge0. + by apply/onem_gt0; rewrite p_of_rsE -(mulR1 1); apply/ltR_pmul => //; + apply/RltP; rewrite -prob_lt1. +rewrite leR_pdivr_mulr ?mul1R. + rewrite p_of_rsE {2}/onem leR_subr_addr -mulRDl addRC onemKC mul1R. + exact/RleP/prob_le1. +by apply onem_gt0; rewrite p_of_rsE -(mulR1 1); apply/ltR_pmul => //; + apply/RltP; rewrite -prob_lt1. +Qed. + +Lemma q_of_rs_prob' (r s : {prob R}) : (0 <= ((Prob.p r).~ * Prob.p s) / (Prob.p [p_of r, s]).~ <= 1)%O. Proof. -case/boolP : (r == 1%:pr :> prob) => r1. - rewrite (eqP r1) onem1 mul0R div0R; apply/andP; split; apply/leRP => //; exact/leRR. -case/boolP : (s == 1%:pr :> prob) => s1. - rewrite (eqP s1) mulR1 p_of_r1 divRR ?onem_neq0 //; apply/andP; split; apply/leRP => //; exact/leRR. -apply/andP; split; apply/leRP. - apply/divR_ge0; first exact/mulR_ge0. - apply/onem_gt0; rewrite p_of_rsE -(mulR1 1); apply/ltR_pmul => //; - by [rewrite -prob_lt1 | rewrite -prob_lt1]. +case/boolP : (r == 1%:pr :> {prob R}) => r1. + by rewrite (eqP r1) onem1 mul0R div0R; apply/andP; split; apply/RleP => //. +case/boolP : (s == 1%:pr :> {prob R}) => s1. + by rewrite (eqP s1) mulR1 p_of_r1 divRR ?onem_neq0 //; apply/andP; split; apply/RleP. +apply/andP; split; apply/RleP. + apply/divR_ge0. + by apply/mulR_ge0 => //; exact: onem_ge0. + by apply/onem_gt0; rewrite p_of_rsE -(mulR1 1); apply/ltR_pmul => //; + apply/RltP; rewrite -prob_lt1. rewrite leR_pdivr_mulr ?mul1R. - by rewrite p_of_rsE {2}/onem leR_subr_addr -mulRDl addRC onemKC mul1R. -apply onem_gt0; rewrite p_of_rsE -(mulR1 1); apply/ltR_pmul => //; - by [rewrite -prob_lt1 | rewrite -prob_lt1]. + rewrite p_of_rsE {2}/onem leR_subr_addr -mulRDl addRC onemKC mul1R. + exact/RleP/prob_le1. +by apply onem_gt0; rewrite p_of_rsE -(mulR1 1); apply/ltR_pmul => //; + apply/RltP; rewrite -prob_lt1. Qed. -Definition q_of_rs (r s : prob) : prob := locked (Prob.mk (q_of_rs_prob r s)). +Definition q_of_rs (r s : {prob R}) : {prob R} := locked (Prob.mk (q_of_rs_prob' r s)). Notation "[ 'q_of' r , s ]" := (q_of_rs r s) : reals_ext_scope. -Lemma q_of_rsE (r s : prob) : [q_of r, s] = (r.~ * s) / [p_of r, s].~ :> R. +Lemma q_of_rsE (r s : {prob R}) : + Prob.p [q_of r, s] = ((Prob.p r).~ * Prob.p s) / (Prob.p [p_of r, s]).~ :> R. Proof. by rewrite /q_of_rs; unlock. Qed. -Lemma q_of_rs_oprob (r s : oprob) : 0 : r.~ * s / (r * s).~ = (s.~ / (r * s).~).~ @@ -988,27 +1106,29 @@ apply/andP; split; apply/ltRP. rewrite -onem_lt. by rewrite -{2}(mul1R s) ltR_pmul2r; [apply/oprob_lt1 | apply/oprob_gt0]. Qed. -Canonical oprob_of_q_of_rs (r s : oprob) := Eval hnf in OProb.mk (q_of_rs_oprob r s). +Canonical oprob_of_q_of_rs (r s : oprob) := Eval hnf in OProb.mk (q_of_rs_oprob r s).*) -Lemma q_of_r0 (r : prob) : [q_of r, 0%:pr] = 0%:pr. +Lemma q_of_r0 (r : {prob R}) : [q_of r, 0%:pr] = 0%:pr. Proof. by apply/val_inj => /=; rewrite q_of_rsE mulR0 div0R. Qed. -Lemma q_of_r1 (r : prob) : r != 1%:pr -> [q_of r, 1%:pr] = 1%:pr. +Lemma q_of_r1 (r : {prob R}) : r != 1%:pr -> [q_of r, 1%:pr] = 1%:pr. Proof. move=> r1. by apply/val_inj => /=; rewrite q_of_rsE /= mulR1 p_of_r1 divRR // onem_neq0. Qed. -Lemma q_of_1s (s : prob) : [q_of 1%:pr, s] = 0%:pr. +Lemma q_of_1s (s : {prob R}) : [q_of 1%:pr, s] = 0%:pr. Proof. by apply/val_inj => /=; rewrite q_of_rsE onem1 mul0R div0R. Qed. -Lemma pq_is_rs (p q : prob) : p.~ * q = [r_of p, q].~ * [s_of p, q]. +Lemma pq_is_rs (p q : {prob R}) : (Prob.p p).~ * Prob.p q = (Prob.p [r_of p, q]).~ * Prob.p [s_of p, q]. Proof. -case/boolP : (p == 0%:pr :> prob) => p0. +case/boolP : (p == 0%:pr :> {prob R}) => p0. by rewrite (eqP p0) onem0 mul1R r_of_0q onem0 mul1R s_of_0q. rewrite r_of_pqE [in RHS]mulRBl mul1R. rewrite /Rdiv -mulRA mulVR ?mulR1; last first. - rewrite prob_gt0; exact/s_of_gt0. + rewrite prob_gt0. + apply/RltP. + exact/s_of_gt0. by rewrite s_of_pqE' addRC addRK. Qed. @@ -1017,19 +1137,25 @@ Lemma s_of_pqK r s : [p_of r, s] != 1%:pr -> Proof. move=> H. apply/val_inj; rewrite /= s_of_pqE p_of_rsE q_of_rsE p_of_rsE /=. -rewrite /onem; field. +rewrite /onem. +rewrite -!RminusE. +rewrite (_ : 1%mcR = 1)//. +field. rewrite subR_eq0; apply/eqP; apply: contra H => /eqP rs1. by apply/eqP/val_inj; rewrite /= p_of_rsE. Qed. -Lemma s_of_pqK_oprob (r s : oprob) : [s_of [p_of r, s], [q_of r, s]] = s. -Proof. apply/s_of_pqK/oprob_neq1. Qed. +(*Lemma s_of_pqK_oprob (r s : oprob) : [s_of [p_of r, s], [q_of r, s]] = s. +Proof. apply/s_of_pqK/oprob_neq1. Qed.*) -Lemma r_of_pqK (r s : prob) : [p_of r, s] != 1%:pr -> s != 0%:pr -> +Lemma r_of_pqK (r s : {prob R}) : [p_of r, s] != 1%:pr -> s != 0%:pr -> [r_of [p_of r, s], [q_of r, s]] = r. Proof. move=> H1 s0; apply/val_inj => /=. -rewrite !(r_of_pqE,s_of_pqE,q_of_rsE,p_of_rsE) /onem; field. +rewrite !(r_of_pqE,s_of_pqE,q_of_rsE,p_of_rsE) /onem. +rewrite -!RminusE. +rewrite (_ : 1%mcR = 1)//. +field. split; last first. by rewrite 2!subRB subRR add0R mulRBl mul1R addRC subRK; exact/eqP. rewrite subR_eq0 => /esym. @@ -1037,14 +1163,17 @@ apply/eqP; apply: contra H1 => /eqP H1. by apply/eqP/val_inj; rewrite /= p_of_rsE. Qed. -Lemma r_of_pqK_oprob (r s : oprob) : [r_of [p_of r, s], [q_of r, s]] = r. -Proof. apply/r_of_pqK/oprob_neq0/oprob_neq1. Qed. +(*Lemma r_of_pqK_oprob (r s : oprob) : [r_of [p_of r, s], [q_of r, s]] = r. +Proof. apply/r_of_pqK/oprob_neq0/oprob_neq1. Qed.*) Lemma s_of_Rpos_probA (p q r : Rpos) : [s_of (p / (p + (q + r)))%:pos%:pr, (q / (q + r))%:pos%:pr] = ((p + q) / (p + q + r))%:pos%:pr. Proof. -apply val_inj; rewrite /= s_of_pqE /onem /=; field. +apply val_inj; rewrite /= s_of_pqE /onem /=. +rewrite -!RminusE. +rewrite (_ : 1%mcR = 1)//. +field. by split; exact/eqP/Rpos_neq0. Qed. @@ -1052,7 +1181,10 @@ Lemma r_of_Rpos_probA (p q r : Rpos) : [r_of (p / (p + (q + r)))%:pos%:pr, (q / (q + r))%:pos%:pr] = (p / (p + q))%:pos%:pr. Proof. -apply/val_inj; rewrite /= r_of_pqE s_of_pqE /onem /=; field. +apply/val_inj; rewrite /= r_of_pqE s_of_pqE /onem /=. +rewrite -!RminusE. +rewrite (_ : 1%mcR = 1)//. +field. do 3 (split; first exact/eqP/Rpos_neq0). rewrite (addRC p (q + r)) addRK {4}[in q + r]addRC addRK. rewrite mulRC -mulRBr (addRC _ p) addRA addRK mulR_neq0. diff --git a/lib/Rstruct_ext.v b/lib/Rstruct_ext.v new file mode 100644 index 00000000..d8f62a7e --- /dev/null +++ b/lib/Rstruct_ext.v @@ -0,0 +1,48 @@ +(* infotheo: information theory and error-correcting codes in Coq *) +(* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) +From mathcomp Require Import all_ssreflect all_algebra. +From mathcomp Require Import Rstruct. +Require Import Reals. +Require Import ssrR Rbigop. + +Local Open Scope ring_scope. +Delimit Scope R_scope with coqR. + +Import (*GRing.Theory Num.Theory*) Order.Theory. + +(* NB: this lemma depends on the internals of Rinv and Rinvx *) +Lemma RinvE' (x : R) : (/ x)%coqR = x^-1. +Proof. +have [-> | ] := eqVneq x 0%coqR; last exact: RinvE. +rewrite /GRing.inv /GRing.mul /= /Rinvx eqxx /=. +rewrite RinvImpl.Rinv_def. +case: (Req_appart_dec 0 R0) => //. +by move=> /[dup] -[] => /RltP; rewrite ltxx. +Qed. + +Lemma RdivE' (x y : R) : (x / y)%coqR = x / y. +Proof. by rewrite ssrR.divRE RinvE'. Qed. + +Lemma bigmaxRE (I : Type) (r : seq I) (P : pred I) (F : I -> R) : + \rmax_(i <- r | P i) F i = \big[Order.max/0]_(i <- r | P i) F i. +Proof. +rewrite /Rmax /Order.max/=. +congr BigOp.bigop. +apply: boolp.funext=> i /=. +congr BigBody. +apply: boolp.funext=> x /=. +apply: boolp.funext=> y /=. +rewrite lt_neqAle. +case: (Rle_dec x y); move/RleP; + first by case/boolP: (x == y) => /= [/eqP -> | _ ->]. +by move/negPf->; rewrite andbF. +Qed. + +Lemma R1E : 1%coqR = GRing.one _. +Proof. by []. Qed. +Lemma R0E : 0%coqR = GRing.zero _. +Proof. by []. Qed. + +Definition coqRE := + (R0E, R1E, INRE, + RinvE', RoppE, RdivE', RminusE, RplusE, RmultE, RpowE). diff --git a/lib/bigop_ext.v b/lib/bigop_ext.v index 122dc5e0..60f8d6d0 100644 --- a/lib/bigop_ext.v +++ b/lib/bigop_ext.v @@ -1,6 +1,6 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg matrix. +From mathcomp Require Import all_ssreflect ssralg matrix. Require Import Reals. Require Import ssrR Reals_ext logb ssr_ext ssralg_ext. diff --git a/lib/binary_entropy_function.v b/lib/binary_entropy_function.v index d1edc203..1f170fd2 100644 --- a/lib/binary_entropy_function.v +++ b/lib/binary_entropy_function.v @@ -118,7 +118,8 @@ apply (@leR_trans (H2ln (1/2))); last first. rewrite -/(H2ln q). case: (Rlt_le_dec q (1/2)) => [H1|]. - by apply increasing_on_0_to_half => //; lra. -- case/Rle_lt_or_eq_dec => [H1|<-]; last exact: leRR. +- case/Rle_lt_or_eq_dec => [H1|<-]; last first. + lra. by apply decreasing_on_half_to_1 => //; lra. Qed. diff --git a/lib/dft.v b/lib/dft.v index 2806b14e..6c87b7e5 100644 --- a/lib/dft.v +++ b/lib/dft.v @@ -1,6 +1,6 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg poly polydiv finalg zmodp. +From mathcomp Require Import all_ssreflect ssralg poly polydiv zmodp. From mathcomp Require Import matrix mxalgebra mxpoly vector cyclic perm. Require Import ssr_ext ssralg_ext hamming. diff --git a/lib/hamming.v b/lib/hamming.v index 15d238df..30c13fbb 100644 --- a/lib/hamming.v +++ b/lib/hamming.v @@ -1,9 +1,9 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) Require Import Reals. -From mathcomp Require Import all_ssreflect fingroup zmodp ssralg perm matrix. -From mathcomp Require Import poly finalg mxalgebra mxpoly. -From mathcomp Require Rstruct. +From mathcomp Require Import all_ssreflect fingroup zmodp ssralg finalg perm matrix. +From mathcomp Require Import poly mxalgebra mxpoly. +From mathcomp Require Import Rstruct. Require Import ssr_ext ssralg_ext f2 num_occ natbin ssrR Reals_ext Rbigop. (******************************************************************************) @@ -849,7 +849,7 @@ Lemma hamming_01 m p : (1 - p) ^ (m - wH u) * p ^ wH u = (1 - p) ^ m + m%:R * p * (1 - p) ^ (m - 1). Proof. -rewrite (@bigID _ _ addR_comoid(*TODO: we shouldn't need to pass this argument*) _ _ [pred i | wH i == O]) /=. +rewrite (bigID [pred i | wH i == O]) /=. rewrite (big_pred1 (GRing.zero _)) /=; last first. by move=> i /=; rewrite !inE -wH_eq0 andb_idl // => /eqP ->. rewrite wH0 pow_O subn0 mulR1; congr (_ + _). @@ -874,7 +874,8 @@ transitivity (((1 - p) + p) ^ m); last by rewrite subRK exp1R. rewrite RPascal. transitivity (\sum_(b : 'rV['F_2]_m) (1 - p) ^ (m - wH b) * p ^ wH b). by apply eq_bigl => /= i; rewrite inE. -rewrite (classify_big (fun s => Ordinal (max_wH' s)) (fun x => (1 - p) ^ (m - x) * p ^ x)) /=. +rewrite (classify_big (fun s => Ordinal (max_wH' s)) + (fun x => (1 - p) ^ (m - x) * p ^ x)) /=. apply eq_bigr => i _; congr (_%:R * _). by rewrite -wH_m_card; apply eq_card => /= x; rewrite !inE. Qed. diff --git a/lib/logb.v b/lib/logb.v index 28afe2be..726469d1 100644 --- a/lib/logb.v +++ b/lib/logb.v @@ -1,9 +1,11 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import ssreflect ssrbool eqtype ssrfun ssrnat. +From mathcomp Require Import all_ssreflect ssralg ssrnum. From mathcomp Require Import Rstruct. Require Import Reals Lra. Require Import ssrR Reals_ext. +From mathcomp Require Import reals. +Require Import realType_ext. (******************************************************************************) (* log_n x and n ^ x *) @@ -23,6 +25,8 @@ Import Prenex Implicits. Local Open Scope R_scope. +Import Order.POrderTheory GRing.Theory Num.Theory. + Section addtional_lemmas_about_ln_exp. Lemma ln_pos x : 1 < x -> 0 < ln x. @@ -43,14 +47,16 @@ Qed. Lemma ln_increasing_le a b : 0 < a -> a <= b -> ln a <= ln b. Proof. move=> Ha. -case/Rle_lt_or_eq_dec; last by move=> ->; exact/leRR. +case/Rle_lt_or_eq_dec; last first. + by move=> ->; by apply/RleP; rewrite lexx. by move/(ln_increasing _ _ Ha)/ltRW. Qed. Lemma exp_le_inv x y : exp x <= exp y -> x <= y. Proof. case/Rle_lt_or_eq_dec; [move/exp_lt_inv => ?; exact/ltRW | - move/exp_inv => ->; exact/leRR]. + move/exp_inv => ->]. +by apply/RleP; rewrite lexx. Qed. Lemma exp_pow n : forall k, exp (k%:R * n) = (exp n) ^ k. @@ -105,8 +111,9 @@ elim => [r rpos | n IH r rpos]. by apply IH, Hx. move/(_ Haux 0 r) => {Haux}. apply => //. - - split; [exact/leRR | exact: ltRW]. - - split; [exact: ltRW | exact/leRR]. + - by split; [by [] | exact: ltRW]. + - split; [exact: ltRW | ]. + by apply/RleP; rewrite lexx. Qed. Lemma exp_strict_lb (n : nat) x : 0 < x -> x ^ n * / (n`!)%:R < exp x. @@ -117,11 +124,12 @@ Proof. move=> Hr. case/boolP : (r == 0) => [/eqP ->|]; last first. - move=> Hr2. - have {Hr Hr2}R_pos : 0 < r by apply/ltRP; rewrite lt0R Hr2 /=; exact/leRP. + have {Hr Hr2}R_pos : 0 < r. + by apply/RltP; rewrite lt0r Hr2/=; exact/RleP. exact/ltRW/exp_dev_gt0. - case: n. - + rewrite /exp_dev exp_0 mul1R invR1 subRR; exact/leRR. - - move=> n. + + by rewrite /exp_dev exp_0 mul1R invR1 subRR. + + move=> n. rewrite -(_ : 1 = exp_dev n.+1 0) //. rewrite /exp_dev exp_0 pow_i ?mul0R ?subR0 //; exact/ltP. Qed. @@ -160,7 +168,12 @@ Proof. move=> *; rewrite LogM //; [by rewrite LogV | exact: invR_gt0]. Qed. Lemma Log_increasing_le n x y : 1 < n -> 0 < x -> x <= y -> Log n x <= Log n y. Proof. move=> n1 x0 xy. -apply leR_wpmul2r; [exact/leRP/ltRW'/ltRP/invR_gt0/ln_pos|]. +apply leR_wpmul2r. + apply/RleP. + rewrite RinvE//; last first. + rewrite gtR_eqF//. + exact/ln_pos. + by rewrite invr_ge0; exact/ltW/RltP/ln_pos. exact: ln_increasing_le. Qed. @@ -190,7 +203,8 @@ Lemma Log_le_inv n x y : 1 < n -> 0 < x -> 0 < y -> Log n x <= Log n y -> x <= y Proof. move=> n1 Hx Hy. case/Rle_lt_or_eq_dec; first by move/(Log_lt_inv n1 Hx Hy)/ltRW. -move/(Log_inv n1 Hx Hy) => ->; exact/leRR. +move/(Log_inv n1 Hx Hy) => ->. +by apply/RleP; rewrite lexx. Qed. (* NB: log is 0 for input < 0 *) @@ -231,7 +245,12 @@ Lemma logexp1E : log (exp 1) = / ln 2. Proof. by rewrite /log /Log ln_exp div1R. Qed. Lemma log_exp1_Rle_0 : 0 <= log (exp 1). -Proof. rewrite logexp1E; exact/leRP/ltRW'/ltRP/invR_gt0. Qed. +Proof. +rewrite logexp1E. +apply/RleP. +rewrite RinvE ?ln2_neq0// invr_ge0. +exact/ltW/RltP/ln2_gt0. +Qed. Definition Exp (n : R) x := exp (x * ln n). @@ -282,15 +301,15 @@ Proof. move=> ? ?; apply/exp_increasing/ltR_pmul2r => //; exact/ln_pos. Qed. Lemma Exp_le_inv n x y : 1 < n -> Exp n x <= Exp n y -> x <= y. Proof. rewrite /Exp => n1 /exp_le_inv H. -apply/leRP; rewrite -(leR_pmul2l' (ln n)); last exact/ltRP/ln_pos. -rewrite mulRC -(mulRC y); exact/leRP. +apply/RleP; rewrite -(@ler_pM2l _ (ln n)); last exact/RltP/ln_pos. +by rewrite mulrC -(mulrC y); exact/RleP. Qed. Lemma Exp_le_increasing n x y : 1 < n -> x <= y -> Exp n x <= Exp n y. Proof. move=> n1; rewrite /Exp; case/Rle_lt_or_eq_dec. move/Exp_increasing => x_y; exact/ltRW/x_y. -move=> ->; exact/leRR. +by move=> ->; apply/RleP; rewrite lexx. Qed. Lemma Exp_Ropp n x : Exp n (- x) = / Exp n x. @@ -324,45 +343,45 @@ Proof. move=> Hx; by rewrite /exp2 -/(Exp 2 (log x)) /log -/(Log 2 _) LogK. Qed. Lemma exp2K x : log (exp2 x) = x. Proof. by rewrite /exp2 -/(Exp 2 x) /log -/(Log 2 _) ExpK. Qed. -Lemma Rle_exp2_log1_L a b : 0 < b -> exp2 a (exp2 a <= b)%mcR = (a <= log b)%mcR. Proof. -move=> Hb; move H1 : (_ [|] /=. -- move/leRP in H1. +move=> Hb; move H1 : (_ <= _ )%mcR => [|] /=. +- move/RleP in H1. have {}H1 : a <= log b. rewrite (_ : a = log (exp2 a)); last by rewrite exp2K. exact: Log_increasing_le. - move/leRP in H1; by rewrite H1. -- move H2 : (_ [|] //=. - move/leRP in H2. + by move/RleP : H1 => ->. +- move H2 : (_ <= _ )%mcR => [|] //=. + move/RleP in H2. rewrite -(@ExpK 2 a _) // in H2. apply Log_le_inv in H2 => //. - move/leRP in H2. + move/RleP in H2. by rewrite H2 in H1. Qed. -Lemma Rle_exp2_log2_R b c : 0 < b -> b (b <= exp2 c)%mcR = (log b <= c)%mcR. Proof. -move=> Hb; move H1 : (_ [|] /=. -- move/leRP in H1. +move=> Hb; move H1 : (_ <= _)%mcR => [|] /=. +- move/RleP in H1. have {}H1 : log b <= c. rewrite (_ : c = log (exp2 c)); last by rewrite exp2K. apply Log_increasing_le => //; exact: exp2_pos. - by move/leRP in H1. -- move H2 : (_ [|] //=. - move/leRP in H2. + by move/RleP in H1. +- move H2 : (_ <= _ )%mcR => [|] //=. + move/RleP in H2. rewrite -(exp2K c) in H2. apply Log_le_inv in H2 => //. - move/leRP in H2. + move/RleP in H2. by rewrite H2 in H1. Qed. Lemma Rle2_exp2_log a b c : 0 < b -> - exp2 a Hb; move H1 : (_ [|] /=. +move=> Hb; move H1 : (_ <= _ )%mcR => [|] /=. - rewrite Rle_exp2_log1_L // in H1. by rewrite H1 /= Rle_exp2_log2_R. -- move H2 : (_ [|] //=. +- move H2 : (_ <= _ )%mcR => [|] //=. rewrite -Rle_exp2_log1_L // in H2. by rewrite H2 in H1. Qed. diff --git a/lib/num_occ.v b/lib/num_occ.v index 895afef5..5bfe8eab 100644 --- a/lib/num_occ.v +++ b/lib/num_occ.v @@ -105,7 +105,7 @@ Lemma sum_num_occ_size (A : finType) s : (\sum_(a in A) N(a|s))%nat = size s. Proof. elim: s => [|a s IH] /=. + by apply big1_eq. -+ by rewrite big_split /= IH -big_mkcond /= (big_pred1 a). ++ by rewrite big_split /= IH -big_mkcond /= (big_pred1 a) // => x; rewrite eq_sym. Qed. Lemma num_occ_flatten (A : finType) (a : A) ss : diff --git a/lib/realType_ext.v b/lib/realType_ext.v new file mode 100644 index 00000000..bd81414c --- /dev/null +++ b/lib/realType_ext.v @@ -0,0 +1,301 @@ +(* infotheo: information theory and error-correcting codes in Coq *) +(* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) +From mathcomp Require Import all_ssreflect ssralg ssrnum. +From mathcomp Require Import reals normedtype. +From mathcomp Require Import mathcomp_extra boolp. +From mathcomp Require Import lra Rstruct. + +Delimit Scope ring_scope with mcR. + +Reserved Notation "p '.~'" (format "p .~", at level 5). +Reserved Notation "x %:pr" (at level 0, format "x %:pr"). +Reserved Notation "x %:opr" (at level 0, format "x %:opr"). +Reserved Notation "x %:pos" (at level 2, format "x %:pos"). +Reserved Notation "x %:nng" (at level 2, format "x %:nng"). +Reserved Notation "P '`<<' Q" (at level 51). + +Set Implicit Arguments. +Unset Strict Implicit. +Import Prenex Implicits. + +Import Order.POrderTheory Order.TotalTheory GRing.Theory Num.Theory. + +Lemma prodR_gt0 (R : numDomainType) (A : finType) (F : A -> R) : (forall a, 0 < F a)%mcR -> + (0 < \prod_(a : A) F a)%mcR. +Proof. by move=> F0; elim/big_ind : _ => // x y ? ?; exact: mulr_gt0. Qed. + +(* ---- onem ---- *) +Section onem. +Local Open Scope ring_scope. +Variable R : realType. + +Local Notation "p '.~'" := (@onem R p). + +(*Lemma onem_ge0 (x : R) : x <= 1 -> 0 <= onem x. +Proof. exact: onem_ge0. Qed.*) + +Lemma onem_le1 (x : R) : 0 <= x -> onem x <= 1. +Proof. exact: onem_le1. Qed. + +Lemma onem_le r s : (r <= s) = (s.~ <= r.~). +Proof. +apply/idP/idP => [|?]; first exact: lerB. +by rewrite -(opprK r) lerNl -(lerD2l 1). +Qed. + +Lemma onemE x : x.~ = 1 - x. Proof. by []. Qed. + +Lemma onem_lt r s : r < s <-> s.~ < r.~. Proof. by rewrite !onemE; lra. Qed. + +Lemma onemKC r : r + r.~ = 1. Proof. by rewrite !onemE; lra. Qed. +(* Lemma onemKC r : r + (onem r) = 1. + Proof. + by rewrite /onem addrC -addrA (addrC (-r) r) subrr addr0. + Qed.*) + +Lemma onemK (x : R): onem (onem x) = x. +Proof. by rewrite /onem opprB addrA addrC addrA (addrC (-1) 1) subrr add0r. Qed. + +Lemma onemD p q : (p + q).~ = p.~ + q.~ - 1. +Proof. rewrite !onemE; lra. Qed. + +Lemma onemM p q : (p * q).~ = p.~ + q.~ - p.~ * q.~. +Proof. rewrite !onemE/=; lra. Qed. + +Lemma onem_div p q : q != 0 -> (p / q).~ = (q - p) /q. +Proof. +rewrite !onemE. +move=> Hq. +rewrite mulrDl. +rewrite mulNr. +rewrite -/(q / q). +by rewrite divrr// unitfE. +Qed. + +Lemma onem_prob (r : R) : 0 <= r <= 1 -> 0 <= onem r <= 1. +Proof. + by move=> /andP [_0r r1]; apply /andP; split; [rewrite onem_ge0 | rewrite onem_le1]. +Qed. + +Lemma onem_eq0 (r : R) : (onem r = 0) <-> (r = 1). +Proof. +rewrite /onem. split; first by move /subr0_eq. +by move=> ->; rewrite subrr. +Qed. + +Lemma onem_eq1 r : r.~ = 1 <-> r = 0. Proof. rewrite onemE; lra. Qed. + +Lemma onem_neq0 (r : R) : (onem r != 0) <-> (r != 1). +Proof. by split; apply: contra => /eqP/onem_eq0/eqP. Qed. + +Lemma onem_gt0 r : r < 1 -> 0 < r.~. Proof. rewrite /onem; lra. Qed. + +Lemma onem_lt1 r : 0 < r -> r.~ < 1. Proof. rewrite /onem; lra. Qed. + +Lemma onem_oprob r : 0 < r < 1 -> 0 < r.~ < 1. +Proof. +by move=> /andP [? ?]; apply/andP; rewrite onem_gt0 // onem_lt1. +Qed. + +Lemma subr_onem r s : r - s.~ = r + s - 1. +Proof. by rewrite /onem opprB addrA. Qed. + +End onem. +Notation "p '.~'" := (onem p). +(* ---- onem ---- *) + +(* ---- Prob ---- *) +Module Prob. +Record t (R : realType) := mk { + p :> R ; + Op1 : (0 <= p <= 1)%R }. +Definition O1 (R : realType) (x : t R) : (0 <= p x <= 1)%R := Op1 x. +Arguments O1 : simpl never. +Definition mk_ (R : realType) (q : R) (Oq1 : (0 <= q <= 1)%R) := mk Oq1. +Module Exports. +Notation prob := t. +Notation "q %:pr" := (@mk _ q (@O1 _ _)). +Canonical prob_subType (R : realType) := Eval hnf in [subType for @p R]. +Definition prob_eqMixin (R : realType) := [eqMixin of (prob R) by <:]. +Canonical prob_eqType (R : realType) := Eval hnf in EqType _ (prob_eqMixin R). +End Exports. +End Prob. +Export Prob.Exports. +Coercion Prob.p : prob >-> Real.sort. +Lemma probpK R p H : Prob.p (@Prob.mk R p H) = p. Proof. by []. Qed. + +Reserved Notation "{ 'prob' T }" (at level 0, format "{ 'prob' T }"). +Definition prob_of (R : realType) := fun phT : phant (Num.NumDomain.sort (*Real.sort*)R) => @prob R. +Notation "{ 'prob' T }" := (@prob_of _ (Phant T)). +Definition prob_coercion (R: realType) (p : {prob R}) : R := Prob.p p. + +Section prob_lemmas. +Import GRing.Theory. +Local Open Scope ring_scope. +Variable R : realType. +Implicit Types p q : {prob R}. + +Lemma OO1 : ((0 <= 0 :> R) && (0 <= 1 :> R))%R. +Proof. by apply /andP; split; [rewrite lexx | rewrite ler01]. Qed. +Lemma O11 : ((0 <= 1 :> R) && (1 <= 1 :> R))%R. +Proof. by apply /andP; split; [rewrite ler01| rewrite lexx]. Qed. + +Canonical prob0 := Eval hnf in Prob.mk OO1. +Canonical prob1 := Eval hnf in Prob.mk O11. +Canonical probcplt (p : prob R) := Eval hnf in Prob.mk (onem_prob (Prob.O1 p)). + +Lemma prob_ge0 (p : prob R) : (0 <= (p : R))%R. +Proof. by case: p => p /= /andP []. Qed. + +Lemma prob_le1 (p : prob R) : ((p : R) <= 1)%R. +Proof. by case: p => p /= /andP []. Qed. + +Lemma prob_gt0 p : p != 0%:pr <-> 0 < Prob.p p. +Proof. +rewrite lt_neqAle; split=> [H|/andP[+ pge0]]. + by apply/andP; split; [rewrite eq_sym|exact: prob_ge0]. +by apply: contra => /eqP ->. +Qed. + +Lemma prob_gt0' p : p != 0 :> R <-> 0 < Prob.p p. +Proof. exact: prob_gt0. Qed. + +Lemma prob_lt1 p : p != 1%:pr <-> Prob.p p < 1. +Proof. +rewrite lt_neqAle; split=> [H|/andP[+ pge0]]. + by apply/andP; split => //; exact: prob_le1. +by apply: contra => /eqP ->. +Qed. + +Lemma prob_lt1' p : p != 1 :> R <-> Prob.p p < 1. +Proof. exact: prob_lt1. Qed. + +Lemma prob_trichotomy p : p = 0%:pr \/ p = 1%:pr \/ 0 < Prob.p p < 1. +Proof. +have [/eqP ->|pneq0]:= boolP (p == 0%:pr); first by left. +right. +have [/eqP ->|pneq1] := boolP (p == 1%:pr); first by left. +by right; apply/andP; split; [exact/prob_gt0|exact/prob_lt1]. +Qed. + +Lemma probK p : p = (onem (Prob.p p)).~%:pr. +Proof. by apply val_inj => /=; rewrite onemK. Qed. + +Lemma probKC (p : {prob R}) : Prob.p p + (Prob.p p).~ = 1 :> R. +Proof. exact: onemKC. Qed. + +Lemma probadd_eq0 p q : Prob.p p + Prob.p q = 0 <-> p = 0%:pr /\ q = 0%:pr. +Proof. +split; last by move=> [-> ->] /=; rewrite addr0. +move/eqP; rewrite paddr_eq0; [|exact: prob_ge0|exact: prob_ge0]. +by move=> /andP[/eqP ? /eqP ?]; split; exact/val_inj. +Qed. + +Lemma probadd_neq0 p q : Prob.p p + Prob.p q != 0 <-> p != 0%:pr \/ q != 0%:pr. +Proof. +apply/iff_not2; split=> [/negP/negPn/eqP/probadd_eq0[-> ->]|]. + by apply/not_orP; split; apply/negP/negPn. +move=> /not_orP[/negP/negPn/eqP -> /negP/negPn/eqP -> /=]; apply/negP/negPn. +by rewrite addr0. +Qed. + +Lemma probmul_eq1 p q : Prob.p p * Prob.p q = 1 <-> p = 1%:pr /\ q = 1%:pr. +Proof. +split => [/= pq1|[-> ->]]; last by rewrite mulr1. +move: (oner_neq0 R); rewrite -{1}pq1 mulf_eq0 negb_or => /andP[p0 q0]. +have := prob_le1 p; rewrite le_eqVlt => /orP[/eqP p1|p1]. + by rewrite p1 mul1r in pq1; split; exact/val_inj. +have := prob_le1 q; rewrite le_eqVlt => /orP[/eqP q1|q1]. + by rewrite q1 mulr1 in pq1; split; exact/val_inj. +have {}p0 : 0 < Prob.p p by rewrite lt_neqAle prob_ge0 eq_sym andbT. +by move: p1; rewrite -[in X in X -> _]pq1 (ltr_pMr _ p0) ltNge (ltW q1). +Qed. + +End prob_lemmas. + + +Global Hint Resolve prob_ge0 : core. +Global Hint Resolve prob_le1 : core. + +#[export] Hint Extern 0 (is_true (Prob.p _ <= 1)%R) => + exact/prob_le1 : core. +#[export] Hint Extern 0 (is_true (0 <= Prob.p _)%R) => + exact/prob_ge0 : core. + +Arguments prob0 {R}. +Arguments prob1 {R}. +(* ---- ---- *) + +Module OProb. +Section def. +Import GRing.Theory. +Local Open Scope ring_scope. +Record t (R: realType):= mk { + p :> {prob R}; + Op1 : (0 < Prob.p p < 1)%R }. +Definition O1 (R: realType) (x : t R) : 0 < Prob.p (p x) < 1 := Op1 x. +Arguments O1 : simpl never. +End def. +Module Exports. +Notation oprob := t. +Notation "q %:opr" := (@mk _ q%:pr (@O1 _ _)). +Canonical oprob_subType (R: realType) := Eval hnf in [subType for @p R]. +Definition oprob_eqMixin (R: realType) := [eqMixin of (oprob R) by <:]. +Canonical oprob_eqType (R : realType) := Eval hnf in EqType _ (oprob_eqMixin R). +End Exports. +End OProb. +Export OProb.Exports. +(*Coercion OProb.p : oprob >-> prob.*) +Canonical oprobcplt [R: realType] (p : oprob R) := Eval hnf in OProb.mk (onem_oprob (OProb.O1 p)). + + +Reserved Notation "{ 'oprob' T }" (at level 0, format "{ 'oprob' T }"). +Definition oprob_of (R : realType) := fun phT : phant (Num.NumDomain.sort R) => @oprob R. +Notation "{ 'oprob' T }" := (@oprob_of _ (Phant T)). +Definition oprob_coercion (R: realType) (p : {oprob R}) : R := OProb.p p. +Notation oprob_to_real o := (Prob.p (OProb.p o)). +(*(R: realType) (o : {oprob R}) := Prob.p (OProb.p o).*) + +Section oprob_lemmas. +Import GRing.Theory. +Local Open Scope ring_scope. +Variable R : realType. +Implicit Types p q : {oprob R}. + +Lemma oprob_gt0 p : 0 < oprob_to_real p. +Proof. by case : p => p /= /andP []. Qed. + +Lemma oprob_lt1 p : oprob_to_real p < 1. +Proof. by case: p => p /= /andP [] _. Qed. + +(*Lemma oprob_ge0 p : 0 <= oprob_to_real p. Proof. exact/ltRW/oprob_gt0. Qed. + +Lemma oprob_le1 p : p <= 1. Proof. exact/ltRW/oprob_lt1. Qed.*) + +Import Order.POrderTheory Order.TotalTheory. + +Lemma oprob_neq0 p : oprob_to_real p != 0 :> R. +Proof. by move:(oprob_gt0 p); rewrite lt_neqAle=> /andP -[] /eqP/nesym/eqP. Qed. + +(*Lemma oprob_neq1 p : p != 1 :> R. +Proof. by move:(oprob_lt1 p); rewrite ltR_neqAle=> -[] /eqP. Qed. + +Lemma oprobK p : p = (p.~).~%:opr. +Proof. by apply/val_inj/val_inj=> /=; rewrite onemK. Qed.*) + + +Lemma prob_trichotomy' (p : {prob R}) (P : {prob R} -> Prop) : + P prob0 -> P prob1 -> (forall o : {oprob R}, P (OProb.p o)) -> P p. +Proof. +move=> p0 p1 po. +have [-> //|[->//|p01]] := prob_trichotomy p. +apply (po (@OProb.mk _ _ p01)). +Qed. +(*Lemma oprobadd_gt0 p q : 0 < p + q. +Proof. exact/addR_gt0/oprob_gt0/oprob_gt0. Qed. + +Lemma oprobadd_neq0 p q : p + q != 0%R. +Proof. by move: (oprobadd_gt0 p q); rewrite ltR_neqAle => -[] /nesym /eqP. Qed. +Qed.*) + +End oprob_lemmas. diff --git a/lib/ssrR.v b/lib/ssrR.v index e019a2fa..80d98d72 100644 --- a/lib/ssrR.v +++ b/lib/ssrR.v @@ -1,6 +1,6 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect. +From mathcomp Require Import all_ssreflect ssralg ssrnum. Require Import Reals. From mathcomp Require Import Rstruct. @@ -53,17 +53,14 @@ From mathcomp Require Import Rstruct. (* Lemma invr_gt0 x : (0 < x^-1) = (0 < x). *) (******************************************************************************) -Reserved Notation "a '>b=' b" (at level 70). -Reserved Notation "a 'b' b" (at level 70). -Reserved Notation "a ' nat -> R *) Notation "x ^- n" := (/ (x ^ n)) : R_scope. @@ -76,37 +73,6 @@ Global Hint Resolve Rlt_R0_R2 : core. Global Hint Resolve Rlt_0_1 : core. Global Hint Resolve Rle_0_1 : core. -Definition leRb a b := if Rle_dec a b is left _ then true else false. -Notation "a 'b=' b" := (geRb a b) : R_scope. - -Definition ltRb (a b : R) := if Rlt_dec a b is left _ then true else false. -Notation "a 'b' b" := (gtRb a b) : R_scope. - -Notation "a ' [/andP[/leRP ? /leRP ?]|[/leRP-> /leRP->]]. -Qed. - -Lemma ltR2P (a b c : R) : reflect (a < b < c) (a [/andP[/ltRP ? /ltRP ?]|[/ltRP-> /ltRP->]]. -Qed. - Definition add0R : left_id 0 Rplus := Rplus_0_l. Definition addR0 : right_id 0 Rplus := Rplus_0_r. @@ -199,19 +165,8 @@ Lemma eqR_mul2r {r r1 r2} : r <> 0 -> (r1 * r = r2 * r) <-> (r1 = r2). Proof. by move=> r0; split => [/Rmult_eq_reg_r/(_ r0)|->]. Qed. Definition ltRR := Rlt_irrefl. -Lemma ltRR' n : (n m <= n := Rlt_le m n. -Lemma ltRW' {a b : R} : a a a <= b <= c. -Proof. by case=> ? ?; split; apply/ltRW. Qed. -Lemma ltR2W' (a b c : R) : a a b != a. Proof. by move=> ab; apply/eqP => ba; move: ab; rewrite ba => /ltRR. Qed. @@ -219,9 +174,6 @@ Proof. by move=> ab; apply/eqP => ba; move: ab; rewrite ba => /ltRR. Qed. Lemma ltR_eqF (r1 r2 : R) : r1 < r2 -> r1 != r2. Proof. by move/Rlt_not_eq/eqP. Qed. -Definition leRR := Rle_refl. -Lemma leRR' r : r y < z -> x < z. Proof. exact: Rlt_trans. Qed. Arguments ltR_trans [_] [_] [_]. @@ -285,48 +237,27 @@ Qed. Lemma leRNlt m n : (m <= n) <-> ~ (n < m). Proof. split; [exact: Rle_not_lt | exact: Rnot_lt_le]. Qed. -Lemma leRNlt' m n : (m [/leRP ? | /ltRP/Rnot_lt_le ?]; - [exact/ltRP/Rle_not_gt | exact/leRP]. -Qed. Lemma ltRNge m n : (m < n) <-> ~ (n <= m). Proof. split; [exact: Rlt_not_le | exact: Rnot_le_lt]. Qed. -Lemma ltRNge' m n : (m ~ (y < x). Proof. by rewrite leRNlt. Qed. -Lemma leRNgt' (x y : R) : (x (m = n) \/ (m < n). Proof. -split => [|[->|]]; [ |exact: leRR|exact: ltRW]. +split => [|[->|]]; [ |exact: Rle_refl|exact: ltRW]. by case/Rle_lt_or_eq_dec => ?; [right|left]. Qed. -Lemma leR_eqVlt' m n : (m [/leRP/leR_eqVlt[/eqP -> //|/ltRP ->]|/orP[/eqP ->|/ltRP]]; - [rewrite orbT|rewrite leRR'|move/ltRP/ltRW']. -Qed. -Lemma ltR_neqAle' m n : (m (m <> n) /\ (m <= n). Proof. -by split => [/ltRP|[/eqP H /leRP K]]; - [rewrite ltR_neqAle' => /andP[/eqP ? /leRP] | - apply/ltRP; rewrite ltR_neqAle' H]. +split. + by move=> /RltP; rewrite Order.POrderTheory.lt_neqAle => /andP[/eqP ? /RleP]. +move=> [/eqP mn /RleP nm]. +by apply/RltP; rewrite Order.POrderTheory.lt_neqAle mn. Qed. -Lemma lt0R x : (0 R) = (n == 0)%N. *) Lemma INR_eq0 n : (n%:R = 0) <-> (n = O). Proof. by split => [|-> //]; rewrite (_ : 0 = 0%:R) // => /INR_eq ->. Qed. @@ -341,13 +272,12 @@ Lemma natRM m n : (m * n)%:R = m%:R * n%:R. Proof. by rewrite mult_INR. Qed. Lemma eqR_le x y : (x = y) <-> (x <= y <= x). -Proof. split => [->| [] ]; by [split; exact/leRR | exact: Rle_antisym]. Qed. +Proof. split => [->| [] ]; by [split; exact/Rle_refl | exact: Rle_antisym]. Qed. Lemma eqR_le_Ngt {x y} : x <= y -> ~ x < y -> y = x. Proof. by case/leR_eqVlt. Qed. Definition leR0n n : 0 <= n%:R := pos_INR n. -Lemma leR0n' n : (0 (O < n)%nat. Proof. by split => [/gtR_eqF/eqP/INR_not_0/Nat.neq_0_lt_0/ltP | /ltP/lt_0_INR]. Qed. -Lemma ltR0n' n : (0 [/ltRP/ltR0n|/ltR0n/ltRP]. Qed. Lemma leR_oppr x y : (x <= - y) <-> (y <= - x). Proof. by split; move/Ropp_le_contravar; rewrite oppRK. Qed. @@ -387,13 +315,9 @@ Definition addR_gt0wr := Rplus_le_lt_0_compat. (* 0 <= r1 -> 0 < r2 -> 0 < r1 + Definition addR_gt0wl := Rplus_lt_le_0_compat. (* 0 < r1 -> 0 <= r2 -> 0 < r1 + r2 *) Definition leR_add := Rplus_le_compat. (* r1 <= r2 -> r3 <= r4 -> r1 + r3 <= r2 + r4 *) -Lemma leR_add' m1 m2 n1 n2 : m1 m2 m1 + m2 ? ?; apply/leRP/Rplus_le_compat; exact/leRP. Qed. Lemma leR_add2r {p m n} : m + p <= n + p <-> m <= n. Proof. by split; [exact: Rplus_le_reg_r | exact: Rplus_le_compat_r]. Qed. -Lemma leR_add2r' p m n : (m + p [/leRP/leR_add2r/leRP //|/leRP/leR_add2r/leRP]. Qed. Lemma leR_add2l {p m n} : p + m <= p + n <-> m <= n. Proof. by split; [exact: Rplus_le_reg_l | exact: Rplus_le_compat_l]. Qed. @@ -402,8 +326,6 @@ Definition ltR_add := Rplus_lt_compat. (* r1 < r2 -> r3 < r4 -> r1 + r3 < r2 + r Lemma ltR_add2r {p m n} : m + p < n + p <-> m < n. Proof. by split; [exact: Rplus_lt_reg_r | exact: Rplus_lt_compat_r]. Qed. -Lemma ltR_add2r' (p m n : R) : (m + p [/ltRP/ltR_add2r/ltRP // | /ltRP/ltR_add2r/ltRP]. Qed. Lemma ltR_add2l {p m n} : p + m < p + n <-> m < n. Proof. by split; [exact: Rplus_lt_reg_l | exact: Rplus_lt_compat_l]. Qed. @@ -416,30 +338,26 @@ split => H. - by move/(@ltR_add2l m) : H; rewrite subRKC. - by apply (@ltR_add2l m); rewrite subRKC. Qed. -Lemma ltR_subRL' m n p : (n /ltRP/ltR_subRL/ltRP. Qed. Lemma ltR_subl_addr x y z : (x - y < z) <-> (x < z + y). Proof. split => H; [apply (@ltR_add2r (-y)) | apply (@ltR_add2r y)]; last by rewrite subRK. -by rewrite -addRA; apply: (ltR_leR_trans H); rewrite Rplus_opp_r addR0; exact/leRR. +by rewrite -addRA; apply: (ltR_leR_trans H); rewrite Rplus_opp_r addR0; exact/Rle_refl. Qed. Lemma leR_subr_addr x y z : (x <= y - z) <-> (x + z <= y). Proof. -split => [|H]; first by move/leRP; rewrite -(leR_add2r' z) subRK => /leRP. -by apply/leRP; rewrite -(leR_add2r' z) subRK; exact/leRP. +split => [|H]. + by move=> /RleP; rewrite RminusE lerBrDr => /RleP. +by apply/RleP; rewrite RminusE lerBrDr; exact/RleP. Qed. -Lemma leR_subr_addr' x y z : (x /leRP/leR_subr_addr/leRP. Qed. Lemma leR_subl_addr x y z : (x - y <= z) <-> (x <= z + y). Proof. -split => [|H]; first by move/leRP; rewrite -(leR_add2r' y) subRK => /leRP. -by apply/leRP; rewrite -(leR_add2r' y) subRK; exact/leRP. +split => [|H]. + by move=> /RleP; rewrite RminusE lerBlDr => /RleP. +by apply/RleP; rewrite RminusE lerBlDr; exact/RleP. Qed. -Lemma leR_subl_addr' x y z : (x - y /leRP/leR_subl_addr/leRP. Qed. Definition leR_sub_addr := (leR_subl_addr, leR_subr_addr). @@ -516,12 +434,6 @@ Lemma leR_pmul2l m n1 n2 : 0 < m -> (m * n1 <= m * n2) <-> (n1 <= n2). Proof. by move=> m0; split; [exact: Rmult_le_reg_l | exact/Rmult_le_compat_l/ltRW]. Qed. -Lemma leR_pmul2l' m n1 n2 : 0 (m * n1 /ltRP Hm. -apply/idP/idP; first by move/leRP/leR_pmul2l => /(_ Hm)/leRP. -by move/leRP/(leR_wpmul2l (ltRW Hm))/leRP. -Qed. Lemma leR_pmul2r m n1 n2 : 0 < m -> (n1 * m <= n2 * m) <-> (n1 <= n2). Proof. @@ -533,8 +445,6 @@ Proof. by move=> m0; split; [exact: Rmult_lt_reg_l | exact/Rmult_lt_compat_l]. Q Lemma ltR_pmul2r m n1 n2 : 0 < m -> (n1 * m < n2 * m) <-> (n1 < n2). Proof. by move=> m0; split; [exact: Rmult_lt_reg_r | exact/Rmult_lt_compat_r]. Qed. -Lemma leR_pmul2r' m n1 n2 : 0 (n1 * m Hm; rewrite -!(mulRC m) leR_pmul2l'. Qed. Lemma pmulR_lgt0 x y : 0 < x -> (0 < y * x) <-> (0 < y). Proof. by move=> x0; rewrite -{1}(mul0R x) ltR_pmul2r. Qed. @@ -557,7 +467,7 @@ Arguments pmulR_lgt0 [_] [_]. Lemma leR_pmull m n : 1 <= n -> 0 <= m -> m <= n * m. Proof. -move=> n1 m0; case/boolP : (m == 0) => [/eqP ->|m0']; first by rewrite mulR0; exact/leRR. +move=> n1 m0; case/boolP : (m == 0) => [/eqP ->|m0']; first by rewrite mulR0; exact/Rle_refl. by rewrite -{1}(mul1R m) leR_pmul2r // ltR_neqAle; split => //; apply/eqP; rewrite eq_sym. Qed. @@ -566,19 +476,12 @@ Proof. by move=> n1 m0; rewrite mulRC; apply leR_pmull. Qed. Lemma leR_nat m n : (m%:R <= n%:R) <-> (m <= n)%nat. Proof. by split => [/INR_le/leP|/leP/le_INR]. Qed. -Lemma leR_nat' m n : (m%:R [/leRP/leR_nat|/leR_nat/leRP]. Qed. Lemma ltR_nat m n : (m%:R < n%:R) <-> (m < n)%nat. Proof. by split => [/INR_lt/ltP|/ltP/lt_INR]. Qed. -Lemma ltR_nat' m n : (m%:R [/ltRP/ltR_nat|/ltR_nat/ltRP]. Qed. - -Lemma ltR0n_neq0 n : (0 < n)%nat <-> n%:R != 0. -Proof. by rewrite lt0n; split => /eqP /INR_eq0 /eqP. Qed. Lemma ltR0n_neq0' n : (0 < n)%nat = (n%:R != 0). -Proof. by apply/(sameP idP)/(iffP idP) => /ltR0n_neq0. Qed. +Proof. by rewrite lt0n INR_eq0'. Qed. (*************) (* invR/divR *) @@ -613,9 +516,6 @@ Proof. by move=> /eqP r10 /eqP r20; rewrite Rinv_mult. Qed. Lemma leR_inv x y : 0 < y -> y <= x -> / x <= / y. Proof. by move=> x0 y0; apply/Rinv_le_contravar. Qed. -(* NB: Rle_Rinv does the same as Rinv_le_contravar with one more hypothesis *) -Lemma leR_inv' : {in [pred x | true] & [pred x | 0 a b; rewrite !inE => _ /ltRP b0 ba; exact/Rinv_le_contravar. Qed. Lemma invR_le x y : 0 < x -> 0 < y -> / y <= / x -> x <= y. Proof. @@ -672,12 +572,6 @@ move=> z0; split => [/(leR_wpmul2l (ltRW z0))|H]. - rewrite mulRC mulRCA mulRV ?mulR1 //; exact/gtR_eqF. - apply/(@leR_pmul2r z) => //; rewrite -mulRA mulVR ?mulR1 //; exact/gtR_eqF. Qed. -Lemma leR_pdivl_mulr' z x y : 0 < z -> (x z0; apply/idP/idP => /leRP. -- by rewrite leR_pdivl_mulr // => /leRP. -- by rewrite -leR_pdivl_mulr // => /leRP. -Qed. Lemma ltR_pdivl_mulr z x y : 0 < z -> (x < y / z) <-> (x * z < y). Proof. @@ -685,12 +579,6 @@ move=> z0; split => [/(ltR_pmul2l z0)|H]. - by rewrite mulRC mulRCA mulRV ?mulR1 //; exact/gtR_eqF. - by apply/(@ltR_pmul2r z) => //; rewrite -mulRA mulVR ?mulR1 //; exact/gtR_eqF. Qed. -Lemma ltR_pdivl_mulr' z x y : 0 < z -> (x z0; apply/idP/idP => /ltRP. -- by rewrite ltR_pdivl_mulr // => /ltRP. -- by rewrite -ltR_pdivl_mulr // => /ltRP. -Qed. Lemma eqR_divr_mulr z x y : z != 0 -> (y / z = x) <-> (y = x * z). Proof. @@ -707,12 +595,6 @@ move=> z0; split => [/(leR_wpmul2r (ltRW z0))|H]. - by rewrite -mulRA mulVR ?mulR1 //; exact/gtR_eqF. - by apply/(@leR_pmul2r z) => //; rewrite -mulRA mulVR ?mulR1 //; exact/gtR_eqF. Qed. -Lemma leR_pdivr_mulr' z x y : 0 < z -> (y / z z0; apply/idP/idP => /leRP. -- by rewrite leR_pdivr_mulr // => /leRP. -- by rewrite -leR_pdivr_mulr // => /leRP. -Qed. Lemma ltR_pdivr_mulr z x y : 0 < z -> (y / z < x) <-> (y < x * z). Proof. @@ -720,17 +602,9 @@ move=> z0; split => [/(ltR_pmul2r z0)|H]. - by rewrite -mulRA mulVR ?mulR1 //; exact/gtR_eqF. - by apply/(@ltR_pmul2r z) => //; rewrite -mulRA mulVR ?mulR1 //; exact/gtR_eqF. Qed. -Lemma ltR_pdivr_mulr' z x y : 0 < z -> (y / z z0; apply/idP/idP => /ltRP. -- by rewrite ltR_pdivr_mulr // => /ltRP. -- by rewrite -ltR_pdivr_mulr // => /ltRP. -Qed. Lemma invR_le1 x : 0 < x -> (/ x <= 1) <-> (1 <= x). Proof. by move=> x0; rewrite -(div1R x) leR_pdivr_mulr // mul1R. Qed. -Lemma invR_le1' x : 0 < x -> (/ x x0; apply/idP/idP => /leRP/(invR_le1 _ x0)/leRP. Qed. Lemma invR_gt1 x : 0 < x -> (1 < / x) <-> (x < 1). Proof. @@ -738,8 +612,6 @@ move=> x0; split => x1; last by rewrite -invR1; apply ltR_inv. move/ltR_inv : x1; rewrite invRK invR1. by apply => //; exact/invR_gt0. Qed. -Lemma invR_gt1' x : 0 < x -> (1 x0; apply/idP/idP => /ltRP/(invR_gt1 _ x0)/ltRP. Qed. (*******) (* pow *) @@ -766,7 +638,7 @@ Proof. by move=> ?; elim => [/= | n IH] => //; exact: mulR_gt0. Qed. Lemma expR_ge0 x : 0 <= x -> forall n : nat, 0 <= x ^ n. Proof. move=> x_pos; elim => [// | n IH]. -by rewrite -(mulR0 0); apply leR_pmul => //; exact/leRR. +by rewrite -(mulR0 0); apply leR_pmul => //; apply/RleP; rewrite Order.POrderTheory.lexx. Qed. Lemma expR_neq0 x (n : nat) : x != 0 -> x ^ n != 0. @@ -799,12 +671,14 @@ Qed. Lemma leR_wiexpR2l x : 0 <= x -> x <= 1 -> {homo (pow x) : m n / (n <= m)%nat >-> m <= n}. Proof. -move/leRP; rewrite le0R => /orP[/eqP -> _ m n|/ltRP x0 x1 m n /leP nm]. +move/RleP; rewrite Num.Theory.le0r=> /orP[/eqP -> _ m n|/RltP x0 x1 m n /leP nm]. case: n => [|n nm]. - case: m => [_ |m _]; first exact/leRR. + case: m => [_ |m _]. + by apply/RleP; rewrite Order.POrderTheory.lexx. by rewrite pow_ne_zero. rewrite pow_ne_zero; last by case: m nm. - by rewrite pow_ne_zero //; exact/leRR. + rewrite pow_ne_zero //. + by apply/RleP; rewrite Order.POrderTheory.lexx. apply invR_le => //. - exact/expR_gt0. - exact/expR_gt0. @@ -853,29 +727,14 @@ Notation "'max(' x ',' y ')'" := (Rmax x y) : R_scope. Module ROrder. -Lemma minRE x y : min(x, y) = if (x /ltRP; [move/ltRW/Rmin_left|rewrite -leRNgt => /Rmin_right]. +by case: ifP => /RltP; [move/ltRW/Rmin_left|rewrite -leRNgt => /Rmin_right]. Qed. -Lemma maxRE x y : max(x, y) = if (x /ltRP; [move/ltRW/Rmax_right|rewrite -leRNgt => /Rmax_left]. -Qed. - -Lemma ltR_def x y : (x x x y /andP[/leRP xy /leRP yx]; rewrite eqR_le. Qed. - -Lemma leR_trans : transitive (fun x y => x z x y => /leRP xz /leRP zy; apply/leRP/(leR_trans xz). Qed. - -Lemma leR_total : forall x y, (x x y; case: (Rle_or_lt x y) => xy; apply/orP; - [left; exact/leRP|right; exact/leRP/ltRW]. +by case: ifP => /RltP; [move/ltRW/Rmax_right|rewrite -leRNgt => /Rmax_left]. Qed. End ROrder. @@ -884,7 +743,10 @@ Definition maxRA : associative Rmax := Rmax_assoc. Definition maxRC : commutative Rmax := Rmax_comm. Lemma maxRR : idempotent Rmax. -Proof. move=> x; rewrite Rmax_left //; exact/leRR. Qed. +Proof. +move=> x; rewrite Rmax_left //. +by apply/RleP; rewrite Order.POrderTheory.lexx. +Qed. Definition leR_maxl m n : m <= max(m, n) := Rmax_l m n. Definition leR_maxr m n : n <= max(m, n) := Rmax_r m n. @@ -894,14 +756,9 @@ Definition geR_minr m n : min(m, n) <= n := Rmin_r m n. Lemma leR_max x y z : max(y, z) <= x <-> (y <= x) /\ (z <= x). Proof. split => [| [yx zx] ]. - move/leRP; rewrite leR_eqVlt' => /orP[/eqP <-|/ltRP/Rmax_Rlt]. + move/RleP. + rewrite Order.POrderTheory.le_eqVlt => /orP[/eqP <-|/RltP/Rmax_Rlt]. by split; [exact: leR_maxl | exact: leR_maxr]. by case=> ?; split; exact/ltRW. by rewrite -(Rmax_right _ _ yx); exact: Rle_max_compat_l. Qed. - -Lemma leR_max' x y z : (max(y, z) [/leRP/leR_max[] /leRP -> /leRP -> //|]. -by case/andP=> /leRP ? /leRP ?; exact/leRP/leR_max. -Qed. diff --git a/lib/ssrZ.v b/lib/ssrZ.v index efc51962..bf5eae8b 100644 --- a/lib/ssrZ.v +++ b/lib/ssrZ.v @@ -9,6 +9,8 @@ Require Import ZArith Lia. (* On the model of ssrR *) (******************************************************************************) +(* TODO: we should maybe extend mczify's ssrZ... *) + Reserved Notation "n %:Z" (at level 2, left associativity, format "n %:Z"). Declare Scope zarith_ext_scope. diff --git a/lib/ssr_ext.v b/lib/ssr_ext.v index 0717bf9c..85f36183 100644 --- a/lib/ssr_ext.v +++ b/lib/ssr_ext.v @@ -962,8 +962,7 @@ Qed. Lemma perm_on_Sn (s : 'S_n) : perm_on [set x | x \in enum 'I_n] s. Proof. apply/subsetP=> /= x _; by rewrite !in_set mem_enum. Qed. -(* TODO: check if used *) -Lemma perm_eq_enum (s : 'S_n) : perm_eq (enum 'I_n) (map (s^-1)%g (enum 'I_n)). +(*Lemma perm_eq_enum (s : 'S_n) : perm_eq (enum 'I_n) (map (s^-1)%g (enum 'I_n)). Proof. apply uniq_perm. - by apply enum_uniq. @@ -977,7 +976,7 @@ apply uniq_perm. + symmetry; apply/mapP; case=> x Hx Hxxi. move: (perm_closed x (perm_on_Sn (s^-1)%g)). by rewrite !in_set -Hxxi Hx Hi. -Qed. +Qed.*) End perm_enum. diff --git a/lib/ssralg_ext.v b/lib/ssralg_ext.v index 103bc58e..33b841f4 100644 --- a/lib/ssralg_ext.v +++ b/lib/ssralg_ext.v @@ -1,6 +1,6 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup perm finalg zmodp. +From mathcomp Require Import all_ssreflect ssralg fingroup finalg perm zmodp. From mathcomp Require Import matrix mxalgebra vector. Require Import ssr_ext f2. diff --git a/lib/vandermonde.v b/lib/vandermonde.v index 81bc06af..aded7f3a 100644 --- a/lib/vandermonde.v +++ b/lib/vandermonde.v @@ -1,6 +1,6 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg perm zmodp. +From mathcomp Require Import all_ssreflect ssralg perm zmodp. From mathcomp Require Import matrix. Require Import ssralg_ext. diff --git a/meta.yml b/meta.yml index afde918b..ef7c4102 100644 --- a/meta.yml +++ b/meta.yml @@ -42,38 +42,42 @@ nix: true supported_coq_versions: text: Coq 8.17 - opam: '{ (>= "8.17" & < "8.18~") | (= "dev") }' + opam: '{ (>= "8.17" & < "8.19~") | (= "dev") }' tested_coq_opam_versions: -- version: '1.16.0-coq-8.17' - repo: 'mathcomp/mathcomp' - version: '1.17.0-coq-8.17' repo: 'mathcomp/mathcomp' +- version: '1.18.0-coq-8.17' + repo: 'mathcomp/mathcomp' +- version: '1.17.0-coq-8.18' + repo: 'mathcomp/mathcomp' +- version: '1.18.0-coq-8.18' + repo: 'mathcomp/mathcomp' dependencies: - opam: name: coq-mathcomp-ssreflect - version: '{ (>= "1.16.0" & < "1.18~") | (= "dev") }' + version: '{ (>= "1.16.0" & < "1.19~") | (= "dev") }' description: |- [MathComp ssreflect](https://math-comp.github.io) - opam: name: coq-mathcomp-fingroup - version: '{ (>= "1.16.0" & < "1.18~") | (= "dev") }' + version: '{ (>= "1.16.0" & < "1.19~") | (= "dev") }' description: |- [MathComp fingroup](https://math-comp.github.io) - opam: name: coq-mathcomp-algebra - version: '{ (>= "1.16.0" & < "1.18~") | (= "dev") }' + version: '{ (>= "1.16.0" & < "1.19~") | (= "dev") }' description: |- [MathComp algebra](https://math-comp.github.io) - opam: name: coq-mathcomp-solvable - version: '{ (>= "1.16.0" & < "1.18~") | (= "dev") }' + version: '{ (>= "1.16.0" & < "1.19~") | (= "dev") }' description: |- [MathComp solvable](https://math-comp.github.io) - opam: name: coq-mathcomp-field - version: '{ (>= "1.16.0" & < "1.18~") | (= "dev") }' + version: '{ (>= "1.16.0" & < "1.19~") | (= "dev") }' description: |- [MathComp field](https://math-comp.github.io) - opam: @@ -83,9 +87,15 @@ dependencies: [MathComp analysis](https://github.com/math-comp/analysis) - opam: name: coq-hierarchy-builder - version: '{ >= "1.3.0" }' + version: '{ = "1.5.0" }' description: |- [Hierarchy Builder](https://github.com/math-comp/hierarchy-builder) +- opam: + name: coq-mathcomp-algebra-tactics + version: '{ = "1.1.1" }' + description: |- + MathComp algebra tactics + namespace: infotheo keywords: diff --git a/probability/bayes.v b/probability/bayes.v index 8cbeea3b..4932d25a 100644 --- a/probability/bayes.v +++ b/probability/bayes.v @@ -1,6 +1,6 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup perm finalg matrix. +From mathcomp Require Import all_ssreflect ssralg ssrnum matrix. From mathcomp Require boolp. From mathcomp Require Import Rstruct. Require Import Reals. (* Lra Nsatz. *) @@ -32,6 +32,8 @@ Set Implicit Arguments. Unset Strict Implicit. Import Prenex Implicits. +Import Num.Theory. + Section ssr_ext. Lemma tnth_uniq (T : eqType) n (t : n.-tuple T) (i j : 'I_n) : uniq t -> (t \_ i == t \_ j) = (i == j). @@ -107,7 +109,7 @@ Qed. End fin_img. Section proba. (* proba.v ? *) -Variables (U : finType) (P : fdist U). +Variables (U : finType) (P : {fdist U}). Definition fdist_choice' : U. move: (fdist_card_neq0 P). @@ -323,9 +325,7 @@ End univ_types. Module BN. Section bn. -Variable U : finType. -Variable P : fdist U. -Variable n : nat. +Variables (U : finType) (P : {fdist U}) (n : nat). Section preim. Local Open Scope R_scope. @@ -405,7 +405,7 @@ Definition cinde_preim (e f g : {set 'I_n}) := (preim_vars f vals) (preim_vars g vals). -Lemma cinde_eventsC A (Q : fdist A) (E F G : {set A}) : +Lemma cinde_eventsC A (Q : fdist _ A) (E F G : {set A}) : cinde_events Q E F G -> cinde_events Q F E G. Proof. rewrite /cinde_events => Hef; by rewrite setIC mulRC. Qed. @@ -733,8 +733,7 @@ have : Pr P (preim_vars (e :&: f :|: g) rewrite -HB set_vals_prod_vars ?ffunE //. move: Hk; cases_in k. rewrite -(@nth_fin_imgK U). - move/psumR_eq0P: Hnum; apply. - move => *; by apply sumR_ge0. + move/psumr_eq0P: Hnum; apply; first by move => *; exact/RleP. apply/eqP => /(f_equal (fun x => nth_fin_img x)). rewrite !nth_fin_imgK => /(prod_types_app i) /prod_vals_eqP Hi. elim: Hvi; rewrite -He //. @@ -887,9 +886,7 @@ End BN. Section Factorization. Import BN. -Variable U : finType. -Variable P : fdist U. -Variable n : nat. +Variables (U : finType) (P : {fdist U}) (n : nat). Variable types : 'I_n -> finType. Variable vars : forall i, {RV P -> types i}. Variable bn : t vars. diff --git a/probability/convex.v b/probability/convex.v index 3627aaf4..2190e284 100644 --- a/probability/convex.v +++ b/probability/convex.v @@ -1,13 +1,17 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) From HB Require Import structures. -From mathcomp Require Import all_ssreflect ssralg fingroup perm finalg matrix. -From mathcomp Require Import boolp classical_sets Rstruct. +From mathcomp Require Import all_ssreflect ssralg fingroup perm matrix. +From mathcomp Require Import mathcomp_extra boolp classical_sets Rstruct. From mathcomp Require Import ssrnum ereal. +From mathcomp Require Import lra Rstruct reals. Require Import Reals. -Require Import ssrR Reals_ext Lra Ranalysis_ext ssr_ext ssralg_ext logb Rbigop. -Require Import fdist. -From mathcomp Require ssrnum vector. +Require Import ssrR Rstruct_ext Reals_ext Ranalysis_ext ssr_ext ssralg_ext logb Rbigop. +Require Import realType_ext fdist. +From mathcomp Require vector. + +Undelimit Scope R_scope. +Delimit Scope R_scope with coqR. (******************************************************************************) (* Convexity *) @@ -134,39 +138,61 @@ Import Prenex Implicits. Local Open Scope reals_ext_scope. Local Open Scope fdist_scope. +Import Order.POrderTheory GRing.Theory Num.Theory. + +Local Notation "{ 'fdist' T }" := (fdist_of _ (Phant T)) : fdist_scope. + +#[export] Hint Extern 0 (0 <= _)%coqR => + solve [apply/RleP/(FDist.ge0 _)] : core. +#[export] Hint Extern 0 (_ <= 1)%coqR => + solve [apply/RleP/(FDist.le1 _)] : core. +#[export] Hint Extern 0 (0 <= Prob.p _)%coqR => + solve [apply/RleP/(prob_ge0 _)] : core. +#[export] Hint Extern 0 (Prob.p _ <= 1)%coqR => + solve [apply/RleP/(prob_le1 _)] : core. + +#[export] Hint Extern 0 (onem _ <= 1)%coqR => + exact/RleP/onem_le1 : core. +#[export] Hint Extern 0 (0 <= onem _)%coqR => + exact/RleP/onem_ge0 : core. + (* TODO: the following lemmas are currently not in use. Maybe remove? *) Section tmp. -Lemma fdist_convn_Add - (n m : nat) (d1 : {fdist 'I_n}) (d2 : {fdist 'I_m}) (p : prob) - (A : finType) (g : 'I_n -> fdist A) (h : 'I_m -> fdist A) : +Local Open Scope ring_scope. + +Lemma fdist_convn_Add (R : realType) + (n m : nat) (d1 : {fdist 'I_n}) (d2 : {fdist 'I_m}) (p : {prob R}) + (A : finType) (g : 'I_n -> {fdist A}) (h : 'I_m -> {fdist A}) : fdist_convn (fdist_add d1 d2 p) [ffun i => match fintype.split i with inl a => g a | inr a => h a end] = (fdist_convn d1 g <| p |> fdist_convn d2 h)%fdist. Proof. apply/fdist_ext => a; rewrite !fdist_convE !fdist_convnE. -rewrite 2!big_distrr /= big_split_ord /=; congr (_ + _)%R; +rewrite 2!big_distrr /= big_split_ord /=; congr (_ + _); apply eq_bigr => i _; rewrite fdist_addE ffunE. case: splitP => /= j ij. -rewrite mulRA; congr (_ * d1 _ * (g _) a)%R; exact/val_inj. +rewrite mulrA; congr (_ * d1 _ * (g _) a); exact/val_inj. move: (ltn_ord i); by rewrite ij -ltn_subRL subnn ltn0. case: splitP => /= j ij. move: (ltn_ord j); by rewrite -ij -ltn_subRL subnn ltn0. move/eqP : ij; rewrite eqn_add2l => /eqP ij. -rewrite mulRA; congr (_ * d2 _ * (h _) a)%R; exact/val_inj. +rewrite mulrA; congr (_ * d2 _ * (h _) a); exact/val_inj. Qed. +Import realType_ext. Lemma fdist_convn_del - (A : finType) (n : nat) (g : 'I_n.+1 -> fdist A) (P : {fdist 'I_n.+1}) - (j : 'I_n.+1) (H : (0 <= P j <= 1)%R) (Pj1 : P j != 1%R) : + (R : realType) + (A : finType) (n : nat) (g : 'I_n.+1 -> {fdist A}) (P : {fdist 'I_n.+1}) + (j : 'I_n.+1) (H : (0 <= P j <= 1)) (Pj1 : P j != 1) : let g' := fun i : 'I_n => g (fdist_del_idx j i) in fdist_convn P g = - (g j <| Prob.mk_ H |> fdist_convn (fdist_del Pj1) g')%fdist. + (g j <| @Prob.mk_ R _ H |> fdist_convn (fdist_del Pj1) g')%fdist. Proof. move=> g' /=; apply/fdist_ext => a. -rewrite fdist_convE /= fdist_convnE (bigD1 j) //=; congr (_ + _)%R. +rewrite fdist_convE /= fdist_convnE (bigD1 j) //=; congr (_ + _). rewrite fdist_convnE big_distrr /=. rewrite (bigID (fun i : 'I_n.+1 => (i < j)%nat)) //=. -rewrite (bigID (fun i : 'I_n => (i < j)%nat)) //=; congr (_ + _)%R. +rewrite (bigID (fun i : 'I_n => (i < j)%nat)) //=; congr (_ + _). rewrite (@big_ord_narrow_cond _ _ _ j n.+1); first by rewrite ltnW. move=> jn; rewrite (@big_ord_narrow_cond _ _ _ j n xpredT); first by rewrite -ltnS. move=> jn'. @@ -175,15 +201,16 @@ rewrite (bigID (fun i : 'I_n => (i < j)%nat)) //=; congr (_ + _)%R. move=> /= i _. rewrite fdist_delE /= ltn_ord fdistD1E /= ifF /=; last first. by apply/negP => /eqP/(congr1 val) /=; apply/eqP; rewrite ltn_eqF. - rewrite mulRA mulRCA mulRV ?mulR1 ?onem_neq0 //. - congr (P _ * _)%R; first exact/val_inj. + rewrite mulrA mulrCA mulrV ?mulr1; last first. +rewrite unitfE. rewrite onem_neq0 ?onem_neq0 //. + congr (P _ * _); first exact/val_inj. by rewrite /g' /fdist_del_idx /= ltn_ord; congr (g _ a); exact/val_inj. rewrite (eq_bigl (fun i : 'I_n.+1 => (j < i)%nat)); last first. move=> i; by rewrite -leqNgt eq_sym -ltn_neqAle. rewrite (eq_bigl (fun i : 'I_n => (j <= i)%nat)); last first. move=> i; by rewrite -leqNgt. rewrite big_mkcond. -rewrite big_ord_recl ltn0 /= add0R. +rewrite big_ord_recl ltn0 /= add0r. rewrite [in RHS]big_mkcond. apply eq_bigr => i _. rewrite /bump add1n ltnS; case: ifPn => // ji. @@ -191,7 +218,7 @@ rewrite fdist_delE fdistD1E ltnNge ji /= ifF; last first. apply/eqP => /(congr1 val) => /=. rewrite /bump add1n => ij. by move: ji; apply/negP; rewrite -ij ltnn. -rewrite /Rdiv mulRAC [in RHS] mulRC -mulRA mulVR // ?mulR1 ?onem_neq0 //. + rewrite -mulrAC [in RHS]mulrC 3!mulrA divrr ?mul1r ?unitfE ?onem_neq0 //. by rewrite /g' /fdist_del_idx ltnNge ji. Qed. End tmp. @@ -224,13 +251,14 @@ End fintype_extra. Module CodomDFDist. Section def. Local Open Scope classical_set_scope. -Variables (A : Type) (n : nat) (g : 'I_n -> A) (e : {fdist 'I_n}) (y : set A). -Definition f := [ffun i : 'I_n => if g i \in y then e i else 0%R]. -Lemma f0 i : (0 <= f i)%R. -Proof. rewrite /f ffunE; case: ifPn => _ //; exact/leRR. Qed. +Local Open Scope ring_scope. +Variables (R: realType) (A : Type) (n : nat) (g : 'I_n -> A). +Variables (e : fdist_of R (Phant 'I_n)) (y : set A). +Definition f := [ffun i : 'I_n => if g i \in y then e i else 0]. +Lemma f0 i : (0 <= f i). Proof. by rewrite /f ffunE; case: ifPn. Qed. Lemma f1 (x : set A) (gX : g @` setT `<=` x `|` y) - (ge : forall i : 'I_n, x (g i) -> e i = 0%R) : - (\sum_(i < n) f i = 1)%R. + (ge : forall i : 'I_n, x (g i) -> e i = 0) : + (\sum_(i < n) f i = 1). Proof. rewrite /f -(FDist.f1 e) /=. apply eq_bigr => i _; rewrite ffunE. @@ -240,15 +268,15 @@ have : (x `|` y) (g i) by apply/gX; by exists i. by case. Qed. Definition d (x : set A) (gX : g @` setT `<=` x `|` y) - (ge : forall i : 'I_n, x (g i) -> e i = 0%R) : {fdist 'I_n} := + (ge : forall i : 'I_n, x (g i) -> e i = 0) : {fdist 'I_n} := locked (FDist.make f0 (f1 gX ge)). Lemma dE (x : set A) (gX : g @` setT `<=` x `|` y) - (ge : forall i : 'I_n, x (g i) -> e i = 0%R) i : - d gX ge i = if g i \in y then e i else 0%R. + (ge : forall i : 'I_n, x (g i) -> e i = 0) i : + d gX ge i = if g i \in y then e i else 0. Proof. by rewrite /d; unlock; rewrite ffunE. Qed. Lemma f1' (x : set A) (gX : g @` setT `<=` x `|` y) - (ge : forall i : 'I_n, (x (g i)) /\ (~ y (g i)) -> e i = 0%R) : - (\sum_(i < n) f i = 1)%R. + (ge : forall i : 'I_n, (x (g i)) /\ (~ y (g i)) -> e i = 0) : + (\sum_(i < n) f i = 1). Proof. rewrite /f -(FDist.f1 e) /=; apply eq_bigr => i _; rewrite ffunE. case: ifPn => // /negP; rewrite in_setE => giy. @@ -257,23 +285,23 @@ have : (x `|` y) (g i) by apply/gX; by exists i. by case. Qed. Definition d' (x : set A) (gX : g @` setT `<=` x `|` y) - (ge : forall i : 'I_n, (x (g i)) /\ (~ y (g i)) -> e i = 0%R) := + (ge : forall i : 'I_n, (x (g i)) /\ (~ y (g i)) -> e i = 0) := locked (FDist.make f0 (f1' gX ge)). Lemma dE' (x : set A) (gX : g @` setT `<=` x `|` y) - (ge : forall i : 'I_n, (x (g i)) /\ (~ y (g i)) -> e i = 0%R) i : - d' gX ge i = if g i \in y then e i else 0%R. + (ge : forall i : 'I_n, (x (g i)) /\ (~ y (g i)) -> e i = 0) i : + d' gX ge i = if g i \in y then e i else 0. Proof. by rewrite /d'; unlock; rewrite ffunE. Qed. End def. End CodomDFDist. - Module isConvexSpace_. + HB.mixin Record isConvexSpace (T : Type) := { convexspacechoiceclass : Choice.class_of T ; - conv : prob -> T -> T -> T ; + conv : {prob R} -> T -> T -> T ; conv1 : forall a b, conv 1%:pr a b = a ; convmm : forall p a, conv p a a = a ; - convC : forall p a b, conv p a b = conv p.~%:pr b a; - convA : forall (p q : prob) (a b c : T), + convC : forall p a b, conv p a b = conv (onem (Prob.p p))%:pr b a ; + convA : forall (p q : {prob R}) (a b c : T), conv p a (conv q b c) = conv [s_of p, q] (conv [r_of p, q] a b) c }. #[short(type=convType)] @@ -297,6 +325,8 @@ Local Open Scope convex_scope. Section convex_space_lemmas. Variables A : convType. Implicit Types a b : A. +Import Reals_ext. + Lemma conv0 a b : a <| 0%:pr |> b = b. Proof. @@ -306,10 +336,10 @@ End convex_space_lemmas. Section segment. Variable A : convType. -Definition segment (x y : A) : set A := (fun p => conv p x y) @` [set: prob]. +Definition segment (x y : A) : set A := (fun p => conv p x y) @` [set: {prob R}]. Lemma segment_sym u v : (segment u v `<=` segment v u)%classic. -Proof. by move=> x [p _ <-]; exists (p.~%:pr); rewrite -?convC. Qed. +Proof. by move=> x [p _ <-]; exists ((Prob.p p).~%:pr); rewrite -?convC. Qed. Lemma segmentC u v : segment u v = segment v u. Proof. by rewrite eqEsubset; split; exact: segment_sym. Qed. @@ -320,17 +350,19 @@ Lemma segmentR x y : segment x y y. Proof. by exists 0%:pr; rewrite ?conv0. Qed. End segment. + Fixpoint Convn (A : convType) n : {fdist 'I_n} -> ('I_n -> A) -> A := match n return forall (e : {fdist 'I_n}) (g : 'I_n -> A), A with | O => fun e g => False_rect A (fdistI0_False e) | m.+1 => fun e g => - match Bool.bool_dec (e ord0 == 1%R) true with + match Bool.bool_dec (e ord0 == 1%coqR) true with | left _ => g ord0 | right H => let G := fun i => g (fdist_del_idx ord0 i) in g ord0 <| probfdist e ord0 |> Convn (fdist_del (Bool.eq_true_not_negb _ H)) G end end. + Notation "'<|>_' d f" := (Convn d f) : convex_scope. Definition affine (U V : convType) (f : U -> V) := @@ -393,15 +425,15 @@ Definition S1_inj : injective S1 := @Scaled_inj Rpos1. Definition raw_weight (pt : scaled) : R := if pt is r *: _ then r else 0. -Lemma weight_ge0 pt : (0 <= raw_weight pt)%R. -Proof. case: pt => /= [[x] /= /ltRP/ltRW //|]; by apply leRR. Qed. +Lemma weight_ge0 pt : (0 <= raw_weight pt)%coqR. +Proof. by case: pt => /= [[x] /= /RltP/ltRW //|]. Qed. Definition weight := mkNNFun weight_ge0. -Definition point pt : (weight pt > 0)%R -> A := +Definition point pt : (weight pt > 0)%coqR -> A := match pt with | t *: a => fun=> a - | Zero => fun H : (weight Zero > 0)%R => match ltRR 0 H with end + | Zero => fun H : (weight Zero > 0)%coqR => match ltRR 0 H with end end. Lemma point_Scaled p x H : @point (p *: x) H = x. @@ -432,11 +464,12 @@ Variable A : eqType. Lemma S1_neq0 a : S1 a != @Zero A. Proof. by []. Qed. -Lemma weight_gt0 a : a != @Zero A -> (0 < weight a)%R. +(* TODO: rm? *) +Lemma weight_gt0 a : a != @Zero A -> (0 < weight a)%coqR. Proof. by case: a => // p x _ /=. Qed. -Lemma weight_gt0b a : a != @Zero A -> (weight a >b 0)%R. -Proof. by move=> ?; exact/ltRP/weight_gt0. Qed. +Lemma weight_gt0b a : a != @Zero A -> (weight a > 0)%mcR. +Proof. by move=> ?; exact/RltP/weight_gt0. Qed. Definition weight_neq0 a (a0 : a != @Zero A) := Rpos.mk (weight_gt0b a0). @@ -448,7 +481,7 @@ Local Notation "[ 'weight' 'of' x ]" := (weight_neq0 x) Lemma point_S1 a : [point of S1_neq0 a] = a. Proof. by []. Qed. -Lemma weight0_Zero a : weight a = 0%R -> a = @Zero A. +Lemma weight0_Zero a : weight a = 0%coqR -> a = @Zero A. Proof. by case: a => //= r c /esym Hr; move/ltR_eqF: (Rpos_gt0 r) => /eqP. Qed. End scaled_eqType. @@ -465,11 +498,11 @@ HB.mixin Record isQuasiRealCone A := { addptA : associative addpt ; addpt0 : right_id zero addpt ; scalept : R -> A -> A ; - scale0pt : forall x, scalept 0%R x = zero ; - scale1pt : forall x, scalept 1%R x = x ; + scale0pt : forall x, scalept 0%coqR x = zero ; + scale1pt : forall x, scalept 1%coqR x = x ; scaleptDr : forall r, {morph scalept r : x y / addpt x y >-> addpt x y} ; - scaleptA : forall p q x, (0 <= p)%R -> (0 <= q)%R -> - scalept p (scalept q x) = scalept (p * q)%R x }. + scaleptA : forall p q x, (0 <= p)%coqR -> (0 <= q)%coqR -> + scalept p (scalept q x) = scalept (p * q)%coqR x }. #[short(type=quasiRealCone)] HB.structure Definition QuasiRealCone := { A & isQuasiRealCone A}. @@ -486,7 +519,7 @@ Variable A : quasiRealCone. Lemma add0pt : left_id (@zero A) addpt. Proof. by move=> ?; rewrite addptC addpt0. Qed. -Lemma scalept0 p : (0 <= p)%R -> scalept p zero = @zero A. +Lemma scalept0 p : (0 <= p)%coqR -> scalept p zero = @zero A. Proof. by move=> p0; rewrite -[in LHS](scale0pt zero) scaleptA// mulR0 scale0pt. Qed. @@ -510,7 +543,7 @@ Lemma barycenter_map (T : finType) (F : T -> A) : barycenter [seq F i | i <- enum T] = \ssum_i F i. Proof. by rewrite /barycenter big_map big_filter. Qed. -Lemma scalept_barycenter p (H : (0 <= p)%R) pts : +Lemma scalept_barycenter p (H : (0 <= p)%coqR) pts : scalept p (barycenter pts) = barycenter [seq scalept p i | i <- pts]. Proof. by rewrite big_morph_scalept ?scalept0// /barycenter big_map. Qed. @@ -531,8 +564,8 @@ Notation "\ssum_ ( i < n | P ) F" := (\big[addpt/@zero _]_(i < n | P%B) F). Notation "\ssum_ ( i < n ) F" := (\big[addpt/@zero _]_(i < n) F). HB.mixin Record isRealCone (A : Type) of isQuasiRealCone A := { - scaleptDl : forall p q x, (0 <= p)%R -> (0 <= q)%R -> - @scalept [the quasiRealCone of A] (p + q)%R x = addpt (scalept p x) (scalept q x) }. + scaleptDl : forall p q x, (0 <= p)%coqR -> (0 <= q)%coqR -> + @scalept [the quasiRealCone of A] (p + q)%coqR x = addpt (scalept p x) (scalept q x) }. #[short(type=realCone)] HB.structure Definition RealCone := { A of isQuasiRealCone A & isRealCone A}. @@ -543,9 +576,9 @@ Variable A : realCone. Lemma scalept_sum (B : finType) (P : pred B) (F : B ->R^+) (x : A) : scalept (\sum_(i | P i) F i) x = \ssum_(b | P b) scalept (F b) x. Proof. -apply: (@proj1 _ (0 <= \sum_(i | P i) F i))%R. -apply: (big_ind2 (fun y q => scalept q x = y /\ 0 <= q))%R. -+ by rewrite scale0pt. +apply: (@proj1 _ (0 <= \sum_(i | P i) F i))%coqR. +apply: (big_ind2 (fun y q => scalept q x = y /\ (0 <= q)))%coqR. ++ by split; [rewrite scale0pt| ]. + move=> _ x2 _ y2 [<- ?] [<- ?]. by rewrite scaleptDl //; split => //; exact: addR_ge0. + by move=> i _; split => //; exact/nneg_f_ge0. @@ -553,8 +586,8 @@ Qed. Section barycenter_fdist_convn. Variables (n : nat) (B : finType). -Variable p : {fdist 'I_n}. -Variable q : 'I_n -> {fdist B}. +Variable p : real_realType.-fdist 'I_n. +Variable q : 'I_n -> real_realType.-fdist B. Variable h : B -> A. Lemma ssum_fdist_convn : @@ -565,7 +598,7 @@ Proof. transitivity (\ssum_i \ssum_(i0 <- enum B) scalept (p i) (scalept (q i i0) (h i0))). by apply eq_bigr => i _; rewrite big_morph_scalept// scalept0. rewrite exchange_big /=; apply eq_bigr => j _; rewrite fdist_convnE. -have HF i : (0 <= p i * q i j)%R by exact/mulR_ge0. +have HF i : (0 <= p i * q i j)%coqR by exact/mulR_ge0. rewrite (scalept_sum _ (mkNNFun HF)) /=; apply eq_bigr => i _. by rewrite scaleptA. Qed. @@ -575,6 +608,8 @@ End barycenter_fdist_convn. End real_cone_theory. Section real_cone_instance. +Import Order.TotalTheory. + Variable A : convType. Local Open Scope R_scope. Local Open Scope convex_scope. @@ -582,21 +617,23 @@ Local Open Scope scaled_scope. Let addpt (a b : scaled A) := match a, b with - | r *: x, q *: y => (r + q)%:pos *: (x <| ((r / (r + q))%:pos)%:pr |> y) + | r *: x, q *: y => (r + q)%:pos *: (x <| (((r / (r + q))%:pos))%:pr |> y) | _, Zero => a | Zero, _ => b end. -Let addptC : commutative addpt. +Let addptC' : commutative addpt. Proof. move=> [r x|] [q y|] //=; congr (_ *: _); first by apply: val_inj; rewrite /= addRC. -by rewrite convC; congr (_ <| _ |> _); exact/val_inj/onem_divRxxy. +rewrite convC; congr (_ <| _ |> _); apply/val_inj => /=. +rewrite RdivE; first by rewrite RplusE onem_divRxxy. +rewrite gt_eqF // RplusE. exact/RltP/Rpos_gt0. Qed. -Let addptA : associative addpt. +Let addptA' : associative addpt. Proof. move=> [p x|] [q y|] [r z|] //=; congr (_ *: _); first by apply val_inj; rewrite /= addRA. -rewrite convA; congr (_ <| _ |> _ ); first exact: s_of_Rpos_probA. +rewrite convA; congr (_<| _ |> _); first exact: s_of_Rpos_probA. by congr (_ <| _ |> _); exact: r_of_Rpos_probA. Qed. @@ -647,7 +684,7 @@ by move=> Hpq; congr (_ *: _); apply val_inj => /=; rewrite mulRA. Qed. HB.instance Definition _ := @isQuasiRealCone.Build (scaled A) - (Choice.class (@scaled_choiceType A)) addpt Zero addptC addptA addpt0 + (Choice.class (@scaled_choiceType A)) addpt Zero addptC' addptA' addpt0 scalept scale0pt scale1pt scaleptDr scaleptA. Let scaleptDl p q x : 0 <= p -> 0 <= q -> @@ -667,24 +704,35 @@ End real_cone_instance. Section convpt_convex_space. Variable A : convType. -Let convpt p (x y : scaled A) := addpt (scalept p x) (scalept p.~ y). +Let convpt (p : {prob R}) (x y : scaled A) := + addpt (scalept (Prob.p p) x) (scalept (Prob.p p).~ y). -Let convpt1 a b : convpt 1 a b = a. +Let convpt1 a b : convpt (1%:pr) a b = a. Proof. by rewrite /convpt onem1 scale1pt scale0pt addpt0. Qed. -Let convptmm (p : prob) a : convpt p a a = a. -Proof. by rewrite /convpt -scaleptDl // onemKC scale1pt. Qed. +Let convptmm (p : {prob R}) a : convpt p a a = a. +Proof. +rewrite /convpt -scaleptDl//. +by rewrite RplusE onemKC scale1pt //. +Qed. -Let convptC (p : prob) a b : convpt p a b = convpt (p.~)%:pr b a. +Let convptC (p : {prob R}) a b : convpt p a b = convpt ((Prob.p p).~)%:pr b a. Proof. by rewrite [RHS]addptC onemK. Qed. -Let convptA (p q : prob) a b c : +Let convptA (p q : {prob R}) a b c : convpt p a (convpt q b c) = convpt [s_of p, q] (convpt [r_of p, q] a b) c. Proof. rewrite /convpt. -rewrite !scaleptDr !scaleptA // -[RHS]addptA; congr addpt. +rewrite !scaleptDr !scaleptA //. +rewrite -[RHS]addptA; congr addpt. by rewrite (p_is_rs p q) mulRC. -by rewrite pq_is_rs mulRC s_of_pqE onemK. +rewrite pq_is_rs mulRC. +f_equal. +f_equal. +rewrite -[LHS]onemK. +f_equal. +apply/esym. +apply: s_of_pqE. Qed. HB.instance Definition __cone := @isConvexSpace.Build (scaled A) @@ -750,12 +798,15 @@ Section adjunction. Lemma affine_S1 : affine (@S1 A). Proof. move=> p x y. -have [p0|p0] := prob_ge0 p; last first. +have /RleP[p0|p0] := prob_ge0 p; last first. by rewrite (_ : p = 0%:pr) ?conv0 //; exact/val_inj. -have [p1|p1] := prob_le1 p; last first. +have /RleP[p1|p1] := prob_le1 p; last first. by rewrite (_ : p = 1%:pr) ?conv1 //; exact/val_inj. -rewrite convptE (scalept_gt0 _ _ p0) (@scalept_gt0 p.~); first exact/onem_gt0. -move=> mp0; congr (_ *: _) => /=; first by apply/val_inj => /=; rewrite !mulR1 onemKC. +rewrite convptE (scalept_gt0 _ _ p0) (@scalept_gt0 (Prob.p p).~). + exact/RltP/onem_gt0/RltP. +move=> mp0; congr (_ *: _) => /=. + apply/val_inj => /=; rewrite !mulR1. + by rewrite RplusE onemKC. by congr (_ <| _ |> _); apply val_inj; rewrite /= !mulR1 addRC subRK divR1. Qed. @@ -769,28 +820,29 @@ Section convex_space_prop1. Variables T : convType. Implicit Types a b : T. -Lemma convA0 (p q r s : prob) a b c : - p = (r * s)%R :> R -> (s.~ = p.~ * q.~)%R -> +Lemma convA0 (p q r s : {prob R}) a b c : + Prob.p p = (Prob.p r * Prob.p s)%coqR :> R -> ((Prob.p s).~ = (Prob.p p).~ * (Prob.p q).~)%coqR -> a <| p |> (b <| q |> c) = (a <| r |> b) <| s |> c. Proof. move=> H1 H2. +rewrite /prob_coercion in H1, H2. have [r0|r0] := eqVneq r 0%:pr. rewrite r0 conv0 (_ : p = 0%:pr) ?conv0; last first. by apply/val_inj; rewrite /= H1 r0 mul0R. congr (_ <| _ |> _); move: H2; rewrite H1 r0 mul0R onem0 mul1R. - by move/(congr1 onem); rewrite !onemK => ?; exact/val_inj. + by move/(congr1 (@onem real_realType)); rewrite !onemK => ?; exact/val_inj. have [s0|s0] := eqVneq s 0%:pr. have p0 : p = 0%:pr by apply/val_inj; rewrite /= H1 s0 mulR0. rewrite s0 conv0 p0 // ?conv0. rewrite (_ : q = 0%:pr) ?conv0 //. - move: H2; rewrite p0 onem0 mul1R => /(congr1 onem); rewrite !onemK => sq. + move: H2; rewrite p0 onem0 mul1R => /(congr1 (@onem real_realType)); rewrite !onemK => sq. by rewrite -s0; exact/val_inj. rewrite convA; congr ((_ <| _ |> _) <| _ |> _). by apply val_inj; rewrite /= s_of_pqE -H2 onemK. by rewrite (@r_of_pq_is_r _ _ r s). Qed. -Lemma convA' (r s : prob) a b c : +Lemma convA' (r s : {prob R}) a b c : a <| [p_of r, s] |> (b <| [q_of r, s] |> c) = (a <| r |> b) <| s |> c. Proof. have [/eqP|H] := eqVneq [p_of r, s] 1%:pr. @@ -799,20 +851,25 @@ have [->|s0] := eqVneq s 0%:pr; first by rewrite p_of_r0 q_of_r0 3!conv0. by rewrite convA s_of_pqK// r_of_pqK. Qed. +(* TODO: move *) +Lemma onem_probR_ge0 (p: {prob R}) : (0 <= (Prob.p p).~)%coqR. +Proof. exact/onem_ge0/RleP/prob_le1. Qed. +Hint Resolve onem_probR_ge0 : core. + Lemma convACA (a b c d : T) p q : (a <|q|> b) <|p|> (c <|q|> d) = (a <|p|> c) <|q|> (b <|p|> d). Proof. apply: S1_inj; rewrite ![in LHS]affine_conv/= !convptE. -rewrite !scaleptDr !scaleptA// !(mulRC p) !(mulRC p.~) addptA addptC. -rewrite (addptC (scalept (q * p) _)) !addptA -addptA -!scaleptA -?scaleptDr//. +rewrite !scaleptDr !scaleptA// !(mulRC (Prob.p p)) !(mulRC (Prob.p p).~) addptA addptC. +rewrite (addptC (scalept (Prob.p q * Prob.p p) _)) !addptA -addptA -!scaleptA -?scaleptDr//. by rewrite !(addptC (scalept _.~ _)) !affine_conv. Qed. -Lemma convDr (x y z : T) (p q : prob) : +Lemma convDr (x y z : T) (p q : {prob R}) : x <| p |> (y <| q |> z) = (x <| p |> y) <| q |> (x <| p |> z). Proof. by rewrite -{1}(convmm q x) convACA. Qed. -Lemma convACA' (a b c d : T) (p q r : prob) : +Lemma convACA' (a b c d : T) (p q r : {prob R}) : (* let p1 := (q * p)%:opr in let p2 := (q.~ * r)%:opr in @@ -845,11 +902,11 @@ Definition map_scaled (x : scaled T) : scaled U := Lemma affine_map_scaled : affine map_scaled. Proof. move=> p [q x|] [r y|] /=; rewrite 2!convptE ?scalept0 //. -- rewrite !(scalept_Scaled p) !(scalept_Scaled p.~) /= /scalept /=. +- rewrite !(scalept_Scaled (Prob.p p)) !(scalept_Scaled (Prob.p p).~) /= /scalept /=. case: Rlt_dec => Hpq; case: Rlt_dec => Hpr //=; congr (_ *: _). by rewrite affine_conv. -- by rewrite !addpt0 !(scalept_Scaled p) /= /scalept /=; case: Rlt_dec. -- by rewrite !add0pt !(scalept_Scaled p.~) /= /scalept/=; case: Rlt_dec. +- by rewrite !addpt0 !(scalept_Scaled (Prob.p p)) /= /scalept /=; case: Rlt_dec. +- by rewrite !add0pt !(scalept_Scaled (Prob.p p).~) /= /scalept/=; case: Rlt_dec. Qed. HB.instance Definition _ := isAffine.Build _ _ map_scaled affine_map_scaled. @@ -864,8 +921,10 @@ rewrite /=; case: Bool.bool_dec => [/eqP|/Bool.eq_true_not_negb]Hd. rewrite addpt0 (@scalept_gt0 _ 1). by congr (_ *: _); apply val_inj; rewrite /= mulR1. move=> i Hi; have := FDist.f1 d. - rewrite (bigD1 ord0) ?inE // Hd /= addRC => /(f_equal (Rminus^~ R1)). - by rewrite addRK subRR => /psumR_eq0P -> //; rewrite scale0pt. + rewrite (bigD1 ord0) ?inE // Hd /= -RplusE addRC => /(f_equal (Rminus^~ R1)). + rewrite addRK subRR => /eqP. + rewrite psumr_eq0// => /allP/= => /(_ i). + by rewrite mem_index_enum Hi implyTb => /(_ isT)/eqP ->; rewrite scale0pt. set d' := fdist_del Hd. set g' := fun i => g (fdist_del_idx ord0 i). rewrite /index_enum -enumT (bigD1_seq ord0) ?enum_uniq ?mem_enum //=. @@ -876,8 +935,10 @@ rewrite IH -barycenter_map scalept_barycenter //. rewrite /barycenter 2!big_map [in RHS]big_map. apply eq_bigr => i _. rewrite scaleptA // fdist_delE fdistD1E /=. -rewrite /Rdiv (mulRC (d _)) mulRA mulRV ?mul1R //. -by move: (Hd); apply contra => /eqP Hd'; rewrite -onem0 -Hd' onemK. +rewrite (mulrC (fun_of_fin (FDist.f d) (lift ord0 i))). +rewrite RmultE mulrA mulrV ?mul1r //. +move: (Hd); apply contra; rewrite R0E R1E => /eqP Hd'. +by rewrite (_ : 1%mcR = 1%coqR)// -onem0 -Hd' onemK. Qed. End with_affine_projection. @@ -894,8 +955,8 @@ Proof. apply: S1_inj; rewrite affine_conv/= !S1_Convn convptE big_split_ord/=. do 2 rewrite [in RHS]big_morph_scalept ?scalept0//. congr addpt; apply eq_bigr => i _; - rewrite (scaleptA _ _ (S1 _) (prob_ge0 _) (FDist.ge0 _ _)); - by rewrite fdist_addE (split_lshift,split_rshift). + rewrite (scaleptA _ _ (S1 _)) //; + by rewrite fdist_addE (split_lshift, split_rshift). Qed. End convex_space_prop1. @@ -963,7 +1024,7 @@ Lemma ConvnI1_eq n (g : 'I_n -> T) (d : {fdist 'I_n}) Proof. rewrite ConvnI1_eq_rect. have -> /= : eq_rect n (fun n0 : nat => 'I_n0 -> T) g 1 n1 = - g \o eq_rect 1 (fun n0 => 'I_1 -> 'I_n0) idfun n (esym n1) + g \o eq_rect 1 (fun n0 : nat => 'I_1 -> 'I_n0) idfun n (esym n1) by subst n. have /(_ i) I_n_contr : forall a b : 'I_n, a = b by rewrite n1 => a b; rewrite (ord1 a) (ord1 b). @@ -971,7 +1032,7 @@ by rewrite -(I_n_contr (eq_rect 1 (fun n => 'I_1 -> 'I_n) idfun n (esym n1) ord0 Qed. Global Arguments ConvnI1_eq [n g d n1]. -Lemma ConvnIE n (g : 'I_n.+1 -> T) (d : {fdist 'I_n.+1}) (i1 : d ord0 != 1%R) : +Lemma ConvnIE n (g : 'I_n.+1 -> T) (d : {fdist 'I_n.+1}) (i1 : d ord0 != 1%coqR) : <|>_d g = g ord0 <| probfdist d ord0 |> <|>_(fdist_del i1) (fun x => g (fdist_del_idx ord0 x)). Proof. @@ -983,7 +1044,7 @@ Qed. Lemma ConvnI2E (g : 'I_2 -> T) (d : {fdist 'I_2}) : <|>_d g = g ord0 <| probfdist d ord0 |> g (lift ord0 ord0). Proof. -have [/eqP|i1] := eqVneq (d ord0) 1%R. +have [/eqP|i1] := eqVneq (d ord0) 1%coqR. rewrite fdist1E1 => /eqP ->; rewrite Convn_fdist1. rewrite (_ : probfdist _ _ = 1%:pr) ?conv1 //. by apply val_inj; rewrite /= fdist1xx. @@ -1012,18 +1073,18 @@ Lemma Convn_cst (a : T) (n : nat) (d : {fdist 'I_n}) : <|>_d (fun=> a) = a. Proof. elim: n d; first by move=> d; move/fdistI0_False: (d). move=> n IHn d. -have [|] := eqVneq (d ord0) 1%R; first by move/(Convn_proj (fun=> a)). +have [|] := eqVneq (d ord0) 1%coqR; first by move/(Convn_proj (fun=> a)). by move=> d0n0; rewrite ConvnIE IHn convmm. Qed. Lemma Convn_idem (a : T) (n : nat) (d : {fdist 'I_n}) (g : 'I_n -> T) : - (forall i : 'I_n, (d i != 0)%R -> g i = a) -> <|>_d g = a. + (forall i : 'I_n, (d i != 0)%coqR -> g i = a) -> <|>_d g = a. Proof. move=> Hg; apply: S1_inj. rewrite S1_Convn (eq_bigr (fun i => scalept (d i) (S1 a))). by rewrite -S1_Convn Convn_cst. move=> /= i _. -by have [-> //|/Hg ->//] := eqVneq (d i) 0%R; rewrite !scale0pt. +by have [-> //|/Hg ->//] := eqVneq (d i) 0%coqR; rewrite !scale0pt. Qed. Lemma Convn_weak n m (u : 'I_m -> 'I_n) (d : {fdist 'I_m}) (g : 'I_n -> T) : @@ -1033,25 +1094,27 @@ apply S1_inj. rewrite !S1_Convn (partition_big u (fun _=> true)) //=. apply eq_bigr => i _. rewrite fdistmapE /=. -have HF (a : 'I_m) : (0 <= d a)%R by []. +have HF (a : 'I_m) : (0 <= d a)%coqR. by []. rewrite (@scalept_sum _ _ _ (mkNNFun HF)) /=. by apply eq_bigr => a /eqP ->. Qed. -Lemma ConvnDr n (p : prob) (x : T) (g : 'I_n -> T) (d : {fdist 'I_n}) : +Lemma ConvnDr n (p : {prob R}) (x : T) (g : 'I_n -> T) (d : {fdist 'I_n}) : x <|p|> <|>_d g = <|>_d (fun i => x <|p|> g i). Proof. elim: n p x g d => [? ? ? d|n IHn p x g d]; first by move/fdistI0_False: (d). -have [d01|d0n1] := eqVneq (d ord0) 1%R. +have [d01|d0n1] := eqVneq (d ord0) 1%coqR. by rewrite (Convn_proj g d01) (Convn_proj (fun i => x <|p|> g i) d01). by rewrite !ConvnIE !IHn; congr (<|>_ _ _); apply funext=> i; rewrite convDr. Qed. -Lemma ConvnDl n (p : prob) (x : T) (g : 'I_n -> T) (d : {fdist 'I_n}) : +Lemma ConvnDl n (p : {prob R}) (x : T) (g : 'I_n -> T) (d : {fdist 'I_n}) : <|>_d g <|p|> x = <|>_d (fun i => g i <|p|> x). Proof. by rewrite convC ConvnDr; apply eq_Convn =>// i; rewrite -convC. Qed. -Lemma ConvnDlr n m (p : prob) (f : 'I_n -> T) (d : {fdist 'I_n}) +Local Open Scope ring_scope. + +Lemma ConvnDlr n m (p : {prob R}) (f : 'I_n -> T) (d : {fdist 'I_n}) (g : 'I_m -> T) (e : {fdist 'I_m}) : <|>_d f <|p|> <|>_e g = <|>_(fdist_add d e p) @@ -1117,7 +1180,7 @@ case: Bool.bool_dec => // H'. exfalso. move: H'; rewrite fdist_delE fdistD1E (eq_sym (lift _ _)) (negbTE (neq_lift _ _)). rewrite fdistI2E (eq_sym (lift _ _)) (negbTE (neq_lift _ _)) fdistI2E. -rewrite eqxx divRR ?eqxx //. +rewrite eqxx mulrV ?eqxx //. by move: H; rewrite fdistI2E eqxx onem_neq0. Qed. @@ -1158,7 +1221,7 @@ apply/idP/idP => H; apply/asboolP. rewrite {IH} (@Convn_proj _ _ _ _ ord0) //. exact/gX/classical_sets.imageP. by apply/eqP; rewrite fdist1E1 (fdist1I1 d). - have [d01|d01] := eqVneq (d ord0) 1%R. + have [d01|d01] := eqVneq (d ord0) 1%coqR. suff -> : <|>_d g = g ord0 by apply gX; exists ord0. by rewrite (@Convn_proj _ _ _ _ ord0). set D : {fdist 'I_n.+1} := fdist_del d01. @@ -1496,11 +1559,10 @@ End split_prod. Section lmodR_convex_space. Variable E : lmodType R. -Implicit Type p q : prob. +Implicit Type p q : {prob R}. Local Open Scope ring_scope. -Import GRing. -Let avg p (a b : E) := (Prob.p p) *: a + p.~ *: b. +Let avg p (a b : E) := (prob_coercion p) *: a + (Prob.p p).~ *: b. Let avg1 a b : avg 1%:pr a b = a. Proof. by rewrite /avg /= scale1r onem1 scale0r addr0. Qed. @@ -1508,11 +1570,11 @@ Proof. by rewrite /avg /= scale1r onem1 scale0r addr0. Qed. Let avgI p x : avg p x x = x. Proof. rewrite /avg -scalerDl. -have ->: (Prob.p p) + p.~ = Rplus (Prob.p p) p.~ by []. -by rewrite onemKC scale1r. +have -> : (Prob.p p) + (Prob.p p).~ = Rplus (Prob.p p) (Prob.p p).~ by []. +by rewrite RplusE onemKC scale1r. Qed. -Let avgC p x y : avg p x y = avg p.~%:pr y x. +Let avgC p x y : avg p x y = avg (Prob.p p).~%:pr y x. Proof. by rewrite /avg onemK addrC. Qed. Let avgA p q (d0 d1 d2 : E) : @@ -1521,13 +1583,13 @@ Proof. rewrite /avg /onem. set s := Prob.p [s_of p, q]. set r := Prob.p [r_of p, q]. -rewrite (scalerDr s) -addrA (scalerA s) (mulrC s); congr add. - by rewrite (p_is_rs p q) -/s. +rewrite (scalerDr s) -addrA (scalerA s) (mulrC s); congr +%R. + by rewrite /prob_coercion (p_is_rs p q) -/s. rewrite scalerDr (scalerA _ _ d2). -rewrite -/p.~ -/q.~ -/r.~ -/s.~. -rewrite {2}/s (s_of_pqE p q) onemK; congr add. -rewrite 2!scalerA; congr scale. -have ->: p.~ * q = (p.~ * q)%R by []. +rewrite -/(Prob.p p).~ -/(Prob.p q).~ -/r.~ -/s.~. +rewrite {2}/s (s_of_pqE p q) onemK; congr +%R. +rewrite 2!scalerA; congr (_ *: _). +have ->: (Prob.p p).~ * Prob.p q = ((Prob.p p).~ * Prob.p q)%coqR by []. by rewrite pq_is_rs -/r -/s mulrC. Qed. @@ -1540,14 +1602,13 @@ End lmodR_convex_space. Section lmodR_convex_space_prop. Variable E : lmodType R. -Implicit Type p q : prob. +Implicit Type p q : {prob R}. Local Open Scope ring_scope. -Import GRing. Lemma avgr_addD p (a b c d : E) : (a + b) <|p|> (c + d) = (a <|p|> c) + (b <|p|> d). Proof. -rewrite !avgrE !scalerDr !addrA; congr add; rewrite -!addrA; congr add. +rewrite !avgrE !scalerDr !addrA; congr +%R; rewrite -!addrA; congr +%R. exact: addrC. Qed. @@ -1556,12 +1617,12 @@ Proof. by rewrite avgrE 2!scalerN -opprD. Qed. Lemma avgr_scalerDr p : right_distributive *:%R (fun x y : E => x <| p |> y). Proof. -by move=> x ? ?; rewrite 2!avgrE scalerDr !scalerA; congr add; congr scale; +by move=> x ? ?; rewrite 2!avgrE scalerDr !scalerA; congr +%R; congr (_ *: _); exact: mulrC. Qed. Lemma avgr_scalerDl p : - left_distributive *:%R (fun x y : regular_lmodType R_ringType => x <|p|> y). + left_distributive *:%R (fun x y : GRing.regular_lmodType R_ringType => x <|p|> y). Proof. by move=> x ? ?; rewrite avgrE scalerDl -2!scalerA. Qed. (* Introduce morphisms to prove avgnE *) @@ -1574,17 +1635,19 @@ Proof. by move=> x /=; rewrite scale1r. Qed. Lemma scaler_addpt : {morph scaler : x y / addpt x y >-> x + y}. Proof. move=> [p x|] [q y|] /=; rewrite ?(add0r,addr0) //. -rewrite avgrE /divRposxxy /= onem_div /Rdiv; last by apply Rpos_neq0. -rewrite -!(mulRC (/ _)%R) scalerDr !scalerA !mulrA. -have ->: (p + q)%R * (/ (p + q))%R = 1 by apply mulRV; last by apply Rpos_neq0. +rewrite avgrE /divRposxxy /= Reals_ext.onem_div /Rdiv; last by apply Rpos_neq0. +rewrite -!(mulRC (/ _)%coqR) scalerDr !scalerA !mulrA. +have ->: (p + q)%coqR * (/ (p + q))%coqR = 1 by apply mulRV; last by apply Rpos_neq0. by rewrite !mul1r (addRC p) addRK. Qed. +(* TODO: the name conflicts with GRing.scaler0 *) Lemma scaler0 : scaler Zero = 0. by []. Qed. -Lemma scaler_scalept r x : (0 <= r -> scaler (scalept r x) = r *: scaler x)%R. +Lemma scaler_scalept r x : (0 <= r -> scaler (scalept r x) = r *: scaler x)%coqR. Proof. -case: x => [q y|r0]; last by rewrite scalept0// GRing.scaler0. +case: x => [q y|r0]; last first. + by rewrite scalept0// scaler0 !GRing.scaler0. case=> r0. by rewrite scalept_gt0 /= scalerA. by rewrite -r0 scale0pt scale0r. @@ -1608,12 +1671,11 @@ Lemma avgnr_add n m (f : 'I_n -> E) (d : {fdist 'I_n}) (g : 'I_m -> E) (fun i => let (i, j) := split_prod i in f i + g j). Proof. rewrite -[<|>_e g]scale1r !avgnrE !/avgnr big_prod_ord. -have<-: 1%R = 1 by []. rewrite -(FDist.f1 d) scaler_suml -big_split; apply congr_big=>// i _. -transitivity (d i *: (1%R *: f i + \sum_(i0 < m) e i0 *: g i0)). +transitivity (d i *: (1%coqR *: f i + \sum_(i0 < m) e i0 *: g i0)). by rewrite scale1r scalerDr. -rewrite -(FDist.f1 e) scaler_suml -big_split scaler_sumr; apply congr_big=>// j _. -rewrite scalerDr -!scalerDr scalerA unsplit_prodK; congr scale. +rewrite R1E -(FDist.f1 e) scaler_suml -big_split scaler_sumr; apply congr_big=>// j _. +rewrite scalerDr -!scalerDr scalerA unsplit_prodK; congr (_ *: _). rewrite fdistmapE (big_pred1 (i, j)) /= ?fdist_prodE//. move=>[i' j'] /=; rewrite xpair_eqE inE /=. apply/eqP/andP => /=; last by case => /eqP -> /eqP ->. @@ -1625,11 +1687,9 @@ End lmodR_convex_space_prop. Section freeN_combination. Import ssrnum vector. -Import Order.POrderTheory Num.Theory. Variable (R : fieldType) (E : vectType R). Local Open Scope ring_scope. Local Open Scope classical_set_scope. -Import GRing. Lemma freeN_combination n (s : n.-tuple E) : ~~ free s -> exists k : 'I_n -> R, (\sum_i k i *: s`_i = 0) /\ exists i, k i != 0. @@ -1670,11 +1730,9 @@ End freeN_combination. Section caratheodory. Import ssrnum vector. -Import Order.POrderTheory Num.Theory. Variable E : vectType R. Local Open Scope ring_scope. Local Open Scope classical_set_scope. -Import GRing. (* TODO: move? *) Import Order.TotalTheory. @@ -1707,7 +1765,7 @@ have [mu [muR muE [i mui]]] : exists mu : 'I_n.+1 -> R, - by exists (lift ord0 i) => /=; rewrite (_ : Ordinal _ = i)//; exact/val_inj. wlog: mu muR muE mui / mu i > 0. move=> H. - have [mui0|mui0] := ltP 0%R (mu i); first exact: (H mu). + have [mui0|mui0] := ltP 0%coqR (mu i); first exact: (H mu). apply (H (fun i => - mu i)). - by rewrite sumrN muR oppr0. - by under eq_bigr do rewrite scaleNr; rewrite sumrN muE oppr0. @@ -1765,14 +1823,14 @@ have mu0 : mu ord0 != 0 by apply /eqP=>mu0; move: muip; rewrite mu0 lt0r eq_refl have k0mu0 : d ord0 / mu ord0 * mu ord0 = d ord0. by rewrite -{2}[mu ord0]divr1 mulf_div [_*1]mulrC -mulf_div divr1 mulfV // mulr1. set ef : 'I_n -> R := finfun (fun i => d (lift ord0 i) - d ord0 / mu ord0 * mu (lift ord0 i)). -have ef0 i : (0 <= ef i)%R. - apply/RleP; rewrite /ef ffunE subr_ge0. +have ef0 i : (0 <= ef i). + rewrite /ef ffunE subr_ge0. have [mujp|mujp] := ltP 0 (mu (lift ord0 i)). - by rewrite -ler_pdivl_mulr // muim. - rewrite (@le_trans _ _ 0)//; last exact/leRP. - by rewrite mulr_ge0_le0//= divr_ge0//; [exact/leRP|exact/ltW]. -have ef1 : (\sum_(a in 'I_n) ef a = 1)%R. - rewrite -[1%R]subr0 -(mulr0 (d ord0 / mu ord0)) -(FDist.f1 d) -muR mulr_sumr. + by rewrite -ler_pdivlMr // muim. + rewrite (@le_trans _ _ 0)//. + by rewrite mulr_ge0_le0//= divr_ge0// ltW. +have ef1 : (\sum_(a in 'I_n) ef a = 1). + rewrite -[1]subr0 -[in RHS](mulr0 (d ord0 / mu ord0)) -(FDist.f1 d) -[in _ * 0]muR mulr_sumr. rewrite -sumrB big_ord_recl k0mu0 subrr add0r. by apply eq_bigr => i _; rewrite /ef ffunE. pose e := FDist.make ef0 ef1. @@ -1783,7 +1841,7 @@ exists n', g', d'; split=> //. rewrite -gde 2!avgnrE /avgnr big_ord_recl -k0mu0 -scalerA. move/eqP: muE; rewrite big_ord_recl addr_eq0 => /eqP ->. rewrite scalerN -scaleNr scaler_sumr -big_split; apply congr_big=>// i _. -by rewrite scalerA /= -scalerDl; congr scale; rewrite addrC mulNr ffunE. +by rewrite scalerA /= -scalerDl; congr (_ *: _); rewrite addrC mulNr ffunE. Qed. End caratheodory. @@ -1791,7 +1849,6 @@ End caratheodory. Section linear_affine. Open Scope ring_scope. Variables (E F : lmodType R) (f : {linear E -> F}). -Import GRing. Let linear_is_affine: affine f. Proof. by move=>p x y; rewrite linearD 2!linearZZ. Qed. @@ -1802,18 +1859,18 @@ End linear_affine. (* TOTHINK: Should we keep this section, only define R_convType, or something else ? *) Section R_convex_space. -Implicit Types p q : prob. +Implicit Types p q : {prob R}. Let avg p (a b : [the lmodType R of R^o]) := a <| p |> b. -Let avgE p a b : avg p a b = (p * a + p.~ * b)%R. +Let avgE p a b : avg p a b = (Prob.p p * a + (Prob.p p).~ * b)%coqR. Proof. by []. Qed. Let avg1 a b : avg 1%:pr a b = a. Proof. by rewrite /avg conv1. Qed. Let avgI p x : avg p x x = x. Proof. by rewrite /avg convmm. Qed. -Let avgC p x y : avg p x y = avg p.~%:pr y x. Proof. by rewrite /avg convC. Qed. +Let avgC p x y : avg p x y = avg (Prob.p p).~%:pr y x. Proof. by rewrite /avg convC. Qed. Let avgA p q (d0 d1 d2 : R) : avg p d0 (avg q d1 d2) = avg [s_of p, q] (avg [r_of p, q] d0 d1) d2. @@ -1822,9 +1879,9 @@ Proof. by rewrite /avg convA. Qed. HB.instance Definition _ := @isConvexSpace.Build R (Choice.class _) _ avg1 avgI avgC avgA. -Lemma avgRE p (x y : R) : x <| p |> y = (p * x + p.~ * y)%R. Proof. by []. Qed. +Lemma avgRE p (x y : R) : x <| p |> y = (Prob.p p * x + (Prob.p p).~ * y)%coqR. Proof. by []. Qed. -Lemma avgR_oppD p x y : (- x <| p |> - y = - (x <| p |> y))%R. +Lemma avgR_oppD p x y : (- x <| p |> - y = - (x <| p |> y))%coqR. Proof. exact: (@avgr_oppD [lmodType R of R^o]). Qed. Lemma avgR_mulDr p : right_distributive Rmult (fun x y => x <| p |> y). @@ -1840,17 +1897,17 @@ Definition scaleR x : R := if x is (p *: y)%scaled then p * y else 0. Lemma Scaled1RK : cancel (@S1 _) scaleR. Proof. by move=> x /=; rewrite mul1R. Qed. -Lemma scaleR_addpt : {morph scaleR : x y / addpt x y >-> (x + y)%R}. +Lemma scaleR_addpt : {morph scaleR : x y / addpt x y >-> (x + y)%coqR}. Proof. move=> [p x|] [q y|] /=; rewrite ?(add0R,addR0) //. -rewrite avgRE /avg /divRposxxy /= onem_div /Rdiv; last by apply Rpos_neq0. -rewrite -!(mulRC (/ _)%R) mulRDr !mulRA mulRV; last by apply Rpos_neq0. +rewrite avgRE /avg /divRposxxy /= Reals_ext.onem_div /Rdiv; last by apply Rpos_neq0. +rewrite -!(mulRC (/ _)%coqR) mulRDr !mulRA mulRV; last by apply Rpos_neq0. by rewrite !mul1R (addRC p) addRK. Qed. Lemma scaleR0 : scaleR Zero = R0. by []. Qed. -Lemma scaleR_scalept r x : (0 <= r -> scaleR (scalept r x) = r * scaleR x)%R. +Lemma scaleR_scalept r x : (0 <= r -> scaleR (scalept r x) = r * scaleR x)%coqR. Proof. case: x => [q y|r0]; last by rewrite scalept0// mulR0. case=> r0. by rewrite scalept_gt0 /= mulRA. @@ -1859,7 +1916,7 @@ Qed. Definition big_scaleR := big_morph scaleR scaleR_addpt scaleR0. -Definition avgnR n (g : 'I_n -> R) (e : {fdist 'I_n}) := (\sum_(i < n) e i * g i)%R. +Definition avgnR n (g : 'I_n -> R) (e : {fdist 'I_n}) := (\sum_(i < n) e i * g i)%coqR. Lemma avgnRE n (g : 'I_n -> R) e : <|>_e g = avgnR g e. Proof. @@ -1872,13 +1929,13 @@ End R_convex_space. Section fun_convex_space. Variables (A : choiceType) (B : convType). Let T := A -> B. -Implicit Types p q : prob. +Implicit Types p q : {prob R}. Let avg p (x y : T) := fun a : A => (x a <| p |> y a). Let avg1 (x y : T) : avg 1%:pr x y = x. Proof. rewrite funeqE => a; exact/conv1. Qed. Let avgI p (x : T) : avg p x x = x. Proof. rewrite funeqE => a; exact/convmm. Qed. -Let avgC p (x y : T) : avg p x y = avg p.~%:pr y x. +Let avgC p (x y : T) : avg p x y = avg (Prob.p p).~%:pr y x. Proof. rewrite funeqE => a; exact/convC. Qed. Let avgA p q (d0 d1 d2 : T) : avg p d0 (avg q d1 d2) = avg [s_of p, q] (avg [r_of p, q] d0 d1) d2. @@ -1890,7 +1947,7 @@ End fun_convex_space. Section depfun_convex_space. Variables (A : choiceType) (B : A -> convType). Let T := dep_arrow_choiceType B. -Implicit Types p q : prob. +Implicit Types p q : {prob R}. Let avg p (x y : T) := fun a : A => (x a <| p |> y a). Let avg1 (x y : T) : avg 1%:pr x y = x. Proof. @@ -1902,7 +1959,7 @@ Proof. apply FunctionalExtensionality.functional_extensionality_dep => a. exact/convmm. Qed. -Let avgC p (x y : T) : avg p x y = avg p.~%:pr y x. +Let avgC p (x y : T) : avg p x y = avg (Prob.p p).~%:pr y x. Proof. apply FunctionalExtensionality.functional_extensionality_dep => a. exact/convC. @@ -1921,13 +1978,13 @@ End depfun_convex_space. Section pair_convex_space. Variables (A B : convType). Let T := (A * B)%type. -Implicit Types p q : prob. +Implicit Types p q : {prob R}. Let avg p (x y : T) := (x.1 <| p |> y.1, x.2 <| p |> y.2). Let avg1 (x y : T) : avg 1%:pr x y = x. Proof. rewrite /avg (conv1 x.1) (conv1 x.2); by case x. Qed. Let avgI p (x : T) : avg p x x = x. Proof. rewrite /avg (convmm _ x.1) (convmm _ x.2); by case x. Qed. -Let avgC p (x y : T) : avg p x y = avg p.~%:pr y x. +Let avgC p (x y : T) : avg p x y = avg (Prob.p p).~%:pr y x. Proof. by congr (pair _ _); apply convC. Qed. Let avgA p q (d0 d1 d2 : T) : avg p d0 (avg q d1 d2) = avg [s_of p, q] (avg [r_of p, q] d0 d1) d2. @@ -1940,43 +1997,46 @@ End pair_convex_space. Section fdist_convex_space. Variable A : finType. -Implicit Types a b c : fdist A. +Implicit Types a b c : real_realType.-fdist A. Let conv1 a b : (a <| 1%:pr |> b)%fdist = a. Proof. -by apply/fdist_ext => a0; rewrite fdist_convE /= onem1 mul1R mul0R addR0. +by apply/fdist_ext => a0; rewrite fdist_convE /= onem1 mul1r mul0r addr0. Qed. -Let convC p a b : (a <| p |> b = b <| p.~%:pr |> a)%fdist. -Proof. by apply/fdist_ext => a0 /=; rewrite 2!fdist_convE onemK addRC. Qed. +Let convC p a b : (a <| p |> b = b <| (Prob.p p).~%:pr |> a)%fdist. +Proof. by apply/fdist_ext => a0 /=; rewrite 2!fdist_convE onemK addrC. Qed. Let convmm p a : (a <| p |> a)%fdist = a. Proof. -by apply/fdist_ext => a0; rewrite fdist_convE mulRBl mul1R addRCA addRN addR0. +by apply/fdist_ext => a0; rewrite fdist_convE mulrBl mul1r addrCA addrN addr0. Qed. +Open Scope ring_scope. + Let convA p q a b c : (a <| p |> (b <| q |> c) = (a <| [r_of p, q] |> b) <| [s_of p, q] |> c)%fdist. Proof. apply/fdist_ext => a0 /=; rewrite 4!fdist_convE /=. set r := r_of_pq p q. set s := s_of_pq p q. -transitivity (p * a a0 + p.~ * q * b a0 + p.~ * q.~ * c a0)%R; first lra. -transitivity (r * s * a a0 + r.~ * s * b a0 + s.~ * c a0)%R; last first. - by rewrite 2!(mulRC _ s) -2!mulRA -mulRDr. -rewrite s_of_pqE onemK; congr (_ + _)%R. -rewrite (_ : (p.~ * q.~).~ = [s_of p, q]); last by rewrite s_of_pqE. -by rewrite -pq_is_rs -p_is_rs. -Qed. - -HB.instance Definition _ := @isConvexSpace.Build (fdist A) - (Choice.class (choice_of_Type (fdist A))) - (@fdist_conv A) conv1 convmm convC convA. +transitivity (prob_coercion p * a a0 + (Prob.p p).~ * Prob.p q * b a0 + (Prob.p p).~ * (Prob.p q).~ * c a0). + by rewrite /onem /prob_coercion /=; lra. +transitivity (prob_coercion r * prob_coercion s * a a0 + (Prob.p r).~ * prob_coercion s * b a0 + (Prob.p s).~ * c a0); last first. + by rewrite 2!(mulrC _ (prob_coercion s)) -2!mulrA -mulrDr. +rewrite -!RmultE. +by congr (_ + _ + _); + [rewrite /prob_coercion (p_is_rs p q) | rewrite -pq_is_rs | rewrite s_of_pqE onemK]. +Qed. + +HB.instance Definition _ := @isConvexSpace.Build (real_realType.-fdist A) + (Choice.class (choice_of_Type (real_realType.-fdist A))) + (@fdist_conv _ A) conv1 convmm convC convA. End fdist_convex_space. Section scaled_convex_lemmas_depending_on_T_convType. Local Open Scope R_scope. -Lemma scalept_conv (T : convType) (x y : R) (s : scaled T) (p : prob): +Lemma scalept_conv (T : convType) (x y : R) (s : scaled T) (p : {prob R}): 0 <= x -> 0 <= y -> scalept (x <|p|> y) s = scalept x s <|p|> scalept y s. Proof. @@ -1985,7 +2045,7 @@ by rewrite convptE !scaleptA. Qed. Lemma big_scalept_conv_split (T : convType) (I : Type) (r : seq I) (P : pred I) - (F G : I -> scaled T) (p : prob) : + (F G : I -> scaled T) (p : {prob R}) : \ssum_(i <- r | P i) (F i <|p|> G i) = (\ssum_(i <- r | P i) F i) <|p|> \ssum_(i <- r | P i) G i. Proof. @@ -1995,7 +2055,7 @@ Qed. Lemma scalept_addRnng (T : convType) (x : scaled T) : {morph (fun (r : Rnng) => scalept r x) : r s / addRnneg r s >-> addpt r s}. -Proof. by move=> -[] r /= /leRP Hr [] s /= /leRP Hs; exact: scaleptDl. Qed. +Proof. by move=> -[] r /= /RleP Hr [] s /= /RleP Hs; exact: scaleptDl. Qed. Definition big_scaleptl (T : convType) (x : scaled T) := @big_morph @@ -2027,8 +2087,9 @@ End scaled_convex_lemmas_depending_on_T_convType. Module Convn_finType. Section def. -Local Open Scope R_scope. -Variables (A : convType) (T : finType) (d' : {fdist T}) (f : T -> A). +Local Open Scope ring_scope. + +Variables (A : convType) (T : finType) (d' : real_realType.-fdist T) (f : T -> A). Let n := #| T |. Definition t0 : T. @@ -2044,7 +2105,7 @@ Lemma d_enum0 : forall b, 0 <= d_enum b. Proof. by move=> ?; rewrite ffunE. Qed. Lemma d_enum1 : \sum_(b in 'I_n) d_enum b = 1. Proof. -rewrite -(@FDist.f1 T d') (eq_bigr (d' \o enum)); last by move=> i _; rewrite ffunE. +rewrite -(@FDist.f1 real_realType T d') (eq_bigr (d' \o enum)); last by move=> i _; rewrite ffunE. rewrite (@reindex _ _ _ _ _ enum_rank) //; last first. by exists enum_val => i; [rewrite enum_rankK | rewrite enum_valK]. apply eq_bigr => i _; congr (d' _); by rewrite -[in RHS](enum_rankK i). @@ -2062,7 +2123,7 @@ End Convn_finType. Export Convn_finType.Exports. Section S1_Convn_finType. -Variables (A : convType) (T : finType) (d : {fdist T}) (f : T -> A). +Variables (A : convType) (T : finType) (d : real_realType.-fdist T) (f : T -> A). Lemma S1_Convn_finType : S1 (<$>_d f) = \ssum_i scalept (d i) (S1 (f i)). Proof. @@ -2077,7 +2138,7 @@ End S1_Convn_finType. Section S1_proj_Convn_finType. Variables (A B : convType) (prj : {affine A -> B}). -Variables (T : finType) (d : {fdist T}) (f : T -> A). +Variables (T : finType) (d : real_realType.-fdist T) (f : T -> A). Lemma S1_proj_Convn_finType : S1 (prj (<$>_d f)) = \ssum_i scalept (d i) (S1 (prj (f i))). @@ -2105,7 +2166,7 @@ Notation "x <= y" := (leconv x y) : ordered_convex_scope. Notation "x <= y <= z" := (leconv x y /\ leconv y z) : ordered_convex_scope. HB.instance Definition _ := - @isOrdered.Build R (Choice.class _) Rle leRR leR_trans eqR_le. + @isOrdered.Build R (Choice.class _) Rle Rle_refl leR_trans eqR_le. Module FunLe. Section lefun. @@ -2177,13 +2238,14 @@ Qed. End leopp. + Section convtype. Local Open Scope convex_scope. Variable A : orderedConvType. Notation T := (T A). -Implicit Types p q : prob. +Implicit Types p q : {prob R}. -Definition unbox (x : T) := match x with mkOpp x' => x' end. +Definition unbox (x : T) := match x with mkOpp x' => x' end. Definition avg p a b := mkOpp (unbox a <| p |> unbox b). @@ -2193,7 +2255,7 @@ Proof. by case a;case b=>b' a';rewrite/avg/unbox/=conv1. Qed. Lemma avgI p x : avg p x x = x. Proof. by case x=>x';rewrite/avg/unbox/=convmm. Qed. -Lemma avgC p x y : avg p x y = avg p.~%:pr y x. +Lemma avgC p x y : avg p x y = avg (Prob.p p).~%:pr y x. Proof. by case x;case y=>y' x'; rewrite/avg/unbox/=convC. Qed. Lemma avgA p q d0 d1 d2 : @@ -2247,8 +2309,8 @@ Definition convex_function_at f a b p := f (a <| p |> b) <= f a <| p |> f b. Definition convex_function_at_Convn f n (a : 'I_n -> T) (d : {fdist 'I_n}) := f (<|>_d a) <= <|>_d (f \o a). -Definition strictly_convexf_at f := forall a b (t : prob), - a <> b -> (0 < t < 1)%R -> convex_function_at f a b t. +Definition strictly_convexf_at f := forall a b (t : {prob R}), + a <> b -> (0 < Prob.p t < 1)%coqR -> convex_function_at f a b t. Lemma convex_function_atxx f a t : convex_function_at f a a t. Proof. rewrite /convex_function_at !convmm; exact/leconvR. Qed. @@ -2256,7 +2318,7 @@ Proof. rewrite /convex_function_at !convmm; exact/leconvR. Qed. End convex_function_def. Definition convex_function (U : convType) (V : orderedConvType) (f : U -> V) := - forall a b (t : prob), convex_function_at f a b t. + forall a b (t : {prob R}), convex_function_at f a b t. (* see Additive in ssralg *) HB.mixin Record isConvexFunction @@ -2280,7 +2342,7 @@ Lemma convex_function_sym (f : T -> U) a b : (forall t, convex_function_at f a b t) -> (forall t, convex_function_at f b a t). Proof. -move=> H t; move: (H t.~%:pr). +move=> H t; move: (H (Prob.p t).~%:pr). by rewrite /convex_function_at /= convC -probK (convC _ (f a)) -probK. Qed. @@ -2350,12 +2412,13 @@ Proof. exists Rmult; split. by split => [a b0 b1 t | b a0 a1 t]; rewrite /convex_function_at /=; rewrite avgRE; - [rewrite avgR_mulDr|rewrite avgR_mulDl]; exact: leRR. -move/convex_in_bothP/(_ (-1)%R 1%R 1%R (-1)%R (probinvn 1)). + [rewrite avgR_mulDr|rewrite avgR_mulDl]; apply/RleP; rewrite lexx. +move/convex_in_bothP/(_ (-1)%coqR 1%coqR 1%coqR (-1)%coqR (probinvn 1)). rewrite /leconv /probinvn /= 3!avgRE /=. -rewrite !(mul1R,mulR1,mulRN1) -oppRD onemKC. -rewrite (_ : - / (1 + 1) + (/ (1 + 1)).~ = 0); last first. - by rewrite /onem addRCA -oppRD -div1R eps2 addRN. +set a := / (1 + 1)%:R. +rewrite !(mul1R,mulR1,mulRN1) -oppRD (RplusE a a.~) onemKC. +rewrite (_ : - a + a.~ = 0)%coqR; last first. + by rewrite /a/onem addRCA -oppRD -div1R eps2 addRN. by rewrite mul0R leR_oppr oppR0 leRNgt; exact. Qed. End counterexample. @@ -2369,8 +2432,8 @@ Implicit Types f : A -> B. Definition concave_function_at f a b t := @convex_function_at A _ (fun a => \opp{f a}) a b t. Definition concave_function_at' f a b t := (f a <| t |> f b <= f (a <| t |> b)). -Definition strictly_concavef_at f := forall a b (t : prob), - a <> b -> (0 < t < 1)%R -> concave_function_at f a b t. +Definition strictly_concavef_at f := forall a b (t : {prob R}), + a <> b -> (0 < Prob.p t < 1)%coqR -> concave_function_at f a b t. Lemma concave_function_at'P f a b t : concave_function_at' f a b t <-> concave_function_at f a b t. Proof. @@ -2380,7 +2443,7 @@ Qed. End concave_function_def. Definition concave_function (U : convType) (V : orderedConvType) (f : U -> V) := - forall a b (t : prob), concave_function_at f a b t. + forall a b (t : {prob R}), concave_function_at f a b t. HB.mixin Record isConcaveFunction (U : convType) (V : orderedConvType) (f : U -> V) := { @@ -2407,41 +2470,41 @@ Section Rprop. Implicit Types f : T -> R. Lemma R_convex_function_atN f a b t : - concave_function_at f a b t -> convex_function_at (fun x => - f x)%R a b t. + concave_function_at f a b t -> convex_function_at (fun x => - f x)%coqR a b t. Proof. by rewrite /convex_function_at /leconv /= avgR_oppD leR_oppl oppRK. Qed. Lemma R_concave_function_atN f a b t : - convex_function_at f a b t -> concave_function_at (fun x => - f x)%R a b t. + convex_function_at f a b t -> concave_function_at (fun x => - f x)%coqR a b t. Proof. rewrite /concave_function_at /convex_function_at. by rewrite /leconv/= /leopp/= avgR_oppD /leconv/= leR_oppl oppRK. Qed. Lemma R_convex_functionN f : - concave_function f -> convex_function (fun x => - f x)%R. + concave_function f -> convex_function (fun x => - f x)%coqR. Proof. by move=> H a b t; exact/R_convex_function_atN/H. Qed. Lemma R_concave_functionN f : - convex_function f -> concave_function (fun x => - f x)%R. + convex_function f -> concave_function (fun x => - f x)%coqR. Proof. by move=> H a b t; exact/R_concave_function_atN/H. Qed. Lemma RNconvex_function_at f a b t : - concave_function_at (fun x => - f x)%R a b t -> convex_function_at f a b t. + concave_function_at (fun x => - f x)%coqR a b t -> convex_function_at f a b t. Proof. by move/(R_convex_function_atN); rewrite/convex_function_at !oppRK. Qed. Lemma RNconcave_function_at f a b t : - convex_function_at (fun x => - f x)%R a b t -> concave_function_at f a b t. + convex_function_at (fun x => - f x)%coqR a b t -> concave_function_at f a b t. Proof. move/(R_concave_function_atN). by rewrite/concave_function_at/convex_function_at !oppRK. Qed. Lemma RNconvex_function f : - concave_function (fun x => - f x)%R -> convex_function f. + concave_function (fun x => - f x)%coqR -> convex_function f. Proof. move=> H a b t; exact/RNconvex_function_at/H. Qed. Lemma RNconcave_function f : - convex_function (fun x => - f x)%R -> concave_function f. + convex_function (fun x => - f x)%coqR -> concave_function f. Proof. move=> H a b t; exact/RNconcave_function_at/H. Qed. End Rprop. @@ -2450,7 +2513,7 @@ Section Rprop2. Lemma R_convex_functionB f (g : T -> R) : convex_function f -> concave_function g -> - convex_function (fun x => f x - g x)%R. + convex_function (fun x => f x - g x)%coqR. Proof. move=> Hf Hg p q t. rewrite /convex_function_at /= avgRE 2!mulRBr addRAC addRA. @@ -2460,10 +2523,10 @@ Qed. Lemma R_concave_functionB f (g : T -> R) : concave_function f -> convex_function g -> - concave_function (fun x => f x - g x)%R. + concave_function (fun x => f x - g x)%coqR. Proof. move=> Hf Hg. -rewrite (_ : (fun _ => _) = (fun x => - (g x - f x)))%R; last first. +rewrite (_ : (fun _ => _) = (fun x => - (g x - f x)))%coqR; last first. by apply/funext => x; rewrite oppRB. exact/R_concave_functionN/R_convex_functionB. Qed. @@ -2564,9 +2627,9 @@ Lemma preimage_add_ker (f : {linear T -> U}) (A: set U) : Proof. rewrite eqEsubset; split. - move=> x [a /= aA] [b /= bker] xe; subst x. - by rewrite GRing.linearD bker GRing.addr0. + by rewrite linearD bker addr0. - move=> x /= fx; exists x=>//. - by exists 0; [ apply GRing.linear0 | apply GRing.addr0]. + by exists 0; [ rewrite linear0 | rewrite addr0]. Qed. End linear_function_image0. @@ -2599,8 +2662,6 @@ rewrite eqEsubset; split. exists (gb ib)=>//; apply gbB; exists ib. Qed. -Import GRing. - Proposition preimage_preserves_convex_hull (f : {linear T -> U}) (Z : set U) : Z `<=` range f -> f @^-1` (hull Z) = hull (f @^-1` Z). Proof. @@ -2619,7 +2680,7 @@ End linear_function_image. Section R_affine_function_prop. Variables (T : convType) (f : T -> R). -Lemma R_affine_functionN : affine f -> affine (fun x => - f x)%R. +Lemma R_affine_functionN : affine f -> affine (fun x => - f x)%coqR. Proof. move/affine_functionP => [H1 H2]; rewrite affine_functionP. split => //; [exact/R_convex_functionN|exact/R_concave_functionN]. @@ -2661,34 +2722,39 @@ TODO: see convex_type.v Section convex_set_R. -Lemma Rpos_convex : is_convex_set (fun x => 0 < x)%R. +Lemma Rpos_convex : is_convex_set (fun x => 0 < x)%coqR. Proof. apply/asboolP => x y t Hx Hy. -case/boolP : (t == 0%:pr) => [/eqP ->| Ht0]; first by rewrite conv0. -apply addR_gt0wl; first by apply mulR_gt0 => //; exact/prob_gt0. +have [->|Ht0] := eqVneq t 0%:pr; first by rewrite conv0. +apply addR_gt0wl; first by apply mulR_gt0 => //; exact/RltP/prob_gt0. apply mulR_ge0 => //; exact: ltRW. Qed. Definition Rpos_interval : {convex_set R} := CSet.Pack (CSet.Mixin Rpos_convex). -Lemma Rnonneg_convex : is_convex_set (fun x => 0 <= x)%R. +Lemma Rnonneg_convex : is_convex_set (fun x => 0 <= x)%coqR. Proof. apply/asboolP=> x y t Hx Hy; apply addR_ge0; exact/mulR_ge0. Qed. Definition Rnonneg_interval := CSet.Pack (CSet.Mixin Rnonneg_convex). -Lemma open_interval_convex a b (Hab : (a < b)%R) : is_convex_set (fun x => a < x < b)%R. +Lemma open_interval_convex a b (Hab : (a < b)%coqR) : + is_convex_set (fun x => a < x < b)%coqR. Proof. apply/asboolP => x y t [xa xb] [ya yb]. -case/boolP : (t == 0%:pr) => [/eqP|]t0; first by rewrite t0 conv0. -case/boolP : (t == 1%:pr) => [/eqP|]t1; first by rewrite t1 conv1. +have [->|t0] := eqVneq t 0%:pr; first by rewrite conv0. +have [->|t1] := eqVneq t 1%:pr; first by rewrite conv1. apply conj. -- rewrite -[X in (X < t * x + t.~ * y)%R]mul1R -(onemKC t) mulRDl. - apply ltR_add; rewrite ltR_pmul2l //; [exact/prob_gt0 | exact/onem_gt0/prob_lt1]. -- rewrite -[X in (_ + _ < X)%R]mul1R -(onemKC t) mulRDl. - apply ltR_add; rewrite ltR_pmul2l //; [exact/prob_gt0 | exact/onem_gt0/prob_lt1]. +- rewrite -[X in (X < Prob.p t * x + (Prob.p t).~ * y)%coqR]mul1r -(onemKC (Prob.p t)). + rewrite (mulrDl _ _ a) -RplusE. + apply ltR_add; rewrite ltR_pmul2l //; [exact/RltP/prob_gt0 | exact/RltP/onem_gt0/prob_lt1]. +- (*rewrite -[X in (_ + _ < X)%coqR]mul1R -(onemKC t) mulRDl.*) +rewrite -[X in (_ + _ < X)%coqR]mul1r. +rewrite -(onemKC (Prob.p t)). +rewrite mulrDl. + apply ltR_add; rewrite ltR_pmul2l //; [exact/RltP/prob_gt0 | exact/RltP/onem_gt0/prob_lt1]. Qed. -Lemma open_unit_interval_convex : is_convex_set (fun x => 0 < x < 1)%R. +Lemma open_unit_interval_convex : is_convex_set (fun x => 0 < x < 1)%coqR. Proof. exact: open_interval_convex. Qed. Definition open_unit_interval := CSet.Pack (CSet.Mixin open_unit_interval_convex). @@ -2700,7 +2766,7 @@ Section convex_function_R. Implicit Types f : R -> R. Lemma concave_function_atN f x y t : concave_function_at f x y t -> - forall k, (0 <= k)%R -> concave_function_at (fun x => f x * k)%R x y t. + forall k, (0 <= k)%coqR -> concave_function_at (fun x => f x * k)%coqR x y t. Proof. move=> H k k0; rewrite /concave_function_at /convex_function_at. rewrite conv_leoppD leoppP avgRE. @@ -2708,18 +2774,18 @@ rewrite /leconv /= -avgR_mulDl. exact: leR_wpmul2r. Qed. -Lemma convexf_at_onem x y (t : prob) f : (0 < x -> 0 < y -> x < y -> - convex_function_at f x y t -> convex_function_at f y x t.~%:pr)%R. +Lemma convexf_at_onem x y (t : {prob R}) f : (0 < x -> 0 < y -> x < y -> + convex_function_at f x y t -> convex_function_at f y x (Prob.p t).~%:pr)%coqR. Proof. move=> x0 y0 xy H; rewrite /convex_function_at. rewrite [in X in leconv _ X]avgRE /= onemK addRC. rewrite /convex_function_at !avgRE in H. rewrite avgRE /= onemK addRC. -apply: (leR_trans H); rewrite addRC; exact/leRR. +by apply: (leR_trans H); rewrite addRC; apply/RleP; rewrite lexx. Qed. -Lemma concavef_at_onem x y (t : prob) f : (0 < x -> 0 < y -> x < y -> - concave_function_at f x y t -> concave_function_at f y x t.~%:pr)%R. +Lemma concavef_at_onem x y (t : {prob R}) f : (0 < x -> 0 < y -> x < y -> + concave_function_at f x y t -> concave_function_at f y x (Prob.p t).~%:pr)%coqR. Proof. move=>x0 y0 xy; rewrite/concave_function_at/convex_function_at. rewrite !conv_leoppD !leoppP/=. @@ -2745,75 +2811,76 @@ Now this is an equivalent condition to the convexity of f. Section twice_derivable_convex. Variables (f : R -> R) (a b : R). -Let I := fun x0 => (a <= x0 <= b)%R. +Let I := fun x0 => (a <= x0 <= b)%coqR. Hypothesis HDf : pderivable f I. Variable Df : R -> R. Hypothesis DfE : forall x (Hx : I x), Df x = derive_pt f x (HDf Hx). Hypothesis HDDf : pderivable Df I. Variable DDf : R -> R. Hypothesis DDfE : forall x (Hx : I x), DDf x = derive_pt Df x (HDDf Hx). -Hypothesis DDf_ge0 : forall x, I x -> (0 <= DDf x)%R. +Hypothesis DDf_ge0 : forall x, I x -> (0 <= DDf x)%coqR. -Definition L (x : R) := (f a + (x - a) / (b - a) * (f b - f a))%R. +Definition L (x : R) := (f a + (x - a) / (b - a) * (f b - f a))%coqR. -Hypothesis ab : (a < b)%R. +Hypothesis ab : (a < b)%coqR. -Lemma LE x : L x = ((b - x) / (b - a) * f a + (x - a) / (b - a) * f b)%R. +Lemma LE x : L x = ((b - x) / (b - a) * f a + (x - a) / (b - a) * f b)%coqR. Proof. -rewrite /L mulRBr [in LHS]addRA addRAC; congr (_ + _)%R. -rewrite addR_opp -{1}(mul1R (f a)) -mulRBl; congr (_ * _)%R. +rewrite /L mulRBr [in LHS]addRA addRAC; congr (_ + _)%coqR. +rewrite addR_opp -{1}(mul1R (f a)) -mulRBl; congr (_ * _)%coqR. rewrite -(mulRV (b - a)); last by rewrite subR_eq0'; exact/gtR_eqF. by rewrite -mulRBl -addR_opp oppRB addRA subRK addR_opp. Qed. -Lemma convexf_ptP : (forall x, a <= x <= b -> 0 <= L x - f x)%R -> - forall t : prob, convex_function_at f a b t. +Lemma convexf_ptP : (forall x, a <= x <= b -> 0 <= L x - f x)%coqR -> + forall t : {prob R}, convex_function_at f a b t. Proof. move=> H t; rewrite /convex_function_at. -set x := (t * a + t.~ * b)%R. -have : (a <= x <= b)%R. +set x := (Prob.p t * a + (Prob.p t).~ * b)%coqR. +have : (a <= x <= b)%coqR. rewrite /x; split. - - apply (@leR_trans (t * a + t.~ * a)). - rewrite -mulRDl addRCA addR_opp subRR addR0 mul1R; exact/leRR. + - apply (@leR_trans (Prob.p t * a + (Prob.p t).~ * a)). + rewrite -mulRDl addRCA addR_opp subRR addR0 mul1R. + by apply/RleP; rewrite lexx. have [->|t1] := eqVneq t 1%:pr. - rewrite /onem subRR !mul0R !addR0; exact/leRR. + by rewrite mul1R onem1 2!mul0R; exact/RleP. rewrite leR_add2l; apply leR_wpmul2l => //; exact/ltRW. - - apply (@leR_trans (t * b + t.~ * b)); last first. - rewrite -mulRDl addRCA addR_opp subRR addR0 mul1R; exact/leRR. + - apply (@leR_trans (Prob.p t * b + (Prob.p t).~ * b)); last first. + rewrite -mulRDl addRCA addR_opp subRR addR0 mul1R. + by apply/RleP; rewrite lexx. rewrite leR_add2r; apply leR_wpmul2l => //; exact/ltRW. move/H; rewrite subR_ge0 => /leR_trans; apply. rewrite LE //. -have -> : ((b - x) / (b - a) = t)%R. +have -> : ((b - x) / (b - a) = Prob.p t)%coqR. rewrite /x -addR_opp oppRD addRCA mulRBl mul1R oppRB (addRCA b). rewrite addR_opp subRR addR0 -mulRN addRC -mulRDr addR_opp. rewrite /Rdiv -mulRA mulRV ?mulR1 // subR_eq0'; exact/gtR_eqF. -have -> : ((x - a) / (b - a) = t.~)%R. - rewrite /x -addR_opp addRAC -{1}(oppRK a) mulRN -mulNR -{2}(mul1R (- a)%R). +have -> : ((x - a) / (b - a) = (Prob.p t).~)%coqR. + rewrite /x -addR_opp addRAC -{1}(oppRK a) mulRN -mulNR -{2}(mul1R (- a)%coqR). rewrite -mulRDl (addRC _ R1) addR_opp -mulRDr addRC addR_opp. rewrite /Rdiv -mulRA mulRV ?mulR1 // subR_eq0'; exact/gtR_eqF. -exact/leRR. +by apply/RleP; rewrite lexx. Qed. -Lemma second_derivative_convexf_pt : forall t : prob, convex_function_at f a b t. +Lemma second_derivative_convexf_pt : forall t : {prob R}, convex_function_at f a b t. Proof. -have note1 : forall x, R1 = ((x - a) / (b - a) + (b - x) / (b - a))%R. +have note1 : forall x, R1 = ((x - a) / (b - a) + (b - x) / (b - a))%coqR. move=> x; rewrite -mulRDl addRC addRA subRK addR_opp mulRV // subR_eq0'. exact/gtR_eqF. -have step1 : forall x, f x = ((x - a) / (b - a) * f x + (b - x) / (b - a) * f x)%R. +have step1 : forall x, f x = ((x - a) / (b - a) * f x + (b - x) / (b - a) * f x)%coqR. by move=> x; rewrite -mulRDl -note1 mul1R. apply convexf_ptP => // x axb. rewrite /L. case: axb. rewrite leR_eqVlt => -[-> _|]. - rewrite /L subRR div0R mul0R addR0 subRR; exact/leRR. + by rewrite /L subRR div0R mul0R addR0 subRR. move=> ax. -rewrite leR_eqVlt => -[->|]. -rewrite /L /Rdiv mulRV ?mul1R; last by rewrite subR_eq0'; exact/gtR_eqF. -rewrite addRC subRK subRR; exact/leRR. -move=> xb. +rewrite leR_eqVlt => -[->|xb]. + rewrite /L /Rdiv mulRV ?mul1R; last by rewrite subR_eq0'; exact/gtR_eqF. + by rewrite addRC subRK subRR. have {step1}step2 : (L x - f x = (x - a) * (b - x) / (b - a) * ((f b - f x) / (b - x)) - - (b - x) * (x - a) / (b - a) * ((f x - f a) / (x - a)))%R. + (b - x) * (x - a) / (b - a) * ((f x - f a) / (x - a)))%coqR. rewrite {1}step1 {step1}. rewrite -addR_opp oppRD addRA addRC addRA. rewrite LE //. @@ -2822,13 +2889,13 @@ have {step1}step2 : (L x - f x = rewrite -mulRN -addRA -mulRDr (addR_opp (f b)). rewrite addRC. rewrite -(oppRK (f a - f x)) mulRN addR_opp oppRB. - congr (_ + _)%R. - - rewrite {1}/Rdiv -!mulRA; congr (_ * _)%R; rewrite mulRCA; congr (_ * _)%R. + congr (_ + _)%coqR. + - rewrite {1}/Rdiv -!mulRA; congr (_ * _)%coqR; rewrite mulRCA; congr (_ * _)%coqR. rewrite mulRCA mulRV ?mulR1 // subR_eq0'; exact/gtR_eqF. - - rewrite -!mulNR -!mulRA; congr (_ * _)%R; rewrite mulRCA; congr (_ * _)%R. + - rewrite -!mulNR -!mulRA; congr (_ * _)%coqR; rewrite mulRCA; congr (_ * _)%coqR. rewrite mulRCA mulRV ?mulR1 // subR_eq0'; exact/gtR_eqF. -have [c2 [Ic2 Hc2]] : exists c2, (x < c2 < b /\ (f b - f x) / (b - x) = Df c2)%R. - have H : pderivable f (fun x0 => x <= x0 <= b)%R. +have [c2 [Ic2 Hc2]] : exists c2, (x < c2 < b /\ (f b - f x) / (b - x) = Df c2)%coqR. + have H : pderivable f (fun x0 => x <= x0 <= b)%coqR. move=> z [z1 z2]; apply HDf; split => //. apply (@leR_trans x) => //; exact: ltRW. case: (@MVT_cor1_pderivable x b f H xb) => c2 [Ic2 [H1 H2]]. @@ -2839,8 +2906,8 @@ have [c2 [Ic2 Hc2]] : exists c2, (x < c2 < b /\ (f b - f x) / (b - x) = Df c2)%R split. apply (@leR_trans x); [exact/ltRW | by case: Ic2 H1]. by case: H2 => _ /ltRW. -have [c1 [Ic1 Hc1]] : exists c1, (a < c1 < x /\ (f x - f a) / (x - a) = Df c1)%R. - have H : pderivable f (fun x0 => a <= x0 <= x)%R. +have [c1 [Ic1 Hc1]] : exists c1, (a < c1 < x /\ (f x - f a) / (x - a) = Df c1)%coqR. + have H : pderivable f (fun x0 => a <= x0 <= x)%coqR. move=> z [z1 z2]; apply HDf; split => //. apply (@leR_trans x) => //; exact: ltRW. case: (@MVT_cor1_pderivable a x f H ax) => c1 [Ic1 [H1 H2]]. @@ -2853,14 +2920,14 @@ have [c1 [Ic1 Hc1]] : exists c1, (a < c1 < x /\ (f x - f a) / (x - a) = Df c1)%R - apply (@leR_trans x). by case: H2 => _ /ltRW. apply (@leR_trans c2); apply/ltRW; by case: Ic2. -have c1c2 : (c1 < c2)%R by apply (@ltR_trans x); [case: Ic1 | case: Ic2]. +have c1c2 : (c1 < c2)%coqR by apply (@ltR_trans x); [case: Ic1 | case: Ic2]. have {step2 Hc1 Hc2}step3 : (L x - f x = - (b - x) * (x - a) * (c2 - c1) / (b - a) * ((Df c2 - Df c1) / (c2 - c1)))%R. - rewrite {}step2 Hc2 Hc1 (mulRC (x - a)%R) -mulRBr {1}/Rdiv -!mulRA. - congr (_ * (_ * _))%R; rewrite mulRCA; congr (_ * _)%R. + (b - x) * (x - a) * (c2 - c1) / (b - a) * ((Df c2 - Df c1) / (c2 - c1)))%coqR. + rewrite {}step2 Hc2 Hc1 (mulRC (x - a)%coqR) -mulRBr {1}/Rdiv -!mulRA. + congr (_ * (_ * _))%coqR; rewrite mulRCA; congr (_ * _)%coqR. rewrite mulRCA mulRV ?mulR1 // subR_eq0'; by move/gtR_eqF : c1c2. -have [d [Id H]] : exists d, (c1 < d < c2 /\ (Df c2 - Df c1) / (c2 - c1) = DDf d)%R. - have H : pderivable Df (fun x0 => c1 <= x0 <= c2)%R. +have [d [Id H]] : exists d, (c1 < d < c2 /\ (Df c2 - Df c1) / (c2 - c1) = DDf d)%coqR. + have H : pderivable Df (fun x0 => c1 <= x0 <= c2)%coqR. move=> z [z1 z2]; apply HDDf; split => //. - apply (@leR_trans c1) => //; by case: Ic1 => /ltRW. - apply (@leR_trans c2) => //; by case: Ic2 => _ /ltRW. @@ -2894,7 +2961,7 @@ End twice_derivable_convex. Section ereal_convex. Local Open Scope ereal_scope. -Let conv_ereal (p : prob) x y := (p : R)%:E * x + p.~%:E * y. +Let conv_ereal (p : {prob R}) x y := (Prob.p p : R)%:E * x + (Prob.p p).~%:E * y. Let conv_ereal_conv1 a b : conv_ereal 1%:pr a b = a. Proof. by rewrite /conv_ereal probpK onem1 /= mul1e mul0e adde0. Qed. @@ -2902,28 +2969,28 @@ Proof. by rewrite /conv_ereal probpK onem1 /= mul1e mul0e adde0. Qed. Let conv_ereal_convmm p a : conv_ereal p a a = a. Proof. rewrite /conv_ereal; case/boolP : (a \is a fin_num) => [?|]. - by rewrite -muleDl// -EFinD /GRing.add /= probKC mul1e. + by rewrite -muleDl// -EFinD probKC mul1e. rewrite fin_numE negb_and !negbK => /predU1P[-> | /eqP->]. - rewrite -ge0_muleDl. - + by rewrite -EFinD /GRing.add /= probKC mul1e. - + by rewrite lee_fin; apply/RleP/prob_ge0. - + by rewrite lee_fin; apply/RleP/prob_ge0. + + by rewrite -EFinD probKC mul1e. + + by rewrite lee_fin; apply/prob_ge0. + + by rewrite lee_fin; apply/prob_ge0. - rewrite -ge0_muleDl. - + by rewrite -EFinD /GRing.add /= probKC mul1e. - + by rewrite lee_fin; apply/RleP/prob_ge0. - + by rewrite lee_fin; apply/RleP/prob_ge0. + + by rewrite -EFinD probKC mul1e. + + by rewrite lee_fin; apply/prob_ge0. + + by rewrite lee_fin; apply/prob_ge0. Qed. -Let conv_ereal_convC p a b : conv_ereal p a b = conv_ereal (p.~)%:pr b a. +Let conv_ereal_convC p a b : conv_ereal p a b = conv_ereal ((Prob.p p).~)%:pr b a. Proof. by rewrite [in RHS]/conv_ereal onemK addeC. Qed. -Lemma oprob_sg1 (p : oprob) : Num.sg (Prob.p p) = 1%R. +Lemma oprob_sg1 (p : {oprob R}) : Num.sg (oprob_to_real p) = 1%mcR. Proof. -case/ltR2P: (OProb.O1 p)=> /[swap] _ /RltP /(conj Num.Theory.sgr_cp0) [] <-. +have /andP[] := OProb.O1 p; move=> /[swap] _. rewrite -sgr_cp0. by move/eqP. Qed. -Let conv_ereal_convA p q a b c : +Let conv_ereal_convA (p q: {prob R}) a b c : conv_ereal p a (conv_ereal q b c) = conv_ereal [s_of p, q] (conv_ereal [r_of p, q] a b) c. Proof. @@ -2933,17 +3000,17 @@ apply (prob_trichotomy' p); | by rewrite s_of_1q r_of_1q !mul1e !onem1 !mul0e !adde0 | rewrite {p}=> p]. apply (prob_trichotomy' q); - [ by rewrite s_of_p0 r_of_p0_oprob onem1 onem0 mul0e !mul1e add0e adde0 + [ by rewrite s_of_p0 Reals_ext.r_of_p0_oprob onem1 onem0 mul0e !mul1e add0e adde0 | by rewrite s_of_p1 r_of_p1 onem1 !mul1e mul0e !adde0 | rewrite {q}=> q]. have sgp := oprob_sg1 p. have sgq := oprob_sg1 q. -have sgonemp := oprob_sg1 p.~%:opr. -have sgonemq := oprob_sg1 q.~%:opr. -have sgrpq := oprob_sg1 [r_of p, q]%:opr. -have sgspq := oprob_sg1 [s_of p, q]%:opr. -have sgonemrpq := oprob_sg1 [r_of p, q].~%:opr. -have sgonemspq := oprob_sg1 [s_of p, q].~%:opr. +have sgonemp := oprob_sg1 (Prob.p (OProb.p p)).~%:opr. +have sgonemq := oprob_sg1 (Prob.p (OProb.p q)).~%:opr. +have sgrpq := oprob_sg1 [r_of OProb.p p, OProb.p q]%:opr. +have sgspq := oprob_sg1 [s_of OProb.p p, OProb.p q]%:opr. +have sgonemrpq := oprob_sg1 (Prob.p [r_of OProb.p p, OProb.p q]).~%:opr. +have sgonemspq := oprob_sg1 (Prob.p [s_of OProb.p p, OProb.p q]).~%:opr. Ltac mulr_infty X := do ! (rewrite mulr_infty X mul1e). set sg := (sgp,sgq,sgonemp,sgonemq,sgrpq,sgspq,sgonemrpq,sgonemspq). case: a=> [a | | ]; case: b=> [b | | ]; case: c=> [c | | ]; @@ -2951,11 +3018,11 @@ case: a=> [a | | ]; case: b=> [b | | ]; case: c=> [c | | ]; rewrite muleDr // addeA. congr (_ + _)%E; last by rewrite s_of_pqE onemK EFinM muleA. rewrite muleDr //. -congr (_ + _)%E; first by rewrite (p_is_rs p q) mulRC EFinM muleA. +congr (_ + _)%E; first by rewrite (p_is_rs (OProb.p p) (OProb.p q)) mulRC EFinM muleA. rewrite muleA -!EFinM. -rewrite /GRing.mul /= (pq_is_rs (OProb.p p) q). +rewrite /GRing.mul /= (pq_is_rs (OProb.p p) (OProb.p q)). rewrite mulRA. -by rewrite (mulRC [r_of p, q].~). +by rewrite (mulRC (Prob.p [r_of OProb.p p, OProb.p q]).~). Qed. HB.instance Definition _ := @isConvexSpace.Build (\bar R) (Choice.class _) _ diff --git a/probability/convex_equiv.v b/probability/convex_equiv.v index 7f847d6b..f5b24f4c 100644 --- a/probability/convex_equiv.v +++ b/probability/convex_equiv.v @@ -1,12 +1,12 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) From HB Require Import structures. -From mathcomp Require Import all_ssreflect ssralg fingroup perm finalg matrix. -From mathcomp Require Import boolp classical_sets. +From mathcomp Require Import all_ssreflect ssralg ssrnum fingroup perm matrix. +From mathcomp Require Import mathcomp_extra boolp classical_sets. Require Import Reals. From mathcomp Require Import Rstruct. -Require Import ssrR Reals_ext Ranalysis_ext ssr_ext ssralg_ext logb Rbigop. -Require Import fdist jfdist_cond fsdist convex. +Require Import ssrR Reals_ext realType_ext Ranalysis_ext ssr_ext ssralg_ext. +Require Import Rbigop fdist jfdist_cond fsdist convex. (******************************************************************************) (* Equivalence of Convexity Definitions *) @@ -31,6 +31,8 @@ Set Implicit Arguments. Unset Strict Implicit. Import Prenex Implicits. +Import GRing.Theory Num.Theory. + Local Open Scope reals_ext_scope. Local Open Scope fdist_scope. Local Open Scope convex_scope. @@ -78,11 +80,11 @@ apply/eq_bigr => a _. rewrite !fdistE /= (big_pred1 (a,i)) ?fdistE /=; last by case=> x y; rewrite /swap /= !xpair_eqE andbC. rewrite eq_sym 2!inE. -by case: eqP => // _; rewrite (mulR0,mulR1). +by case: eqP => // _; rewrite (mulr0,mulr1). Qed. -Lemma dE j : fdistmap K e i != 0%R -> - d j = (e j * (i == K j)%:R / \sum_(j | K j == i) e j)%R. +Lemma dE j : fdistmap K e i != 0%coqR -> + d j = (e j * (i == K j)%:R / \sum_(j | K j == i) e j)%coqR. Proof. rewrite -denE => NE. rewrite jfdist_condE // {NE} /jcPr /proba.Pr. @@ -90,6 +92,7 @@ rewrite (big_pred1 (j,i)); last first. by move=> k; rewrite !inE [in RHS](surjective_pairing k) xpair_eqE. rewrite (big_pred1 i); last by move=> k; rewrite !inE. rewrite !fdistE big_mkcond [in RHS]big_mkcond /=. +rewrite -RmultE -INRE. congr (_ / _)%R. under eq_bigr => k do rewrite {2}(surjective_pairing k). rewrite -(pair_bigA _ (fun k l => @@ -98,7 +101,7 @@ rewrite -(pair_bigA _ (fun k l => else R0))%R /=. apply eq_bigr => k _. rewrite -big_mkcond /= big_pred1_eq !fdistE /= eq_sym. -by case: ifP; rewrite (mulR1,mulR0). +by case: ifP; rewrite (mulr1,mulr0). Qed. End fdistpart. @@ -106,12 +109,12 @@ Lemma dK n m K (e : {fdist 'I_m}) j : e j = (\sum_(i < n) fdistmap K e i * d K e i j)%R. Proof. under eq_bigr => /= a _. - case/boolP: (fdistmap K e a == 0%R) => Ka0. - rewrite (eqP Ka0) mul0R. + have [Ka0|Ka0] := eqVneq (fdistmap K e a) 0%R. + rewrite Ka0 mul0R. have <- : (e j * (a == K j)%:R = 0)%R. - have [Kj|] := boolP (a == K j); last by rewrite mulR0. - move/eqP: Ka0; rewrite fdistE /=. - move/psumR_eq0P => -> //; by rewrite ?(mul0R,inE) // eq_sym. + have [/eqP Kj|] := eqVneq a (K j); last by rewrite mulR0. + move: Ka0; rewrite fdistE /=. + by move/psumr_eq0P => -> //; rewrite ?(mul0R,inE) // eq_sym. over. rewrite FDistPart.dE // fdistE /= mulRCA mulRV ?mulR1; last by rewrite fdistE in Ka0. @@ -218,7 +221,7 @@ rewrite axbary (_ : fdist_convn _ _ = fdist1 k) ?axproj ?Hd //. apply fdist_ext => /= i. rewrite fdist_convnE sum_fdist_supp fdistE. under eq_bigr => j /= -> do rewrite fdistE. -by rewrite -sum_fdist_supp -big_distrl FDist.f1 /= mul1R. +by rewrite -sum_fdist_supp -big_distrl FDist.f1 /= mul1r. Qed. (* axconst is also a corollary of axidem *) @@ -230,7 +233,7 @@ Definition binconv p (a b : T) := <&>_(fdistI2 p) (fun x => if x == ord0 then a else b). Notation "a <& p &> b" := (binconv p a b). -Lemma binconvC p a b : a <& p &> b = b <& (p.~)%:pr &> a. +Lemma binconvC p a b : a <& p &> b = b <& ((Prob.p p).~)%:pr &> a. Proof. rewrite /binconv. set g1 := fun x => _. @@ -243,7 +246,7 @@ rewrite axmap. congr (<&>_ _ _); apply fdist_ext => i. rewrite fdistmapE (bigD1 (tperm ord0 (Ordinal (erefl (1 < 2))) i)) /=; last first. by rewrite !inE tpermK. -rewrite big1 ?addR0. +rewrite big1 ?addr0. rewrite !fdistI2E onemK. by case/orP: (ord2 i) => /eqP -> /=; rewrite (tpermL,tpermR). by move=> j /andP[] /eqP <-; rewrite tpermK eqxx. @@ -272,24 +275,28 @@ have -> : c = g ord23 by []. rewrite -2!axproj 2!convn_if 2!axbary. congr (<&>_ _ _); apply fdist_ext => j. rewrite !fdist_convnE !big_ord_recl !big_ord0 /=. -rewrite !fdistI2E !fdistmapE !fdist1E !addR0 /=. +rewrite !fdistI2E !fdistmapE !fdist1E !addr0 /=. case: j => -[|[|[]]] //= Hj. - rewrite [in RHS](big_pred1 ord0) //. rewrite big1; last by case => -[]. - by rewrite fdistI2E eqxx !(mulR0,addR0) mulR1 mulRC -p_is_rs. + by rewrite fdistI2E eqxx !(mulr0,addr0) mulr1 mulrC -RmultE -p_is_rs. - rewrite (big_pred1 ord0) // (big_pred1 (Ordinal (ltnSn 1))) //. - rewrite !fdistI2E !eqxx !(mulR0,addR0,add0R). - rewrite {2}/onem mulRDr mulR1 mulRN [in RHS]mulRC -p_is_rs s_of_pqE'. - by rewrite (addRC p) -addRA addRN addR0. + rewrite !fdistI2E !eqxx !(mulr0,addr0,add0r). + + rewrite {2}/onem mulrDr mulr1 mulrN [in RHS]GRing +.mulrC. rewrite -[in RHS]RmultE. rewrite -p_is_rs s_of_pqE'. + + rewrite RplusE RmultE. + by rewrite (addrC (Prob.p p)) addrK. - rewrite (big_pred1 (Ordinal (ltnSn 1))) //. rewrite big1; last by case => -[|[]]. - by rewrite !fdistI2E !(mulR0,addR0,add0R,mulR1) s_of_pqE onemK. + by rewrite !fdistI2E 2!mulr0 2!add0r mulr1 s_of_pqE onemK. Qed. -Lemma binconv1 a b : binconv 1%:pr a b = a. +Lemma binconv1 a b : binconv R1%:pr a b = a. Proof. apply axidem => /= i; rewrite inE fdistI2E; case: ifP => //=. -by rewrite /onem subRR eqxx. +by rewrite /onem subrr eqxx. Qed. Lemma binconvmm p a : binconv p a a = a. @@ -336,13 +343,15 @@ rewrite /(_ <| _ |> _)/= /binconv. set d' := fdistmap _ _. rewrite -(axproj ord0) convn_if axbary. congr (<&>_ _ _); apply fdist_ext => i. -rewrite fdist_convnE !big_ord_recl big_ord0 addR0 /= !fdistI2E /=. + +rewrite fdist_convnE !big_ord_recl big_ord0 addr0 /= !fdistI2E /=. rewrite fdist1E /d' fdistmapE /=. -have [->|] := eqVneq i ord0; first by rewrite big1 // mulR0 mulR1 addR0. -rewrite /= mulR0 add0R. + +have [->|] := eqVneq i ord0; first by rewrite big1 // mulr0 mulr1 addr0. case: (unliftP ord0 i) => //= [j|] -> // Hj. rewrite (big_pred1 j) //=. -rewrite fdist_delE fdistD1E /= /onem mulRC -mulRA mulVR ?mulR1 //. +rewrite fdist_delE fdistD1E /= /onem. +rewrite mulr0 add0r mulrA (mulrC (1 - d ord0)%R) mulrK //. apply/eqP => /(congr1 (Rplus (d ord0))). rewrite addRCA addRN !addR0 => b'. by elim b; rewrite -b' eqxx. @@ -373,7 +382,7 @@ have -> : d = fdistmap f d'. case/boolP: (i \in supp) => Hi. - rewrite (bigD1 i) /=; last first. by rewrite !inE /f /f' /= enum_rankK_in. - rewrite big1; first by rewrite addR0. + rewrite big1; first by rewrite addr0. move=> j /andP[] /eqP <-. case/boolP: (j \in supp). by move=> Hj; rewrite /f /f' /= enum_rankK_in // eqxx. @@ -450,7 +459,7 @@ rewrite /= in f. rewrite [LHS](axpart h'). rewrite [RHS](axpart (fun j => proj1_sig (f j))). have trivIK i j x : x \in fdist_supp (e i) -> x \in fdist_supp (e j) -> i = j. - case/boolP: (i == j) => [/eqP // | ij] xi xj. + have [|] := eqVneq i j => [// | ij] xi xj. move/setP/(_ x): (HP _ _ ij); by rewrite inE xi xj inE. have neqj j a k : a \in fdist_supp (e (h j)) -> k != (h j) -> (d k * e k a = 0)%R. @@ -462,7 +471,7 @@ have neqj j a k : have Hmap' i : fdistmap h' d i = (\sum_j d (h i) * e (h i) j)%R. rewrite -big_distrr fdistE /= FDist.f1 /= mulR1. rewrite (bigD1 (h i)) /=; last by rewrite /h /h' !inE enum_valK_in eqxx. - rewrite big1 /= ?addR0 // => j /andP[] /eqP <-. + rewrite big1 /= ?addr0 // => j /andP[] /eqP <-. case /boolP: (j \in fdist_supp d) => Hj. by rewrite /h /h' (enum_rankK_in Hn0 Hj) eqxx. move: Hj; by rewrite inE negbK => /eqP. @@ -479,16 +488,17 @@ have Hmap i : move: (Ha (h' k)). by rewrite inE negbK /h/h' enum_rankK_in // => /eqP ->; rewrite mulR0. by rewrite inE negbK => /eqP -> ; rewrite mul0R. - rewrite (proj2 (psumR_eq0P _)) ?(if_same,Ha0,mulR0) // => k _. - exact: mulR_ge0. + case: ifPn => [/eqP|] _. + by rewrite Ha0 big1. + by rewrite Ha0. case: ifPn => [/eqP/esym ->{i}|ji]. - by rewrite (bigD1 (h j)) //= big1 ?addR0 // => *; rewrite (neqj j). + by rewrite (bigD1 (h j)) //= big1 ?addr0 // => *; rewrite -RmultE (neqj j). by rewrite (neqj j) //; apply: contra ji => /eqP/enum_val_inj ->. congr (<&>_ _ _); first by apply fdist_ext => /= i; rewrite Hmap. apply funext => i /=. have HF : fdistmap h' d i != 0%R. rewrite fdistE /=. - apply/eqP => /psumR_eq0P => H. + apply/eqP => /psumr_eq0P H. have: h i \in fdist_supp d by apply enum_valP. by rewrite inE H ?eqxx // 2!inE /h /h' enum_valK_in. rewrite (@axidem (<&>_(e (h i)) g)); last first. @@ -507,7 +517,7 @@ rewrite FDistPart.dE; last first. rewrite (bigD1 (h i)) //=. rewrite -big_distrr big_mkcond /=. rewrite (eq_bigr (e (h i))). - rewrite FDist.f1 mulR1; apply paddR_neq0 => //. + rewrite FDist.f1 mulr1; apply paddR_neq0 => //. by apply/sumR_ge0 => *; apply/sumR_ge0 => *; apply/mulR_ge0. by left; move: (enum_valP i); rewrite inE. move=> /= k _; rewrite 2!inE; case: ifP => //. @@ -529,8 +539,8 @@ case: (f j) => /= k /orP[Hn|jk]. case/boolP: (a \in fdist_supp d). rewrite /h /h'. move/(enum_rankK_in _) ->. - by rewrite inE negbK => /eqP ->; rewrite mulR0. - by rewrite inE negbK => /eqP ->; rewrite mul0R. + by rewrite inE negbK => /eqP ->; rewrite mulr0. + by rewrite inE negbK => /eqP ->; rewrite mul0r. rewrite (bigD1 (h k)) //= big1 ?addR0; last first. by move=> a Ha; apply (neqj k). case/boolP: (j \in fdist_supp (e (h i))) => ji. @@ -538,6 +548,7 @@ case/boolP: (j \in fdist_supp (e (h i))) => ji. subst k => {jk}. move: HF; rewrite eqxx mulR1 Hmap'. rewrite -big_distrr /= FDist.f1 mulR1 => HF. + rewrite addr0 -RmultE. by rewrite /Rdiv mulRAC mulRV // mul1R. case: eqP ji => [->|ik]; first by rewrite jk. by rewrite inE negbK => /eqP ->; rewrite mulR0 div0R. @@ -588,7 +599,7 @@ have {2}-> : g = (fun j => <&>_(e' j) (g \o h')). rewrite inE /e' fdistE (big_pred1 (f' k)) /=; last first. by move=> i; rewrite 2!inE -{1}(enum_valK k) /f (can_eq enum_rankK). rewrite !fdistE. - by have [<-//f'kj|] := eqVneq _ j; rewrite mulR0 eqxx. + by have [<-//f'kj|] := eqVneq _ j; rewrite mulr0 eqxx. rewrite [RHS]axbarypart; last first. move=> i j ij; apply/setP => x. rewrite inE [RHS]inE. @@ -600,8 +611,8 @@ rewrite [RHS]axbarypart; last first. rewrite (big_pred1 (f' x)) in ky; last first. by move=> a; rewrite -{1}(enum_valK x) !inE (can_eq enum_rankK) eq_sym. move: kx ky; rewrite !fdistE. - case/boolP: ((f' x).2 == i) ij => [/eqP <-|] ij; last by rewrite mulR0 eqxx. - by case/boolP: ((f' x).2 == j) ij => [/eqP <-|] //; rewrite mulR0 eqxx. + case/boolP: ((f' x).2 == i) ij => [/eqP <-|] ij; last by rewrite mulr0 eqxx. + by case/boolP: ((f' x).2 == j) ij => [/eqP <-|] //; rewrite mulr0 eqxx. congr (<&>_ _ _); apply fdist_ext => k. rewrite /d1 !fdistE. under eq_bigr do rewrite fdistE big_distrr big_mkcond /=. @@ -615,18 +626,19 @@ have [->|Hj] := eqVneq j p.2; last first. move=> i; apply/negbTE; apply: contra Hj. rewrite !inE -(enum_valK k) (can_eq enum_rankK). by rewrite (surjective_pairing (enum_val k)) => /eqP [] _ /eqP. - by rewrite !fdistE eq_sym (negbTE Hj) !mulR0. + by rewrite !fdistE eq_sym (negbTE Hj) !mulr0. rewrite (big_pred1 p.1) /=; last first. move=> i; rewrite !inE -(enum_valK k) (can_eq enum_rankK). by rewrite (surjective_pairing (enum_val k)) xpair_eqE eqxx andbT. have [Hp|Hp] := eqVneq (\sum_(i < n) d i * e i p.2)%R 0%R. - by rewrite Hp mul0R (proj1 (psumR_eq0P _) Hp) // => *; exact: mulR_ge0. + rewrite Hp mul0r -RmultE. + by move/psumr_eq0P : Hp => ->//= i _; rewrite RmultE mulr_ge0. rewrite [RHS]mulRC !fdistE jfdist_condE !fdistE /=; last first. by under eq_bigr do rewrite fdistXE fdist_prodE. rewrite /jcPr /proba.Pr (big_pred1 p); last first. by move=> i; rewrite !inE -xpair_eqE -!surjective_pairing. rewrite (big_pred1 p.2); last by move=> i; rewrite !inE. -rewrite eqxx mulR1 fdist_sndE /= fdist_prodE. +rewrite eqxx mulr1 fdist_sndE /= fdist_prodE. under eq_bigr do rewrite fdist_prodE /=. by rewrite -mulRA mulVR ?mulR1. Qed. diff --git a/probability/convex_stone.v b/probability/convex_stone.v index 2cff3408..70d6457b 100644 --- a/probability/convex_stone.v +++ b/probability/convex_stone.v @@ -1,10 +1,11 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup perm finalg matrix. +From mathcomp Require Import all_ssreflect ssralg ssrnum matrix fingroup perm. From mathcomp Require boolp. Require Import Reals Lra. -From mathcomp Require Import Rstruct. -Require Import ssrR Reals_ext Ranalysis_ext ssr_ext ssralg_ext logb Rbigop. +From mathcomp Require Import mathcomp_extra Rstruct. +Require Import ssrR Rstruct_ext Reals_ext realType_ext Ranalysis_ext ssr_ext. +Require Import ssralg_ext logb Rbigop. Require Import fdist convex. (****************************************************************************) @@ -17,6 +18,8 @@ Set Implicit Arguments. Unset Strict Implicit. Import Prenex Implicits. +Import GRing.Theory Num.Theory Order.POrderTheory. + Local Open Scope fdist_scope. Local Open Scope convex_scope. Local Open Scope reals_ext_scope. @@ -213,12 +216,11 @@ Lemma swap_asaE n (s : 'S_n.+2) (K : s ord0 != ord0) : Proof. apply/permP => i. rewrite [in RHS]permE /=. -case/boolP : (i == ord0 :> 'I_n.+2) => i0. - by rewrite (eqP i0) lift_perm_id permE. +have [->|i0] := eqVneq i ord0; first by rewrite lift_perm_id permE. have Hi : i = lift ord0 (inord i.-1). apply/val_inj => /=. rewrite /bump leq0n /= add1n inordK. - by rewrite prednK // lt0n. + by rewrite prednK // lt0n. by rewrite -ltnS prednK // lt0n. rewrite {2}Hi lift_perm_lift 2!permE /= /swap_asa. case: ifPn => /=. @@ -298,10 +300,9 @@ Lemma suff_generators0 n (P : 'S_n.+2 -> Prop) : forall s : 'S_n.+2, P s. Proof. move=> H0 H1 H2 s. -case/boolP : (s ord0 == ord0 :> 'I__) => K. - apply H2; exact/eqP. +have [K|K] := eqVneq (s ord0) ord0; first exact: H2. rewrite (swap_asaE K); apply H0; first exact/H1. -apply H2; by rewrite lift_perm_id. +by apply H2; rewrite lift_perm_id. Qed. Lemma decomp_swap (n : nat) (s : 'S_n.+2) (K : s ord0 != ord0) : @@ -311,21 +312,18 @@ Lemma decomp_swap (n : nat) (s : 'S_n.+2) (K : s ord0 != ord0) : (tperm (lift ord0 ord0) (s ord0)))%g :> 'S_n.+2. Proof. apply /permP => /= i. -case/boolP : (i == ord0 :> 'I__) => [/eqP ->|Hi]; +have [->|Hi] := eqVneq i ord0; first by do ! rewrite permE /=; have -> : (if ord0 == s ord0 then lift ord0 ord0 else ord0) = ord0 by move => n0; rewrite ifN_eqC //=. do ! rewrite permE /=. rewrite ifN_eq //. -case/boolP : (i == lift ord0 ord0 :> 'I__) => [/eqP ->|Hi1]. -- case/boolP : (s ord0 == lift ord0 ord0 :> 'I__) => [/eqP ->|Hs]; - first by rewrite eq_refl; - have -> : (if lift ord0 ord0 == ord0 then lift ord0 ord0 else ord0) = ord0; - done. -- rewrite ifN_eqC //=. - have -> : (if s ord0 == ord0 then lift ord0 ord0 else s ord0) = s ord0 by rewrite ifN_eq. - by rewrite ifN_eq //= eq_refl. -case/boolP : (i == s ord0 :> 'I__) => His; +have [->|Hi1] := eqVneq i (lift ord0 ord0). +- have [->|Hs] := eqVneq (s ord0) (lift ord0 ord0); + first by + by have -> : (if lift ord0 ord0 == ord0 then lift ord0 ord0 else ord0) = ord0. + by rewrite (negbTE K) eqxx (negbTE Hs). +have [His|His] := eqVneq i (s ord0); first by have -> : (if lift ord0 ord0 == lift ord0 ord0 then ord0 else lift ord0 ord0) = ord0; [by move => *; rewrite eq_refl|rewrite ifN_eqC //|done]. have -> : (if i == ord0 then lift ord0 ord0 @@ -340,17 +338,15 @@ Lemma suff_generators n (P : 'S_n.+2 -> Prop) : forall s : 'S_n.+2, P s. Proof. move=> H0 H1 H2 s. -case/boolP : (s ord0 == ord0 :> 'I__) => K. - apply H2; exact/eqP. +have [K|K] := eqVneq (s ord0) ord0; first exact: H2. apply suff_generators0 => // s'. -case/boolP : (s' ord0 == lift ord0 ord0 :> 'I__) => K'; first by rewrite (eqP K'). -case/boolP : (s' ord0 == ord0 :> 'I__) => K''. - by rewrite (eqP K''); apply H2; rewrite permE. +have [->//|K'] := eqVneq (s' ord0) (lift ord0 ord0). +have [->|K''] := eqVneq (s' ord0) ord0; first by apply H2; rewrite permE. rewrite decomp_swap //. apply H0. - apply H2; by rewrite permE /= eq_sym (negbTE K''). + by apply H2; rewrite permE /= eq_sym (negbTE K''). apply H0; first exact: H1. -apply H2; by rewrite permE /= eq_sym (negbTE K''). +by apply H2; rewrite permE /= eq_sym (negbTE K''). Qed. End Sn. @@ -358,62 +354,65 @@ End Sn. Section convex_space_prop. Variables A : convType. Implicit Types a b : A. -Lemma conv0 a b : a <| 0%:pr |> b = b. +Lemma conv0 a b : a <| R0%:pr |> b = b. Proof. -by rewrite convC (_ : _%:pr = 1%:pr) ?conv1 //=; apply val_inj; exact: onem0. +by rewrite convC (_ : _%:pr = R1%:pr) ?conv1 //=; apply val_inj; exact: onem0. Qed. -Lemma convA0 (p q r s : prob) a b c : - p = (r * s)%R :> R -> (s.~ = p.~ * q.~)%R -> +Lemma convA0 (p q r s : {prob R}) a b c : + Prob.p p = (Prob.p r * Prob.p s)%coqR :> R -> ((Prob.p s).~ = (Prob.p p).~ * (Prob.p q).~)%coqR -> a <| p |> (b <| q |> c) = (a <| r |> b) <| s |> c. Proof. move=> H1 H2. -case/boolP : (r == 0%:pr) => r0. - rewrite (eqP r0) conv0 (_ : p = 0%:pr) ?conv0; last first. - by apply/val_inj; rewrite /= H1 (eqP r0) mul0R. - congr (_ <| _ |> _); move: H2; rewrite H1 (eqP r0) mul0R onem0 mul1R. - move/(congr1 onem); rewrite !onemK => ?; exact/val_inj. -case/boolP : (s == 0%:pr) => s0. - rewrite (eqP s0) conv0 (_ : p = 0%:pr) ?conv0; last first. - by apply/val_inj; rewrite /= H1 (eqP s0) mulR0. - rewrite (_ : q = 0%:pr) ?conv0 //. - move: H1; rewrite (eqP s0) mulR0 => p0. - move: H2; rewrite p0 onem0 mul1R => /(congr1 onem); rewrite !onemK => sq. - rewrite -(eqP s0); exact/val_inj. +have [r0|r0] := eqVneq r R0%:pr. + rewrite r0 conv0 (_ : p = R0%:pr) ?conv0; last first. + by apply/val_inj; rewrite /= H1 r0 mul0R. + congr (_ <| _ |> _); move: H2; rewrite H1 r0 mul0R onem0 mul1R. + move/(congr1 (@onem _)); rewrite !onemK => ?; exact/val_inj. +have [s0|s0] := eqVneq s R0%:pr. + rewrite s0 conv0 (_ : p = R0%:pr) ?conv0; last first. + by apply/val_inj; rewrite /= H1 s0 mulR0. + rewrite (_ : q = R0%:pr) ?conv0 //. + move: H1; rewrite s0 mulR0 => p0. + move: H2; rewrite p0 onem0 mul1R => /(congr1 (@onem _)); rewrite !onemK => sq. + by rewrite -s0; exact/val_inj. rewrite convA; congr ((_ <| _ |> _) <| _ |> _). by apply val_inj; rewrite /= s_of_pqE -H2 onemK. by rewrite (@r_of_pq_is_r _ _ r s). Qed. -Lemma convA' (r s : prob) a b c : [p_of r, s] != 1%:pr -> +Lemma convA' (r s : {prob R}) a b c : [p_of r, s] != R1%:pr -> a <| [p_of r, s] |> (b <| [q_of r, s] |> c) = (a <| r |> b) <| s |> c. Proof. -move=> H; case/boolP : (s == 0%:pr) => s0. -- by rewrite (eqP s0) p_of_r0 conv0 q_of_r0 conv0 conv0. +move=> H; have [->|s0] := eqVneq s R0%:pr. +- by rewrite p_of_r0 conv0 q_of_r0 conv0 conv0. - by rewrite convA s_of_pqK // r_of_pqK. Qed. Lemma convACA (x1 y1 x2 y2 : A) p q : (x1 <|q|> y1) <|p|> (x2 <|q|> y2) = (x1 <|p|> x2) <|q|> (y1 <|p|> y2). Proof. -case/boolP : (p == 0%:pr) => [/eqP|] p0; first by rewrite p0 !conv0. -case/boolP : (q == 0%:pr) => [/eqP|] q0; first by rewrite q0 !conv0. -case/boolP : (p == 1%:pr) => [/eqP|] p1; first by rewrite p1 !conv1. -case/boolP : (q == 1%:pr) => [/eqP|] q1; first by rewrite q1 !conv1. +have [->|p0] := eqVneq p R0%:pr; first by rewrite !conv0. +have [->|q0] := eqVneq q R0%:pr; first by rewrite !conv0. +have [->|p1] := eqVneq p R1%:pr; first by rewrite !conv1. +have [->|q1] := eqVneq q R1%:pr; first by rewrite !conv1. set r := [p_of q, p]. -have r1 : (r != 1%:pr)%R by rewrite p_of_neq1 // -prob_gt0 -prob_lt1. +have r1 : (r != R1%:pr)%coqR by rewrite p_of_neq1 //; + by split; apply /RltP; [rewrite -prob_gt0 |rewrite -prob_lt1]. rewrite -(convA' x1 y1) //. rewrite (convC _ y1). set s := [q_of q, p]. -set t := (s.~%:pr * q)%:pr. -have t1 : (t < 1)%R. - rewrite -prob_lt1; apply/eqP => t1; subst t. - have {q1} : (q < 1)%R by rewrite -prob_lt1. - move/(congr1 Prob.p) : t1 => /= <-. - rewrite -ltR_pdivr_mulr; last by rewrite -prob_gt0. +set t := (Prob.p (Prob.p s).~%:pr * Prob.p q)%:pr. +have t1 : (Prob.p t < 1)%coqR. + apply/RltP. rewrite -prob_lt1; apply/eqP => t1; subst t. + have {q1} : (Prob.p q < 1)%coqR by apply/RltP; rewrite -prob_lt1. + move/RltP. rewrite R1E. + move/(congr1 (@Prob.p _)) : t1 => /= <-. move/RltP. + rewrite -ltR_pdivr_mulr; last by apply/RltP; rewrite -prob_gt0. rewrite divRR // /onem ltR_subr_addl ltRNge; apply. - by rewrite -{1}(add0R 1%R) leR_add2r. -rewrite -(convA' x2); last by rewrite prob_lt1 p_of_rsC /= p_of_rsE. + by rewrite -{1}[in (1%R <= _)%coqR](add0R 1%R) leR_add2r. + +rewrite -(convA' x2); last by rewrite prob_lt1 p_of_rsC /= p_of_rsE; apply/RltP. rewrite -(convA' x1) //; last by rewrite p_of_rsC. rewrite (convC _ y2 y1) /=. congr (_ <| _ |> _); first by rewrite p_of_rsC. @@ -421,19 +420,24 @@ congr (_ <| _ |> _). (* TODO: lemma? *) apply val_inj => /=. rewrite /s /onem /= !(p_of_rsE,q_of_rsE) /= !(p_of_rsE,q_of_rsE) /= /onem. + rewrite -!RminusE -R1E. field. rewrite subR_eq0 mulRC; apply/nesym/eqP; by rewrite -p_of_rsE. congr (_ <| _ |> _). apply val_inj => /=. -rewrite -[in RHS](onemK p); congr onem. -rewrite q_of_rsE {1}p_of_rsE /= q_of_rsE p_of_rsE /= /onem; field. +rewrite -[in RHS](onemK (Prob.p p)); congr onem. +rewrite q_of_rsE {1}p_of_rsE /= q_of_rsE p_of_rsE /= /onem. +rewrite -!RminusE. +rewrite -!R1E. +field. + split. rewrite subR_eq0; apply/nesym/eqP; by rewrite -p_of_rsE. rewrite mulRBl mul1R subRBA subRK mulRDr mulR1 mulRN addR_opp subRBA subRK. rewrite subR_eq0 => /esym; exact/eqP. Qed. -Lemma distribute (x y z : A) (p q : prob) : +Lemma distribute (x y z : A) (p q : {prob R}) : x <| p |> (y <| q |> z) = (x <| p |> y) <| q |> (x <| p |> z). Proof. by rewrite -{1}(convmm q x) convACA. Qed. @@ -443,8 +447,8 @@ elim: n j g => [[] [] //|n IH j g /=]. case: Bool.bool_dec => [/eqP|/Bool.eq_true_not_negb b01]. rewrite fdist1E; case j0 : (_ == _) => /=. by move=> _; rewrite (eqP j0). - by rewrite (_ : (0%:R)%R = 0%R) //; lra. -rewrite (_ : probfdist _ _ = 0%:pr) ?conv0; last first. + by move/eqP; rewrite eq_sym R1E oner_eq0. +rewrite (_ : probfdist _ _ = R0%:pr) ?conv0; last first. apply val_inj => /=; move: b01; rewrite !fdist1E => j0. by case j0' : (_ == _) => //; rewrite j0' eqxx in j0. have j0 : ord0 != j by apply: contra b01 => /eqP <-; rewrite fdist1xx. @@ -453,8 +457,8 @@ move=> [:H]; have @j' : 'I_n. by apply: (@Ordinal _ j.-1 _); abstract: H; rewrite prednK // -ltnS. rewrite (_ : fdist_del b01 = fdist1 j'); last first. apply/fdist_ext => /= k. - rewrite fdist_delE fdistD1E /= !fdist1E /= (negbTE j0) subR0 divR1. - congr (INR (nat_of_bool _)). + rewrite fdist_delE fdistD1E /= !fdist1E /= (negbTE j0) subr0 divr1. + congr (GRing.natmul _ (nat_of_bool _)). move R : (k == _) => [|]. - apply/eqP/val_inj; rewrite /= /bump leq0n add1n. by move/eqP : R => -> /=; rewrite prednK // lt0n. @@ -471,7 +475,7 @@ rewrite /=; case: Bool.bool_dec => // /Bool.eq_true_not_negb H; exfalso; move/eq by apply/eqP; rewrite fdist1E1 (fdist1I1 e). Qed. -Lemma convnE n (g : 'I_n.+1 -> A) (d : {fdist 'I_n.+1}) (i1 : d ord0 != 1%R) : +Lemma convnE n (g : 'I_n.+1 -> A) (d : {fdist 'I_n.+1}) (i1 : d ord0 != 1%coqR) : <|>_d g = g ord0 <| probfdist d ord0 |> <|>_(fdist_del i1) (fun x => g (fdist_del_idx ord0 x)). Proof. @@ -483,9 +487,9 @@ Qed. Lemma convn2E (g : 'I_2 -> A) (d : {fdist 'I_2}) : <|>_d g = g ord0 <| probfdist d ord0 |> g (Ordinal (erefl (1 < 2))). Proof. -case/boolP : (d ord0 == 1%R) => [|i1]. +have [/eqP |i1] := eqVneq (d ord0) 1%coqR. rewrite fdist1E1 => /eqP ->; rewrite Convn_fdist1. - rewrite (_ : probfdist _ _ = 1%:pr) ?conv1 //. + rewrite (_ : probfdist _ _ = R1%:pr) ?conv1 //. by apply val_inj; rewrite /= fdist1xx. rewrite convnE; congr (_ <| _ |> _). rewrite (_ : (fun _ => _) = (fun=> g (fdist_del_idx ord0 ord0))); last first. @@ -493,18 +497,20 @@ rewrite (_ : (fun _ => _) = (fun=> g (fdist_del_idx ord0 ord0))); last first. by rewrite convn1E /fdist_del_idx ltnn; congr g; exact/val_inj. Qed. -Lemma convn3E (g : 'I_3 -> A) (d : {fdist 'I_3}) (p : prob) : +Open Scope ring_scope. + +Lemma convn3E (g : 'I_3 -> A) (d : {fdist 'I_3}) (p : {prob R}) : d ord0 != 1%R -> - p = (d (lift ord0 ord0) / (1 - d ord0))%R :> R -> + (d (lift ord0 ord0) / (1 - d ord0)) = p -> <|>_d g = g ord0 <| probfdist d ord0 |> (g (Ordinal (erefl (1 < 3)%nat)) <| p |> g (Ordinal (erefl (2 < 3)%nat))). Proof. move=> i1 Hp. -case/boolP : (p == 1%:pr) => p1. +have [p1|p1] := eqVneq p R1%:pr. rewrite convnE; congr (_ <| _ |> _). rewrite convn2E /fdist_del_idx ltnn /=; congr (g _ <| _ |> g _). - apply val_inj => /=. - by rewrite fdist_delE fdistD1E (eq_sym (lift _ _)) (negbTE (neq_lift _ _)) -Hp. - exact/val_inj. + apply val_inj => /=. + by rewrite fdist_delE fdistD1E (eq_sym (lift _ _)) (negbTE (neq_lift _ _)). + exact/val_inj. exact/val_inj. rewrite convnE; congr (_ <| _ |> _). rewrite convn2E /fdist_del_idx ltnn /=; congr (g _ <| _ |> g _). @@ -518,13 +524,13 @@ Lemma convn_proj n (g : 'I_n -> A) (d : {fdist 'I_n}) i : d i = R1 -> <|>_d g = g i. Proof. elim: n g d i => [d d0|n IH g d i di1]; first by move: (fdistI0_False d0). -case/boolP : (i == ord0) => [/eqP|]i0. +have [i0|i0] := eqVneq i ord0. move/eqP : di1; rewrite i0 fdist1E1 => /eqP ->. by rewrite Convn_fdist1. have d00 : d ord0 = R0 by move/eqP/fdist1P : di1 => -> //; rewrite eq_sym. rewrite convnE; first by rewrite d00; apply/eqP; lra. move=> d01. -rewrite (_ : probfdist _ _ = 0%:pr); last exact/val_inj. +rewrite (_ : probfdist _ _ = R0%:pr); last exact/val_inj. rewrite conv0. move=> [:Hj]. have @j : 'I_n. @@ -534,7 +540,7 @@ rewrite (IH _ _ j) // ?ltn0. congr g; apply val_inj => /=. by rewrite /bump leq0n add1n prednK // lt0n. rewrite fdist_delE ltn0 fdistD1E eq_sym (negbTE (neq_lift _ _ )). -rewrite d00 subR0 divR1 -di1; congr (d _). +rewrite d00 subr0 divr1 -di1; congr (d _). by apply val_inj; rewrite /= /bump leq0n add1n prednK // lt0n. Qed. @@ -561,88 +567,86 @@ Proof. have [->|Hs] := S2.generators s. rewrite fdistI_perm1; congr Convn. by rewrite boolp.funeqE => i; rewrite /= perm1. -move: (FDist.ge0 d ord0); rewrite leR_eqVlt => -[/esym d00|d00]. - have d11 : d (Ordinal (erefl (1 < 2))) = 1%R. - rewrite -(FDist.f1 d) 2!big_ord_recl big_ord0 addR0 d00 add0R; f_equal; exact/val_inj. - have H1 : d = fdist1 (Ordinal (erefl (1 < 2))). +move: (FDist.ge0 d ord0); rewrite le0r => /orP -[/eqP /esym d00|d00]. + have d11 : d (Ordinal (erefl (1 < 2)%nat)) = 1. + rewrite -(FDist.f1 d) 2!big_ord_recl big_ord0 addr0 -d00 add0r; f_equal; exact/val_inj. + have H1 : d = fdist1 (Ordinal (erefl (1 < 2)%nat)). rewrite -fdistI20; apply/fdist_ext => /= i. - rewrite fdistI2E; case: ifPn => [/eqP ->//|/= i0]; rewrite onem0. - rewrite -(FDist.f1 d) 2!big_ord_recl big_ord0 addR0 d00 add0R; congr (d _). + rewrite fdistI2E; case: ifPn => [/eqP ->//|/= i0]. + rewrite onem0 (_ : 1%coqR = 1%mcR)// -(FDist.f1 d) 2!big_ord_recl big_ord0 addr0 -d00 add0r; congr (d _). by case: i i0 => -[//|] -[|//] //= i12 _; exact/val_inj. rewrite {1}H1 Convn_fdist1 {1}Hs. - have H2 : fdistI_perm d (tperm ord0 (Ordinal (erefl (1 < 2)))) = fdist1 ord0. + have H2 : fdistI_perm d (tperm ord0 (Ordinal (erefl (1 < 2)%nat))) = fdist1 ord0. apply/fdist_ext => /= i; rewrite fdistI_permE fdist1E. - case/boolP : (i == ord0 :> 'I__) => i0. - by rewrite (eqP i0) permE /= d11. + have [->|i0] := eqVneq i ord0; first by rewrite permE /= d11. rewrite permE /= (negbTE i0). by case: ifPn => //; case: i i0 => -[|[|]]. by rewrite H2 Convn_fdist1 /=; congr g; rewrite Hs permE /=. -case/boolP : (d (lift ord0 ord0) == 0%R :> R) => d10. - have d01 : d ord0 = 1%R. - rewrite -(FDist.f1 d) !big_ord_recl big_ord0 addR0. - by rewrite addRC -subR_eq subRR (eqP d10). +have [d10|d10] := eqVneq (d (lift ord0 ord0)) 0%coqR. + have d01 : d ord0 = 1. + rewrite -(FDist.f1 d) !big_ord_recl big_ord0 addr0. + by rewrite addrC -subR_eq subRR d10. have -> : d = fdist1 ord0 by apply/eqP; rewrite -fdist1E1; exact/eqP. by rewrite Convn_fdist1 {1}Hs fdistI_tperm Convn_fdist1 /= Hs permE. rewrite convn2E. rewrite convn2E. rewrite /= Hs permE /= convC !permE /=; congr (_ <| _ |> _); apply val_inj => /=. rewrite fdistI_permE permE /= /onem -(FDist.f1 d) !big_ord_recl big_ord0. -by rewrite addR0 addRC addRK; congr (d _); exact/val_inj. +by rewrite addr0 (addrC (d ord0)) addrK; congr (d _); exact/val_inj. Qed. Lemma Convn_permI3_p01 (d : {fdist 'I_3}) (g : 'I_3 -> A) : <|>_d g = <|>_(fdistI_perm d S3.p01) (g \o S3.p01). Proof. have : (d ord0 + d (lift ord0 ord0) = 0 \/ d (lift ord0 ord0) + d ord_max = 0 \/ - (0 < d ord0 + d (lift ord0 ord0) /\ 0 < d (lift ord0 ord0) + d ord_max))%R. - have : (0 <= d ord0 + d (lift ord0 ord0))%R by apply addR_ge0. - have : (0 <= d (lift ord0 ord0) + d ord_max)%R by apply addR_ge0. - rewrite leR_eqVlt => -[|H]; first by auto. - rewrite leR_eqVlt => -[|H']; first by auto. + (0 < d ord0 + d (lift ord0 ord0) /\ 0 < d (lift ord0 ord0) + d ord_max)). + have : (0 <= d ord0 + d (lift ord0 ord0)) by apply addr_ge0. + have : (0 <= d (lift ord0 ord0) + d ord_max) by apply addr_ge0. + rewrite le0r => /orP -[/eqP|H]; first by auto. + rewrite le0r => /orP -[/eqP|H']; first by auto. right; right; by auto. move=> [ H | [ H | [H1 H2] ] ]. - have /eqP d1 : d ord_max = 1%R. - rewrite -(FDist.f1 d) !big_ord_recl big_ord0 addR0 addRA H add0R. + have /eqP d1 : d ord_max = 1. + rewrite -(FDist.f1 d) !big_ord_recl big_ord0 addr0 addrA H add0r. by congr (d _); exact/val_inj. rewrite fdist1E1 in d1. rewrite {1}(eqP d1) Convn_fdist1. by rewrite (eqP d1) fdistI_perm_fdist1 Convn_fdist1 /= permKV. - have /eqP : d ord0 = 1%R. - rewrite -(FDist.f1 d) !big_ord_recl big_ord0 addR0 addRC -subR_eq subRR. - by rewrite (_ : lift ord0 (lift _ _) = ord_max) ?H //; exact/val_inj. + have /eqP : d ord0 = 1. + rewrite -(FDist.f1 d) !big_ord_recl big_ord0 addr0. + rewrite (_ : lift ord0 (lift _ _) = ord_max); last exact/val_inj. + by rewrite H addr0. rewrite fdist1E1 => /eqP ->. by rewrite Convn_fdist1 fdistI_perm_fdist1 Convn_fdist1 /= permKV. -have d01 : d ord0 <> 1%R. +have d01 : d ord0 <> 1. move=> /eqP d01. move: H2. move/fdist1P : (d01) => -> //. move/fdist1P : d01 => -> //. - by rewrite add0R; move/ltRR. + by rewrite add0r ltxx. move=> [:Hp]. -have @p : prob. - apply: (@Prob.mk_ (d (lift ord0 ord0) / (1 - d ord0))). +have @p : {prob R}. + apply: (@Prob.mk_ _ (d (lift ord0 ord0) / (1 - d ord0))). abstract: Hp. - split. - apply/divR_ge0 => //. - by rewrite subR_gt0 -fdist_lt1; exact/eqP. - rewrite leR_pdivr_mulr ?mul1R ?subR_gt0 -?fdist_lt1; last exact/eqP. - rewrite leR_subr_addr -(FDist.f1 d) !big_ord_recl big_ord0 addR0. - by rewrite addRC leR_add2l addRC -leR_subl_addr subRR. -case/boolP : (p == 1%:pr :> prob) => [/eqP |p1]. - move/(congr1 Prob.p); rewrite [in X in X -> _]/=. - rewrite eqR_divr_mulr ?mul1R; last by apply/eqP; rewrite subR_eq0; exact/nesym. - move=> H. - rewrite (@convn3E _ _ 1%:pr) ?conv1; last 2 first. - exact/eqP. - by rewrite H divRR // subR_eq0' eq_sym; exact/eqP. - case/boolP : (d ord0 == 0 :> R)%R => d00. - rewrite (_ : probfdist _ _ = 0%:pr) ?conv0; last by apply val_inj => /=; exact/eqP. - move: H; rewrite (eqP d00) subR0 => /eqP; rewrite fdist1E1 => /eqP ->. + apply/andP; split. + by rewrite divr_ge0 // subr_ge0. + rewrite ler_pdivrMr ?mul1r ?subr_gt0 -?fdist_lt1; last exact/eqP. + rewrite lerBrDr -(FDist.f1 d) !big_ord_recl big_ord0 addr0. + by rewrite addrC lerD2l addrC -lerBlDr subrr. +have [|p1] := eqVneq p R1%:pr. + move/(congr1 (@Prob.p _)); rewrite [in X in X -> _]/=. + move/divr1_eq => H. + rewrite (@convn3E _ _ R1%:pr) ?conv1; last 2 first. + exact/eqP. + by rewrite H divrr // unitfE subr_eq0 eq_sym; exact/eqP. + have [d00|d00] := eqVneq (d ord0) 0. + rewrite (_ : probfdist _ _ = R0%:pr) ?conv0; last by apply val_inj => /=. + move: H; rewrite d00 subr0 => /eqP; rewrite fdist1E1 => /eqP ->. by rewrite fdistI_perm_fdist1 Convn_fdist1 /= permKV; congr g; exact/val_inj. - rewrite (@convn3E _ _ 1%:pr) ?conv1; last first. + rewrite (@convn3E _ _ R1%:pr) ?conv1; last first. rewrite !fdistI_permE /S3.p01 /= !permE /=. rewrite (_ : Ordinal _ = lift ord0 ord0); last exact/val_inj. - by rewrite H subRB subRR add0R divRR. + by rewrite H opprB addrC subrK divrr. rewrite /S3.p01 /= fdistI_permE permE /=. rewrite (_ : Ordinal _ = lift ord0 ord0); last exact/val_inj. apply: contra d00 => /eqP d001. @@ -655,69 +659,72 @@ case/boolP : (p == 1%:pr :> prob) => [/eqP |p1]. rewrite (@convn3E _ _ p) //; last exact/eqP. rewrite convA. rewrite (convC _ (g ord0)). -have H : [p_of [r_of probfdist d ord0, p].~%:pr, [s_of probfdist d ord0, p]] != 1%:pr :> R. +have ? : 1 - d ord0 != 0 by rewrite subr_eq0; exact/eqP/nesym. +have H : [p_of (Prob.p [r_of probfdist d ord0, p]).~%:pr, [s_of probfdist d ord0, p]] != R1%:pr :> R. apply p_of_neq1. rewrite s_of_pqE /=. - rewrite onemM !onemK -subRBA -[X in (_ < _ - (_ - X) < _)%R]mul1R. - rewrite -mulRBl -addR_opp -mulNR oppRB /Rdiv mulRCA mulRV ?mulR1; last first. - apply/eqP; rewrite subR_eq0; by auto. - split => //. + rewrite Reals_ext.onemM !onemK -subRBA -[X in (_ < _ - (_ - X) < _)%coqR]mul1R. + rewrite -mulRBl -addR_opp -mulNR oppRB mulRCA -RinvE' mulRV // mulR1. + split; first exact/RltP. rewrite ltR_neqAle; split. apply/eqP; apply: contra p1 => p1. apply/eqP/val_inj => /=. move: p1; rewrite eq_sym addRC -subR_eq' => /eqP <-. - rewrite divRR // subR_eq0'; apply/eqP; by auto. - by rewrite -(FDist.f1 d) !big_ord_recl /= big_ord0 addR0 addRA leR_addl. + by rewrite RminusE divff. + by rewrite R1E -(FDist.f1 d) !big_ord_recl /= big_ord0 addr0 addrA leR_addl. rewrite -convA'; last by []. -case/boolP : (d (S3.p01 ord0) == 1 :> R)%R => ds01. +have [/eqP ds01|ds01] := eqVneq (d (S3.p01 ord0)) 1. move: (ds01); rewrite /S3.p01 permE => d01'. rewrite /= in d01'. rewrite (_ : Ordinal _ = lift ord0 ord0) in d01'; last exact/val_inj. rewrite fdist1E1 in d01'. rewrite fdist1E1 in ds01. rewrite [in RHS](eqP ds01) fdistI_perm_fdist1 Convn_fdist1 /= permKV. - rewrite (_ : [p_of _, _] = 1%:pr); last first. + rewrite (_ : [p_of _, _] = R1%:pr); last first. apply/val_inj => /=. rewrite p_of_rsE /= r_of_pqE /= s_of_pqE /= (eqP d01'). - by rewrite fdist10// div0R onem0 subR0 !mul1R divR1 onemK fdist1xx. - by rewrite conv1 /S3.p01 permE /= (_ : Ordinal _ = lift ord0 ord0) //; exact/val_inj. + by rewrite fdist10// div0R onem0 subr0 !mul1R divr1 onemK fdist1xx. + rewrite conv1 /S3.p01 permE /= (_ : Ordinal _ = lift ord0 ord0) //. + exact/val_inj. move=> [:Hq]. -have @q : prob. - apply: (@Prob.mk_ +have @q : {prob R}. + apply: (@Prob.mk_ _ ((fdistI_perm d S3.p01) (lift ord0 ord0) / (1 - (fdistI_perm d S3.p01) ord0))). abstract: Hq. rewrite !fdistI_permE. - split; first by apply/divR_ge0 => //; rewrite subR_gt0 -fdist_lt1. - rewrite leR_pdivr_mulr ?mul1R; last by rewrite subR_gt0 -fdist_lt1. - rewrite leR_subr_addr -(FDist.f1 (fdistI_perm d S3.p01)) !big_ord_recl big_ord0. - by rewrite addR0 !fdistI_permE addRCA addRA -[X in (X <= _)%R]addR0 leR_add2l. + apply/andP. split. + by apply/divr_ge0 => //; rewrite subr_ge0; apply ltW; rewrite -fdist_lt1. + rewrite ler_pdivrMr ?mul1r; last by rewrite subr_gt0 -fdist_lt1. + rewrite lerBrDr -(FDist.f1 (fdistI_perm d S3.p01)) !big_ord_recl big_ord0. + by rewrite addr0 !fdistI_permE addrCA addrA -[X in (X <= _)]addr0 lerD2l. rewrite (@convn3E _ _ q) //; last by rewrite fdistI_permE. congr (_ <| _ |> _). - apply/val_inj => /=. +- apply/val_inj => /=. rewrite fdistI_permE permE /= p_of_rsE /= r_of_pqE /=. rewrite s_of_pqE /= /onem. rewrite (_ : Ordinal _ = lift ord0 ord0); last exact/val_inj. - field. + rewrite -R1E -!RminusE -!RdivE'//; field. split; first by rewrite subR_eq0; exact/nesym. rewrite -addR_opp oppRB -addR_opp oppRB addRC addRA subRK. - by apply/eqP; rewrite gtR_eqF // addRC. -by rewrite /= /S3.p01 permE /=; congr g; exact/val_inj. -congr (_ <| _ |> _). - apply val_inj => /=. - rewrite q_of_rsE /= !fdistI_permE p_of_rsE /= r_of_pqE /= s_of_pqE. - rewrite /= /onem !permE /=. - rewrite (_ : Ordinal _ = lift ord0 ord0); last exact/val_inj. - field. - split. + by apply/eqP; rewrite gtR_eqF // addRC; apply/RltP. +- by rewrite /= /S3.p01 permE /=; congr g; exact/val_inj. +- congr (_ <| _ |> _). + + apply val_inj => /=. + rewrite q_of_rsE /= !fdistI_permE p_of_rsE /= r_of_pqE /= s_of_pqE. + rewrite /= /onem !permE /=. + rewrite (_ : Ordinal _ = lift ord0 ord0); last exact/val_inj. + rewrite -[RHS]RdivE'. + rewrite -R1E -!RminusE -!RdivE //. field. + split. rewrite subR_eq0. apply/nesym/eqP. apply: contra ds01. rewrite /S3.p01 permE /= (_ : Ordinal _ = lift ord0 ord0) //; exact/val_inj. - split; first by rewrite subR_eq0; exact/nesym. - rewrite -addR_opp oppRB -addR_opp oppRB addRC addRA subRK. - by apply/eqP; rewrite gtR_eqF // addRC. -by congr g; apply val_inj => /=; rewrite /S3.p01 permE. -by rewrite /= /S3.p01 permE. + split; first by rewrite subR_eq0; exact/nesym. + rewrite -addR_opp oppRB -addR_opp oppRB addRC addRA subRK. + by apply/eqP; rewrite gt_eqF // addRC. + + by congr g; apply val_inj => /=; rewrite /S3.p01 permE. + + by rewrite /= /S3.p01 permE. Qed. Lemma Convn_permI3_p02 (d : {fdist 'I_3}) (g : 'I_3 -> A) : @@ -725,107 +732,112 @@ Lemma Convn_permI3_p02 (d : {fdist 'I_3}) (g : 'I_3 -> A) : Proof. (* TODO(rei): redundant part with Convn_perm3_p02 *) have : (d ord0 + d (lift ord0 ord0) = 0 \/ d (lift ord0 ord0) + d ord_max = 0 \/ - (0 < d ord0 + d (lift ord0 ord0) /\ 0 < d (lift ord0 ord0) + d ord_max))%R. - have : (0 <= d ord0 + d (lift ord0 ord0))%R by apply addR_ge0. - have : (0 <= d (lift ord0 ord0) + d ord_max)%R by apply addR_ge0. - rewrite leR_eqVlt => -[|H]; first by auto. - rewrite leR_eqVlt => -[|H']; first by auto. + (0 < d ord0 + d (lift ord0 ord0) /\ 0 < d (lift ord0 ord0) + d ord_max)). + have : (0 <= d ord0 + d (lift ord0 ord0)) by apply addr_ge0. + have : (0 <= d (lift ord0 ord0) + d ord_max) by apply addr_ge0. + rewrite le_eqVlt => /orP -[|H]; first by move/eqP; auto. + rewrite le_eqVlt => /orP -[|H']; first by move/eqP; auto. right; right; by auto. move=> [ H | [ H | [H1 H2] ] ]. - have /eqP d1 : d ord_max = 1%R. - rewrite -(FDist.f1 d) !big_ord_recl big_ord0 addR0 addRA H add0R; congr (d _); exact/val_inj. + have /eqP d1 : d ord_max = 1. + rewrite -(FDist.f1 d) !big_ord_recl big_ord0 addr0 addrA H add0r; congr (d _); exact/val_inj. rewrite fdist1E1 in d1. rewrite {1}(eqP d1) Convn_fdist1. by rewrite (eqP d1) fdistI_perm_fdist1 Convn_fdist1 /= permKV. - have /eqP d1 : d ord0 = 1%R. - rewrite -(FDist.f1 d) !big_ord_recl big_ord0 addR0 addRC -subR_eq subRR. + have /eqP d1 : d ord0 = 1. + rewrite -(FDist.f1 d) !big_ord_recl big_ord0 addr0 addrC. apply/eqP. rewrite -subr_eq subrr. rewrite (_ : lift ord0 (lift _ _) = ord_max) ?H //; exact/val_inj. rewrite fdist1E1 in d1. by rewrite (eqP d1) Convn_fdist1 fdistI_perm_fdist1 Convn_fdist1 /= permKV. -have d01 : d ord0 <> 1%R. +have d01 : d ord0 <> 1%coqR. move=> /eqP d01. move: H2. move/fdist1P : (d01) => -> //. move/fdist1P : d01 => -> //. - by rewrite add0R; move/ltRR. + by rewrite add0r ltxx. move=> [:Hp]. -have @p : prob. - apply: (@Prob.mk_ (d (lift ord0 ord0) / (1 - d ord0))). +have @p : {prob R}. + apply: (@Prob.mk_ _ (d (lift ord0 ord0) / (1 - d ord0))). abstract: Hp. - split; first by apply/divR_ge0 => //; rewrite subR_gt0 -fdist_lt1; exact/eqP. - rewrite leR_pdivr_mulr ?mul1R ?subR_gt0 -?fdist_lt1; last exact/eqP. - rewrite leR_subr_addr -(FDist.f1 d) !big_ord_recl big_ord0 addR0. - by rewrite addRC leR_add2l addRC -leR_subl_addr subRR. + apply/andP. split; + first by apply/divr_ge0/ltW => //; rewrite subr_gt0 -fdist_lt1; exact/eqP. + rewrite ler_pdivrMr; last by rewrite subr_gt0 -fdist_lt1; exact/eqP. + rewrite mul1r. + rewrite lerBrDr -(FDist.f1 d) !big_ord_recl big_ord0 addr0. + by rewrite addrC lerD2l addrC -lerBlDr subrr. rewrite (@convn3E _ _ p) //; last exact/eqP. rewrite convC. -rewrite (convC _ _ (g (Ordinal (erefl (2 < 3))))). -case/boolP : (d ord_max == 1%R :> R) => dmax1. +rewrite (convC _ _ (g (Ordinal (erefl (2 < 3)%nat)))). +have [/eqP dmax1|dmax1] := eqVneq (d ord_max) 1%coqR. move/fdist1P in dmax1. - by move: H1; rewrite dmax1 // dmax1 // addR0 => /ltRR. -case/boolP : (d ord0 == 0 :> R)%R => d00. - rewrite (_ : (probfdist _ _).~%:pr = 1%:pr) ?conv1; last first. - by apply/val_inj; rewrite /= (eqP d00) onem0. - rewrite (@convn3E _ _ 1%:pr); last 2 first. + by move: H1; rewrite dmax1 // dmax1 // addr0 ltxx. +have [d00|d00] := eqVneq (d ord0) 0. + rewrite (_ : (Prob.p (probfdist d ord0)).~%:pr = R1%:pr) ?conv1; last first. + by apply/val_inj; rewrite /= d00 onem0. + rewrite (@convn3E _ _ 1%coqR%:pr); last 2 first. rewrite fdistI_permE /= !permE /=. rewrite (_ : Ordinal _ = ord_max) //; exact/val_inj. rewrite !fdistI_permE /S3.p02 !permE /=. rewrite (_ : Ordinal _ = ord_max) //; last exact/val_inj. - rewrite -{2}(FDist.f1 d) !big_ord_recl big_ord0 addR0 (eqP d00) add0R. + rewrite R1E -[in LHS](FDist.f1 d) !big_ord_recl big_ord0 addr0 d00 add0r. rewrite (_ : lift _ (lift _ _) = ord_max); last exact/val_inj. - rewrite addRK divRR //. + rewrite addrK divrr //. apply/eqP => d10. - by move: H1; rewrite (eqP d00) d10 addR0 => /ltRR. + by move: H1; rewrite d00 d10 addr0 ltxx. rewrite /= /S3.p02 !permE /= conv1. congr (g _ <| _ |> _). apply/val_inj => /=. rewrite fdistI_permE permE /=. rewrite (_ : Ordinal _ = ord_max) //; last exact/val_inj. - rewrite (eqP d00) subR0 divR1 /onem -(FDist.f1 d) /= !big_ord_recl big_ord0 addR0. - rewrite (eqP d00) add0R addRC addRK; congr (d _); exact/val_inj. -have H : [p_of p.~%:pr, (probfdist d ord0).~%:pr] != 1%:pr. + rewrite d00 subr0 divr1 /onem -(FDist.f1 d) /= !big_ord_recl big_ord0 addr0. + rewrite d00 add0r [X in X - _]addrC addrK; congr (d _); exact/val_inj. +have H : [p_of (Prob.p p).~%:pr, (Prob.p (probfdist d ord0)).~%:pr] != 1%coqR%:pr. apply p_of_neq1 => /=; split. - apply/onem_gt0; rewrite -fdist_lt1; exact/eqP. - by rewrite ltR_subl_addr ltR_addl -fdist_gt0. + apply/RltP/onem_gt0; rewrite -fdist_lt1; exact/eqP. + by apply/RltP; rewrite ltrBlDr ltrDl -fdist_gt0. rewrite -convA'; last by []. move=> [:Hq]. -have @q : prob. - apply: (@Prob.mk_ ((fdistI_perm d S3.p02) (lift ord0 ord0) +have @q : {prob R}. + apply: (@Prob.mk_ _ ((fdistI_perm d S3.p02) (lift ord0 ord0) / (1 - (fdistI_perm d S3.p02) ord0))). abstract: Hq. rewrite !fdistI_permE !permE /= (_ : Ordinal _ = ord_max); last exact/val_inj. - split. - apply/divR_ge0 => //; first by rewrite subR_gt0 -fdist_lt1. - rewrite leR_pdivr_mulr ?mul1R ?subR_gt0 -?fdist_lt1 //. - rewrite leR_subr_addr -(FDist.f1 d) !big_ord_recl big_ord0 addR0. - by rewrite (_ : lift _ (lift _ _) = ord_max) ?leR_addr //; exact/val_inj. + apply/andP. split. + apply/divr_ge0 => //; first by apply/ltW; rewrite subr_gt0 -fdist_lt1. + rewrite ler_pdivrMr ?mul1r; last by rewrite subr_gt0 -fdist_lt1 //. + rewrite lerBrDr -(FDist.f1 d) !big_ord_recl big_ord0 addr0. + by rewrite (_ : lift _ (lift _ _) = ord_max) ?lerDr //; exact/val_inj. rewrite (@convn3E _ _ q) //; last first. rewrite fdistI_permE permE /= (_ : Ordinal _ = ord_max) //; exact/val_inj. rewrite /= !permE /=. +have ? : 1 - d ord0 != 0; first by rewrite subr_eq0 eq_sym; exact/eqP. congr (g _ <| _ |> (_ <| _ |> _)). apply val_inj => /=. rewrite !fdistI_permE p_of_rsE /= permE /=. rewrite (_ : Ordinal _ = ord_max); last exact/val_inj. rewrite {1}/onem. - rewrite mulRBl mul1R /Rdiv -mulRA mulVR ?mulR1; last first. - rewrite subR_eq0' eq_sym; exact/eqP. - rewrite /onem -subRD subR_eq -(FDist.f1 d) !big_ord_recl big_ord0 addR0. + rewrite mulRBl mul1R -mulRA -RinvE' // mulVR ?mulR1 //. + rewrite /onem -subRD subR_eq -(FDist.f1 d) !big_ord_recl big_ord0 addr0. rewrite (_ : lift _ (lift _ _) = ord_max); last exact/val_inj. by rewrite [in RHS]addRC -addRA. apply val_inj => /=. rewrite !fdistI_permE !permE /= q_of_rsE /= p_of_rsE /=. rewrite (_ : Ordinal _ = ord_max); last exact/val_inj. rewrite onemK. +rewrite -!RdivE' //. +rewrite -!RminusE. rewrite {1 2}/Rdiv. rewrite -2!mulRA. rewrite [in RHS]/Rdiv. -congr (_ * _)%R. +congr (_ * _)%coqR. rewrite mulRA mulVR; last first. rewrite subR_eq0' eq_sym; exact/eqP. rewrite mul1R. congr Rinv. rewrite onemM !onemK. +rewrite -RminusE -!RplusE -!RmultE. rewrite addRC. -rewrite -{1}(mulR1 (d (lift ord0 ord0) / _))%R. +rewrite -{1}(mulR1 (d (lift ord0 ord0) / _))%coqR. rewrite -subRBA. rewrite -mulRBr. rewrite -addR_opp. @@ -835,9 +847,9 @@ rewrite /Rdiv. rewrite -mulRA. rewrite mulVR ?mulR1; last first. rewrite subR_eq0' eq_sym; exact/eqP. -apply/esym; rewrite subR_eq -(FDist.f1 d) !big_ord_recl big_ord0 addR0. +apply/esym; rewrite subR_eq -(FDist.f1 d) !big_ord_recl big_ord0 addr0. rewrite (_ : lift _ (lift _ _) = ord_max); last exact/val_inj. -by rewrite addRA. +by rewrite addrA. Qed. Lemma Convn_permI3 (d : {fdist 'I_3}) (g : 'I_3 -> A) (s : 'S_3) : @@ -854,8 +866,8 @@ exact: Convn_perm_1. Qed. Lemma Convn_perm_projection n (d : {fdist 'I_n.+2}) - (g : 'I_n.+2 -> A) (s : 'S_n.+2) (H : s ord0 = ord0) (dmax1 : d ord0 != 1%R) - (m : nat) (nm : n.+1 < m) (IH : forall n : nat, n < m -> forall (d : {fdist 'I_n}) (g : 'I_n -> A) (s : 'S_n), + (g : 'I_n.+2 -> A) (s : 'S_n.+2) (H : s ord0 = ord0) (dmax1 : d ord0 != 1%coqR) + (m : nat) (nm : (n.+1 < m)%nat) (IH : forall n : nat, (n < m)%nat -> forall (d : {fdist 'I_n}) (g : 'I_n -> A) (s : 'S_n), <|>_d g = <|>_(fdistI_perm d s) (g \o s)) : <|>_d g = <|>_(fdistI_perm d s) (g \o s). Proof. @@ -877,7 +889,7 @@ congr (Convn _ _). rewrite /s' /=. rewrite permE. rewrite /f /=. - rewrite H; congr (_ / _)%R. + rewrite H; congr (_ / _). congr (d _). apply val_inj => /=. rewrite /bump leq0n add1n /=. @@ -911,48 +923,48 @@ by apply/eqP => /(@perm_inj _ s). Qed. Lemma Convn_perm_tperm (n : nat) (d : {fdist 'I_n.+3}) - (g : 'I_n.+3 -> A) (s : 'S_n.+3) (H : s = tperm ord0 (lift ord0 ord0)) (dmax1 : d ord0 != 1%R) - (m : nat) (nm : n.+3 < m.+1) (IH : forall n : nat, n < m -> + (g : 'I_n.+3 -> A) (s : 'S_n.+3) (H : s = tperm ord0 (lift ord0 ord0)) (dmax1 : d ord0 != 1%coqR) + (m : nat) (nm : (n.+3 < m.+1)%nat) (IH : forall n : nat, (n < m)%nat -> forall (d : {fdist 'I_n}) (g : 'I_n -> A) (s : 'S_n), <|>_d g = <|>_(fdistI_perm d s) (g \o s)) : <|>_d g = <|>_(fdistI_perm d s) (g \o s). Proof. -case/boolP : (d (lift ord0 ord0) == 1 - d ord0 :> R)%R => K. - case/boolP : (d (lift ord0 ord0) == 1%R :> R) => [|d11]. +have [K|K] := eqVneq (d (lift ord0 ord0)) (1 - d ord0). + case/boolP : (d (lift ord0 ord0) == 1%coqR :> R) => [|d11]. by rewrite fdist1E1 => /eqP ->; rewrite fdistI_perm_fdist1 !Convn_fdist1 /= permKV. rewrite convnE. rewrite [in RHS]convnE. by rewrite fdistI_permE H permE. move=> K'. rewrite (_ : <|>_ _ _ = g (lift ord0 ord0)); last first. - have /eqP : (fdist_del dmax1) ord0 = 1%R. - by rewrite fdist_delE fdistD1E /= (eqP K) divRR // subR_eq0' eq_sym. + have /eqP : (fdist_del dmax1) ord0 = 1%coqR. + by rewrite fdist_delE fdistD1E /= K divrr // unitfE subr_eq0 eq_sym. rewrite fdist1E1 => /eqP ->. by rewrite Convn_fdist1. rewrite (_ : <|>_ _ _ = g ord0); last first. - have /eqP : (fdist_del K') ord0 = 1%R. + have /eqP : (fdist_del K') ord0 = 1%coqR. rewrite fdist_delE fdistD1E /= !fdistI_permE H !permE /=. - rewrite (eqP K) subRB subRR add0R divRR //. - apply/eqP => d00. - move: K; by rewrite d00 subR0 (negbTE d11). + rewrite K opprB (addrC (d _) (-1)) addrA subrr add0r divrr // unitfE. + apply /eqP => d00. + by move: K; rewrite d00 subr0; apply/eqP. by rewrite fdist1E1 => /eqP ->; rewrite Convn_fdist1 /= H !permE /=. rewrite convC /= H permE /=; congr (_ <| _ |> _). - by apply val_inj => /=; rewrite fdistI_permE /= permE /= (eqP K). -case/boolP : (d (lift ord0 ord0) == 1%R :> R) => [|K1]. + by apply val_inj => /=; rewrite fdistI_permE /= permE /= K. +have [/eqP |K1] := eqVneq (d (lift ord0 ord0)) 1%coqR. by rewrite fdist1E1 => /eqP ->; rewrite fdistI_perm_fdist1 !Convn_fdist1 /= permKV. (* TODO: isolate this construction? *) pose D' : {ffun 'I_3 -> R} := [ffun x => [eta (fun=>R0) with ord0 |-> d ord0, lift ord0 ord0 |-> d (lift ord0 ord0), - ord_max |-> (\sum_(i < n.+3 | (2 <= i)%nat) d i)%R] x]. -have D'0 : (forall i, 0 <= D' i)%R. + ord_max |-> (\sum_(i < n.+3 | (2 <= i)%nat) d i)%coqR] x]. +have D'0 : (forall i, 0 <= D' i). move=> i; rewrite /D' ffunE /=; case: ifPn => _ //. - by case: ifPn => _ //; case: ifPn => _; [exact: sumR_ge0 | exact/leRR]. -have D'1 : (\sum_(i < 3) (D' i) = 1)%R. - rewrite !big_ord_recr big_ord0 /= add0R. + by case: ifPn => _ //; case: ifPn => _; [exact: sumr_ge0 | exact/lexx]. +have D'1 : (\sum_(i < 3) (D' i) = 1). + rewrite !big_ord_recr big_ord0 /= add0r. rewrite /D' !ffunE /= -(FDist.f1 d). apply/esym. - rewrite 2!big_ord_recl addRA; congr (_ + _)%R. + rewrite 2!big_ord_recl addrA; congr (_ + _)%coqR. apply/esym. set h : 'I_n.+1 -> 'I_n.+3 := fun i => lift ord0 (lift ord0 i). set h' : 'I_n.+3 -> 'I_n.+1 := fun i => inord (i.-2). @@ -969,11 +981,10 @@ have D'1 : (\sum_(i < 3) (D' i) = 1)%R. rewrite /h' /h. by apply/eqP/val_inj => /=; rewrite inordK. set D := FDist.make D'0 D'1. -have H1 : (fdist_del dmax1) ord0 != 1%R. +have H1 : (fdist_del dmax1) ord0 != 1%coqR. rewrite fdist_delE fdistD1E (eq_sym (lift _ _)) (negbTE (neq_lift _ _)). apply/eqP. - rewrite eqR_divr_mulr ?mul1R; first exact/eqP. - by apply/eqP; rewrite subR_eq0; exact/nesym/eqP. + move/divr1_eq. exact/eqP. pose G : 'I_3 -> A := [eta (fun=>g ord0) with ord0 |-> g ord0, lift ord0 ord0 |-> g (lift ord0 ord0), @@ -989,18 +1000,19 @@ transitivity (Convn D G). by rewrite ffunE. by rewrite /= !ffunE fdist_delE fdistD1E. rewrite (Convn_permI3 _ _ S3.p01). -pose q' := (d ord0 / (1 - d (lift ord0 ord0)))%R. +pose q' := (d ord0 / (1 - d (lift ord0 ord0))). move=> [:Hq]. -have @q : prob. - apply: (@Prob.mk_ q'). +have @q : {prob R}. + apply: (@Prob.mk_ _ q'). abstract: Hq. - split; first by apply/divR_ge0 => //; rewrite subR_gt0 -fdist_lt1. - rewrite leR_pdivr_mulr. - rewrite mul1R. - rewrite leR_subr_addr -(FDist.f1 d). - rewrite 2!big_ord_recl addRA leR_addl. - apply: sumR_ge0 => i _ //. - by rewrite subR_gt0 -fdist_lt1. + apply/andP. split. + by apply/divr_ge0/ltW => //; rewrite subr_gt0 -fdist_lt1. + rewrite ler_pdivrMr. + rewrite mul1r. + rewrite lerBrDr -(FDist.f1 d). + rewrite 2!big_ord_recl addrA lerDl. + by apply: sumr_ge0 => i _. + by rewrite subr_gt0 -fdist_lt1. rewrite (@convn3E _ _ q); last 2 first. rewrite fdistI_permE permE /= (_ : Ordinal _ = lift ord0 ord0); last exact/val_inj. by rewrite /D' ffunE /=. @@ -1017,12 +1029,8 @@ by rewrite /= /G /= permE /= H permE /=. rewrite convnE. rewrite fdist_delE fdistD1E !fdistI_permE H !permE /=. apply/eqP. - rewrite eqR_divr_mulr ?mul1R. - move/esym. - rewrite subR_eq; apply/eqP. - apply: contra K => /eqP ->. - by rewrite addRC addRK. - by rewrite subR_eq0' eq_sym. + move/divr1_eq. + by move/eqP; rewrite eq_sym subr_eq addrC -subr_eq; apply/negP; rewrite eq_sym. move=> K3. congr (_ <| _ |> _). apply val_inj => /=. @@ -1036,14 +1044,14 @@ congr (Convn _ _). apply/fdist_ext => j. rewrite !(fdist_delE,fdistI_permE,fdistD1E). rewrite H !permE /=. - field. - split. - rewrite subR_eq0; by apply/nesym/eqP. - split. - apply/eqP; apply: contra K => /eqP. - rewrite subR_eq0 => <-. - by rewrite subRB subRR add0R. -by rewrite subR_eq0; apply/nesym/eqP. + (* TODO: using field *) + rewrite -!mulrA. congr (_ * _). + have d0_1 : 1 - d ord0 != 0; first by rewrite subr_eq0 eq_sym. + rewrite -[I in I - _ / _](mulfV d0_1). + rewrite -mulrBl invf_div mulrA mulVf //. + have dl0_1 : 1 - d (lift ord0 ord0) != 0; first by rewrite subr_eq0 eq_sym. + rewrite -[I in I - _ / _](mulfV dl0_1) -mulrBl invf_div mulrA mulVf //. + by rewrite addrAC. by rewrite boolp.funeqE => j; rewrite /= permE H permE. Qed. @@ -1058,23 +1066,23 @@ destruct n as [|n]; first exact: Convn_permI2. destruct n as [|n]; first exact: Convn_permI3. move: m IH nm d g. apply (@Sn.suff_generators _ (fun s => forall m : nat, - (forall n0, n0 < m -> + (forall n0, (n0 < m)%nat -> forall (d : {fdist 'I_n0}) (g : 'I_n0 -> A) (s0 : 'S_n0), <|>_d g = <|>_(fdistI_perm d s0) (g \o s0)) -> - n.+4 < m.+1 -> + (n.+4 < m.+1)%nat -> forall (d : {fdist 'I_n.+4}) (g : 'I_n.+4 -> A), <|>_d g = <|>_(fdistI_perm d s) (g \o s))). - move=> s1 s2 H1 H2 m IH nm d g. rewrite (H1 m) // (H2 m) // fdistI_permM; congr (Convn _ _). by rewrite boolp.funeqE => i; rewrite /= permM. - move=> m IH nm d g. - case/boolP : (d ord0 == 1%R :> R) => [|dmax1]. + have [/eqP|dmax1] := eqVneq (d ord0) 1%coqR. rewrite fdist1E1 => /eqP ->. by rewrite Convn_fdist1 fdistI_perm_fdist1 Convn_fdist1 /= permKV. by apply Convn_perm_tperm with m. - move=> {}s H. move=> m IH nm d g. - case/boolP : (d ord0 == 1%R :> R) => [|dmax1]. + have [/eqP|dmax1] := eqVneq (d ord0) 1%coqR. rewrite fdist1E1 => /eqP ->. by rewrite Convn_fdist1 fdistI_perm_fdist1 Convn_fdist1 /= permKV. by apply Convn_perm_projection with m. @@ -1088,7 +1096,7 @@ Lemma affine_function_Sum (A B : convType) (f : {affine A -> B}) (n : nat) f (<|>_e g) = <|>_e (f \o g). Proof. elim: n g e => [g e|n IH g e]; first by move: (fdistI0_False e). -case/boolP : (e ord0 == 1%R :> R) => [|e01]. +have [/eqP|e10] := eqVneq (e ord0) 1%coqR. by rewrite fdist1E1 => /eqP ->; rewrite 2!Convn_fdist1. by rewrite 2!convnE affine_conv IH. Qed. @@ -1097,19 +1105,19 @@ End affine_function_prop0. Section convn_convnfdist. Variable A : finType. -Lemma convn_convnfdist n (g : 'I_n -> fdist A) (d : {fdist 'I_n}) : +Lemma convn_convnfdist n (g : 'I_n -> {fdist A}) (d : {fdist 'I_n}) : <|>_d g = fdist_convn d g. Proof. elim: n g d => /= [g d|n IH g d]; first by move: (fdistI0_False d). case: Bool.bool_dec => [/eqP|/Bool.eq_true_not_negb] H. apply/fdist_ext => a. - rewrite fdist_convnE big_ord_recl H mul1R big1 ?addR0 //= => j _. - by move/eqP/fdist1P : H => -> //; rewrite ?mul0R. + rewrite fdist_convnE big_ord_recl H mul1r big1 ?addr0 //= => j _. + by move/eqP/fdist1P : H => -> //; rewrite ?mul0r. apply/fdist_ext => a. -rewrite fdist_convE fdist_convnE /= big_ord_recl; congr (_ + _)%R. +rewrite fdist_convE fdist_convnE /= big_ord_recl; congr (_ + _)%coqR. rewrite IH fdist_convnE big_distrr /=; apply eq_bigr => i _. rewrite fdist_delE fdistD1E eq_sym (negbTE (neq_lift _ _)). -by rewrite /Rdiv mulRAC mulRC -mulRA mulVR ?mulR1 //; exact/onem_neq0. +by rewrite mulrAC mulrC !mulrA mulrV ?mul1r //; exact/onem_neq0. Qed. End convn_convnfdist. diff --git a/probability/divergence.v b/probability/divergence.v index 1b78797f..0147e489 100644 --- a/probability/divergence.v +++ b/probability/divergence.v @@ -1,9 +1,9 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect. +From mathcomp Require Import all_ssreflect ssralg all_algebra reals. Require Import Reals. From mathcomp Require Import Rstruct. -Require Import ssrR Reals_ext ln_facts logb Rbigop fdist. +Require Import ssrR Reals_ext ln_facts logb Rbigop fdist proba. (******************************************************************************) (* Divergence (or the Kullback-Leibler distance or relative entropy) *) @@ -26,6 +26,7 @@ Unset Strict Implicit. Import Prenex Implicits. Local Open Scope R_scope. +Local Open Scope fdist_scope. (* TODO: rename, move? *) Section log_facts. @@ -34,7 +35,7 @@ Lemma div_diff_ub x y : 0 <= x -> (y = 0 -> x = 0) -> 0 <= y -> x * (log (y / x)) <= (y - x) * log (exp 1). Proof. move=> x0 yx /leR_eqVlt[/esym|] y0. -- move: (yx y0) => ->; rewrite y0 subRR 2!mul0R; exact/leRR. +- by move: (yx y0) => ->; rewrite y0 subRR 2!mul0R. - case/leR_eqVlt : x0 => [/esym ->|x0]. + rewrite mul0R subR0; apply mulR_ge0; [exact: ltRW | exact: log_exp1_Rle_0]. + rewrite (_ : y - x = x * (y / x - 1)); last first. @@ -62,7 +63,7 @@ End log_facts. Section divergence_def. -Variables (A : finType) (P Q : fdist A). +Variables (A : finType) (P Q : {fdist A}). Definition div := \sum_(a in A) P a * log (P a / Q a). @@ -72,10 +73,11 @@ Notation "'D(' P '||' Q ')' " := (div P Q) : divergence_scope. Local Open Scope divergence_scope. Local Open Scope reals_ext_scope. +Local Open Scope fdist_scope. Section divergence_prop. -Variables (A : finType) (P Q : fdist A). +Variables (A : finType) (P Q : {fdist A}). Hypothesis P_dom_by_Q : P `<< Q. Lemma div_ge0 : 0 <= D(P || Q). @@ -86,14 +88,14 @@ rewrite /div [X in _ <= X](_ : _ = case/boolP : (P a == 0) => [/eqP ->|H0]; first by rewrite !mul0R. congr (_ * _). have Qa0 := dominatesEN P_dom_by_Q H0. - by rewrite -logV ?Rinv_div//; apply divR_gt0; rewrite -fdist_gt0. + by rewrite -logV ?Rinv_div//; apply divR_gt0; apply /RltP; rewrite -fdist_gt0. rewrite leR_oppr oppR0. apply (@leR_trans ((\sum_(a | a \in A) (Q a - P a)) * log (exp 1))). rewrite (big_morph _ (morph_mulRDl _) (mul0R _)). apply leR_sumR => a _; apply div_diff_ub => //. by move/dominatesP : P_dom_by_Q; exact. rewrite -{1}(mul0R (log (exp 1))); apply (leR_wpmul2r log_exp1_Rle_0). -by rewrite big_split /= -big_morph_oppR !FDist.f1 addR_opp subRR; exact/leRR. +by rewrite big_split /= -big_morph_oppR !FDist.f1 addR_opp subRR. Qed. Lemma divPP : D(Q || Q) = 0. @@ -116,7 +118,7 @@ apply/esym; move: a (erefl true); apply leR_sumR_eq. case/boolP : (P a == 0) => [/eqP ->| H0]; first by rewrite !mul0R. congr (_ * _). have Qa0 := dominatesEN P_dom_by_Q H0. - by rewrite -logV ?Rinv_div//; apply divR_gt0; rewrite -fdist_gt0. + by rewrite -logV ?Rinv_div//; apply divR_gt0; apply /RltP; rewrite -fdist_gt0. rewrite -(big_morph _ (morph_mulRDl _) (mul0R _)) big_split /=. by rewrite -big_morph_oppR !FDist.f1 addR_opp subRR mul0R. Qed. diff --git a/probability/fdist.v b/probability/fdist.v index 9d57390b..b6fb267f 100644 --- a/probability/fdist.v +++ b/probability/fdist.v @@ -1,10 +1,10 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup perm finalg matrix. -From mathcomp Require boolp. +From mathcomp Require Import all_ssreflect ssralg fingroup perm matrix. +From mathcomp Require Import all_algebra vector reals normedtype. +From mathcomp Require Import mathcomp_extra boolp. From mathcomp Require Import Rstruct. -Require Import Reals Lra Nsatz. -Require Import ssrR Reals_ext logb ssr_ext ssralg_ext bigop_ext Rbigop. +Require Import ssrR logb realType_ext ssr_ext ssralg_ext bigop_ext Rbigop. (******************************************************************************) (* Finite distributions *) @@ -68,6 +68,7 @@ Require Import ssrR Reals_ext logb ssr_ext ssralg_ext bigop_ext Rbigop. (******************************************************************************) Reserved Notation "{ 'fdist' T }" (at level 0, format "{ 'fdist' T }"). +Reserved Notation "R '.-fdist' T" (at level 2, format "R '.-fdist' T"). Reserved Notation "'`U' C0 " (at level 10, C0 at next level). Reserved Notation "P `^ n" (at level 5). Reserved Notation "P `X W" (at level 6). @@ -81,8 +82,7 @@ Set Implicit Arguments. Unset Strict Implicit. Import Prenex Implicits. -Local Open Scope R_scope. -Local Open Scope reals_ext_scope. +Declare Scope proba_scope. (* NB: f @^-1: [set y] would require to have finType's *) Notation "f @^-1 y" := (preim f (pred1 y)) : fdist_scope. @@ -99,63 +99,76 @@ Arguments bij_swap {A B}. Lemma swapK A B : (@swap A B) \o swap = @id (B * A). Proof. by rewrite boolp.funeqE => -[]. Qed. +Unset Printing Implicit Defensive. + +Import Order.POrderTheory Order.TotalTheory GRing.Theory Num.Theory. +(* on the model of infotheo *) Module FDist. Section fdist. -Variable A : finType. +Variables (R : numDomainType) (A : finType). +Local Open Scope ring_scope. Record t := mk { - f :> A ->R+ ; - _ : \sum_(a in A) f a == 1 :> R }. + f :> {ffun A -> R}; + _ : [forall a, 0 <= f a] && (\sum_(a in A) f a == 1) }. Lemma ge0 (d : t) a : 0 <= d a. -Proof. by case: d => /= f _; exact/nneg_finfun_ge0. Qed. -Lemma f1 (d : t) : \sum_(a in A) d a = 1 :> R. -Proof. by case: d => f /= /eqP. Qed. +Proof. by case: d => ? /= /andP[/forallP ]. Qed. +Lemma f1 (d : t) : \sum_(a in A) d a = 1. +Proof. by case: d => ? /= /andP[? /eqP]. Qed. Lemma le1 (d : t) a : d a <= 1. Proof. rewrite -(f1 d) (_ : d a = \sum_(a' in A | a' == a) d a'). - apply (@leR_sumRl_support _ _ _ xpredT) => // ?; exact/ge0. + rewrite big_mkcond /=. apply: ler_sum => a0 _. case: ifPn => // _. exact: ge0. by rewrite big_pred1_eq. Qed. -Definition make (f : {ffun A -> R}) (H0 : forall a, 0 <= f a) - (H1 : \sum_(a in A) f a = 1) := @mk (@mkNNFinfun _ f - (proj1 (@reflect_iff _ _ (forallP_leRP _)) H0)) (introT eqP H1). + +Definition make (f : {ffun A -> R}) (H0 : forall a, (0 <= f a)%R) + (H1 : \sum_(a in A) f a = 1) : t. +refine (@mk f _). apply/andP. split; [exact /forallP | exact/eqP]. +Defined. + End fdist. Module Exports. Notation fdist := t. End Exports. End FDist. Export FDist.Exports. -Coercion FDist.f : fdist >-> nneg_finfun. -Canonical fdist_subType A := Eval hnf in [subType for @FDist.f A]. -Definition fdist_eqMixin A := [eqMixin of fdist A by <:]. -Canonical fdist_eqType A := Eval hnf in EqType _ (fdist_eqMixin A). - -Global Hint Resolve FDist.ge0 : core. -Global Hint Resolve FDist.le1 : core. +Coercion FDist.f : fdist >-> finfun_of. +Canonical fdist_subType R A := Eval hnf in [subType for @FDist.f R A]. +Definition fdist_eqMixin R A := [eqMixin of fdist R A by <:]. +Canonical fdist_eqType R A := Eval hnf in EqType _ (fdist_eqMixin R A). -Definition fdist_of (A : finType) := fun phT : phant (Finite.sort A) => fdist A. +#[global] Hint Extern 0 (is_true (0 <= _)%R) => solve [exact: FDist.ge0] : core. +#[global] Hint Extern 0 (is_true (_ <= 1)%R) => solve [exact: FDist.le1] : core. -Notation "{ 'fdist' T }" := (fdist_of (Phant T)) : fdist_scope. +Definition fdist_of (R : realType) (A : finType) := + fun phT : phant (Finite.sort A) => fdist R A. +Notation "R '.-fdist' T" := (fdist_of R (Phant T)) : fdist_scope. +Notation "{ 'fdist' T }" := (fdist_of real_realType (Phant T)) : fdist_scope. -Lemma fdist_ge0_le1 (A : finType) (d : fdist A) a : 0 <= d a <= 1. -Proof. by []. Qed. +Lemma fdist_ge0_le1 (R : numDomainType) (A : finType) (d : fdist R A) a : + (0 <= d a <= 1)%R. +Proof. by apply/andP. Qed. -Definition probfdist (A : finType) (d : fdist A) a := - Eval hnf in Prob.mk_ (fdist_ge0_le1 d a). +Definition probfdist (R: realType) (A : finType) (d : fdist R A) a := + Eval hnf in Prob.mk_ (@fdist_ge0_le1 R A d a). Section fdist_lemmas. +Local Open Scope ring_scope. +Variable R : numDomainType. Variable A : finType. -Implicit Types d : fdist A. +Implicit Types d : fdist R A. Definition is_fdist (f : A -> R) : Prop := (forall a, 0 <= f a) /\ (\sum_(a in A) f a = 1). Lemma fdist_is_fdist d : is_fdist d. -Proof. by case: d; case => f /= /forallP_leRP H0 /eqP H1. Qed. +Proof. by case: d => f /= /andP[] /forallP ? /eqP. Qed. Lemma fdist_card_neq0 d : (0 < #| A |)%nat. Proof. -apply/negPn/negP => abs; apply R1_neq_R0. +apply/negPn/negP => abs. +have /eqP := oner_neq0 R; apply. rewrite -(FDist.f1 d) (eq_bigl xpred0) ?big_pred0_eq // => a. apply/negP => aA. by move/card_gt0P : abs; apply; exists a. @@ -166,24 +179,24 @@ Definition fdist_supp d := [set a | d a != 0]. Lemma sum_fdist_supp (f : A -> R) d (P : pred A): \sum_(a in A | P a) d a * f a = \sum_(a | P a && (a \in fdist_supp d)) d a * f a. Proof. -rewrite (bigID (mem (fdist_supp d))) /= addRC big1 ?add0R//. -by move=> i; rewrite inE negbK => /andP[_ /eqP] ->; rewrite mul0R. +rewrite (bigID (mem (fdist_supp d))) /= addrC big1 ?add0r//. +by move=> i; rewrite inE negbK => /andP[_ /eqP] ->; rewrite mul0r. Qed. -Lemma fdist_supp_neq0 (d : fdist A) : fdist_supp d != set0. +Lemma fdist_supp_neq0 (d : fdist R A) : fdist_supp d != set0. Proof. apply/eqP => H; move: (FDist.f1 d). -rewrite -[LHS]mulR1 big_distrl sum_fdist_supp H big1 //=. - by move/esym; exact: R1_neq_R0. +rewrite -[LHS]mulr1 big_distrl sum_fdist_supp H big1 //=. + by move=> /esym/eqP; rewrite oner_eq0. by move=> i; rewrite inE. Qed. -Lemma fdist_supp_mem (d : fdist A) : {i | i \in fdist_supp d}. +Lemma fdist_supp_mem (d : fdist R A) : {i | i \in fdist_supp d}. Proof. by case: (set_0Vmem (fdist_supp d)) (fdist_supp_neq0 d) => // ->; rewrite eqxx. Qed. -Lemma fdist_ind (P : fdist A -> Type) : +Lemma fdist_ind (P : fdist R A -> Type) : (forall n : nat, (forall X, #|fdist_supp X| = n -> P X) -> forall X b, #|fdist_supp X| = n.+1 -> X b != 0 -> P X) -> forall X, P X. @@ -192,8 +205,8 @@ move=> H1 d. move: {-2}(#|fdist_supp d|) (erefl (#|fdist_supp d|)) => n; move: n d. elim=> [d /esym /card0_eq Hd0|n IH d n13]. move: (FDist.f1 d). - rewrite -[X in X = _]mulR1 big_distrl sum_fdist_supp big1 => [|a]. - by move/esym/R1_neq_R0. + rewrite -[X in X = _]mulr1 big_distrl sum_fdist_supp big1 => [|a]. + by move=> /esym/eqP; rewrite oner_eq0. by rewrite Hd0. have [b Hb] : {b : A | d b != 0}. suff : {x | x \in fdist_supp d} by case => a; rewrite inE => ?; exists a. @@ -203,101 +216,107 @@ Qed. Lemma fdist_gt0 d a : (d a != 0) <-> (0 < d a). Proof. -split => H; [|by move/gtR_eqF : H]. -by rewrite ltR_neqAle; split => //; exact/nesym/eqP. +split => H; last by rewrite gt_eqF. +by rewrite lt_neqAle eq_sym H /=. Qed. Lemma fdist_lt1 d a : (d a != 1) <-> (d a < 1). Proof. -split=> H; first by rewrite ltR_neqAle; split => //; exact/eqP. -exact/ltR_eqF. +split=> H; first by rewrite lt_neqAle H /=. +by rewrite lt_eqF. Qed. Lemma fdist_ext d d' : (forall x, d x = d' x) -> d = d'. -Proof. by move=> ?; exact/val_inj/val_inj/ffunP. Qed. +Proof. by move=> ?; exact/val_inj/ffunP. Qed. End fdist_lemmas. Section fdist1. -Variables (A : finType) (a : A). -Let f := [ffun b => INR (b == a)%bool]. +Local Open Scope ring_scope. +Variables (R : numDomainType) (A : finType) (a : A). +Let f := [ffun b => (b == a)%bool%:R : R]. -Let f0 b : 0 <= f b. Proof. by rewrite ffunE; exact: leR0n. Qed. +Let f0 b : 0 <= f b. Proof. by rewrite ffunE; exact: ler0n. Qed. Let f1 : \sum_(b in A) f b = 1. Proof. rewrite (bigD1 a) //= {1}/f ffunE eqxx /= (eq_bigr (fun=> 0)); last first. by move=> b ba; rewrite /f ffunE (negbTE ba). -by rewrite big1_eq // addR0. +by rewrite big1_eq // addr0. Qed. -Definition fdist1 : fdist A := locked (FDist.make f0 f1). +Definition fdist1 : fdist R A := locked (FDist.make f0 f1). -Lemma fdist1E a0 : fdist1 a0 = INR (a0 == a)%bool. +Lemma fdist1E a0 : fdist1 a0 = (a0 == a)%bool%:R. Proof. by rewrite /fdist1; unlock; rewrite ffunE. Qed. Lemma supp_fdist1 : fdist_supp fdist1 = [set a] :> {set A}. Proof. -apply/setP => a0; rewrite !inE; case/boolP : (_ == _ :> A) => [/eqP ->|a0a]. -by rewrite fdist1E eqxx; apply/negbT => /=; apply/eqP; rewrite INR_eq0. +apply/setP => a0; rewrite !inE. +have [->|a0a] := eqVneq a0 a; first by rewrite fdist1E eqxx oner_eq0. by apply/negbTE; rewrite negbK fdist1E (negbTE a0a). Qed. End fdist1. +Arguments fdist1 {R A}. Section fdist1_prop. -Variable A : finType. +Local Open Scope ring_scope. +Variable (R : realType) (A : finType). -Lemma fdist1P (d : {fdist A}) a : reflect (forall i, i != a -> d i = 0) (d a == 1). +Lemma fdist1P (d : R.-fdist A) a : + reflect (forall i, i != a -> d i = 0) (d a == 1 :> R). Proof. apply: (iffP idP) => [/eqP H b ?|H]. - move: (FDist.f1 d); rewrite (bigD1 a) //= H => /esym/eqP. - rewrite addRC -subR_eq' subRR. - by move/eqP/esym/psumR_eq0P => -> // c ca; exact/fdist_ge0. -- move: (FDist.f1 d); rewrite (bigD1 a) //= => /esym. - by rewrite -subR_eq => <-; rewrite big1 // subR0. + rewrite addrC -subr_eq subrr. + by move/eqP/esym/psumr_eq0P => -> // c ca; exact/fdist_ge0. +- move: (FDist.f1 d); rewrite (bigD1 a) //= => /esym /eqP. + by rewrite -subr_eq => /eqP <-; rewrite big1 // subr0. Qed. -Lemma fdist1E1 (d' : fdist A) a : (d' a == 1 :> R) = (d' == fdist1 a :> {fdist A}). +Lemma fdist1E1 (d' : fdist R A) a : + (d' a == 1 :> R) = (d' == fdist1 a :> R.-fdist A). Proof. apply/idP/idP => [Pa1|/eqP ->]; last by rewrite fdist1E eqxx. apply/eqP/fdist_ext => a0; rewrite fdist1E. -case/boolP : (a0 == a :> A) => Ha. -by rewrite (eqP Ha); exact/eqP. +have [->|Ha] := eqVneq a0 a; first exact/eqP. by move/fdist1P : Pa1 => ->. Qed. -Lemma fdist1I1 (d : {fdist 'I_1}) : d = fdist1 ord0. +Lemma fdist1I1 (d : R.-fdist 'I_1) : d = fdist1 ord0 :> fdist R _. Proof. apply/fdist_ext => /= i; rewrite fdist1E (ord1 i) eqxx. -by move: (FDist.f1 d); rewrite big_ord_recl big_ord0 addR0. +by move: (FDist.f1 d); rewrite big_ord_recl big_ord0 addr0. Qed. -Lemma fdist1xx (a : A) : fdist1 a a = 1. +Lemma fdist1xx (a : A) : fdist1 a a = 1 :> R. Proof. by rewrite fdist1E eqxx. Qed. -Lemma fdist10 (a a0 : A) : a0 != a -> fdist1 a a0 = 0. +Lemma fdist10 (a a0 : A) : a0 != a -> fdist1 a a0 = 0 :> R. Proof. by move=> a0a; rewrite fdist1E (negbTE a0a). Qed. End fdist1_prop. Section fdistbind. -Variables (A B : finType) (p : fdist A) (g : A -> fdist B). +Local Open Scope ring_scope. +Variable R : numDomainType. +Variables (A B : finType) (p : fdist R A) (g : A -> fdist R B). Let f := [ffun b => \sum_(a in A) p a * (g a) b]. Let f0 b : 0 <= f b. -Proof. rewrite /f ffunE; apply sumR_ge0 => a _; exact: mulR_ge0. Qed. +Proof. rewrite /f ffunE; apply sumr_ge0 => a _; exact: mulr_ge0. Qed. Let f1 : \sum_(b in B) f b = 1. Proof. rewrite /f. under eq_bigr do rewrite ffunE. rewrite exchange_big /= -[RHS](FDist.f1 p); apply eq_bigr => a _. -by rewrite -big_distrr /= FDist.f1 mulR1. +by rewrite -big_distrr /= FDist.f1 mulr1. Qed. -Definition fdistbind : fdist B := locked (FDist.make f0 f1). +Definition fdistbind : fdist R B := locked (FDist.make f0 f1). Lemma fdistbindE x : fdistbind x = \sum_(a in A) p a * (g a) x. Proof. by rewrite /fdistbind; unlock; rewrite ffunE. Qed. @@ -307,51 +326,55 @@ End fdistbind. Reserved Notation "m >>= f" (at level 49). Notation "m >>= f" := (fdistbind m f) : fdist_scope. -Lemma fdist1bind (A B : finType) (a : A) (f : A -> fdist B) : +Lemma fdist1bind (R : realType) (A B : finType) (a : A) + (f : A -> fdist R B) : fdist1 a >>= f = f a. Proof. -apply/fdist_ext => b; rewrite fdistbindE /= (bigD1 a) //= fdist1xx mul1R. -rewrite (eq_bigr (fun=> 0)) ?big_const ?iter_addR ?mulR0 ?addR0 // => c ca. -by rewrite fdist10// mul0R. +apply/fdist_ext => b; rewrite fdistbindE /= (bigD1 a) //= fdist1xx mul1r. +by rewrite big1 ?addr0// => a0 a0a; rewrite fdist10// mul0r. Qed. -Lemma fdistbind1 A (p : fdist A) : p >>= @fdist1 A = p. +Lemma fdistbind1 (R: realType) A (p : fdist R A) : p >>= @fdist1 R A = p. Proof. -apply/fdist_ext => /= a; rewrite fdistbindE /= (bigD1 a) //= fdist1xx mulR1. -rewrite (eq_bigr (fun=> 0)) ?big_const ?iter_addR ?mulR0 /= ?addR0 //. -by move=> b ba; rewrite fdist10 ?mulR0// eq_sym. +apply/fdist_ext => /= a; rewrite fdistbindE /= (bigD1 a) //= fdist1xx mulr1. +by rewrite big1 ?addr0// => a0 a0a; rewrite fdist10 ?mulr0// eq_sym. Qed. -Lemma fdistbindA A B C (m : fdist A) (f : A -> fdist B) (g : B -> fdist C) : +Lemma fdistbindA R A B C (m : fdist R A) (f : A -> fdist R B) + (g : B -> fdist R C) : (m >>= f) >>= g = m >>= (fun x => f x >>= g). Proof. apply/fdist_ext => c; rewrite !fdistbindE /=. -rewrite (eq_bigr (fun a => \sum_(a0 in A) m a0 * f a0 a * g a c)); last first. +rewrite (eq_bigr (fun a => \sum_(a0 in A) m a0 * f a0 a * g a c)%R); last first. by move=> b _; rewrite fdistbindE big_distrl. rewrite exchange_big /=; apply eq_bigr => a _. -by rewrite fdistbindE big_distrr /=; apply eq_bigr => b _; rewrite mulRA. +by rewrite fdistbindE big_distrr /=; apply eq_bigr => b _; rewrite mulrA. Qed. Section fdistmap. -Variables (A B : finType) (g : A -> B) (p : fdist A). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A B : finType) (g : A -> B) (p : fdist R A). -Definition fdistmap : {fdist B} := p >>= (fun a => fdist1 (g a)). +Definition fdistmap : R.-fdist B := p >>= (fun a => fdist1 (g a)). Lemma fdistmapE (b : B) : fdistmap b = \sum_(a in A | a \in g @^-1 b) p a. Proof. rewrite /fdistmap fdistbindE [in RHS]big_mkcond /=; apply eq_bigr => a _. -case: ifPn => [|]; first by rewrite inE => /eqP->; rewrite fdist1xx mulR1. -by rewrite !inE => gab; rewrite fdist10 ?mulR0// eq_sym. +case: ifPn => [|]; first by rewrite inE => /eqP->; rewrite fdist1xx mulr1. +by rewrite !inE => gab; rewrite fdist10 ?mulr0// eq_sym. Qed. End fdistmap. Section fdistmap_prop. +Local Open Scope ring_scope. +Variable R : realType. Variables (A B C : finType). -Lemma fdistmap_id P : fdistmap (@id A) P = P. Proof. +Lemma fdistmap_id (P : fdist R A) : fdistmap (@id A) P = P. Proof. by rewrite /fdistmap fdistbind1. Qed. -Lemma fdistmap_comp (g : A -> B) (h : C -> A) P : +Lemma fdistmap_comp (g : A -> B) (h : C -> A) (P : fdist R C) : fdistmap g (fdistmap h P) = fdistmap (g \o h) P. Proof. rewrite /fdistmap fdistbindA; congr (_ >>= _). @@ -361,168 +384,187 @@ Qed. End fdistmap_prop. Section fdist_uniform. +Local Open Scope ring_scope. +Context {R : numFieldType}. Variables (A : finType) (n : nat). Hypothesis domain_not_empty : #|A| = n.+1. -Let f := [ffun a : A => INR 1 / INR #|A|]. + +Let f : {ffun A -> R} := [ffun a : A => #|A|%:R^-1]. Let f0 a : 0 <= f a. -Proof. -by rewrite ffunE; apply/divR_ge0 => //; apply/ltR0n; rewrite domain_not_empty. -Qed. +Proof. by rewrite ffunE invr_ge0 ler0n. Qed. Let f1 : \sum_(a in A) f a = 1. Proof. under eq_bigr do rewrite ffunE. -rewrite -big_distrr /= mul1R big_const iter_addR mulRV //. -by rewrite INR_eq0' domain_not_empty. +rewrite big_const iter_addr -[_ *+ _]mulr_natr. +by rewrite mulVr ?addr0// unitf_gt0// ltr0n domain_not_empty. Qed. -Definition fdist_uniform : fdist A := locked (FDist.make f0 f1). +Definition fdist_uniform : fdist R A := locked (FDist.make f0 f1). -Lemma fdist_uniformE a : fdist_uniform a = / INR #|A|. -Proof. by rewrite /fdist_uniform; unlock => /=; rewrite /f div1R ffunE. Qed. +Lemma fdist_uniformE a : fdist_uniform a = #|A|%:R^-1. +Proof. by rewrite /fdist_uniform; unlock => /=; rewrite /f ffunE. Qed. End fdist_uniform. Section fdist_uniform_prop. +Local Open Scope ring_scope. +Variable R : numFieldType. Lemma fdist_uniform_neq0 (C : finType) (domain_non_empty : { m : nat | #| C | = m.+1 }) : - forall x, fdist_uniform (projT2 domain_non_empty) x != 0. + forall x, @fdist_uniform R _ _ (projT2 domain_non_empty) x != 0. Proof. -move=> c; rewrite fdist_uniformE invR_neq0' //; apply/eqP. -case: domain_non_empty => x' ->; by rewrite INR_eq0. +move=> c; rewrite fdist_uniformE invr_eq0 pnatr_eq0. +by case domain_non_empty => x' ->. Qed. End fdist_uniform_prop. -Lemma dom_by_uniform A (P : fdist A) n (An1 : #|A| = n.+1) : P `<< fdist_uniform An1. +(*TODO yoshihiro503: move these *) +Definition dominates {R: realType} {A : Type} (Q P : A -> R) := + locked (forall a, Q a = 0 -> P a = 0)%R. +Notation "P '`<<' Q" := (dominates Q P). +Lemma dominatesP (R: realType) A (Q P : A -> R) : + P `<< Q <-> forall a, Q a = 0%R -> P a = 0%R. +Proof. by rewrite /dominates; unlock. Qed. + +Lemma dom_by_uniform (R: realType) A (P : fdist R A) n (An1 : #|A| = n.+1) : + P `<< fdist_uniform An1. Proof. apply/dominatesP => a; rewrite fdist_uniformE => /esym abs; exfalso. -by move: abs; rewrite An1; apply/eqP; rewrite ltR_eqF //; apply/invR_gt0/ltR0n. +by move: abs; rewrite An1; apply/eqP; rewrite lt_eqF // invr_gt0 ltr0n. Qed. Section fdist_uniform_supp. +Local Open Scope ring_scope. +Variable R : realType. Variables (A : finType) (C : {set A}). Hypothesis C0 : (0 < #|C|)%nat. -Let f := [ffun a : A => if a \in C then 1 / INR #|C| else 0]. +Let f : {ffun A -> R} := [ffun a : A => if a \in C then #|C|%:R^-1 else 0]. Let f0 a : 0 <= f a. Proof. rewrite /f ffunE. -case e : (a \in C); last exact/leRR. -apply divR_ge0; [lra|exact/ltR0n]. +case e : (a \in C); last exact/lexx. +by rewrite invr_ge0 ler0n. Qed. -Lemma f1 : \sum_(a in A) f a = 1. +Let f1 : \sum_(a in A) f a = 1. Proof. rewrite /f. -have HC' : #|C|%:R != 0 by rewrite INR_eq0' -lt0n. -transitivity (\sum_(a in A) (if a \in C then 1 else 0) / INR #|C|). -apply eq_bigr => a _. - rewrite ffunE; case aC : (a \in C); by [ | move/eqP in HC'; field]. -have HC'' : \sum_(a in A) (if a \in C then 1 else 0) = #|C|%:R. - by rewrite -big_mkcondr /= big_const iter_addR mulR1. -by rewrite /Rdiv -big_distrl HC'' /= mulRV. +have HC' : #|C|%:R != 0 :> R; first by rewrite pnatr_eq0 -lt0n. +under eq_bigr do rewrite ffunE. +rewrite -big_mkcondr big_const iter_addr. +by rewrite -[_ *+ _]mulr_natr mulVf// addr0. Qed. -Definition fdist_uniform_supp : fdist A := locked (FDist.make f0 f1). +Definition fdist_uniform_supp : fdist R A := locked (FDist.make f0 f1). End fdist_uniform_supp. -Notation "'`U' C0 " := (fdist_uniform_supp C0). +Notation "'`U' C0 " := (fdist_uniform_supp _ C0). Section fdist_uniform_supp_prop. +Local Open Scope ring_scope. +Variable R : realType. Variables (A : finType) (C : {set A}) (HC : (0 < #| C |)%nat). -Lemma fdist_uniform_supp_in z : z \in C -> (`U HC) z = 1 / INR #|C|. -Proof. by rewrite /fdist_uniform_supp; unlock; rewrite /= /f ffunE => ->. Qed. +Lemma fdist_uniform_supp_in z : z \in C -> (`U HC) z = #|C|%:R^-1 :> R. -Lemma fdist_uniform_supp_notin z : z \notin C -> (`U HC) z = 0. +Proof. by rewrite /fdist_uniform_supp; unlock; rewrite /= ffunE => ->. Qed. + +Lemma fdist_uniform_supp_notin z : z \notin C -> (`U HC) z = 0 :> R. Proof. -by rewrite /fdist_uniform_supp; unlock; move/negbTE; rewrite /= /f ffunE => ->. +by rewrite /fdist_uniform_supp; unlock; move/negbTE; rewrite /= ffunE => ->. Qed. Lemma fdist_uniform_supp_restrict g : - \sum_(t in A) ((`U HC) t * g t) = \sum_(t in C) ((`U HC) t * g t). + \sum_(t in A) ((`U HC) t * g t) = \sum_(t in C) ((`U HC) t * g t) :> R. Proof. -rewrite (bigID (fun x => x \in C)) /= addRC big1 ?add0R// => a aC. -by rewrite fdist_uniform_supp_notin // mul0R. +rewrite (bigID (fun x => x \in C)) /= addrC big1 ?add0r// => a aC. +by rewrite fdist_uniform_supp_notin // mul0r. Qed. Lemma fdist_uniform_supp_distrr g : - \sum_(t in C) ((`U HC) t * g t) = (/ INR #|C| * \sum_(t in C) g t). + \sum_(t in C) ((`U HC) t * g t) = (#|C|%:R^-1 * \sum_(t in C) g t) :> R. Proof. rewrite /= big_distrr /=; apply eq_bigr => /= i Hi. -by rewrite fdist_uniform_supp_in // div1R. +by rewrite fdist_uniform_supp_in. Qed. -Lemma fdist_uniform_supp_neq0 z : ((`U HC) z != 0) = (z \in C). +Lemma fdist_uniform_supp_neq0 z : ((`U HC) z != 0 :> R) = (z \in C). Proof. -case/boolP : (z \in C) => [/fdist_uniform_supp_in ->|/fdist_uniform_supp_notin ->]. - by rewrite div1R; apply/invR_neq0'; rewrite INR_eq0' -lt0n. +case/boolP : (z \in C) => [/fdist_uniform_supp_in ->| + /fdist_uniform_supp_notin ->]. + by rewrite invr_neq0// pnatr_eq0 -lt0n. by rewrite eqxx. Qed. End fdist_uniform_supp_prop. Section fdist_binary. +Local Open Scope ring_scope. +Variable R : realType. Variable A : finType. Hypothesis HA : #|A| = 2%nat. -Variable p : prob. +Variable p : prob R. -Let f (a : A) := [ffun a' => if a' == a then p.~ else p]. +Let f (a : A) := [ffun a' => (if a' == a then (Prob.p p).~ else p : R)]. -Let f0 (a a' : A) : 0 <= f a a'. +Let f0 (a a' : A) : 0 <= (f a a' : R). Proof. by rewrite /f ffunE; case: ifP. Qed. -Let f1 (a : A) : \sum_(a' in A) f a a' = 1. +Let f1 (a : A) : \sum_(a' in A) (f a a' : R) = 1. Proof. rewrite Set2sumE /= /f !ffunE; case: ifPn => [/eqP <-|]. - by rewrite eq_sym (negbTE (Set2.a_neq_b HA)) subRK. -by rewrite eq_sym; move/Set2.neq_a_b/eqP => <-; rewrite eqxx subRKC. + by rewrite eq_sym (negbTE (Set2.a_neq_b HA)) addrC onemKC. +by rewrite eq_sym; move/Set2.neq_a_b/eqP => <-; rewrite eqxx onemKC. Qed. -Definition fdist_binary : A -> fdist A := +Definition fdist_binary : A -> fdist R A := fun a => locked (FDist.make (f0 a) (f1 a)). -Lemma fdist_binaryE a a' : fdist_binary a a' = if a' == a then 1 - p else p. +Lemma fdist_binaryE a a' : fdist_binary a a' = (if a' == a then (Prob.p p).~ else p : R). Proof. by rewrite /fdist_binary; unlock; rewrite ffunE. Qed. Lemma sum_fdist_binary_swap a : \sum_(a' in A) fdist_binary a a' = \sum_(a' in A) fdist_binary a' a. Proof. by rewrite 2!Set2sumE /= !fdist_binaryE !(eq_sym a). Qed. -Lemma fdist_binaryxx a : fdist_binary a a = 1 - p. +Lemma fdist_binaryxx a : fdist_binary a a = (Prob.p p).~. Proof. by rewrite fdist_binaryE eqxx. Qed. End fdist_binary. Section fdist_binary_prop. -Variables (A : finType) (P Q : fdist A). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A : finType) (P Q : fdist R A). Hypothesis card_A : #|A| = 2%nat. -Lemma charac_bdist : {r : prob | P = fdist_binary card_A r (Set2.a card_A)}. -Proof. -destruct P as [[pf pf0] pf1]. -have /leR2P r01 : 0 <= 1 - pf (Set2.a card_A) <= 1. - move: (FDist.le1 (FDist.mk pf1) (Set2.a card_A)) => /= H1. - have {}pf1 : \sum_(a in A) pf a = 1 by rewrite -(eqP pf1); apply eq_bigr. - move/forallP_leRP : pf0 => /(_ (Set2.a card_A)) => H0. - split; first lra. - suff : forall a, a <= 1 -> 0 <= a -> 1 - a <= 1 by apply. - move=> *; lra. -exists (Prob.mk r01). +Lemma charac_bdist : {r : prob R | P = fdist_binary card_A r (Set2.a card_A)}. +Proof. +destruct P as [pf pf01]. +have rb : 0 <= pf (Set2.b card_A) <= 1. + move: (FDist.le1 (FDist.mk pf01) (Set2.b card_A)) => /= H1. + by move: pf01 => /andP [/forallP pf0 _]; apply/andP. +exists (Prob.mk rb). apply/fdist_ext => a /=. -rewrite fdist_binaryE; case: ifPn => [/eqP -> /=|Ha/=]; first by rewrite subRB subRR add0R. -by rewrite -(eqP pf1) /= Set2sumE /= addRC addRK; move/Set2.neq_a_b/eqP : Ha => ->. +move: pf01 => /andP [/forallP pf0 /eqP pf1]. +rewrite fdist_binaryE; case: ifPn => [/eqP -> |Ha/=]. + by rewrite /onem -pf1 /= Set2sumE /= addrK. +by move/Set2.neq_a_b/eqP : Ha <-. Qed. End fdist_binary_prop. Section fdist_binary_supp. -Variables (A : finType) (d : fdist A). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A : finType) (d : fdist R A). Hypothesis Hd : #|fdist_supp d| = 2%nat. @@ -543,14 +585,16 @@ Lemma sum_fdist_binary_supp (f : A -> R) : \sum_(i in fdist_supp d) f i = f fdist_binary_supp0 + f fdist_binary_supp1. Proof. transitivity (\sum_(i <- enum (fdist_supp d)) f i); last first. - by rewrite enum_fdist_binary_supp 2!big_cons big_nil addR0. + by rewrite enum_fdist_binary_supp 2!big_cons big_nil addr0. by rewrite big_filter; apply eq_bigl => ?; rewrite !inE. Qed. End fdist_binary_supp. Section fdistD1. -Variables (B : finType) (X : fdist B) (b : B). +Local Open Scope ring_scope. +Variable R : realType. +Variables (B : finType) (X : fdist R B) (b : B). Definition f : B -> R := [ffun a => if a == b then 0 else X a / (1 - X b)]. @@ -559,21 +603,21 @@ Hypothesis Xb1 : X b != 1. Let f0 : forall a, 0 <= f a. Proof. move=> a; rewrite /f ffunE. -case: ifPn => [_ |ab]; first exact/leRR. -apply mulR_ge0 => //; exact/invR_ge0/subR_gt0/fdist_lt1. +case: ifPn => [_ |ab]; first exact/lexx. +by apply: mulr_ge0 => //; rewrite invr_ge0 subr_ge0 ltW// -fdist_lt1. Qed. Let f1 : \sum_(a in B) f a = 1. Proof. -rewrite (bigD1 b) //= {1}/f ffunE eqxx add0R. +rewrite (bigD1 b) //= {1}/f ffunE eqxx add0r. rewrite (eq_bigr (fun c => X c / (1 - X b))); last first. by move=> ? cb; rewrite /f ffunE (negbTE cb). rewrite -big_distrl /=. move: (FDist.f1 X); rewrite (bigD1 b) //=. -move=> /esym; rewrite addRC -subR_eq => H. -have ?: 1 - X b != 0 by rewrite subR_eq0' eq_sym. -rewrite -(@eqR_mul2r (1 - X b)); last exact/eqP. -by rewrite mul1R -mulRA mulVR ?mulR1 // H. +move=> /esym /eqP. rewrite addrC -subr_eq => /eqP H. +have ?: 1 - X b != 0 by rewrite subr_eq0 eq_sym. +rewrite -H. +exact: mulfV. Qed. Definition fdistD1 := locked (FDist.make f0 f1). @@ -584,7 +628,9 @@ Proof. by rewrite /fdistD1; unlock; rewrite ffunE. Qed. End fdistD1. Section fdistD1_prop. -Variables (B : finType) (X : fdist B) (b : B). +Local Open Scope ring_scope. +Variable R : realType. +Variables (B : finType) (X : fdist R B) (b : B). Hypothesis Xb1 : X b != 1. @@ -594,56 +640,61 @@ Proof. rewrite /fdist_supp (cardsD1 b [set a | X a != 0]) !inE Xb0 add1n /=. apply eq_card => i; rewrite !inE fdistD1E. case: ifPn => //= ib; first by rewrite eqxx. -apply/idP/idP; first by apply: contra => /eqP ->; rewrite div0R. -apply: contra; rewrite /Rdiv mulR_eq0' => /orP[//|H]. +apply/idP/idP; first by apply: contra => /eqP ->; rewrite mul0r. +apply: contra. rewrite mulf_eq0 => /orP[// | H]. exfalso. move/negPn/negP : H; apply. -by apply/invR_neq0'; rewrite subR_eq0' eq_sym. +by rewrite invr_neq0// subr_eq0 eq_sym. Qed. Lemma fdistD1_eq0 a (Xa0 : X a != 0) : ((fdistD1 Xb1 a == 0) = (b == a))%bool. Proof. rewrite fdistD1E; case: ifPn => [/eqP ->|ab]; first by rewrite !eqxx. apply/idP/idP => [|]; last by rewrite eq_sym (negbTE ab). -rewrite mulR_eq0' => /orP[]; first by rewrite (negbTE Xa0). -by move/invR_eq0'; rewrite subR_eq0' eq_sym (negbTE Xb1). +rewrite mulf_eq0 => /orP[]; first by rewrite (negbTE Xa0). +by rewrite invr_eq0 subr_eq0 eq_sym (negbTE Xb1). Qed. Lemma fdistD1_0 a : X a = 0 -> fdistD1 Xb1 a = 0. -Proof. by move=> Xa0; rewrite fdistD1E Xa0 div0R; case: ifP. Qed. +Proof. by move=> Xa0; rewrite fdistD1E Xa0 mul0r; case: ifP. Qed. End fdistD1_prop. (* TODO: move? *) (* about_distributions_of_ordinals.*) -Lemma fdistI0_False (d : {fdist 'I_O}) : False. +Lemma fdistI0_False (R: realType) (d : R.-fdist 'I_O) + : False. Proof. move: (fdist_card_neq0 d); by rewrite card_ord. Qed. Section fdistI2. -Variable p : prob. +Local Open Scope ring_scope. +Variable R : realType. +Variable p : prob R. -Definition fdistI2: {fdist 'I_2} := fdist_binary (card_ord 2) p (lift ord0 ord0). +Definition fdistI2: R.-fdist 'I_2 := + fdist_binary (card_ord 2) p (lift ord0 ord0). -Lemma fdistI2E a : fdistI2 a = if a == ord0 then Prob.p p else p.~. +Lemma fdistI2E a : fdistI2 a = if a == ord0 then p : R else (Prob.p p).~. Proof. rewrite /fdistI2 fdist_binaryE; case: ifPn => [/eqP ->|]. -by rewrite eq_sym (negbTE (neq_lift _ _)). + by rewrite eq_sym (negbTE (neq_lift _ _)). by case: ifPn => //; move: a => -[[//|[|]//]]. Qed. End fdistI2. Section fdistI2_prop. -Variable p : prob. +Local Open Scope ring_scope. +Variable R : realType. -Lemma fdistI21 : fdistI2 1%:pr = fdist1 ord0. +Lemma fdistI21 : @fdistI2 R 1%:pr = fdist1 ord0. Proof. apply/fdist_ext => /= i; rewrite fdistI2E fdist1E; case: ifPn => //= _. -exact: onem1. +by rewrite onem1. Qed. -Lemma fdistI20 : fdistI2 0%:pr = fdist1 (Ordinal (erefl (1 < 2)%nat)). +Lemma fdistI20 : @fdistI2 R 0%:pr = fdist1 (Ordinal (erefl (1 < 2)%nat)). Proof. apply/fdist_ext => /= i; rewrite fdistI2E fdist1E; case: ifPn => [/eqP ->//|]. by case: i => -[//|] [|//] i12 _ /=; rewrite onem0. @@ -652,18 +703,24 @@ Qed. End fdistI2_prop. Section fdist_add. -Variables (n m : nat) (d1 : {fdist 'I_n}) (d2 : {fdist 'I_m}) (p : prob). +Local Open Scope ring_scope. +Variable R : realType. + +Variables (n m : nat) + (d1 : R.-fdist 'I_n) + (d2 : R.-fdist 'I_m) + (p : prob R). Let f := [ffun i : 'I_(n + m) => let si := fintype.split i in - match si with inl a => (p * d1 a) | inr a => p.~ * d2 a end]. + match si with inl a => ((p : R) * d1 a) | inr a => (Prob.p p).~ * d2 a end]. Let f0 i : 0 <= f i. -Proof. by rewrite /f ffunE; case: splitP => a _; exact: mulR_ge0. Qed. +Proof. by rewrite /f ffunE; case: splitP => a _; exact: mulr_ge0. Qed. Let f1 : \sum_(i < n + m) f i = 1. Proof. -rewrite -(onemKC p) -{1}(mulR1 p) -(mulR1 p.~). +rewrite -(onemKC (p : R)) -{1}(mulr1 (p : R)) -(mulr1 (Prob.p p).~). rewrite -{1}(FDist.f1 d1) -(FDist.f1 d2) big_split_ord /=; congr (_ + _). - rewrite big_distrr /f /=; apply eq_bigr => i _; rewrite ffunE. case: splitP => [j Hj|k /= Hi]. @@ -675,18 +732,20 @@ rewrite -{1}(FDist.f1 d1) -(FDist.f1 d2) big_split_ord /=; congr (_ + _). + by rewrite eqn_add2l => /eqP ik; congr (_ * d2 _); exact/val_inj. Qed. -Definition fdist_add : {fdist 'I_(n + m)} := locked (FDist.make f0 f1). +Definition fdist_add : R.-fdist 'I_(n + m) := locked (FDist.make f0 f1). Lemma fdist_addE i : fdist_add i = - match fintype.split i with inl a => p * d1 a | inr a => p.~ * d2 a end. + match fintype.split i with inl a => (p : R) * d1 a | inr a => (Prob.p p).~ * d2 a end. Proof. by rewrite /fdist_add; unlock; rewrite ffunE. Qed. End fdist_add. Section fdist_del. -Variables (n : nat) (P : {fdist 'I_n.+1}) (j : 'I_n.+1) (Pj_neq1 : P j != 1). +Local Open Scope ring_scope. +Variable R : realType. +Variables (n : nat) (P : R.-fdist 'I_n.+1) (j : 'I_n.+1) (Pj_neq1 : P j != 1). -Let D : {fdist 'I_n.+1} := fdistD1 Pj_neq1. +Let D : R.-fdist 'I_n.+1 := fdistD1 Pj_neq1. Let h (i : 'I_n) := if (i < j)%nat then widen_ord (leqnSn _) i else lift ord0 i. @@ -701,19 +760,19 @@ rewrite (bigID (fun i : 'I_n => (i < j)%nat)) /=; congr (_ + _). move=> jn; rewrite (@big_ord_narrow_cond _ _ _ j n xpredT); first by rewrite -ltnS. move=> jn'; apply eq_bigr => i _; rewrite ffunE; congr (D _). rewrite /h /= ltn_ord; exact/val_inj. -rewrite (bigID (pred1 j)) /= [X in _ = X + _](_ : _ = 0) ?add0R; last first. +rewrite (bigID (pred1 j)) /= [X in _ = X + _](_ : _ = 0) ?add0r; last first. rewrite (big_pred1 j). by rewrite /D fdistD1E eqxx. by move=> /= i; rewrite -leqNgt andbC andb_idr // => /eqP ->. rewrite [in RHS]big_mkcond big_ord_recl. -set X := (X in _ = addR_monoid _ X). -rewrite /= -leqNgt leqn0 eq_sym andbN add0R. +set X := (X in _ = GRing.add_monoid R _ X). +rewrite /= -leqNgt leqn0 eq_sym andbN add0r. rewrite big_mkcond; apply eq_bigr => i _. rewrite -2!leqNgt andbC eq_sym -ltn_neqAle ltnS. case: ifPn => // ji; by rewrite /h ffunE ltnNge ji. Qed. -Definition fdist_del : {fdist 'I_n} := locked (FDist.make f0 f1). +Definition fdist_del : R.-fdist 'I_n := locked (FDist.make f0 f1). Lemma fdist_delE i : fdist_del i = D (h i). Proof. by rewrite /fdist_del; unlock; rewrite ffunE. Qed. @@ -723,11 +782,13 @@ Definition fdist_del_idx (i : 'I_n) := h i. End fdist_del. Section fdist_belast. -Variables (n : nat) (P : {fdist 'I_n.+1}) (Pmax_neq1 : P ord_max != 1). +Local Open Scope ring_scope. +Variable R : realType. +Variables (n : nat) (P : fdist_of R (Phant 'I_n.+1)) (Pmax_neq1 : P ord_max != 1). -Let D : {fdist 'I_n.+1} := fdistD1 Pmax_neq1. +Let D : R.-fdist 'I_n.+1 := fdistD1 Pmax_neq1. -Definition fdist_belast : {fdist 'I_n} := locked (fdist_del Pmax_neq1). +Definition fdist_belast : R.-fdist 'I_n := locked (fdist_del Pmax_neq1). Lemma fdist_belastE i : fdist_belast i = D (widen_ord (leqnSn _) i). Proof. by rewrite /fdist_belast; unlock; rewrite fdist_delE ltn_ord. Qed. @@ -735,21 +796,24 @@ Proof. by rewrite /fdist_belast; unlock; rewrite fdist_delE ltn_ord. Qed. End fdist_belast. Section fdist_convn. -Variables (A : finType) (n : nat) (e : {fdist 'I_n}) (g : 'I_n -> fdist A). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A : finType) (n : nat) (e : R.-fdist 'I_n) + (g : 'I_n -> fdist R A). Let f := [ffun a => \sum_(i < n) e i * g i a]. Let f0 a : 0 <= f a. -Proof. by rewrite ffunE; apply: sumR_ge0 => /= i _; apply mulR_ge0. Qed. +Proof. by rewrite ffunE; apply: sumr_ge0 => /= i _; apply mulr_ge0. Qed. Let f1 : \sum_(a in A) f a = 1. Proof. under eq_bigr do rewrite ffunE. rewrite exchange_big /= -(FDist.f1 e) /=; apply eq_bigr => i _. -by rewrite -big_distrr /= FDist.f1 mulR1. +by rewrite -big_distrr /= FDist.f1 mulr1. Qed. -Definition fdist_convn : fdist A := locked (FDist.make f0 f1). +Definition fdist_convn : fdist R A := locked (FDist.make f0 f1). Lemma fdist_convnE a : fdist_convn a = \sum_(i < n) e i * g i a. Proof. by rewrite /fdist_convn; unlock; rewrite ffunE. Qed. @@ -757,50 +821,56 @@ Proof. by rewrite /fdist_convn; unlock; rewrite ffunE. Qed. End fdist_convn. Section fdist_convn_prop. +Local Open Scope ring_scope. +Variable R : realType. Variables (A : finType) (n : nat). -Lemma fdist_convn1 (g : 'I_n -> fdist A) a : fdist_convn (fdist1 a) g = g a. +Lemma fdist_convn1 (g : 'I_n -> fdist R A) a : fdist_convn (fdist1 a) g = g a. Proof. -apply/fdist_ext => a0; rewrite fdist_convnE (bigD1 a) //= fdist1xx mul1R. -by rewrite big1 ?addR0 // => i ia; rewrite fdist10// mul0R. +apply/fdist_ext => a0; rewrite fdist_convnE (bigD1 a) //= fdist1xx mul1r. +by rewrite big1 ?addr0 // => i ia; rewrite fdist10// mul0r. Qed. -Lemma fdist_convn_cst (e : {fdist 'I_n}) (a : {fdist A}) : +Lemma fdist_convn_cst (e : R.-fdist 'I_n) (a : R.-fdist A) : fdist_convn e (fun=> a) = a. Proof. -by apply/fdist_ext => ?; rewrite fdist_convnE -big_distrl /= FDist.f1 mul1R. +by apply/fdist_ext => ?; rewrite fdist_convnE -big_distrl /= FDist.f1 mul1r. Qed. End fdist_convn_prop. Section fdist_conv. -Variables (A : finType) (p : prob) (d1 d2 : fdist A). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A : finType) (p : prob R) (d1 d2 : fdist R A). -Definition fdist_conv : {fdist A} := locked +Definition fdist_conv : R.-fdist A := locked (fdist_convn (fdistI2 p) (fun i => if i == ord0 then d1 else d2)). -Lemma fdist_convE a : fdist_conv a = p * d1 a + p.~ * d2 a. +Lemma fdist_convE a : fdist_conv a = (p : R) * d1 a + (Prob.p p).~ * d2 a. Proof. rewrite /fdist_conv; unlock => /=. -by rewrite fdist_convnE !big_ord_recl big_ord0 /= addR0 !fdistI2E. + by rewrite fdist_convnE !big_ord_recl big_ord0 /= addr0 !fdistI2E. Qed. End fdist_conv. Notation "x <| p |> y" := (fdist_conv p x y) : fdist_scope. -Lemma fdist_conv_bind_left_distr (A B : finType) p a b (f : A -> fdist B) : +Lemma fdist_conv_bind_left_distr (R : realType) (A B : finType) p a b (f : A -> fdist R B) : (a <| p |> b) >>= f = (a >>= f) <| p |> (b >>= f). Proof. apply/fdist_ext => a0 /=; rewrite !(fdistbindE,fdist_convE) /=. rewrite 2!big_distrr /= -big_split /=; apply/eq_bigr => a1 _. -by rewrite fdist_convE mulRDl !mulRA. +by rewrite fdist_convE mulrDl !mulrA. Qed. Section fdist_perm. -Variables (A : finType) (n : nat) (P : {fdist 'rV[A]_n}) (s : 'S_n). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A : finType) (n : nat) (P : R.-fdist 'rV[A]_n) (s : 'S_n). -Definition fdist_perm : {fdist 'rV[A]_n} := fdistmap (col_perm s^-1) P. +Definition fdist_perm : R.-fdist 'rV[A]_n := fdistmap (col_perm s^-1) P. Lemma fdist_permE v : fdist_perm v = P (col_perm s v). Proof. @@ -811,7 +881,9 @@ Qed. End fdist_perm. Section fdistI_perm. -Variables (n : nat) (P : {fdist 'I_n}) (s : 'S_n). +Local Open Scope ring_scope. +Variable R : realType. +Variables (n : nat) (P : R.-fdist 'I_n) (s : 'S_n). Let f := [ffun i : 'I_n => P (s i)]. @@ -832,7 +904,7 @@ rewrite -(FDist.f1 P) /= big_map; apply congr_big => //. move=> i _; by rewrite /f ffunE permKV. Qed. -Definition fdistI_perm : {fdist 'I_n} := locked (FDist.make f0 f1). +Definition fdistI_perm : R.-fdist 'I_n := locked (FDist.make f0 f1). Lemma fdistI_permE i : fdistI_perm i = P (s i). Proof. by rewrite /fdistI_perm; unlock; rewrite ffunE. Qed. @@ -840,16 +912,18 @@ Proof. by rewrite /fdistI_perm; unlock; rewrite ffunE. Qed. End fdistI_perm. Section fdistI_perm_prop. +Local Open Scope ring_scope. +Variable R : realType. -Lemma fdistI_perm1 (n : nat) (P : {fdist 'I_n}) : fdistI_perm P 1%g = P. +Lemma fdistI_perm1 (n : nat) (P : R.-fdist 'I_n) : @fdistI_perm R n P 1%g = P. Proof. by apply/fdist_ext => /= i; rewrite fdistI_permE perm1. Qed. -Lemma fdistI_permM (n : nat) (P : {fdist 'I_n}) (s s' : 'S_n) : - fdistI_perm (fdistI_perm P s) s' = fdistI_perm P (s' * s). +Lemma fdistI_permM (n : nat) (P : R.-fdist 'I_n) (s s' : 'S_n) : + @fdistI_perm R n (fdistI_perm P s) s' = fdistI_perm P (s' * s). Proof. by apply/fdist_ext => /= i; rewrite !fdistI_permE permM. Qed. Lemma fdistI_tperm (n : nat) (a b : 'I_n) : - fdistI_perm (fdist1 a) (tperm a b) = fdist1 b. + @fdistI_perm R n (fdist1 a) (tperm a b) = fdist1 b. Proof. apply/fdist_ext => /= x; rewrite fdistI_permE !fdist1E permE /=. case: ifPn => [/eqP ->|xa]; first by rewrite eq_sym. @@ -857,9 +931,9 @@ case: ifPn; by [rewrite eqxx | move=> _; rewrite (negbTE xa)]. Qed. Lemma fdistI_perm_fdist1 (n : nat) (a : 'I_n) (s : 'S_n) : - fdistI_perm (fdist1 a) s = fdist1 (s^-1 a)%g. + @fdistI_perm R n (fdist1 a) s = fdist1 (s^-1 a)%g. Proof. -apply/fdist_ext => /= i; rewrite fdistI_permE !fdist1E; congr (INR (nat_of_bool _)). +apply/fdist_ext => /= i; rewrite fdistI_permE !fdist1E. congr ((nat_of_bool _)%:R). by apply/eqP/eqP => [<-|->]; rewrite ?permK // ?permKV. Qed. @@ -869,9 +943,12 @@ Reserved Notation "d `1" (at level 2, left associativity, format "d `1"). Reserved Notation "d `2" (at level 2, left associativity, format "d `2"). Section fdist_fst_snd. -Variables (A B : finType) (P : {fdist A * B}). +Local Open Scope ring_scope. +Variable R : realType. + +Variables (A B : finType) (P : R.-fdist (A * B)). -Definition fdist_fst : fdist A := fdistmap fst P. +Definition fdist_fst : fdist R A := fdistmap fst P. Lemma fdist_fstE a : fdist_fst a = \sum_(i in B) P (a, i). Proof. @@ -879,12 +956,12 @@ by rewrite fdistmapE /= -(pair_big_fst _ _ (pred1 a)) //= ?big_pred1_eq. Qed. Lemma dom_by_fdist_fst a b : fdist_fst a = 0 -> P (a, b) = 0. -Proof. rewrite fdist_fstE => /psumR_eq0P -> // ? _; exact: fdist_ge0. Qed. +Proof. rewrite fdist_fstE => /psumr_eq0P -> // ? _; exact: fdist_ge0. Qed. Lemma dom_by_fdist_fstN a b : P (a, b) != 0 -> fdist_fst a != 0. Proof. by apply: contra => /eqP /dom_by_fdist_fst ->. Qed. -Definition fdist_snd : fdist B := fdistmap snd P. +Definition fdist_snd : fdist R B := fdistmap snd P. Lemma fdist_sndE b : fdist_snd b = \sum_(i in A) P (i, b). Proof. @@ -893,7 +970,7 @@ by apply eq_bigr => a ?; rewrite big_pred1_eq. Qed. Lemma dom_by_fdist_snd a b : fdist_snd b = 0 -> P (a, b) = 0. -Proof. by rewrite fdist_sndE => /psumR_eq0P -> // ? _; exact: fdist_ge0. Qed. +Proof. by rewrite fdist_sndE => /psumr_eq0P -> // ? _; exact: fdist_ge0. Qed. Lemma dom_by_fdist_sndN a b : P (a, b) != 0 -> fdist_snd b != 0. Proof. by apply: contra => /eqP /dom_by_fdist_snd ->. Qed. @@ -904,17 +981,19 @@ Notation "d `1" := (fdist_fst d) : fdist_scope. Notation "d `2" := (fdist_snd d) : fdist_scope. Section fdist_prod. -Variables (A B : finType) (P : fdist A) (W : A -> fdist B). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A B : finType) (P : fdist R A) (W : A -> fdist R B). Let f := [ffun ab => P ab.1 * W ab.1 ab.2]. -Let f0 ab : 0 <= f ab. Proof. by rewrite ffunE; apply/mulR_ge0. Qed. +Let f0 ab : 0 <= f ab. Proof. by rewrite ffunE; apply/mulr_ge0. Qed. Let f1 : \sum_(ab in {: A * B}) f ab = 1. Proof. under eq_bigr do rewrite ffunE. rewrite -(pair_bigA _ (fun i j => P i * W i j)) /= -(FDist.f1 P). -by apply eq_bigr => a _; rewrite -big_distrr FDist.f1 /= mulR1. +by apply eq_bigr => a _; rewrite -big_distrr FDist.f1 /= mulr1. Qed. Definition fdist_prod := locked (FDist.make f0 f1). @@ -925,7 +1004,7 @@ Proof. by rewrite /fdist_prod; unlock; rewrite ffunE. Qed. Lemma fdist_prod1 : fdist_prod`1 = P. Proof. apply/fdist_ext=> a; rewrite fdist_fstE (eq_bigr _ (fun b _ => fdist_prodE (a,b))) /=. -by rewrite -big_distrr FDist.f1 /= mulR1. +by rewrite -big_distrr FDist.f1 /= mulr1. Qed. End fdist_prod. @@ -933,40 +1012,49 @@ End fdist_prod. Notation "P `X W" := (fdist_prod P W) : fdist_scope. Section fdist_prod_prop. -Variables (A B : finType) (W : A -> fdist B). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A B : finType) (W : A -> fdist R B). -Lemma fdist_prod1_conv p (a b : fdist A) : +Lemma fdist_prod1_conv p (a b : fdist R A) : ((a <| p |> b) `X W)`1 = (a `X W)`1 <| p |> (b `X W)`1. Proof. by rewrite !fdist_prod1. Qed. -Lemma fdist_prod2_conv p (a b : fdist A) : +Lemma fdist_prod2_conv p (a b : fdist R A) : ((a <| p |> b) `X W)`2 = (a `X W)`2 <| p |> (b `X W)`2. Proof. apply/fdist_ext => b0. rewrite fdist_sndE fdist_convE !fdist_sndE 2!big_distrr /=. -by rewrite -big_split; apply eq_bigr => a0 _; rewrite !fdist_prodE fdist_convE /=; field. + +rewrite -big_split; apply eq_bigr => a0 _; rewrite !fdist_prodE fdist_convE /=. +by rewrite mulrDl !mulrA. Qed. End fdist_prod_prop. + Notation "P1 `x P2" := (P1 `X (fun _ => P2)) : fdist_scope. Section prod_dominates_joint. -Local Open Scope reals_ext_scope. -Variables (A B : finType) (P : {fdist A * B}). +Local Open Scope ring_scope. +Variable R : realType. + +Variables (A B : finType) (P : R.-fdist (A * B)). Lemma Prod_dominates_Joint : P `<< P`1 `x P`2. Proof. apply/dominatesP => -[a b]. -rewrite fdist_prodE /= mulR_eq0 => -[P1a|P2b]; +rewrite fdist_prodE /= => /eqP. rewrite mulf_eq0 => /orP -[/eqP P1a| /eqP P2b]; by [rewrite dom_by_fdist_fst | rewrite dom_by_fdist_snd]. Qed. End prod_dominates_joint. Section fdistX. -Variables (A B : finType) (P : {fdist A * B}). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A B : finType) (P : R.-fdist (A * B)). -Definition fdistX : {fdist B * A} := fdistmap swap P. +Definition fdistX : R.-fdist (B * A) := fdistmap swap P. Lemma fdistXE a b : fdistX (b, a) = P (a, b). Proof. @@ -982,13 +1070,16 @@ Proof. by rewrite /fdist_snd /fdistX fdistmap_comp. Qed. End fdistX. Section fdistX_prop. -Variables (A B : finType) (P : fdist A) (Q : fdist B) (R S : {fdist A * B}). +Local Open Scope ring_scope. +Variable T : realType. +Variables (A B : finType) (P : fdist T A) (Q : fdist T B) + (R S : fdist_of T (Phant (A * B))). Lemma fdistXI : fdistX (fdistX R) = R. Proof. by rewrite /fdistX fdistmap_comp swapK fdistmap_id. Qed. Lemma fdistX_prod : fdistX (Q `x P) = P `x Q. -Proof. by apply/fdist_ext => -[a b]; rewrite fdistXE !fdist_prodE mulRC. Qed. +Proof. by apply/fdist_ext => -[a b]; rewrite fdistXE !fdist_prodE mulrC. Qed. Local Open Scope reals_ext_scope. @@ -999,29 +1090,30 @@ Qed. End fdistX_prop. -Lemma fdistX_prod2 (A B : finType) (P : fdist A) (W : A -> fdist B) : +Lemma fdistX_prod2 {R: realType} + (A B : finType) (P : fdist R A) (W : A -> fdist R B) : (fdistX (P `X W))`2 = P. Proof. by rewrite fdistX2 fdist_prod1. Qed. Section fdist_rV. +Local Open Scope ring_scope. +Variable R : realType. Local Open Scope vec_ext_scope. -Variables (A : finType) (P : fdist A) (n : nat). +Variables (A : finType) (P : fdist R A) (n : nat). Let f := [ffun t : 'rV[A]_n => \prod_(i < n) P t ``_ i]. Let f0 t : 0 <= f t. -Proof. by rewrite ffunE; apply prodR_ge0. Qed. +Proof. by rewrite ffunE; apply prodr_ge0. Qed. Let f1 : \sum_(t in 'rV_n) f t = 1. Proof. pose P' := fun (a : 'I_n) b => P b. suff : \sum_(g : {ffun 'I_n -> A }) \prod_(i < n) P' i (g i) = 1. -Local Open Scope ring_scope. rewrite (reindex_onto (fun j : 'rV[A]_n => finfun (fun x => j ``_ x)) (fun i => \row_(j < n) i j)) /=. -Local Close Scope ring_scope. - - move=> H; rewrite /f -H {H}. - apply eq_big => t /=. + - move=> H. rewrite /f -[RHS]H {H}. + apply: eq_big => t /=. + by apply/esym/eqP/rowP => i; rewrite mxE ffunE. + move=> _; rewrite ffunE; apply eq_bigr => i _ /=; by rewrite ffunE. move=> g _; apply/ffunP => i; by rewrite ffunE mxE. @@ -1030,7 +1122,7 @@ rewrite [RHS](_ : _ = \prod_(i < n) 1); last by rewrite big1. by apply eq_bigr => i _; exact: FDist.f1. Qed. -Definition fdist_rV : {fdist 'rV[A]_n} := locked (FDist.make f0 f1). +Definition fdist_rV : R.-fdist 'rV[A]_n := locked (FDist.make f0 f1). Lemma fdist_rVE t : fdist_rV t = \prod_(i < n) P t ``_ i. Proof. by rewrite /fdist_rV; unlock; rewrite ffunE. Qed. @@ -1040,46 +1132,47 @@ End fdist_rV. Notation "P `^ n" := (fdist_rV P n) : fdist_scope. Section wolfowitz_counting. +Local Open Scope ring_scope. +Variable R : realType. -Variables (C : finType) (P : fdist C) (k : nat) (s : {set 'rV[C]_k}). +Variables (C : finType) (P : fdist R C) (k : nat) (s : {set 'rV[C]_k}). Lemma wolfowitz a b A B : 0 < A -> 0 < B -> a <= \sum_(x in s) P `^ k x <= b -> (forall x : 'rV_k, x \in s -> A <= P `^ k x <= B) -> - a / B <= INR #| s | <= b / A. -Proof. -move=> A0 B0 [Ha Hb] H. -have HB : \sum_(x in s) P `^ _ x <= INR #|s| * B. - have HB : \sum_(x in s | predT s ) P `^ _ x <= INR #|s| * B. - apply (@leR_trans (\sum_(x in s | predT s) [fun _ => B] x)). - by apply leR_sumR_support => /= i iA _; apply H. - rewrite -big_filter /= big_const_seq /= iter_addR /=. - apply leR_wpmul2r; first lra. - apply Req_le. - have [/= l el [ul ls] [pl sl]] := big_enumP _. - rewrite count_predT sl; congr (_%:R)%R. - by apply: eq_card => /= v; rewrite inE andbT. - by apply/(leR_trans _ HB)/Req_le/eq_bigl => i; rewrite andbC. -have HA : INR #|s| * A <= \sum_(x in s) P `^ _ x. - have HA : INR #|s| * A <= \sum_(x in s | predT s) P `^ _ x. - apply (@leR_trans (\sum_(x in s | predT s) [fun _ => A] x)); last first. - apply leR_sumR_support => i Hi _; by case: (H i Hi). - rewrite -big_filter /= big_const_seq /= iter_addR /=. - apply leR_wpmul2r; first lra. - apply Req_le. - have [/= l el [ul ls] [pl sl]] := big_enumP _. - rewrite count_predT sl; congr (_%:R)%R. - by apply: eq_card => /= v; rewrite inE andbT. - by apply/(leR_trans HA)/Req_le/eq_bigl => i; rewrite andbC. -split. -- by rewrite leR_pdivr_mulr //; move/leR_trans : Ha; exact. -- by rewrite leR_pdivl_mulr //; exact: (leR_trans HA). + a / B <= (#| s |)%:R <= b / A. +Proof. +move=> A0 B0 /andP [Ha Hb] H. +have eq_le_ : forall x y, (x = y) -> (x <= y)%O. by move=> ? ? ? ? ->. +have HB : \sum_(x in s) P `^ _ x <= #|s|%:R * B. + apply (@le_trans _ _ (\sum_(x in s) [fun _ => B] x)). + by apply: ler_sum => /= i iA; move: (H i iA) => /andP []. + rewrite -big_filter /= big_const_seq /= iter_addr /=. + rewrite addr0 -(mulr_natl B (count _ _)). + apply: ler_wpM2r; first by rewrite ltW. + apply eq_le_. + have [/= l el [ul ls] [pl sl]] := big_enumP _. + by rewrite count_predT sl; congr (_%:R)%R. +have HA : (#|s|)%:R * A <= \sum_(x in s) P `^ _ x. + apply (@le_trans _ _ (\sum_(x in s) [fun _ => A] x)); last first. + by apply: ler_sum => i Hi /=; case/andP: (H i Hi). + rewrite -big_filter /= big_const_seq /= iter_addr /=. + rewrite addr0 -(mulr_natl A (count _ _)). + apply: ler_wpM2r; first by rewrite ltW. + apply eq_le_. + have [/= l el [ul ls] [pl sl]] := big_enumP _. + by rewrite count_predT sl; congr (_%:R)%R. +apply/andP. split. +- by rewrite ler_pdivrMr //; move/le_trans : Ha; exact. +- by rewrite ler_pdivlMr //; exact: (le_trans HA). Qed. End wolfowitz_counting. Section fdist_prod_of_rV. -Variables (A : finType) (n : nat) (P : {fdist 'rV[A]_n.+1}). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A : finType) (n : nat) (P : fdist_of R (Phant 'rV[A]_n.+1)). Let f (v : 'rV[A]_n.+1) : A * 'rV[A]_n := (v ord0 ord0, rbehead v). @@ -1089,7 +1182,7 @@ move=> a b -[H1 H2]; rewrite -(row_mx_rbehead a) -(row_mx_rbehead b). by rewrite {}H2; congr (@row_mx _ 1 1 n _ _); apply/rowP => i; rewrite !mxE. Qed. -Definition fdist_prod_of_rV : {fdist A * 'rV[A]_n} := fdistmap f P. +Definition fdist_prod_of_rV : R.-fdist (A * 'rV[A]_n) := fdistmap f P. Lemma fdist_prod_of_rVE a : fdist_prod_of_rV a = P (row_mx (\row_(i < 1) a.1) a.2). @@ -1110,7 +1203,7 @@ Proof. by move=> a b -[H1 H2]; rewrite -(row_mx_rbelast a) -(row_mx_rbelast b) H1 H2. Qed. -Definition fdist_belast_last_of_rV : {fdist 'rV[A]_n * A} := fdistmap g P. +Definition fdist_belast_last_of_rV : R.-fdist ('rV[A]_n * A) := fdistmap g P. Lemma fdist_belast_last_of_rVE a : fdist_belast_last_of_rV a = P (castmx (erefl, addn1 n) (row_mx a.1 (\row_(i < 1) a.2))). @@ -1123,8 +1216,8 @@ Qed. End fdist_prod_of_rV. -Lemma head_of_fdist_rV_belast_last (A : finType) (n : nat) (P : {fdist 'rV[A]_n.+2}) : - head_of_fdist_rV ((fdist_belast_last_of_rV P)`1) = head_of_fdist_rV P. +Lemma head_of_fdist_rV_belast_last (R: realType) (A : finType) (n : nat) (P : R.-fdist 'rV[A]_n.+2) : + head_of_fdist_rV ((fdist_belast_last_of_rV P)`1) = @head_of_fdist_rV R _ _ P. Proof. rewrite /head_of_fdist_rV /fdist_fst /fdist_prod_of_rV /fdist_belast_last_of_rV. rewrite !fdistmap_comp; congr (fdistmap _ P). @@ -1133,8 +1226,10 @@ rewrite /rbelast mxE; congr (v ord0 _); exact: val_inj. Qed. Section fdist_rV_of_prod. +Local Open Scope ring_scope. +Variable R : realType. Local Open Scope vec_ext_scope. -Variables (A : finType) (n : nat) (P : {fdist A * 'rV[A]_n}). +Variables (A : finType) (n : nat) (P : R.-fdist (A * 'rV[A]_n)). Let f (x : A * 'rV[A]_n) : 'rV[A]_n.+1 := row_mx (\row_(_ < 1) x.1) x.2. Lemma inj_f : injective f. @@ -1145,7 +1240,7 @@ rewrite !mxE => ->; congr (_, _). by move: H => /(congr1 (@rsubmx A 1 1 n)); rewrite 2!row_mxKr. Qed. -Definition fdist_rV_of_prod : {fdist 'rV[A]_n.+1} := fdistmap f P. +Definition fdist_rV_of_prod : R.-fdist 'rV[A]_n.+1 := fdistmap f P. Lemma fdist_rV_of_prodE a : fdist_rV_of_prod a = P (a ``_ ord0, rbehead a). Proof. @@ -1159,34 +1254,36 @@ End fdist_rV_of_prod. Section fdist_rV_prop. Local Open Scope vec_ext_scope. +Local Open Scope ring_scope. +Variable R : realType. Variable A : finType. -Lemma fdist_prod_of_rVK n : cancel (@fdist_rV_of_prod A n) (@fdist_prod_of_rV A n). +Lemma fdist_prod_of_rVK n : cancel (@fdist_rV_of_prod R A n) (@fdist_prod_of_rV R A n). Proof. move=> P; apply/fdist_ext => /= -[a b]. by rewrite fdist_prod_of_rVE /= fdist_rV_of_prodE /= row_mx_row_ord0 rbehead_row_mx. Qed. -Lemma fdist_rV_of_prodK n : cancel (@fdist_prod_of_rV A n) (@fdist_rV_of_prod A n). +Lemma fdist_rV_of_prodK n : cancel (@fdist_prod_of_rV R A n) (@fdist_rV_of_prod R A n). Proof. move=> P; apply/fdist_ext => v. by rewrite fdist_rV_of_prodE fdist_prod_of_rVE row_mx_rbehead. Qed. -Lemma fdist_rV0 (x : 'rV[A]_0) P : P `^ 0 x = 1. +Lemma fdist_rV0 (x : 'rV[A]_0) (P: fdist R A) : P `^ 0 x = 1. Proof. by rewrite fdist_rVE big_ord0. Qed. -Lemma fdist_rVS n (x : 'rV[A]_n.+1) P : +Lemma fdist_rVS n (x : 'rV[A]_n.+1) (P : fdist R A) : P `^ n.+1 x = P (x ``_ ord0) * P `^ n (rbehead x). Proof. rewrite 2!fdist_rVE big_ord_recl; congr (_ * _). by apply eq_bigr => i _; rewrite /rbehead mxE. Qed. -Lemma fdist_rV1 (a : 'rV[A]_1) P : (P `^ 1) a = P (a ``_ ord0). -Proof. by rewrite fdist_rVS fdist_rV0 mulR1. Qed. +Lemma fdist_rV1 (a : 'rV[A]_1) (P : fdist R A) : (P `^ 1) a = P (a ``_ ord0). +Proof. by rewrite fdist_rVS fdist_rV0 mulr1. Qed. -Lemma fdist_prod_of_fdist_rV n (P : fdist A) : +Lemma fdist_prod_of_fdist_rV n (P : fdist R A) : fdist_prod_of_rV (P `^ n.+1) = P `x P `^ n. Proof. apply/fdist_ext => /= -[a b]. @@ -1195,32 +1292,34 @@ rewrite fdist_prod_of_rVE /= fdist_rVS fdist_prodE; congr (P _ * P `^ n _) => /= by rewrite rbehead_row_mx. Qed. -Lemma head_of_fdist_rV_fdist_rV n (P : fdist A) : +Lemma head_of_fdist_rV_fdist_rV n (P : fdist R A) : head_of_fdist_rV (P `^ n.+1) = P. Proof. apply/fdist_ext => a; rewrite /head_of_fdist_rV fdist_fstE /=. under eq_bigr. move=> v _; rewrite fdist_prod_of_rVE /= fdist_rVS. by rewrite row_mx_row_ord0 rbehead_row_mx; over. -by rewrite -big_distrr /= FDist.f1 mulR1. +by rewrite -big_distrr /= FDist.f1 mulr1. Qed. -Lemma tail_of_fdist_rV_fdist_rV n (P : fdist A) : +Lemma tail_of_fdist_rV_fdist_rV n (P : fdist R A) : tail_of_fdist_rV (P `^ n.+1) = P `^ n. Proof. apply/fdist_ext => a; rewrite /tail_of_fdist_rV fdist_sndE /=. under eq_bigr. move=> v _; rewrite fdist_prod_of_rVE /= fdist_rVS. by rewrite row_mx_row_ord0 rbehead_row_mx; over. -by rewrite -big_distrl /= FDist.f1 mul1R. +by rewrite -big_distrl /= FDist.f1 mul1r. Qed. End fdist_rV_prop. Section fdist_col'. -Variables (A : finType) (n : nat) (P : {fdist 'rV[A]_n.+1}) (i : 'I_n.+1). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A : finType) (n : nat) (P : R.-fdist 'rV[A]_n.+1) (i : 'I_n.+1). -Definition fdist_col' : {fdist 'rV[A]_n} := fdistmap (col' i) P. +Definition fdist_col' : R.-fdist 'rV[A]_n := fdistmap (col' i) P. Lemma fdist_col'E v : fdist_col' v = \sum_(x : 'rV[A]_n.+1 | col' i x == v) P x. Proof. by rewrite fdistmapE. Qed. @@ -1228,7 +1327,9 @@ Proof. by rewrite fdistmapE. Qed. End fdist_col'. Section fdist_col'_prop. -Variables (A : finType) (n : nat) (P : {fdist 'rV[A]_n.+1}). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A : finType) (n : nat) (P : R.-fdist 'rV[A]_n.+1). Lemma tail_of_fdist_rV_fdist_col' : tail_of_fdist_rV P = fdist_col' P ord0. Proof. @@ -1239,9 +1340,11 @@ End fdist_col'_prop. Section fdist_nth. Local Open Scope vec_ext_scope. -Variables (A : finType) (n : nat) (P : {fdist 'rV[A]_n}) (i : 'I_n). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A : finType) (n : nat) (P : R.-fdist 'rV[A]_n) (i : 'I_n). -Definition fdist_nth : {fdist A} := fdistmap (fun v : 'rV[A]_n => v ``_ i) P. +Definition fdist_nth : R.-fdist A := fdistmap (fun v : 'rV[A]_n => v ``_ i) P. Lemma fdist_nthE a : fdist_nth a = \sum_(x : 'rV[A]_n | x ``_ i == a) P x. Proof. by rewrite fdistmapE. Qed. @@ -1249,8 +1352,10 @@ Proof. by rewrite fdistmapE. Qed. End fdist_nth. Section fdist_nth_prop. +Local Open Scope ring_scope. +Variable R : realType. -Lemma head_of_fdist_rV_fdist_nth (A : finType) (n : nat) (P : {fdist 'rV[A]_n.+1}) : +Lemma head_of_fdist_rV_fdist_nth (A : finType) (n : nat) (P : R.-fdist 'rV[A]_n.+1) : head_of_fdist_rV P = fdist_nth P ord0. Proof. by rewrite /head_of_fdist_rV /fdist_nth /fdist_fst /head_of_fdist_rV fdistmap_comp. @@ -1259,9 +1364,11 @@ Qed. End fdist_nth_prop. Section fdist_take. -Variable (A : finType) (n : nat) (P : {fdist 'rV[A]_n}). +Local Open Scope ring_scope. +Variable R : realType. +Variable (A : finType) (n : nat) (P : R.-fdist 'rV[A]_n). -Definition fdist_take (i : 'I_n.+1) : {fdist 'rV[A]_i} := fdistmap (row_take i) P. +Definition fdist_take (i : 'I_n.+1) : R.-fdist 'rV[A]_i := fdistmap (row_take i) P. Lemma fdist_takeE i v : fdist_take i v = \sum_(w in 'rV[A]_(n - i)) P (castmx (erefl, subnKC (ltnS' (ltn_ord i))) (row_mx v w)). @@ -1282,8 +1389,10 @@ Qed. End fdist_take. Section fdist_take_prop. +Local Open Scope ring_scope. +Variable R : realType. -Lemma fdist_take_all (A : finType) (n : nat) (P : {fdist 'rV[A]_n.+2}) : +Lemma fdist_take_all (A : finType) (n : nat) (P : R.-fdist 'rV[A]_n.+2) : fdist_take P (lift ord0 ord_max) = P. Proof. rewrite /fdist_take (_ : row_take (lift ord0 ord_max) = ssrfun.id) ?fdistmap_id //. @@ -1292,10 +1401,11 @@ by rewrite /row_take mxE castmxE /= cast_ord_id; congr (v _ _); exact: val_inj. Qed. End fdist_take_prop. -Arguments fdist_takeE {A} {n} _ _ _. +Arguments fdist_takeE {R} {A} {n} _ _ _. Local Open Scope vec_ext_scope. -Lemma fdist_take_nth (A : finType) (n : nat) (P : {fdist 'rV[A]_n.+1}) (i : 'I_n.+1) : +Lemma fdist_take_nth (R : realType) (A : finType) (n : nat) + (P : R.-fdist 'rV[A]_n.+1) (i : 'I_n.+1) : (fdist_belast_last_of_rV (fdist_take P (lift ord0 i)))`2 = fdist_nth P i. Proof. rewrite /fdist_snd /fdist_belast_last_of_rV /fdist_take /fdist_nth !fdistmap_comp. @@ -1304,7 +1414,9 @@ by rewrite /rlast mxE castmxE /= cast_ord_id /=; congr (v ``_ _); exact: val_inj Qed. Section fdistA. -Variables (A B C : finType) (P : {fdist A * B * C}). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A B C : finType) (P : R.-fdist (A * B * C)). Definition prodA (x : A * B * C) := (x.1.1, (x.1.2, x.2)). @@ -1321,7 +1433,7 @@ Qed. Definition inj_prodA : injective prodA. Proof. by rewrite /f => -[[? ?] ?] [[? ?] ?] /= [-> -> ->]. Qed. -Definition fdistA : {fdist A * (B * C)} := fdistmap prodA P. +Definition fdistA : R.-fdist (A * (B * C)) := fdistmap prodA P. Lemma fdistAE x : fdistA x = P (x.1, x.2.1, x.2.2). Proof. @@ -1339,7 +1451,9 @@ End fdistA. Arguments inj_prodA {A B C}. Section fdistA_prop. -Variables (A B C : finType) (P : {fdist A * B * C}). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A B C : finType) (P : R.-fdist (A * B * C)). Implicit Types (E : {set A}) (F : {set B}) (G : {set C}). Lemma fdistA1 : (fdistA P)`1 = (P`1)`1. @@ -1360,14 +1474,16 @@ Proof. by rewrite /fdist_snd /fdist_fst /fdistX !fdistmap_comp. Qed. End fdistA_prop. Section fdistC12. -Variables (A B C : finType) (P : {fdist A * B * C}). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A B C : finType) (P : R.-fdist (A * B * C)). Let f (x : A * B * C) := (x.1.2, x.1.1, x.2). Let inj_f : injective f. Proof. by rewrite /f => -[[? ?] ?] [[? ?] ?] /= [-> -> ->]. Qed. -Definition fdistC12 : {fdist B * A * C} := fdistmap f P. +Definition fdistC12 : R.-fdist (B * A * C) := fdistmap f P. Lemma fdistC12E x : fdistC12 x = P (x.1.2, x.1.1, x.2). Proof. @@ -1387,7 +1503,9 @@ Proof. by rewrite /fdist_fst /fdistA /fdist_snd !fdistmap_comp. Qed. End fdistC12. Section fdistC12_prop. -Variables (A B C : finType) (P : {fdist A * B * C}). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A B C : finType) (P : R.-fdist (A * B * C)). Lemma fdistC12I : fdistC12 (fdistC12 P) = P. Proof. @@ -1398,7 +1516,9 @@ Qed. End fdistC12_prop. Section fdistAC. -Variables (A B C : finType) (P : {fdist A * B * C}). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A B C : finType) (P : R.-fdist (A * B * C)). Definition prodAC := fun x : A * B * C => (x.1.1, x.2, x.1.2). @@ -1413,7 +1533,7 @@ apply/setP => -[[a c] b]; apply/imsetP/idP. - by rewrite !inE /= => /andP [] /andP [] aE cG bF; exists ((a, b), c); rewrite // !inE /= aE cG bF. Qed. -Definition fdistAC : {fdist A * C * B} := fdistX (fdistA (fdistC12 P)). +Definition fdistAC : R.-fdist (A * C * B) := fdistX (fdistA (fdistC12 P)). Lemma fdistACE x : fdistAC x = P (x.1.1, x.2, x.1.2). Proof. by case: x => x1 x2; rewrite /fdistAC fdistXE fdistAE fdistC12E. Qed. @@ -1422,7 +1542,9 @@ End fdistAC. Arguments inj_prodAC {A B C}. Section fdistAC_prop. -Variables (A B C : finType) (P : {fdist A * B * C}). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A B C : finType) (P : R.-fdist (A * B * C)). Implicit Types (E : {set A}) (F : {set B}) (G : {set C}). Lemma fdistAC2 : (fdistAC P)`2 = (P`1)`2. @@ -1440,9 +1562,11 @@ Proof. by rewrite /fdist_fst !fdistmap_comp. Qed. End fdistAC_prop. Section fdistC13. -Variables (A B C : finType) (P : {fdist A * B * C}). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A B C : finType) (P : R.-fdist (A * B * C)). -Definition fdistC13 : {fdist C * B * A} := fdistC12 (fdistX (fdistA P)). +Definition fdistC13 : R.-fdist (C * B * A) := fdistC12 (fdistX (fdistA P)). Lemma fdistC13E x : fdistC13 x = P (x.2, x.1.2, x.1.1). Proof. by rewrite /fdistC13 fdistC12E fdistXE fdistAE. Qed. @@ -1462,9 +1586,11 @@ Proof. by rewrite /fdist_snd /fdistX !fdistmap_comp. Qed. End fdistC13. Section fdist_proj13. -Variables (A B C : finType) (P : {fdist A * B * C}). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A B C : finType) (P : R.-fdist (A * B * C)). -Definition fdist_proj13 : {fdist A * C} := (fdistA (fdistC12 P))`2. +Definition fdist_proj13 : R.-fdist (A * C) := (fdistA (fdistC12 P))`2. Lemma fdist_proj13E x : fdist_proj13 x = \sum_(b in B) P (x.1, b, x.2). Proof. @@ -1472,7 +1598,7 @@ by rewrite /fdist_proj13 fdist_sndE; apply eq_bigr => b _; rewrite fdistAE fdist Qed. Lemma fdist_proj13_domin a b c : fdist_proj13 (a, c) = 0 -> P (a, b, c) = 0. -Proof. by rewrite fdist_proj13E /= => /psumR_eq0P ->. Qed. +Proof. by rewrite fdist_proj13E /= => /psumr_eq0P ->. Qed. Lemma fdist_proj13_dominN a b c : P (a, b, c) != 0 -> fdist_proj13 (a, c) != 0. Proof. by apply: contra => /eqP H; apply/eqP/fdist_proj13_domin. Qed. @@ -1486,9 +1612,11 @@ Proof. by rewrite /fdist_proj13 fdistA21 fdistC12_fst fdistX2 fdistA1. Qed. End fdist_proj13. Section fdist_proj23. -Variables (A B C : finType) (P : {fdist A * B * C}). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A B C : finType) (P : R.-fdist (A * B * C)). -Definition fdist_proj23 : {fdist B * C} := (fdistA P)`2. +Definition fdist_proj23 : R.-fdist (B * C) := (fdistA P)`2. Lemma fdist_proj23E x : fdist_proj23 x = \sum_(a in A) P (a, x.1, x.2). Proof. @@ -1496,7 +1624,7 @@ by rewrite /fdist_proj23 fdist_sndE; apply eq_bigr => a _; rewrite fdistAE. Qed. Lemma fdist_proj23_domin a b c : fdist_proj23 (b, c) = 0 -> P (a, b, c) = 0. -Proof. by rewrite fdist_proj23E /= => /psumR_eq0P ->. Qed. +Proof. by rewrite fdist_proj23E /= => /psumr_eq0P ->. Qed. Lemma fdist_proj23_dominN a b c : P (a, b, c) != 0 -> fdist_proj23 (b, c) != 0. Proof. by apply: contra => /eqP H; apply/eqP; apply: fdist_proj23_domin. Qed. @@ -1509,7 +1637,8 @@ Proof. by rewrite /fdist_proj23 fdistA22. Qed. End fdist_proj23. -Lemma fdist_proj13_AC (A B C : finType) (P : {fdist A * B * C}) : +Lemma fdist_proj13_AC (R : realType) (A B C : finType) + (P : R.-fdist (A * B * C)) : fdist_proj13 (fdistAC P) = P`1. Proof. rewrite /fdist_proj13 /fdist_snd /fdistA /fdistC12 /fdistAC /fdist_fst. @@ -1518,12 +1647,14 @@ by rewrite boolp.funeqE => -[[]]. Qed. Section fdist_self. -Variable (A : finType) (P : {fdist A}). +Local Open Scope ring_scope. +Variable R : realType. +Variable (A : finType) (P : R.-fdist A). Let f := [ffun a : A * A => if a.1 == a.2 then P a.1 else 0]. Let f0 x : 0 <= f x. -Proof. rewrite /f ffunE; case: ifPn => [/eqP -> //| _]; exact: leRR. Qed. +Proof. rewrite /f ffunE; case: ifPn => [/eqP -> //| _]; exact: lexx. Qed. Let f1 : \sum_(x in {: A * A}) f x = 1. Proof. @@ -1532,10 +1663,10 @@ rewrite -(pair_bigA _ (fun a1 a2 => f (a1, a2))) /=. rewrite -(FDist.f1 P); apply/eq_bigr => a _. under eq_bigr do rewrite ffunE. rewrite /= (bigD1 a) //= eqxx. -by rewrite big1 ?addR0 // => a' /negbTE; rewrite eq_sym => ->. +by rewrite big1 ?addr0 // => a' /negbTE; rewrite eq_sym => ->. Qed. -Definition fdist_self : {fdist A * A} := locked (FDist.make f0 f1). +Definition fdist_self : R.-fdist (A * A) := locked (FDist.make f0 f1). Lemma fdist_selfE a : fdist_self a = if a.1 == a.2 then P a.1 else 0. Proof. by rewrite /fdist_self; unlock; rewrite ffunE. Qed. @@ -1543,12 +1674,14 @@ Proof. by rewrite /fdist_self; unlock; rewrite ffunE. Qed. End fdist_self. Section fdist_self_prop. -Variables (A : finType) (P : {fdist A}). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A : finType) (P : R.-fdist A). Lemma fdist_self1 : (fdist_self P)`1 = P. Proof. apply/fdist_ext => a /=; rewrite fdist_fstE (bigD1 a) //= fdist_selfE eqxx /=. -by rewrite big1 ?addR0 // => a' /negbTE; rewrite fdist_selfE /= eq_sym => ->. +by rewrite big1 ?addr0 // => a' /negbTE; rewrite fdist_selfE /= eq_sym => ->. Qed. Lemma fdistX_self : fdistX (fdist_self P) = fdist_self P. @@ -1561,7 +1694,7 @@ End fdist_self_prop. Local Open Scope ring_scope. (* TODO: rm? *) -Lemma rsum_rmul_rV_pmf_tnth A n k (P : fdist A) : +Lemma rsum_rmul_rV_pmf_tnth (R : realType) A n k (P : fdist R A) : \sum_(t : 'rV[ 'rV[A]_n]_k) \prod_(m < k) (P `^ n) t ``_ m = 1. Proof. transitivity (\sum_(j : {ffun 'I_k -> 'rV[A]_n}) \prod_(m : 'I_k) P `^ _ (j m)). @@ -1572,7 +1705,7 @@ transitivity (\sum_(j : {ffun 'I_k -> 'rV[A]_n}) \prod_(m : 'I_k) P `^ _ (j m)). - by move=> v /=; apply/esym/eqP/rowP => i; rewrite mxE ffunE. - by move=> i _; apply eq_bigr => j _; rewrite ffunE. rewrite -(bigA_distr_bigA (fun m => P `^ _)) /= big_const. -by rewrite iter_mulR FDist.f1 exp1R. +by rewrite iter_mulr FDist.f1 expr1n mulr1. Qed. Local Close Scope ring_scope. Local Close Scope vec_ext_scope. @@ -1580,17 +1713,21 @@ Local Close Scope vec_ext_scope. (* wip *) Module Subvec. Section def. -Variables (A : finType) (n : nat) (P : {fdist 'rV[A]_n}) (s : {set 'I_n}). -Definition d : {fdist 'rV[A]_#|s| } := fdistmap (fun x => sub_vec x s) P. +Local Open Scope ring_scope. +Variable R : realType. +Variables (A : finType) (n : nat) (P : R.-fdist 'rV[A]_n) (s : {set 'I_n}). +Definition d : R.-fdist 'rV[A]_#|s| := fdistmap (fun x => sub_vec x s) P. End def. End Subvec. Section subvec_prop. +Local Open Scope ring_scope. +Variable R : realType. Local Open Scope vec_ext_scope. -Variables (A : finType) (n : nat) (P : {fdist 'rV[A]_n.+1}). +Variables (A : finType) (n : nat) (P : R.-fdist 'rV[A]_n.+1). Definition marginal1_cast (i : 'I_n.+1) (v : 'rV[A]_#|[set i]|) : A := (castmx (erefl, cards1 i) v) ``_ ord0. Lemma head_ofE : - head_of_fdist_rV P = fdistmap (@marginal1_cast ord0) (@Subvec.d A n.+1 P [set ord0]). + head_of_fdist_rV P = fdistmap (@marginal1_cast ord0) (@Subvec.d R A n.+1 P [set ord0]). Proof. apply fdist_ext => a. rewrite fdistmapE /= /head_of_fdist_rV fdist_fstE /= /head_of_fdist_rV. @@ -1601,10 +1738,12 @@ Abort. End subvec_prop. Section fdist_prod_nth. +Local Open Scope ring_scope. +Variable R : realType. Local Open Scope vec_ext_scope. -Variables (A B : finType) (n : nat) (P : {fdist 'rV[A]_n * B}) (i : 'I_n). +Variables (A B : finType) (n : nat) (P : R.-fdist ('rV[A]_n * B)) (i : 'I_n). -Definition fdist_prod_nth : {fdist A * B} := +Definition fdist_prod_nth : R.-fdist (A * B) := fdistmap (fun x : 'rV[A]_n * B => (x.1 ord0 i, x.2)) P. Lemma fdist_prod_nthE ab : @@ -1614,18 +1753,21 @@ Proof. by rewrite fdistmapE. Qed. End fdist_prod_nth. Section fdist_prod_take. -Variables (A B : finType) (n : nat) (P : {fdist 'rV[A]_n.+1 * B}) (i : 'I_n.+1). +Local Open Scope ring_scope. +Variable R : realType. +Variables (A B : finType) (n : nat) (P : R.-fdist ('rV[A]_n.+1 * B)) (i : 'I_n.+1). -Definition fdist_prod_take : {fdist 'rV_i * A * B} := +Definition fdist_prod_take : R.-fdist ('rV_i * A * B) := fdistmap (fun x : 'rV[A]_n.+1 * B => (row_take (widen_ord (leqnSn _) i) x.1, x.1 ord0 i, x.2)) P. End fdist_prod_take. Section to_bivar_last_take. - +Local Open Scope ring_scope. +Variable R : realType. Variables (A B : finType). -Variables (n : nat) (PY : {fdist 'rV[A]_n.+1 * B}). -Let P : {fdist 'rV[A]_n.+1} := PY`1. +Variables (n : nat) (PY : R.-fdist ('rV[A]_n.+1 * B)). +Let P : R.-fdist 'rV[A]_n.+1 := PY`1. Lemma belast_last_take (j : 'I_n.+1) : fdist_belast_last_of_rV (fdist_take P (lift ord0 j)) = (fdist_prod_take PY j)`1. @@ -1640,10 +1782,12 @@ Qed. End to_bivar_last_take. Section fdist_take_drop. +Local Open Scope ring_scope. +Variable R : realType. Local Open Scope vec_ext_scope. -Variables (A : finType) (n : nat) (P : {fdist 'rV[A]_n.+1}) (i : 'I_n.+1). +Variables (A : finType) (n : nat) (P : R.-fdist 'rV[A]_n.+1) (i : 'I_n.+1). -Definition fdist_take_drop : {fdist A * 'rV[A]_i * 'rV[A]_(n - i)} := +Definition fdist_take_drop : R.-fdist (A * 'rV[A]_i * 'rV[A]_(n - i)) := fdistmap (fun x : 'rV[A]_n.+1 => (x ord0 ord0, row_take i (rbehead x), row_drop i (rbehead x))) P. @@ -1713,4 +1857,3 @@ Defined. *) End tuple_prod_cast.*) - diff --git a/probability/fsdist.v b/probability/fsdist.v index eed710fb..2f1942b3 100644 --- a/probability/fsdist.v +++ b/probability/fsdist.v @@ -1,12 +1,13 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) From HB Require Import structures. -From mathcomp Require Import all_ssreflect. +From mathcomp Require Import all_ssreflect ssralg ssrnum. From mathcomp Require Import finmap. +From mathcomp Require Import mathcomp_extra. From mathcomp Require boolp. Require Import Reals. From mathcomp Require Import Rstruct. -Require Import ssrR Reals_ext ssr_ext ssralg_ext bigop_ext Rbigop fdist. +Require Import ssrR realType_ext Reals_ext ssr_ext ssralg_ext bigop_ext Rbigop fdist. Require Import convex. (******************************************************************************) @@ -57,6 +58,16 @@ Import Prenex Implicits. Local Open Scope R_scope. Local Open Scope fset_scope. +Local Open Scope fdist_scope. + +Import Order.POrderTheory Num.Theory. + +Lemma fdist_Rgt0 (A : finType) (d : real_realType.-fdist A) a : + (d a != 0) <-> (0 < d a)%coqR. +Proof. by rewrite fdist_gt0; split=> /RltP. Qed. +Lemma fdist_Rge0 (A : finType) (d : real_realType.-fdist A) a : + 0 <= d a. +Proof. by apply/RleP; rewrite FDist.ge0. Qed. (* NB: PR to finmap in progress *) Lemma bigfcup_imfset (T I : choiceType) (P : {fset I}) (f : I -> T) : @@ -90,19 +101,22 @@ Variable A : choiceType. Record t := mk { f :> {fsfun A -> R with 0} ; - _ : all (fun x => 0 (0 < f x)%mcR) (finsupp f) && \sum_(a <- finsupp f) f a == 1}. Lemma ge0 (d : t) a : 0 <= d a. Proof. case: d => /= [f /andP[/allP f0 _]]. -have [/f0/ltRP/ltRW|/fsfun_dflt->] := boolP (a \in finsupp f); first exact. -exact/leRR. +have [/f0/RltP/ltRW|/fsfun_dflt->] := boolP (a \in finsupp f); first exact. +by apply/RleP; rewrite lexx. Qed. +Lemma ge0' (d : t) a : (0 <= d a)%mcR. +Proof. by apply/RleP/ge0. Qed. + Lemma gt0 (d : t) a : a \in finsupp d -> 0 < d a. Proof. -by rewrite mem_finsupp => da; apply/ltRP; rewrite lt0R da; exact/leRP/ge0. +by rewrite mem_finsupp => da; apply/RltP; rewrite lt0r da; exact/RleP/ge0. Qed. Lemma f1 (d : t) : \sum_(a <- finsupp d) d a = 1. @@ -115,13 +129,16 @@ rewrite -(f1 d) (big_fsetD1 _ ad)/=; apply/leR_addl. by apply sumR_ge0 => ? _; exact: ge0. Qed. +Lemma le1' (d : t) a : (d a <= 1)%mcR. +Proof. by apply/RleP/le1. Qed. + Obligation Tactic := idtac. Program Definition make (f : {fsfun A -> R with 0}) (H0 : forall a, a \in finsupp f -> 0 < f a) (H1 : \sum_(a <- finsupp f) f a = 1) : t := @mk f _. Next Obligation. -by move=> f H0 ->; rewrite eqxx andbT; apply/allP => a /H0/ltRP. +by move=> f H0 ->; rewrite eqxx andbT; apply/allP => a /H0/RltP. Qed. End fsdist. @@ -222,11 +239,11 @@ rewrite {2}/f. under eq_bigr do rewrite fsfunE. rewrite -big_mkcond /= exchange_big /=. rewrite -[RHS](FSDist.f1 p); apply eq_bigr => a _. -have [->|pa0] := eqVneq (p a) 0%R. +have [->|pa0] := eqVneq (p a) 0%coqR. by rewrite big1 // => *; rewrite mul0R. rewrite -big_distrr /= (_ : \sum_(_ <- _ | _) _ = 1) ?mulR1 //. rewrite (bigID (mem (finsupp (g a)))) /=. -rewrite [X in (_ + X)%R = _]big1 ?addR0; last first. +rewrite [X in (_ + X)%coqR = _]big1 ?addR0; last first. by move=> b /andP[_]; rewrite memNfinsupp => /eqP. rewrite (eq_bigl (fun i => i \in finsupp (g a))); last first. move=> b; rewrite andb_idl // mem_finsupp => gab0. @@ -239,11 +256,12 @@ apply/idP/idP => [|gab0]; first by rewrite mem_filter mem_finsupp => /andP[]. rewrite mem_filter 2!mem_finsupp gab0 /= /f fsfunE ifT; last first. apply/bigfcupP; exists (g a); rewrite ?mem_finsupp // andbT. by apply/imfsetP; exists a => //; rewrite mem_finsupp. -apply: contra gab0 => /eqP/psumR_seq_eq0P. -rewrite fset_uniq => /(_ isT) H. +apply: contra gab0; rewrite psumr_eq0; last first. + by move=> a0 _; rewrite RmultE mulr_ge0//; exact/RleP. +move=> /allP H. suff : p a * g a b = 0. by rewrite mulR_eq0 => -[/eqP|->//]; rewrite (negbTE pa0). -apply/H; rewrite ?mem_finsupp // => a0 _; exact/mulR_ge0. +by apply/eqP/H; rewrite mem_finsupp. Qed. Definition fsdistbind : {dist B} := locked (FSDist.make f0 f1). @@ -279,10 +297,12 @@ case/bigfcupP => dB. rewrite andbT => /imfsetP[a] /= ap ->{dB} bga. rewrite fsdistbindE. apply/eqP => H. -have : (p a) * (g a) b <> 0. +have : p a * g a b <> 0. by rewrite mulR_eq0 => -[]; apply/eqP; rewrite -mem_finsupp. apply. -by move/psumR_seq_eq0P : H; apply => // b0 _; exact/mulR_ge0. +move/eqP : H; rewrite psumr_eq0; last first. + by move=> a0 _; rewrite RmultE mulr_ge0//; exact/RleP. +by move=> /allP H; exact/eqP/H. Qed. End fsdistbind. @@ -309,7 +329,7 @@ rewrite fsdistbindEcond; case: ifPn => [|H]. rewrite supp_fsdist1 inE => /eqP ->{b}. rewrite (big_fsetD1 a) //= fsdist1xx mulR1 big1_fset ?addR0 // => a0. by rewrite !inE => /andP[aa0] a0p _; rewrite fsdist10 ?mulR0// eq_sym. -have [->//|pb0] := eqVneq (p b) 0%R. +have [->//|pb0] := eqVneq (p b) 0%coqR. case/bigfcupP : H. exists (fsdist1 b); last by rewrite supp_fsdist1 inE. by rewrite andbT; apply/imfsetP; exists b => //=; rewrite mem_finsupp. @@ -395,8 +415,8 @@ by rewrite fsfun_dflt // mem_fsetD1 // FSDist.f1 addR0 subRR. Qed. Local Close Scope reals_ext_scope. -Definition FSDist_prob (C : choiceType) (d : {dist C}) (x : C) : prob := - Eval hnf in Prob.mk_ (conj (FSDist.ge0 d x) (FSDist.le1 d x)). +Definition FSDist_prob (C : choiceType) (d : {dist C}) (x : C) : {prob R} := + Eval hnf in Prob.mk_ (andb_true_intro (conj (FSDist.ge0' d x) (FSDist.le1' d x))). Canonical FSDist_prob. Definition fsdistjoin A (D : {dist (FSDist_choiceType A)}) : {dist A} := @@ -486,7 +506,7 @@ End FSDist_lift_supp. Module FSDist_of_fdist. Section def. -Variable (A : finType) (P : fdist A). +Variable (A : finType) (P : real_realType.-fdist A). Let D := [fset a0 : A | P a0 != 0]. Definition f : {fsfun A -> R with 0} := [fsfun a in D => P a | 0]. @@ -494,13 +514,13 @@ Definition f : {fsfun A -> R with 0} := [fsfun a in D => P a | 0]. Let f0 a : a \in finsupp f -> 0 < f a. Proof. rewrite fsfunE mem_finsupp /f fsfunE. -case: ifPn => [_|]; by [rewrite fdist_gt0 | rewrite eqxx]. +case: ifPn => [_|]; by [rewrite fdist_Rgt0 | rewrite eqxx]. Qed. Let f1 : \sum_(a <- finsupp f) f a = 1. Proof. rewrite -[RHS](FDist.f1 P) [in RHS](bigID (mem (finsupp f))) /=. -rewrite [in X in _ = (_ + X)%R]big1 ?addR0; last first. +rewrite [in X in _ = (_ + X)%coqR]big1 ?addR0; last first. move=> a; rewrite memNfinsupp fsfunE !inE /=. by case: ifPn => [_ /eqP //|]; rewrite negbK => /eqP. rewrite (@eq_fbigr _ _ _ _ _ _ _ P) /=; last first. @@ -523,7 +543,10 @@ Lemma f1 : \sum_(b in D) f b = 1. Proof. rewrite -(FSDist.f1 P) big_seq_fsetE /=; apply eq_bigr => a; by rewrite ffunE. Qed. -Definition d : fdist D := locked (FDist.make f0 f1). +Lemma f0' b : (0 <= f b)%O. (* TODO: we shouldn't see %O *) +Proof. exact/RleP/f0. Qed. + +Definition d : real_realType.-fdist D := locked (FDist.make f0' f1). End def. Module Exports. Notation fdist_of_fs := d. @@ -549,15 +572,17 @@ Definition f := [ffun d : A => P d]. Lemma f0 b : 0 <= f b. Proof. by rewrite ffunE. Qed. +Lemma f0' b : (0 <= f b)%O. Proof. exact/RleP/f0. Qed. + Lemma f1 : \sum_(b in A) f b = 1. Proof. rewrite -(FSDist.f1 P) (bigID (fun x => x \in finsupp P)) /=. -rewrite [X in (_ + X = _)%R](_ : _ = 0) ?addR0. +rewrite [X in (_ + X = _)%coqR](_ : _ = 0) ?addR0. by rewrite big_uniq /= ?fset_uniq //; apply eq_bigr => i _; rewrite ffunE. by rewrite big1 // => a; rewrite mem_finsupp negbK ffunE => /eqP. Qed. -Definition d : fdist A := locked (FDist.make f0 f1). +Definition d : real_realType.-fdist A := locked (FDist.make f0' f1). Lemma dE a : d a = P a. Proof. by rewrite /d; unlock; rewrite ffunE. Qed. @@ -571,10 +596,10 @@ Export fdist_of_finFSDist.Exports. Section fsdist_convn. Local Open Scope fdist_scope. -Variables (A : choiceType) (n : nat) (e : {fdist 'I_n}) (g : 'I_n -> {dist A}). +Variables (A : choiceType) (n : nat) (e : real_realType.-fdist 'I_n) (g : 'I_n -> {dist A}). Definition fsdist_convn_supp : {fset A} := - \big[fsetU/fset0]_(i < n | 0 a; apply/idP/idP => [|]. rewrite mem_finsupp fsfunE => aD. rewrite aD. case/bigfcupP : aD => /= i. -rewrite mem_index_enum /= => /ltRP ei0. +rewrite mem_index_enum /= => /RltP ei0. rewrite mem_finsupp => gia0. apply: contra gia0 => /eqP H; apply/eqP. rewrite -(@eqR_mul2l (e i)) ?mulR0; last exact/eqP/gtR_eqF. -by move/psumR_eq0P : H; apply => //= j _; exact/mulR_ge0. +move/psumr_eq0P : H; apply => //= j _. +by rewrite RmultE mulr_ge0//; exact/RleP. Qed. Let f0 a : a \in finsupp f -> 0 < f a. @@ -607,10 +633,10 @@ under eq_big_seq. by move=> b; rewrite supp => bD; rewrite fsfunE bD; over. rewrite exchange_big /= -[RHS](FDist.f1 e) /=; apply eq_bigr => i _. rewrite -big_distrr /=. -have [-> | ei0] := eqVneq (e i) 0%R; first by rewrite mul0R. +have [-> | ei0] := eqVneq (e i) 0%coqR; first by rewrite mul0R. rewrite -(@big_fset_incl _ _ _ _ (finsupp (g i))). - by rewrite FSDist.f1 mulR1. -- by rewrite supp /D bigfcup_sup //; exact/ltRP/fdist_gt0. +- by rewrite supp /D bigfcup_sup //; exact/RltP/fdist_Rgt0. - by move=> a _; rewrite memNfinsupp => /eqP. Qed. @@ -623,45 +649,43 @@ Proof. by rewrite /fsdist_convn; unlock; rewrite fsfunE. Qed. End fsdist_convn. Section fsdist_conv. -Variables (A : choiceType) (p : prob) (d1 d2 : {dist A}). +Variables (A : choiceType) (p : {prob R}) (d1 d2 : {dist A}). Definition fsdist_conv : {dist A} := locked (fsdist_convn (fdistI2 p) (fun i => if i == ord0 then d1 else d2)). -Local Open Scope reals_ext_scope. -Lemma fsdist_convE a : (fsdist_conv a = p * d1 a + p.~ * d2 a)%R. +Lemma fsdist_convE a : (fsdist_conv a = p * d1 a + (Prob.p p).~ * d2 a)%coqR. Proof. rewrite /fsdist_conv; unlock => /=; rewrite fsdist_convnE fsfunE. case: ifPn => [?|H]. rewrite !big_ord_recl big_ord0 /= addR0 !fdistI2E. by rewrite eqxx eq_sym (negbTE (neq_lift _ _)). -have [p0|p0] := eqVneq (p : R) 0%R. +have [p0|p0] := eqVneq p R0%:pr. rewrite p0 mul0R add0R onem0 mul1R. apply/esym/eqP; rewrite -memNfinsupp. apply: contra H => H. - rewrite (_ : p = 0%:pr) //; last exact/val_inj. - rewrite fdistI20 (_ : Ordinal _ = @ord_max 1); last exact/val_inj. + rewrite p0 fdistI20 (_ : Ordinal _ = @ord_max 1); last exact/val_inj. (* TODO: generalize *) suff : fsdist_convn_supp (fdist1 ord_max) (fun i : 'I_2 => if i == ord0 then d1 else d2) = finsupp d2 by move=> ->. rewrite /fsdist_convn_supp; apply/fsetP => a0; apply/bigfcupP/idP. case => /= i; rewrite mem_index_enum /= fdist1E. - by case/orP : (ord2 i) => /eqP -> // /ltRP/ltRR. + by case/orP : (ord2 i) => /eqP -> // /RltP/ltRR. move=> a0d2. - by exists ord_max => //=; rewrite mem_index_enum /= fdist1xx; exact/ltRP. + by exists ord_max => //=; rewrite mem_index_enum /= fdist1xx; exact/RltP. have d1a0 : d1 a = 0. apply/eqP; rewrite -memNfinsupp. apply: contra H => H. rewrite /fsdist_convn_supp; apply/bigfcupP; exists ord0; last by rewrite eqxx. - by rewrite mem_index_enum /= fdistI2E eqxx; exact/ltRP/prob_gt0. + by rewrite mem_index_enum /= fdistI2E eqxx; exact/RltP/probR_gt0. rewrite d1a0 mulR0 add0R. -have [p1|p1] := eqVneq (p : R) 1%R; first by rewrite p1 onem1 mul0R. +have [p1|p1] := eqVneq p R1%:pr; first by rewrite p1 onem1 mul0R. suff : d2 a = 0 by move=> ->; rewrite mulR0. apply/eqP; rewrite -memNfinsupp. apply: contra H => H. rewrite /fsdist_convn_supp; apply/bigfcupP; exists (lift ord0 ord0). rewrite mem_index_enum /= fdistI2E eq_sym (negbTE (neq_lift _ _)). - exact/ltRP/onem_gt0/prob_lt1. + exact/RltP/onem_gt0/probR_lt1. by rewrite eq_sym (negbTE (neq_lift _ _)). Qed. @@ -674,26 +698,24 @@ Variables (A : choiceType). Implicit Types a b c : {dist A}. Local Open Scope reals_ext_scope. -Lemma finsupp_conv_subr (a b : {dist A}) (p : prob) : - p != 0%:pr -> finsupp a `<=` finsupp (a <|p|> b). +Lemma finsupp_conv_subr (a b : {dist A}) (p : {prob R}) : + p != R0%:pr -> finsupp a `<=` finsupp (a <|p|> b). Proof. move=> p0; apply/fsubsetP => a1. rewrite !mem_finsupp => aa1. rewrite fsdist_convE. -apply: contra aa1 => /eqP. -rewrite paddR_eq0; [move=> [+ _]|exact/mulR_ge0|exact/mulR_ge0]. -rewrite mulR_eq0 => -[p0'|/eqP //]. -exfalso. -move/eqP : p0; apply. -by apply/val_inj; rewrite /= p0'. +apply/paddR_neq0; [exact/mulR_ge0|exact/mulR_ge0|left]. +by rewrite mulR_neq0' aa1 andbT. Qed. -Let conv0 (mx my : {dist A}) : mx <| 0%:pr |> my = my. +Let conv0 (mx my : {dist A}) : mx <| R0%:pr |> my = my. +(*Let conv0 (mx my : {dist A}) : mx <| R0%:pr |> my = my.*) + Proof. by apply/fsdist_ext => a; rewrite fsdist_convE /= mul0R add0R onem0 mul1R. Qed. -Let conv1 (mx my : {dist A}) : mx <| 1%:pr |> my = mx. +Let conv1 (mx my : {dist A}) : mx <| R1%:pr |> my = mx. Proof. by apply/fsdist_ext => a; rewrite fsdist_convE /= mul1R onem1 mul0R addR0. Qed. @@ -703,45 +725,45 @@ Proof. by move=> d; apply/fsdist_ext => a; rewrite fsdist_convE -mulRDl onemKC mul1R. Qed. -Let convC (p : prob) (mx my : {dist A}) : mx <| p |> my = my <| p.~%:pr |> mx. +Let convC (p : {prob R}) (mx my : {dist A}) : mx <| p |> my = my <| (Prob.p p).~%:pr |> mx. Proof. by apply/fsdist_ext => a; rewrite 2!fsdist_convE /= onemK addRC. Qed. -Definition fsdist_convA (p q r s : prob) (mx my mz : {dist A}) : - p = r * s :> R /\ s.~ = p.~ * q.~ -> +Definition fsdist_convA (p q r s : {prob R}) (mx my mz : {dist A}) : + p = r * s :> R /\ (Prob.p s).~ = (Prob.p p).~ * (Prob.p q).~ -> mx <| p |> (my <| q |> mz) = (mx <| r |> my) <| s |> mz. Proof. -move=> [Hp Hs]; apply/fsdist_ext => a. -rewrite !fsdist_convE [in RHS]mulRDr (@mulRCA _ r) (@mulRA r) -Hp -addRA; congr (_ + _)%R. -rewrite mulRDr (@mulRA p.~ q.~) -Hs; congr (_ + _)%R. -rewrite !mulRA; congr (_ * _)%R. +rewrite !Prob_pE; move=> [Hp Hs]; apply/fsdist_ext => a. +rewrite !fsdist_convE [in RHS]mulRDr (@mulRCA _ r) (@mulRA r) -Hp -addRA; congr (_ + _)%coqR. +rewrite mulRDr (@mulRA (Prob.p p).~ (Prob.p q).~) -Hs; congr (_ + _)%coqR. +rewrite !mulRA; congr (_ * _)%coqR. rewrite -p_of_rsE in Hp. -move/(congr1 onem) : Hs; rewrite onemK => Hs. +move/(congr1 (@onem _)) : Hs; rewrite onemK => Hs. rewrite -s_of_pqE in Hs. -have [r0|r0] := eqVneq r 0%:pr. - rewrite r0 /= onem0 mulR1 Hs s_of_pqE. - by rewrite Hp p_of_rsE r0 /= mul0R onem0 !mul1R onemK. -have [s0|s0] := eqVneq s 0%:pr. +have [r0|r0] := eqVneq r R0%:pr. + rewrite r0 onem0 mulR1 !Prob_pE Hs s_of_pqE. + by rewrite Hp p_of_rsE r0 /= mul0R onem0 2!mul1R onemK. +have [s0|s0] := eqVneq s R0%:pr. rewrite Hp p_of_rsE s0 /= mulR0 onem0 mul0R mul1R. by move: Hs; rewrite s_of_pqE Hp p_of_rsE s0 /= mulR0 onem0 mul1R onemK. rewrite p_of_rsE in Hp. rewrite s_of_pqE in Hs. -move/(congr1 onem) : Hs; rewrite onemK => Hs. +move/(congr1 (@onem _)) : Hs; rewrite onemK => Hs. move: (@r_of_pq_is_r p q r s r0 s0 Hp Hs) => <-. -rewrite pq_is_rs mulRC; congr (_ * _)%R. +rewrite pq_is_rs mulRC; congr (_ * _)%coqR. by rewrite s_of_pqE -Hs onemK. Qed. (* TODO: move the glue lemma to convex *) -Let convA (p q : prob) (a b c : {dist A}) : +Let convA (p q : {prob R}) (a b c : {dist A}) : a <| p |> (b <| q |> c) = (a <| r_of_pq p q |> b) <| s_of_pq p q |> c. Proof. rewrite (fsdist_convA (r := r_of_pq p q) (s := s_of_pq p q)) //. -rewrite {2}s_of_pqE onemK; split => //. -have [s0|s0] := eqVneq (s_of_pq p q) 0%:pr. +rewrite !Prob_pE {2}s_of_pqE onemK; split => //. +have [s0|s0] := eqVneq (s_of_pq p q) R0%:pr. - rewrite s0 mulR0; apply/eqP; move/eqP: s0. - by apply: contraTT => /(s_of_gt0 q); rewrite prob_gt0. + by apply: contraTT => /(s_of_gt0 q); rewrite probR_gt0. - by rewrite -p_is_rs. Qed. @@ -749,22 +771,23 @@ HB.instance Definition _ := @isConvexSpace.Build (FSDist.t _) (Choice.class _) (@fsdist_conv A) conv1 convmm convC convA. -Lemma finsupp_conv_subl (a b : {dist A}) (p : prob) : - p != 1%:pr -> finsupp b `<=` finsupp (a <|p|> b). +Lemma finsupp_conv_subl (a b : {dist A}) (p : {prob R}) : + p != R1%:pr -> finsupp b `<=` finsupp (a <|p|> b). Proof. move=> p1; rewrite convC; apply: finsupp_conv_subr. apply: contra p1 => /eqP/(congr1 val) /= /onem_eq0 p1. exact/eqP/val_inj. Qed. -Lemma fsdist_conv_bind_left_distr (B : choiceType) (p : prob) a b (f : A -> {dist B}) : +Lemma fsdist_conv_bind_left_distr (B : choiceType) (p : {prob R}) a b (f : A -> {dist B}) : (a <| p |> b) >>= f = (a >>= f) <| p |> (b >>= f). Proof. apply/fsdist_ext => b0 /=; rewrite fsdistbindE fsdist_convE. -have [->|p0] := eqVneq p 0%:pr. +have [->|p0] := eqVneq p R0%:pr. by rewrite conv0 mul0R add0R onem0 mul1R fsdistbindE. -have [->|p1] := eqVneq p 1%:pr. +have [->|p1] := eqVneq p R1%:pr. by rewrite conv1 mul1R onem1 mul0R addR0 fsdistbindE. + under eq_bigr. by move=> a1 _; rewrite fsdist_convE (@mulRDl _ _ (f a1 b0)) -!mulRA; over. rewrite big_split /= -2!big_distrr /= -!fsdistbindEwiden //. @@ -788,7 +811,7 @@ Local Open Scope reals_ext_scope. Local Open Scope proba_scope. Local Open Scope convex_scope. -Lemma supp_fsdist_conv (C : choiceType) p (p0 : p != 0%:pr) (p1 : p != 1%:pr) +Lemma supp_fsdist_conv (C : choiceType) p (p0 : p != R0%:pr) (p1 : p != R1%:pr) (d e : {dist C}) : finsupp (d <|p|> e) = (finsupp d `|` finsupp e)%fset. Proof. @@ -798,8 +821,8 @@ apply/eqP; rewrite eqEfsubset; apply/andP; split; apply/fsubsetP => j; apply: contra H => /eqP/paddR_eq0. move => /(_ (FSDist.ge0 _ _ ))/(_ (FSDist.ge0 _ _)) [-> ->]. by rewrite 2!mulR0 addR0. -move/prob_gt0 in p0. -move: p1 => /onem_neq0 /prob_gt0 /= p1. +move/probR_gt0 in p0. +move: p1 => /onem_neq0 /probR_gt0 /= p1. by rewrite 2!mem_finsupp => /orP[dj0|ej0]; apply/gtR_eqF; [apply/addR_gt0wl; last exact/mulR_ge0; apply/mulR_gt0 => //; apply/ltR_neqAle; split => //; exact/nesym/eqP | @@ -810,7 +833,7 @@ Qed. Section misc_scaled. Local Open Scope R_scope. -Lemma fsdist_scalept_conv (C : convType) (x y : {dist C}) (p : prob) (i : C) : +Lemma fsdist_scalept_conv (C : convType) (x y : {dist C}) (p : {prob R}) (i : C) : scalept ((x <|p|> y) i) (S1 i) = scalept (x i) (S1 i) <|p|> scalept (y i) (S1 i). Proof. by rewrite fsdist_convE scalept_conv. Qed. @@ -845,7 +868,7 @@ have [gia0|gia0] := eqVneq (g i a) 0. by rewrite /f gia0 scaleR_scalept/= ?mulR0. move/bigfcupP : adg => abs; exfalso; apply: abs. exists i; last by rewrite mem_finsupp. -by rewrite mem_index_enum/=; apply/ltRP; rewrite -fdist_gt0. +by rewrite mem_index_enum/=; apply/RltP; rewrite -fdist_Rgt0. Qed. End FSDist_convex_space. @@ -915,9 +938,9 @@ Qed. Lemma Convn_of_fsdist_affine : affine Convn_of_fsdist. Proof. move=> p x y. -have [->|pn0] := eqVneq p 0%:pr; first by rewrite !conv0. -have [->|pn1] := eqVneq p 1%:pr; first by rewrite !conv1. -have opn0 : p.~ != 0%:pr by apply onem_neq0. +have [->|pn0] := eqVneq p R0%:pr; first by rewrite !conv0. +have [->|pn1] := eqVneq p R1%:pr; first by rewrite !conv1. +have opn0 : (Prob.p p).~ != R0. by apply onem_neq0. apply: S1_inj; rewrite affine_conv/= !S1_Convn_finType ssum_seq_finsuppE. under [LHS]eq_bigr do rewrite fsdist_scalept_conv. rewrite big_seq_fsetE big_scalept_conv_split /=. @@ -936,7 +959,7 @@ Proof. apply: fsdist_ext => a; rewrite -[LHS]Scaled1RK. rewrite (S1_proj_Convn_finType [the {affine _ -> _} of fsdist_eval a]). rewrite big_scaleR fsdistjoinE big_seq_fsetE; apply eq_bigr => -[d dD] _. -by rewrite (scaleR_scalept _ (FDist.ge0 _ _)) fdist_of_fsE Scaled1RK. +by rewrite (scaleR_scalept _ (fdist_Rge0 _ _)) fdist_of_fsE Scaled1RK. Qed. Section lemmas_for_probability_monad_and_adjunction. diff --git a/probability/graphoid.v b/probability/graphoid.v index 0da40735..7d423125 100644 --- a/probability/graphoid.v +++ b/probability/graphoid.v @@ -1,6 +1,6 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg matrix. +From mathcomp Require Import all_ssreflect ssralg matrix. Require Import Reals. From mathcomp Require Import Rstruct. Require Import ssrR Reals_ext logb ssr_ext ssralg_ext bigop_ext Rbigop fdist. @@ -64,8 +64,7 @@ End prop. End QuadA23. Section cinde_rv_prop. - -Variables (U : finType) (P : fdist U) (A B C D : finType). +Variables (U : finType) (P : {fdist U}) (A B C D : finType). Variables (X : {RV P -> A}) (Y : {RV P -> B}) (Z : {RV P -> C}) (W : {RV P -> D}). Lemma cinde_drv_2C : P |= X _|_ [% Y, W] | Z -> P |= X _|_ [% W, Y] | Z. @@ -84,7 +83,7 @@ End cinde_rv_prop. Section symmetry. -Variable (U : finType) (P : fdist U). +Variable (U : finType) (P : {fdist U}). Variables (A B C : finType) (X : {RV P -> A}) (Y : {RV P -> B}) (Z : {RV P -> C}). Lemma symmetry : P |= X _|_ Y | Z -> P |= Y _|_ X | Z. @@ -100,7 +99,7 @@ End symmetry. Section decomposition. -Variables (U : finType) (P : fdist U) (A B C D : finType). +Variables (U : finType) (P : {fdist U}) (A B C D : finType). Variables (X : {RV P -> A}) (Y : {RV P -> B}) (Z : {RV P -> C}) (W : {RV P -> D}). Lemma decomposition : P |= X _|_ [% Y, W] | Z -> P |= X _|_ Y | Z. @@ -122,7 +121,7 @@ End decomposition. Section weak_union. -Variables (U : finType) (P : fdist U) (A B C D : finType). +Variables (U : finType) (P : {fdist U}) (A B C D : finType). Variables (X : {RV P -> A}) (Y : {RV P -> B}) (Z : {RV P -> C}) (W : {RV P -> D}). Lemma weak_union : P |= X _|_ [% Y, W] | Z -> P |= X _|_ Y | [% Z, W]. @@ -146,7 +145,7 @@ End weak_union. Section contraction. -Variables (U : finType) (P : fdist U) (A B C D : finType). +Variables (U : finType) (P : {fdist U}) (A B C D : finType). Variables (X : {RV P -> A}) (Y : {RV P -> B}) (Z : {RV P -> C}) (W : {RV P -> D}). Lemma contraction : P |= X _|_ W | [% Z, Y] -> P |= X _|_ Y | Z -> P |= X _|_ [% Y, W] | Z. @@ -170,7 +169,7 @@ End contraction. (* Probabilistic Reasoning in Intelligent Systems: Networks of Plausible Inference, Pearl, p.88 *) Section derived_rules. -Variables (U : finType) (P : fdist U) (A B C D : finType). +Variables (U : finType) (P : {fdist U}) (A B C D : finType). Variables (X : {RV P -> A}) (Y : {RV P -> B}) (Z : {RV P -> C}) (W : {RV P -> D}). Lemma chaining_rule : P |= X _|_ Z | Y /\ P |= [% X, Y] _|_ W | Z -> P |= X _|_ W | Y. @@ -192,7 +191,7 @@ End derived_rules. Section intersection. -Variables (U : finType) (P : fdist U) (A B C D : finType). +Variables (U : finType) (P : {fdist U}) (A B C D : finType). Variables (X : {RV P -> A}) (Y : {RV P -> B}) (Z : {RV P -> C}) (W : {RV P -> D}). Hypothesis P0 : forall b c d, `Pr[ [% Y, Z, W] = (b, c, d) ] != 0. diff --git a/probability/jensen.v b/probability/jensen.v index a5889333..7b2b19fe 100644 --- a/probability/jensen.v +++ b/probability/jensen.v @@ -1,9 +1,9 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg matrix. +From mathcomp Require Import all_ssreflect ssralg matrix. From mathcomp Require Import boolp Rstruct. Require Import Reals. -Require Import ssrR Reals_ext ssr_ext ssralg_ext logb Rbigop. +Require Import ssrR Reals_ext ssr_ext realType_ext ssralg_ext logb Rbigop. Require Import fdist proba convex. (******************************************************************************) @@ -17,6 +17,9 @@ Import Prenex Implicits. Local Open Scope R_scope. Local Open Scope reals_ext_scope. Local Open Scope convex_scope. +Local Open Scope fdist_scope. + +Import GRing.Theory. Section jensen_inequality. @@ -25,16 +28,16 @@ Variable D : {convex_set R}. Hypothesis convex_f : convex_function_in D f. Variables A : finType. -Local Hint Resolve leRR : core. +Local Hint Resolve Rle_refl : core. -Lemma jensen_dist (r : A -> R) (X : fdist A) : +Lemma jensen_dist (r : A -> R) (X : {fdist A}) : (forall a, r a \in D) -> f (\sum_(a in A) X a * r a) <= \sum_(a in A) X a * f (r a). Proof. move=> HDr. apply (@proj1 _ (\sum_(a in fdist_supp X) X a * r a \in D)). rewrite [in X in _ <= X]sum_fdist_supp [in X in X <= _]sum_fdist_supp /=. -apply: (@fdist_ind A (fun X => +apply: (@fdist_ind _ A (fun X => f (\sum_(a in fdist_supp X) X a * r a) <= \sum_(a in fdist_supp X) X a * f (r a) /\ _)) => //. move=> n IH {}X b cardA Hb. @@ -49,7 +52,7 @@ have HsumD1 q: rewrite (eq_bigr (fun a => /(X b).~ * (X a * q a))); last first. move=> i; rewrite inE fdistD1E. case: ifP => Hi; first by rewrite eqxx. - by rewrite /Rdiv mulRCA mulRA. + by rewrite mulRCA mulRA -divRE RdivE. by rewrite -big_distrr. have {HsumD1}HsumXD1 q: \sum_(a in fdist_supp X) X a * q a = @@ -73,7 +76,7 @@ Qed. Local Open Scope proba_scope. -Lemma Jensen (P : fdist A) (X : {RV P -> R}) : (forall x, X x \in D) -> +Lemma Jensen (P : {fdist A}) (X : {RV P -> R}) : (forall x, X x \in D) -> f (`E X) <= `E (f `o X). Proof. move=> H. @@ -99,7 +102,7 @@ rewrite /convex_function_in => x y t Dx Dy. apply /R_convex_function_atN/concave_f => //; by case: t. Qed. -Lemma jensen_dist_concave (r : A -> R) (X : fdist A) : +Lemma jensen_dist_concave (r : A -> R) (X : {fdist A}) : (forall x, r x \in D) -> \sum_(a in A) X a * f (r a) <= f (\sum_(a in A) X a * r a). Proof. diff --git a/probability/jfdist_cond.v b/probability/jfdist_cond.v index b12581e6..2f953dc3 100644 --- a/probability/jfdist_cond.v +++ b/probability/jfdist_cond.v @@ -1,6 +1,6 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup perm finalg matrix. +From mathcomp Require Import all_ssreflect ssralg matrix. From mathcomp Require boolp. From mathcomp Require Import Rstruct. Require Import Reals. @@ -117,7 +117,7 @@ End conditional_probability. Notation "\Pr_ P [ E | F ]" := (jcPr P E F) : proba_scope. Section jPr_Pr. -Variables (U : finType) (P : fdist U) (A B : finType). +Variables (U : finType) (P : {fdist U}) (A B : finType). Variables (X : {RV P -> A}) (Y : {RV P -> B}) (E : {set A}) (F : {set B}). Lemma jPr_Pr : \Pr_(`p_[% X, Y]) [E | F] = `Pr[X \in E |Y \in F]. @@ -277,20 +277,22 @@ by apply/eqP/eqP => [[] -> | ->]. Qed. Section jfdist_cond0. -Variables (A B : finType) (PQ : {fdist A * B}) (a : A). +Variables (A B : finType) (PQ : {fdist (A * B)}) (a : A). Hypothesis Ha : PQ`1 a != 0. Let f := [ffun b => \Pr_(fdistX PQ) [[set b] | [set a]]]. Let f0 b : 0 <= f b. Proof. rewrite ffunE; exact: jcPr_ge0. Qed. +Let f0' b : (0 <= f b)%O. Proof. by apply/RleP. Qed. + Let f1 : \sum_(b in B) f b = 1. Proof. under eq_bigr do rewrite ffunE. by rewrite /jcPr -big_distrl /= PrX_snd mulRV // Pr_set1 fdistX2. Qed. -Definition jfdist_cond0 : {fdist B} := locked (FDist.make f0 f1). +Definition jfdist_cond0 : {fdist B} := locked (@FDist.make _ _ _ f0' f1). Lemma jfdist_cond0E b : jfdist_cond0 b = \Pr_(fdistX PQ) [[set b] | [set a]]. Proof. by rewrite /jfdist_cond0; unlock; rewrite ffunE. Qed. @@ -327,13 +329,13 @@ Qed. End jfdist_cond. Notation "P `(| a ')'" := (jfdist_cond P a). -Lemma cPr_1 (U : finType) (P : fdist U) (A B : finType) +Lemma cPr_1 (U : finType) (P : {fdist U}) (A B : finType) (X : {RV P -> A}) (Y : {RV P -> B}) a : `Pr[X = a] != 0 -> \sum_(b <- fin_img Y) `Pr[ Y = b | X = a ] = 1. Proof. rewrite -pr_eq_set1 pr_inE' Pr_set1 -{1}(fst_RV2 _ Y) => Xa0. set Q := `p_[% X, Y] `(| a ). -rewrite -(FDist.f1 Q) [in RHS](bigID (mem (fin_img Y))) /=. +rewrite -[RHS](FDist.f1 Q) [in RHS](bigID (mem (fin_img Y))) /=. rewrite [X in _ = _ + X](eq_bigr (fun=> 0)); last first. move=> b bY. rewrite /Q jfdist_condE // /jcPr /Pr !(big_setX,big_set1) /= fdistXE fdistX2 fst_RV2. @@ -353,11 +355,11 @@ Qed. Lemma jcPr_1 (A B : finType) (P : {fdist A * B}) a : P`1 a != 0 -> \sum_(b in B) \Pr_(fdistX P)[ [set b] | [set a] ] = 1. Proof. -move=> Xa0; rewrite -(FDist.f1 (P `(| a ))); apply eq_bigr => b _. +move=> Xa0; rewrite -[RHS](FDist.f1 (P `(| a ))); apply eq_bigr => b _. by rewrite jfdist_condE. Qed. -Lemma jfdist_cond_prod (A B : finType) (P : fdist A) (W : A -> fdist B) (a : A) : +Lemma jfdist_cond_prod (A B : finType) (P : {fdist A}) (W : A -> {fdist B}) (a : A) : (P `X W)`1 a != 0 -> W a = (P `X W) `(| a ). Proof. move=> a0; apply/fdist_ext => b. @@ -366,7 +368,7 @@ rewrite fdist_prodE /= /Rdiv mulRAC mulRV ?mul1R //. by move: a0; rewrite fdist_prod1. Qed. -Lemma jcPr_fdistX_prod (A B : finType) (P : fdist A) (W : A -> fdist B) a b : +Lemma jcPr_fdistX_prod (A B : finType) (P : {fdist A}) (W : A -> {fdist B}) a b : P a <> 0 -> \Pr_(fdistX (P `X W))[ [set b] | [set a] ] = W a b. Proof. move=> Pxa. @@ -379,14 +381,14 @@ Variables (A B : finType). Definition fdist_split (PQ : {fdist A * B}) := (PQ`1, fun x => PQ `(| x )). -Lemma fdist_prodK : cancel fdist_split (uncurry (@fdist_prod A B)). +Lemma fdist_prodK : cancel fdist_split (uncurry (@fdist_prod _ A B)). Proof. move=> PQ; apply/fdist_ext => ab; rewrite fdist_prodE. have [Ha|Ha] := eqVneq (PQ`1 ab.1) 0. - rewrite Ha mul0R; apply/esym/(dominatesE (Prod_dominates_Joint PQ)). - by rewrite fdist_prodE Ha mul0R. -rewrite jfdist_condE // -fdistX2 mulRC. -rewrite -(Pr_set1 _ ab.1) -jproduct_rule setX1 Pr_set1 fdistXE. + rewrite Ha GRing.mul0r; apply/esym/(dominatesE (Prod_dominates_Joint PQ)). + by rewrite fdist_prodE Ha GRing.mul0r. +rewrite jfdist_condE // -fdistX2 GRing.mulrC. +rewrite -(Pr_set1 _ ab.1) -RmultE -jproduct_rule setX1 Pr_set1 fdistXE. by case ab. Qed. diff --git a/probability/ln_facts.v b/probability/ln_facts.v index 0882110e..2fc4870a 100644 --- a/probability/ln_facts.v +++ b/probability/ln_facts.v @@ -1,10 +1,10 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect. +From mathcomp Require Import all_ssreflect ssralg ssrnum. From mathcomp Require boolp. From mathcomp Require Import Rstruct. Require Import Reals Lra. -Require Import ssrR Reals_ext Ranalysis_ext logb convex. +Require Import ssrR realType_ext Reals_ext Ranalysis_ext logb convex. (******************************************************************************) (* Results about the Analysis of ln *) @@ -27,7 +27,7 @@ Import Prenex Implicits. Local Open Scope R_scope. -Import Order.Theory. +Import Order.Theory GRing.Theory Num.Theory. Section ln_id_sect. @@ -90,7 +90,8 @@ Proof. case: (ltgtP x 1) => [| |] x1 x0. - by apply/ltRW/ln_idlt0_xlt1; split=> //; apply/RltP. - by apply/ltRW/ln_idlt0_xgt1 => //; exact/RltP. -- by rewrite x1 /ln_id ln_1 2!subRR; exact/leRR. +- rewrite x1 /ln_id ln_1 2!subRR. + by apply/RleP; rewrite lexx. Qed. Lemma ln_id_cmp x : 0 < x -> ln x <= x - 1. @@ -124,7 +125,7 @@ Section xlnx_sect. Section xlnx. -Definition xlnx := fun x => if 0 if (0 < x)%mcR then x * ln x else 0. Lemma xlnx_0 : xlnx 0 = 0. Proof. rewrite /xlnx mul0R; by case : ifP. Qed. @@ -136,7 +137,7 @@ Lemma xlnx_neg x : 0 < x < 1 -> xlnx x < 0. Proof. case => lt0x ltx1. rewrite /xlnx. -have -> : 0 : (0 < x)%mcR ; first exact/RltP. rewrite -(oppRK 0) ltR_oppr oppR0 -mulRN. apply mulR_gt0 => //. rewrite ltR_oppr oppR0. @@ -158,14 +159,14 @@ case (total_order_T 0 r) ; first case ; move=> Hcase. exists (Rmin k r); split; first exact/Rlt_gt/Rmin_pos. - move=> x ; rewrite /D_x ; move => [[_ Hx1] Hx2]. rewrite /xlnx. - have -> : 0 : (0 < x)%mcR. + apply/RltP. + rewrite -(addR0 x) -{1}(subRR r) addRA addRAC. apply (@leR_ltR_trans ((x + - r) + `| x + - r |)). rewrite addRC -leR_subl_addr sub0R -normRN; exact: Rle_abs. rewrite /R_dist in Hx2. - apply/ltR_add2l/(@ltR_leR_trans (Rmin k r)) => //; exact: geR_minr. - have -> : 0 //; exact: geR_minr. + have -> : (0 < r)%mcR by apply/RltP. apply Hk. split => //. exact/(ltR_leR_trans Hx2)/geR_minl. @@ -173,8 +174,8 @@ case (total_order_T 0 r) ; first case ; move=> Hcase. exists (exp (- 2 * / eps)). split ; first exact: exp_pos. move=> x; rewrite /R_dist subR0; case=> Hx1 Hx2. - rewrite /xlnx ltRR'. - case: ifPn => Hcase; move/ltRP in Hcase. + rewrite /xlnx ltxx. + case: ifPn => /RltP Hcase. + rewrite (geR0_norm _ (ltRW Hcase)) in Hx2. rewrite subR0 -{1}(exp_ln _ Hcase). set X := ln x. @@ -214,13 +215,13 @@ case (total_order_T 0 r) ; first case ; move=> Hcase. - exists (- r); split; first exact/oppR_gt0. move=> x [[_ Hx1] Hx2]. rewrite /R_dist /xlnx. - have -> : 0 : (0 < x)%mcR = false. + apply/RltP/leRNgt. rewrite -(addR0 x) -{1}(subRR r) addRA addRAC. apply (@leR_trans ((x + - r) - `| x + - r |)). apply/leR_add2l/ltRW; by rewrite ltR_oppr. exact/Rle_minus/Rle_abs. - have -> : 0 : (0 < r)%mcR = false by apply/negbTE; rewrite -leNgt; apply/RleP/ltRW. by rewrite subRR normR0. Qed. @@ -242,7 +243,7 @@ by apply derivable_pt_ln. Defined. Lemma xlnx_total_xlnx x : 0 < x -> xlnx x = xlnx_total x. -Proof. by rewrite /xlnx /f => /ltRP ->. Qed. +Proof. by rewrite /xlnx /f => /RltP ->. Qed. Lemma derivable_pt_xlnx x (x_pos : 0 < x) : derivable_pt xlnx x. Proof. apply (@derivable_f_eq_g _ _ x 0 xlnx_total_xlnx x_pos (derivable_xlnx_total x_pos)). Defined. @@ -288,7 +289,7 @@ case/boolP : (x == 0) => [/eqP ->|x0]. - rewrite xlnx_0; apply xlnx_neg. exact: (conj (@leR_ltR_trans x _ _ _ _) (leR_ltR_trans y2 ltRinve1)). - rewrite -[X in _ < X]oppRK ltR_oppr. - have {}x0 : 0 < x by apply/ltRP; rewrite lt0R x0; exact/leRP. + have {}x0 : 0 < x by apply/RltP; rewrite lt0r x0; exact/RleP. have {x1 y1}y0 : 0 < y by exact: (@ltR_trans x). exact: (pderive_increasing (exp_pos _) xlnx_sdecreasing_0_Rinv_e_helper). Qed. @@ -297,7 +298,8 @@ Lemma xlnx_decreasing_0_Rinv_e x y : 0 <= x <= exp (-1) -> 0 <= y <= exp (-1) -> x <= y -> xlnx y <= xlnx x. Proof. move=> Hx Hy Hxy. -case/boolP : (x == y) => [/eqP ->|/eqP H]; first exact/leRR. +case/boolP : (x == y) => [/eqP ->|/eqP H]. + by apply/RleP; rewrite lexx. by apply/ltRW/xlnx_sdecreasing_0_Rinv_e => //; rewrite ltR_neqAle. Qed. @@ -384,9 +386,11 @@ Proof. move=> [Hx1 Hx2]. apply Rge_le, Rminus_ge, Rle_ge. rewrite -diff_xlnx_0 -/(diff_xlnx x). -case/boolP : (0 == x) => [/eqP ->|/eqP xnot0]; first exact/leRR. +case/boolP : (0 == x) => [/eqP ->|/eqP xnot0]. + by apply/RleP; rewrite lexx. apply/ltRW/diff_xlnx_sincreasing_0_Rinv_e2 => //. - split; [exact/leRR | exact/ltRW/exp_pos]. + split; [ | exact/ltRW/exp_pos]. + by apply/RleP; rewrite lexx. by rewrite ltR_neqAle. Qed. @@ -450,23 +454,23 @@ Lemma xlnx_delta_bound eps : 0 < eps <= exp (-2) -> forall x, 0 <= x <= 1 - eps -> `| xlnx_delta eps x | <= - xlnx eps. Proof. move=> [Heps1 Heps2] x [Hx1 Hx2]. -apply/leRP; rewrite leR_Rabsl oppRK; apply/andP; split; apply/leRP. -- rewrite (_ : xlnx eps = xlnx_delta eps 0); last first. +apply/RleP; rewrite ler_norml; apply/andP; split; apply/RleP. +- rewrite RoppE opprK (_ : xlnx eps = xlnx_delta eps 0); last first. by rewrite /xlnx_delta add0R xlnx_0 subR0. - case/boolP : (0 == x) => [/eqP <-|/eqP xnot0]; first exact/leRR. + have [->|xnot0] := eqVneq x 0; first by apply/RleP; rewrite lexx. apply/ltRW/increasing_xlnx_delta => //. + exact: (conj Heps1 (leR_ltR_trans Heps2 ltRinve21)). - + split; by [apply (@leR_trans x) | exact: leRR]. - + by rewrite ltR_neqAle. -- apply (@leR_trans (xlnx_delta eps (1 - eps))). - case/boolP : (x == 1 - eps) => [/eqP ->|/eqP xnot0]; first exact/leRR. + + split; by [apply (@leR_trans x) |]. + + by apply/RltP; rewrite lt0r xnot0/=; exact/RleP. +- apply: (@leR_trans (xlnx_delta eps (1 - eps))). + have [->|xnot0] := eqVneq x (1 - eps); first by apply/RleP; rewrite lexx. apply/ltRW/increasing_xlnx_delta => //. + exact: (conj Heps1 (leR_ltR_trans Heps2 ltRinve21)). - + split; by [apply (@leR_trans x) | exact: leRR]. - + by rewrite ltR_neqAle. + + split; [by apply (@leR_trans x) | ]. + by apply/RleP; rewrite lexx. + + by apply/RltP; rewrite lt_neqAle xnot0/=; exact/RleP. rewrite /xlnx_delta subRK xlnx_1 sub0R leR_oppr oppRK. - apply xlnx_ineq. - split => //; exact: ltRW. + by apply: xlnx_ineq; split => //; apply/RleP/ltW/RltP. Qed. Lemma Rabs_xlnx a (Ha : 0 <= a <= exp(-2)) x y : @@ -495,9 +499,10 @@ case : (Rtotal_order x y) ; last case ; move => Hcase. apply/ltRW/exp_increasing; lra. - subst x ; rewrite subRR normR0 leR_oppr oppR0. case/orP : (orbN (0 == a)); last move=> anot0. - by move=> /eqP <-; rewrite xlnx_0; exact: leRR. + move=> /eqP <-; rewrite xlnx_0. + by apply/RleP; rewrite lexx. apply/ltRW/xlnx_neg; split. - - apply/ltRP; rewrite lt0R eq_sym anot0; exact/leRP/(proj1 Ha). + - by apply/RltP; rewrite lt0r eq_sym anot0; exact/RleP/(proj1 Ha). - exact: (leR_ltR_trans (proj2 Ha) ltRinve21). - apply Rgt_lt in Hcase. have Haux : x = y + `| x - y | by rewrite gtR0_norm ?subR_gt0 // subRKC. @@ -536,7 +541,7 @@ rewrite /log /Log (_ : (fun x0 => ln x0 / ln 2) = apply/derivable_pt_scal/derivable_pt_ln/(leR_ltR_trans a0); by case: Hx. Qed. -Lemma ln_concave_at_gt0 x y (t : prob) : x < y -> +Lemma ln_concave_at_gt0 x y (t : {prob R}) : x < y -> 0 < x -> 0 < y -> concave_function_at ln x y t. Proof. move=> xy x0 y0; apply RNconcave_function_at. @@ -576,26 +581,29 @@ Qed. Local Open Scope reals_ext_scope. -Lemma log_concave_at_gt0W x y (t : prob) : x < y -> +Lemma log_concave_at_gt0W x y (t : {prob R}) : x < y -> 0 < x -> 0 < y -> concave_function_at log x y t. Proof. move=> xy x0 y0; rewrite /log /Log. apply concave_function_atN; [exact: ln_concave_at_gt0 | exact/ltRW/invR_gt0/ln2_gt0]. Qed. -Lemma log_concave_at_gt0 x y (t : prob) : 0 < x -> 0 < y -> concave_function_at log x y t. +Lemma log_concave_at_gt0 x y (t : {prob R}) : 0 < x -> 0 < y -> concave_function_at log x y t. Proof. move=> x0 y0. -case/boolP : (x [/ltRP xy|]. +case/boolP : (x < y)%mcR => [/RltP xy|]. exact: log_concave_at_gt0W. -rewrite -leRNgt' => /leRP; rewrite leR_eqVlt => -[->|yx]. -exact: concave_function_atxx. -rewrite (probK t); apply: concavef_at_onem => //; exact: log_concave_at_gt0W. +rewrite -leNgt le_eqVlt => /predU1P[->|yx]. + exact: concave_function_atxx. +rewrite (probK t); apply: concavef_at_onem => //. + exact/RltP. +by apply: log_concave_at_gt0W => //; exact/RltP. Qed. Lemma log_concave : concave_function_in Rpos_interval log. Proof. -by move=> x y t; rewrite !classical_sets.in_setE => Hx Hy; apply log_concave_at_gt0. +move=> x y t; rewrite !classical_sets.in_setE(*TODO: import?*) => Hx Hy. +exact: log_concave_at_gt0. Qed. End log_concave. diff --git a/probability/log_sum.v b/probability/log_sum.v index 145bc33c..df354b65 100644 --- a/probability/log_sum.v +++ b/probability/log_sum.v @@ -1,74 +1,80 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect. +From mathcomp Require Import all_ssreflect all_algebra. Require Import Reals Lra. -From mathcomp Require Import Rstruct. +From mathcomp Require Import Rstruct lra. Require Import ssrR Reals_ext Ranalysis_ext logb ln_facts bigop_ext Rbigop. (******************************************************************************) (* The log-sum Inequality *) (******************************************************************************) +Import GRing.Theory Num.Theory Order.TTheory. + Local Open Scope reals_ext_scope. Local Open Scope R_scope. Local Notation "'\sum_{' C '}' f" := (\sum_(a | a \in C) f a) (at level 10, format "\sum_{ C } f"). -Definition log_sum_stmt {A : finType} (C : {set A}) (f g : A ->R+) := +Definition log_sum_stmt {A : finType} (C : {set A}) (f g : {ffun A -> R}) := + (forall x, 0 <= f x) -> + (forall x, 0 <= g x) -> f `<< g -> \sum_{C} f * log (\sum_{C} f / \sum_{C} g) <= \sum_(a | a \in C) f a * log (f a / g a). -Lemma log_sum1 {A : finType} (C : {set A}) (f g : A ->R+) : +Lemma log_sum1 {A : finType} (C : {set A}) (f g : {ffun A -> R}) : (forall a, a \in C -> 0 < f a) -> log_sum_stmt C f g. Proof. -move=> fspos fg. +move=> fspos f0 g0 fg. case/boolP : (C == set0) => [ /eqP -> | Hc]. - rewrite !big_set0 mul0R; exact/leRR. + by apply/RleP; rewrite !big_set0 mul0R lexx. have gspos : forall a, a \in C -> 0 < g a. - move=> a a_C; case/Rle_lt_or_eq_dec : ((nneg_finfun_ge0 g) a) => //. - move=> /esym/(dominatesE fg) abs. + move=> a a_C. case (g0 a) => //. + move=>/esym/(dominatesE fg) abs. by move: (fspos _ a_C); rewrite abs => /ltRR. have Fnot0 : \sum_{ C } f != 0. - apply/eqP => /psumR_eq0P abs. + apply/eqP => /psumr_eq0P abs. case/set0Pn : Hc => a aC. - move: (fspos _ aC); rewrite abs //; last by move=> b bC; apply/ltRW/fspos. - by move/ltRR. + move: (fspos _ aC); rewrite abs //. + by move=> /RltP; rewrite ltxx. + by move=> i iC; exact/RleP. have Gnot0 : \sum_{ C } g != 0. - apply/eqP => /psumR_eq0P abs. + apply/eqP => /psumr_eq0P abs. case/set0Pn : Hc => a aC. - move: (gspos _ aC); rewrite abs //; last by move=> b bC; apply/ltRW/gspos. - by move/ltRR. -wlog : Fnot0 g Gnot0 fg gspos / \sum_{ C } f = \sum_{ C } g. + move: (gspos _ aC); rewrite abs //. + by move=> /RltP; rewrite ltxx. + by move=> i iC; exact/RleP. +wlog : Fnot0 g g0 Gnot0 fg gspos / \sum_{ C } f = \sum_{ C } g. move=> Hwlog. - set k := \sum_{ C } f / \sum_{ C } g. + set k := (\sum_{ C } f / \sum_{ C } g). have Fspos : 0 < \sum_{ C } f. - suff Fpos : 0 <= \sum_{ C } f by apply/ltRP; rewrite lt0R Fnot0; exact/leRP. + suff Fpos : 0 <= \sum_{ C } f by apply/RltP; rewrite lt0r Fnot0; exact/RleP. by apply: sumR_ge0 => ? ?; exact/ltRW/fspos. have Gspos : 0 < \sum_{ C } g. - suff Gpocs : 0 <= \sum_{ C } g by apply/ltRP; rewrite lt0R Gnot0; exact/leRP. + suff Gpocs : 0 <= \sum_{ C } g by apply/RltP; rewrite lt0r Gnot0; exact/RleP. by apply: sumR_ge0 => ? ?; exact/ltRW/gspos. - have kspos : 0 < k by apply divR_gt0. - have kg_pos : [forall a, 0 k * g x] a]. - apply/forallP => a. - by rewrite ffunE; apply/leRP/mulR_ge0; [exact: ltRW|exact: nneg_finfun_ge0]. - have kabs_con : f `<< mkNNFinfun kg_pos. - by apply/dominates_scale => //; exact/gtR_eqF. - have kgspos : forall a, a \in C -> 0 < (mkNNFinfun kg_pos) a. + have kspos : 0 < k by exact: divR_gt0. + set kg := [ffun x => k * g x]. + have kg_pos : forall a, 0 <= kg a. + by move=> a; rewrite /kg /= ffunE; apply mulR_ge0 => //; exact: ltRW. + have kabs_con : f `<< kg. + apply/dominates_scale => //; exact/gtR_eqF. + have kgspos : forall a, a \in C -> 0 < kg a. by move=> a a_C; rewrite ffunE; apply mulR_gt0 => //; exact: gspos. - have Hkg : \sum_{C} (mkNNFinfun kg_pos) = \sum_{C} f. + have Hkg : \sum_{C} kg = \sum_{C} f. transitivity (\sum_(a in C) k * g a). by apply eq_bigr => a aC; rewrite /= ffunE. by rewrite -big_distrr /= /k /Rdiv -mulRA mulRC mulVR // mul1R. - have Htmp : \sum_{ C } (mkNNFinfun kg_pos) != 0. + have Htmp : \sum_{ C } kg != 0. rewrite /=. evar (h : A -> R); rewrite (eq_bigr h); last first. by move=> a aC; rewrite ffunE /h; reflexivity. rewrite {}/h (_ : \sum_(i in C) _ = \sum_{C} f) // -Hkg. by apply eq_bigr => a aC /=; rewrite ffunE. symmetry in Hkg. - move: {Hwlog}(Hwlog Fnot0 (@mkNNFinfun _ _ kg_pos) Htmp kabs_con kgspos Hkg) => /= Hwlog. + move: {Hwlog}(Hwlog Fnot0 kg kg_pos Htmp kabs_con kgspos Hkg) => /= Hwlog. rewrite Hkg {1}/Rdiv mulRV // /log Log_1 mulR0 in Hwlog. set rhs := \sum_(_ | _) _ in Hwlog. rewrite (_ : rhs = \sum_(a | a \in C) (f a * log (f a / g a) - f a * log k)) in Hwlog; last first. @@ -85,8 +91,7 @@ wlog : Fnot0 g Gnot0 fg gspos / \sum_{ C } f = \sum_{ C } g. by apply invR_gt0 => //; apply gspos. by rewrite LogV; [field | apply gspos]. rewrite big_split /= -big_morph_oppR -big_distrl /= in Hwlog. - have : forall a b, 0 <= a + - b -> b <= a by move=> *; lra. - exact. + by rewrite -subR_ge0. move=> Htmp; rewrite Htmp. rewrite /Rdiv mulRV; last by rewrite -Htmp. rewrite /log Log_1 mulR0. @@ -101,8 +106,9 @@ suff : 0 <= \sum_(a | a \in C) f a * ln (f a / g a). by apply mulR_ge0 => //; exact/invR_ge0. apply (@leR_trans (\sum_(a | a \in C) f a * (1 - g a / f a))). apply (@leR_trans (\sum_(a | a \in C) (f a - g a))). - rewrite big_split /= -big_morph_oppR Htmp addRN; exact/leRR. - apply Req_le, eq_bigr => a a_C. + rewrite big_split /= -big_morph_oppR Htmp addRN. + by apply/RleP; rewrite lexx. + apply/Req_le/eq_bigr => a a_C. rewrite mulRDr mulR1 mulRN. case: (Req_EM_T (g a) 0) => [->|ga_not_0]. by rewrite div0R mulR0. @@ -120,10 +126,10 @@ apply Req_le. by field; exact/eqP/gtR_eqF/(fspos _ C_a). Qed. -Lemma log_sum {A : finType} (C : {set A}) (f g : A ->R+) : +Lemma log_sum {A : finType} (C : {set A}) (f g : {ffun A -> R}) : log_sum_stmt C f g. Proof. -move=> fg. +move=> f0 g0 fg. set D := [set a | (a \in C) && (f a != 0)]. suff : \sum_{D} f * log (\sum_{D} f / \sum_{D} g) <= \sum_(a | a \in D) f a * log (f a / g a). @@ -152,32 +158,32 @@ suff : \sum_{D} f * log (\sum_{D} f / \sum_{D} g) <= by rewrite big_const iter_addR mulR0 add0R. rewrite -H1 in H. have pos_F : 0 <= \sum_{C} f. - by apply sumR_ge0 => ? ?; exact: nneg_finfun_ge0. + by apply sumR_ge0 => ? ?. apply (@leR_trans (\sum_{C} f * log (\sum_{C} f / \sum_{D} g))). case/Rle_lt_or_eq_dec : pos_F => pos_F; last first. - by rewrite -pos_F !mul0R; exact/leRR. + by rewrite -pos_F !mul0R. have H2 : 0 <= \sum_(a | a \in D) g a. - by apply: sumR_ge0 => ? _; exact: nneg_finfun_ge0. + by apply: sumR_ge0 => ? _. case/Rle_lt_or_eq_dec : H2 => H2; last first. have : 0 = \sum_{D} f. transitivity (\sum_(a | a \in D) 0). by rewrite big_const iter_addR mulR0. - apply eq_bigr => a a_C1. - rewrite (dominatesE fg) // (proj1 (@psumR_eq0P _ (mem D) _ _)) // => ? ?. - exact/nneg_finfun_ge0. + apply: eq_bigr => a a_C1. + rewrite (dominatesE fg) //. + apply/(@psumr_eq0P _ _ (mem D) g) => // i _. + exact/RleP. move=> abs; rewrite -abs in H1; rewrite H1 in pos_F. by move/ltRR : pos_F. have H3 : 0 < \sum_(a | a \in C) g a. rewrite setUC in DUD'. rewrite DUD' (big_union _ g DID') /=. - apply addR_gt0wr => //. - by apply: sumR_ge0 => *; exact/nneg_finfun_ge0. + by apply: addR_gt0wr => //; exact: sumR_ge0. apply/(leR_wpmul2l (ltRW pos_F))/Log_increasing_le => //. apply divR_gt0 => //; by rewrite -HG. apply/(leR_wpmul2l (ltRW pos_F))/leR_inv => //. rewrite setUC in DUD'. rewrite DUD' (big_union _ g DID') /= -[X in X <= _]add0R; apply leR_add2r. - by apply: sumR_ge0 => ? ?; exact/nneg_finfun_ge0. + by apply: sumR_ge0 => ? ?. apply: (leR_trans H). rewrite setUC in DUD'. rewrite DUD' (big_union _ (fun a => f a * log (f a / g a)) DID') /=. @@ -186,10 +192,10 @@ suff : \sum_{D} f * log (\sum_{D} f / \sum_{D} g) <= apply eq_bigr => a. by rewrite /D' in_set => /andP[a_C /eqP ->]; rewrite mul0R. by rewrite big_const iter_addR mulR0. - by rewrite add0R; exact/leRR. -apply log_sum1 => // a. + by apply/RleP; rewrite add0R lexx. +apply: log_sum1 => // a. rewrite /C1 in_set. case/andP => a_C fa_not_0. -case/Rle_lt_or_eq_dec: (nneg_finfun_ge0 f a) => // abs. +case(f0 a) => // abs. by rewrite abs eqxx in fa_not_0. Qed. diff --git a/probability/necset.v b/probability/necset.v index c721a464..8aea505e 100644 --- a/probability/necset.v +++ b/probability/necset.v @@ -5,7 +5,7 @@ Require Import Reals. From mathcomp Require Import all_ssreflect. From mathcomp Require Import boolp classical_sets Rstruct. From mathcomp Require Import finmap. -Require Import Reals_ext classical_sets_ext Rbigop ssrR fdist fsdist. +Require Import Reals_ext realType_ext classical_sets_ext Rbigop ssrR fdist fsdist. Require Import convex. (******************************************************************************) @@ -188,7 +188,7 @@ Definition conv_pt_set (p : prob) (x : L) (Y : set L) := Definition conv_pt_set (p : prob) (x : L) (Y : set L) := (fun y => x <| p |> y) @` Y. *) -Definition conv_pt_set (p : prob) (x : L) (Y : set L) := +Definition conv_pt_set (p : {prob R}) (x : L) (Y : set L) := locked (fun y => x <| p |> y) @` Y. Local Notation "x <| p |>: Y" := (conv_pt_set p x Y). @@ -225,7 +225,7 @@ Proof. by case=> x ?; rewrite conv_pt_setE=> -[] y ? <-; exists x, y. Qed. -Lemma convC_set p (X Y : set A) : X :<| p |>: Y = Y :<| p.~%:pr |>: X. +Lemma convC_set p (X Y : set A) : X :<| p |>: Y = Y :<| (Prob.p p).~%:pr |>: X. Proof. by rewrite eqEsubset; split=> u; case=> x Xx; rewrite conv_pt_setE => -[] y Yy <-; @@ -250,7 +250,7 @@ rewrite eqEsubset; split=> u. - by case=> xy -[] x Xx xYxy; exists x=> //; rewrite convA_pt_set; exists xy. Qed. -Lemma conv_cset1 (p : prob) (x y : A) : +Lemma conv_cset1 (p : {prob R}) (x y : A) : [set x] :<|p|>: [set y] = [set x <|p|> y]. Proof. rewrite eqEsubset; split=> [u|u ->]; last exact: conv_in_conv_set. @@ -283,7 +283,7 @@ rewrite convC_set /= (_ : 0.~%:pr = 1%:pr) ?conv1_set //. by apply val_inj; rewrite /= onem0. Qed. -Definition probset := @setT prob. +Definition probset := @setT {prob R}. Definition natset := @setT nat. @@ -330,16 +330,16 @@ Fixpoint iter_conv_set_neq0 (X : neset A) (n : nat) : Canonical probset_neset := NESet.Pack (NESet.Mixin probset_neq0). Canonical natset_neset := NESet.Pack (NESet.Mixin natset_neq0). -Canonical conv_pt_set_neset (p : prob) (x : A) (Y : neset A) := +Canonical conv_pt_set_neset (p : {prob R}) (x : A) (Y : neset A) := NESet.Pack (NESet.Mixin (conv_pt_set_neq0 p x Y)). -Canonical conv_set_neset (p : prob) (X Y : neset A) := +Canonical conv_set_neset (p : {prob R}) (X Y : neset A) := NESet.Pack (NESet.Mixin (conv_set_neq0 p X Y)). Canonical oplus_conv_set_neset (X Y : neset A) := NESet.Pack (NESet.Mixin (oplus_conv_set_neq0 X Y)). Canonical iter_conv_set_neset (X : neset A) (n : nat) := NESet.Pack (NESet.Mixin (iter_conv_set_neq0 X n)). -Lemma conv_pt_cset_is_convex (p : prob) (x : A) (Y : {convex_set A}) : +Lemma conv_pt_cset_is_convex (p : {prob R}) (x : A) (Y : {convex_set A}) : is_convex_set (conv_pt_set p x Y). Proof. apply/asboolP=> u v q. @@ -348,10 +348,10 @@ rewrite -convDr; apply/imageP. by move/asboolP: (convex_setP Y); apply. Qed. -Canonical conv_pt_cset (p : prob) (x : A) (Y : {convex_set A}) := +Canonical conv_pt_cset (p : {prob R}) (x : A) (Y : {convex_set A}) := CSet.Pack (CSet.Mixin (conv_pt_cset_is_convex p x Y)). -Lemma conv_cset_is_convex (p : prob) (X Y : {convex_set A}) : +Lemma conv_cset_is_convex (p : {prob R}) (X Y : {convex_set A}) : is_convex_set (conv_set p X Y). Proof. apply/asboolP=> u v q. @@ -361,7 +361,7 @@ by rewrite convACA; apply/conv_in_conv_set; [move/asboolP: (convex_setP X); apply | move/asboolP: (convex_setP Y); apply]. Qed. -Canonical conv_cset (p : prob) (X Y : {convex_set A}) := +Canonical conv_cset (p : {prob R}) (X Y : {convex_set A}) := CSet.Pack (CSet.Mixin (conv_cset_is_convex p X Y)). Lemma oplus_conv_cset_is_convex (X Y : {convex_set A}) : @@ -401,11 +401,11 @@ Fixpoint iter_conv_cset_is_convex (X : {convex_set A}) (n : nat) : Canonical iter_conv_cset (X : {convex_set A}) (n : nat) := CSet.Pack (CSet.Mixin (iter_conv_cset_is_convex X n)). -Lemma conv_pt_set_monotone (p : prob) (x : A) (Y Y' : set A) : +Lemma conv_pt_set_monotone (p : {prob R}) (x : A) (Y Y' : set A) : Y `<=` Y' -> x <| p |>: Y `<=` x <| p |>: Y'. Proof. by move=> YY' u [] y /YY' Y'y <-; exists y. Qed. -Lemma conv_set_monotone (p : prob) (X Y Y' : set A) : +Lemma conv_set_monotone (p : {prob R}) (X Y Y' : set A) : Y `<=` Y' -> X :<| p |>: Y `<=` X :<| p |>: Y'. Proof. by move/conv_pt_set_monotone=> YY' u [] x Xx /YY' HY'; exists x. Qed. @@ -459,10 +459,10 @@ Lemma oplus_convC_set (X Y : set A) : oplus_conv_set X Y = oplus_conv_set Y X. Proof. suff H : forall X' Y', oplus_conv_set X' Y' `<=` oplus_conv_set Y' X' by rewrite eqEsubset; split => // /H. -by move=> {X} {Y} X Y u [] p _; rewrite convC_set => H; exists p.~%:pr. +by move=> {X} {Y} X Y u [] p _; rewrite convC_set => H; exists (Prob.p p).~%:pr. Qed. -Lemma convmm_cset (p : prob) (X : {convex_set A}) : X :<| p |>: X = X. +Lemma convmm_cset (p : {prob R}) (X : {convex_set A}) : X :<| p |>: X = X. Proof. rewrite eqEsubset; split=> [x /conv_in_conv_set'[] | x ?]. - by move=> x0 [] x1 [] ? [] ? ->; move/asboolP : (convex_setP X); apply. @@ -496,7 +496,7 @@ by move/subset_trans; apply; rewrite oplus_convmm_set_hull. Qed. (* tensorial strength for hull and conv_set *) -Lemma hull_conv_set_strr (p : prob) (X Y : set A) : +Lemma hull_conv_set_strr (p : {prob R}) (X Y : set A) : hull (X :<| p |>: hull Y) = hull (X :<| p |>: Y). Proof. apply hull_eqEsubset=> u. @@ -684,7 +684,7 @@ Local Open Scope latt_scope. Local Open Scope classical_set_scope. HB.mixin Record isSemiLattConv L of ConvexSpace L & SemiLattice L := { - lubDr : forall (p : prob) (x y z : L), + lubDr : forall (p : {prob R}) (x y z : L), conv p x (y [+] z) = (conv p x y) [+] (conv p x z) }. #[short(type=semiLattConvType)] @@ -743,7 +743,7 @@ End semilattconvtype_lemmas. HB.mixin Record isSemiCompSemiLattConv L of SemiCompSemiLatt L & ConvexSpace L := { - biglubDr : forall (p : prob) (x : L) (I : neset L), + biglubDr : forall (p : {prob R}) (x : L) (I : neset L), conv p x (|_| I) = |_| ((conv p x) @` I)%:ne }. @@ -787,7 +787,7 @@ Local Open Scope classical_set_scope. Variable L : semiCompSemiLattConvType. -Lemma biglubDl (p : prob) (X : neset L) (y : L) : +Lemma biglubDl (p : {prob R}) (X : neset L) (y : L) : |_| X <|p|> y = |_| ((fun x => x <|p|> y) @` X)%:ne. Proof. rewrite convC biglubDr; congr (|_| _); apply/neset_ext/eq_imagel=> x ?. @@ -928,13 +928,13 @@ Definition conv p (X Y : necset A) : necset A := locked Lemma convE p (X Y : necset A) : conv p X Y = conv_set p X Y :> set A. Proof. by rewrite /conv; unlock. Qed. -Lemma conv1 X Y : conv 1%:pr X Y = X. +Lemma conv1 X Y : conv 1%R%:pr X Y = X. Proof. by apply necset_ext; rewrite convE conv1_set. Qed. Lemma convmm p X : conv p X X = X. Proof. by apply necset_ext; rewrite convE convmm_cset. Qed. -Lemma convC p X Y : conv p X Y = conv p.~%:pr Y X. +Lemma convC p X Y : conv p X Y = conv (Prob.p p).~%:pr Y X. Proof. by apply necset_ext; rewrite !convE convC_set. Qed. Lemma convA p q X Y Z : @@ -1048,7 +1048,7 @@ Section def. Variable A : convType. Let L := necset A. -Let biglubDr' (p : prob) (X : L) (I : neset L) : +Let biglubDr' (p : {prob R}) (X : L) (I : neset L) : necset_convType.conv p X (|_| I) = |_| ((necset_convType.conv p X) @` I)%:ne. Proof. apply necset_ext => /=. @@ -1063,7 +1063,7 @@ congr hull; rewrite eqEsubset; split=> u /=. by case=> y Yy yXu; exists y=> //; exists Y. Qed. -Let lubDr' (p : prob) (x y z : L) : +Let lubDr' (p : {prob R}) (x y z : L) : x <|p|> (y [+] z) = (x <|p|> y) [+] (x <|p|> z). Proof. rewrite /conv /=; rewrite lubE biglubDr' lubE; congr (|_| _). diff --git a/probability/partition_inequality.v b/probability/partition_inequality.v index e21936eb..6774bdb9 100644 --- a/probability/partition_inequality.v +++ b/probability/partition_inequality.v @@ -1,10 +1,10 @@ -(* infotheo: information theory and error-correcting codes in Coq *) -(* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect. +(* infotheo: information theory and error-correcting codes in Coq *) +(* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) +From mathcomp Require Import all_ssreflect ssrnum. Require Import Reals Lra. From mathcomp Require Import Rstruct. -Require Import ssrR Reals_ext Ranalysis_ext ssr_ext logb ln_facts bigop_ext. -Require Import Rbigop fdist divergence log_sum variation_dist. +Require Import ssrR Rstruct_ext Reals_ext Ranalysis_ext ssr_ext logb ln_facts. +Require Import bigop_ext Rbigop fdist divergence log_sum variation_dist. (******************************************************************************) (* Partition inequality *) @@ -18,8 +18,11 @@ Unset Strict Implicit. Import Prenex Implicits. Local Open Scope divergence_scope. +Local Open Scope fdist_scope. Local Open Scope R_scope. +Import Num.Theory. + Local Notation "0" := (false). Local Notation "1" := (true). @@ -29,13 +32,13 @@ Variable A : finType. Variable A_ : bool -> {set A}. Hypothesis dis : A_ 0 :&: A_ 1 = set0. Hypothesis cov : A_ 0 :|: A_ 1 = [set: A]. -Variable P : fdist A. +Variable P : {fdist A}. Definition bipart_pmf := [ffun i => \sum_(a in A_ i) P a]. -Definition bipart : fdist [finType of bool]. -apply (@FDist.make _ bipart_pmf). -- by move=> a; rewrite ffunE; apply: sumR_ge0. +Definition bipart : {fdist [finType of bool]}. +apply (@FDist.make _ _ bipart_pmf). +- by move=> a; rewrite ffunE; apply: sumr_ge0. - rewrite big_bool /= /bipart_pmf /= !ffunE. transitivity (\sum_(a | (a \in A_ 0 :|: A_ 1)) P a). by rewrite [X in _ = X](@big_union _ _ _ _ (A_ 0) (A_ 1)) // -setI_eq0 setIC dis eqxx. @@ -52,7 +55,7 @@ Variable A : finType. Variable A_ : bool -> {set A}. Hypothesis dis : A_ 0 :&: A_ 1 = set0. Hypothesis cov : A_ 0 :|: A_ 1 = setT. -Variable P Q : fdist A. +Variable P Q : {fdist A}. Hypothesis P_dom_by_Q : P `<< Q. Let P_A := bipart dis cov P. @@ -68,7 +71,7 @@ have step2 : (\sum_(a in A_ 0) P a) * log ((\sum_(a in A_ 0) P a) / \sum_(a in A_ 0) Q a) + (\sum_(a in A_ 1) P a) * log ((\sum_(a in A_ 1) P a) / \sum_(a in A_ 1) Q a) <= \sum_(a in A_ 0) P a * log (P a / Q a) + \sum_(a in A_ 1) P a * log (P a / Q a). - apply leR_add; by apply log_sum. + apply: leR_add; by apply log_sum => //; move=> x; apply/RleP/FDist.ge0. apply: (leR_trans _ step2) => {step2}. rewrite [X in _ <= X](_ : _ = P_A 0 * log ((P_A 0) / (Q_A 0)) + P_A 1 * log ((P_A 1) / (Q_A 1))); last first. @@ -89,7 +92,7 @@ have [A0_P_neq0 | /esym A0_P_0] : {0 < P_A 0} + {0%R = P_A 0}. rewrite LogV //. apply Req_le; by field. - rewrite A1_P_0 !mul0R addR0; exact/Req_le. - * rewrite ffunE in A0_Q_0; move/psumR_eq0P in A0_Q_0. + * rewrite ffunE in A0_Q_0; move/psumr_eq0P in A0_Q_0. have {}A0_Q_0 : forall i : A, i \in A_ 0 -> P i = 0%R. move=> i ?; rewrite (dominatesE P_dom_by_Q) // A0_Q_0 // => a ?; exact/pos_ff_ge0. have Habs : P_A 0 = 0%R. @@ -99,20 +102,20 @@ have [A0_P_neq0 | /esym A0_P_0] : {0 < P_A 0} + {0%R = P_A 0}. by rewrite big_const iter_addR mulR0. by move: A0_P_neq0; rewrite Habs; move/ltRR. + have H2 : P_A 1 = 0%R. - rewrite ffunE in A1_Q_0; move/psumR_eq0P in A1_Q_0. + rewrite ffunE in A1_Q_0; move/psumr_eq0P in A1_Q_0. rewrite /bipart /= ffunE /bipart_pmf (eq_bigr (fun=> 0%R)). by rewrite big_const iter_addR mulR0. move=> a ?; rewrite (dominatesE P_dom_by_Q) // A1_Q_0 // => b ?; exact/pos_ff_ge0. rewrite H2 !mul0R !addR0. have H3 : Q_A 0 = 1%R. - rewrite -[X in X = _]addR0 -[X in _ + X = _]A1_Q_0 -(FDist.f1 Q). + rewrite -[X in X = _]addR0 -[X in _ + X = _]A1_Q_0 R1E -(FDist.f1 Q). rewrite !ffunE -big_union //. apply eq_bigl => i; by rewrite cov in_set inE. by rewrite -setI_eq0 -dis setIC. rewrite H3 /Rdiv /log LogM //; last lra. by rewrite LogV; [apply Req_le; field | lra]. - have H1 : P_A 1 = 1%R. - rewrite -[X in X = _]add0R -[X in X + _ = _]A0_P_0 -(FDist.f1 P). + rewrite -[X in X = _]add0R -[X in X + _ = _]A0_P_0 R1E -(FDist.f1 P). rewrite !ffunE -big_union //. apply eq_bigl => i; by rewrite cov in_set inE. by rewrite -setI_eq0 -dis setIC. @@ -124,7 +127,7 @@ have [A0_P_neq0 | /esym A0_P_0] : {0 < P_A 0} + {0%R = P_A 0}. exact/invR_gt0. rewrite /log LogV //; apply Req_le; by field. + (* contradiction H1 / Bi_true_Q_0 *) - rewrite ffunE in A1_Q_0; move/psumR_eq0P in A1_Q_0. + rewrite ffunE in A1_Q_0; move/psumr_eq0P in A1_Q_0. have : P_A 1 = 0%R. rewrite !ffunE /bipart /= /bipart_pmf (eq_bigr (fun=> 0%R)). by rewrite big_const iter_addR mulR0. diff --git a/probability/pinsker.v b/probability/pinsker.v index 3df36093..f16c1659 100644 --- a/probability/pinsker.v +++ b/probability/pinsker.v @@ -1,10 +1,11 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect. +From mathcomp Require Import all_ssreflect ssralg ssrnum. Require Import Reals Lra. -From mathcomp Require Import Rstruct. -Require Import ssrR Reals_ext Ranalysis_ext ssr_ext logb ln_facts bigop_ext. -Require Import Rbigop fdist divergence variation_dist partition_inequality. +From mathcomp Require Import mathcomp_extra Rstruct. +Require Import ssrR Rstruct_ext Reals_ext realType_ext Ranalysis_ext ssr_ext. +Require Import logb ln_facts bigop_ext convex Rbigop fdist divergence. +Require Import variation_dist partition_inequality. (******************************************************************************) (* Pinsker's Inequality *) @@ -18,7 +19,10 @@ Set Implicit Arguments. Unset Strict Implicit. Import Prenex Implicits. +Import Order.TTheory GRing.Theory Num.Theory. + Local Open Scope R_scope. +Local Open Scope fdist_scope. Definition pinsker_fun p c := fun q => p * log (div_fct (fun _ => p) id q) + @@ -30,10 +34,10 @@ Lemma derive_pinsker_fun (p : R) c : 0 < p < 1 -> Proof. move=> [H0p Hp1] q /= [Hq1 Hq2]. rewrite /pinsker_fun. -apply derivable_pt_minus. +apply: derivable_pt_minus. apply derivable_pt_plus. apply derivable_pt_mult. - apply derivable_pt_const. + exact: derivable_pt_const. apply derivable_pt_comp. apply derivable_pt_mult. apply derivable_pt_const. @@ -43,19 +47,17 @@ apply derivable_pt_minus. apply derivable_pt_Log. exact: divR_gt0. apply derivable_pt_mult. - apply derivable_pt_const. + exact: derivable_pt_const. apply derivable_pt_comp. apply derivable_pt_div. apply derivable_pt_const. apply derivable_pt_Rminus. move=> abs; lra. apply derivable_pt_Log. - apply divR_gt0 => //; lra. + by apply divR_gt0 => //; lra. apply derivable_pt_mult. - apply derivable_pt_const. -apply derivable_pt_comp. - apply derivable_pt_Rminus. -apply derivable_pt_pow. + exact: derivable_pt_const. +by apply: derivable_pt_comp; [exact: derivable_pt_Rminus|exact: derivable_pt_pow]. Defined. Definition pinsker_fun' p c := fun q => @@ -70,7 +72,9 @@ transitivity (derive_pt (pinsker_fun p c) q (@derive_pinsker_fun _ c Hp q Hq)). rewrite /pinsker_fun /derive_pinsker_fun. case: Hp => Hp1 Hp2. case: Hq => Hq1 Hq2. -rewrite !(derive_pt_minus,derive_pt_plus,derive_pt_comp,derive_pt_ln,derive_pt_const,derive_pt_mult,derive_pt_inv,derive_pt_id,derive_pt_div,derive_pt_pow). +rewrite !(derive_pt_minus,derive_pt_plus,derive_pt_comp,derive_pt_ln, + derive_pt_const,derive_pt_mult,derive_pt_inv,derive_pt_id,derive_pt_div, + derive_pt_pow). rewrite !(mul0R,mulR0,addR0,add0R,Rminus_0_l) /= (_ : INR 2 = 2) //. rewrite /pinsker_fun' /div_fct [X in _ = X]mulRBr. f_equal; last by field. @@ -106,9 +110,7 @@ apply derivable_pt_minus. apply derivable_pt_Log. rewrite /= in Hq0. decompose [and] Hq0; clear Hq0; lra. -apply derivable_pt_mult. - apply derivable_pt_const. -apply derivable_pt_pow. +by apply: derivable_pt_mult; [exact: derivable_pt_const|exact: derivable_pt_pow]. Defined. Lemma derive_pt_pinsker_function_spec c q0 (Hq0 : 0 <= q0 < 1) @@ -129,8 +131,10 @@ field. split; [exact/eqP/ln2_neq0|case: Hq0 => ? ? ?; lra]. Defined. -Lemma pinsker_fun_increasing_on_0_to_1 (c : R) (Hc : c <= / (2 * ln 2)) : forall x y, - 0 <= x < 1 -> 0 <= y < 1 -> x <= y -> pinsker_function_spec c x <= pinsker_function_spec c y. +Lemma pinsker_fun_increasing_on_0_to_1 (c : R) (Hc : c <= / (2 * ln 2)) : + forall x y, + 0 <= x < 1 -> 0 <= y < 1 -> x <= y -> + pinsker_function_spec c x <= pinsker_function_spec c y. Proof. apply pderive_increasing_closed_open with (pderivable_pinsker_function_spec c). lra. @@ -155,8 +159,8 @@ have H2 : -2 <= - 8 * t * (1 - t). rewrite !mulNR -mulRA. rewrite leR_oppr oppRK [X in _ <= X](_ : 2 = 8 * / 4); last by field. apply leR_wpmul2l; [lra | exact: x_x2_max]. -apply (@leR_trans (2 - 2)); first lra. -by apply leR_add; [exact/leRR | by rewrite -mulRA -mulNR mulRA]. +move: H2 => /RleP; rewrite -mulRA RmultE mulNr lerNl opprK. +by move=> /RleP; rewrite -!RmultE mulRA subR_ge0. Qed. Lemma pinsker_function_spec_pos c q : @@ -172,15 +176,14 @@ by case: Hc. Qed. Section pinsker_function_analysis. - -Variables p q : prob. +Variables p q : {prob R}. Lemma pinsker_fun_p c : pinsker_fun p c p = 0. Proof. rewrite /pinsker_fun /= /div_fct /comp subRR mul0R mulR0 subR0. -have [->|p0] := eqVneq p 0%:pr. +have [->|p0] := eqVneq p 0%coqR%:pr. by rewrite mul0R !subR0 add0R mul1R div1R invR1 /log Log_1. -have [->|p1] := eqVneq p 1%:pr. +have [->|p1] := eqVneq p 1%coqR%:pr. by rewrite divR1 /log Log_1 subRR mul0R mulR0 addR0. rewrite divRR; last by rewrite subR_eq0' eq_sym. by rewrite /log Log_1 divRR // /log Log_1; field. @@ -196,18 +199,19 @@ split => //. lra. Defined. -Lemma pinsker_fun_decreasing_on_0_to_p (c : R) (Hc : c <= / (2 * ln 2)) (Hp' : 0 < p < 1) : - forall x y, 0 < x <= p -> 0 < y <= p -> x <= y -> pinsker_fun p c y <= pinsker_fun p c x. +Lemma pinsker_fun_decreasing_on_0_to_p (c : R) (Hc : c <= / (2 * ln 2)) + (p01 : 0 < p < 1) : + forall x y, 0 < x <= p -> 0 < y <= p -> x <= y -> + pinsker_fun p c y <= pinsker_fun p c x. Proof. move=> x y Hx Hy xy. rewrite -[X in _ <= X]oppRK leR_oppr. move: x y Hx Hy xy. -apply pderive_increasing_open_closed with (pinsker_fun_pderivable1 c Hp'). - by case: Hp'. -move=> t [Ht1 Ht2]. +apply pderive_increasing_open_closed with (pinsker_fun_pderivable1 c p01). + by case: p01. +move=> t [t0 tp]. rewrite /pinsker_fun_pderivable1. rewrite derive_pt_opp. -destruct Hp' as [Hp'1 Hp'2]. rewrite derive_pt_pinsker_fun //; last lra. rewrite /pinsker_fun' /div_fct. have Hlocal : 0 <= / ln 2 by exact/invR_ge0. @@ -239,14 +243,15 @@ case: Hp' => Hp'1 Hp'2. lra. Defined. -Lemma pinsker_fun_increasing_on_p_to_1 (c : R) (Hc : c <= / (2 * ln 2)) (Hp' : 0 < p < 1) : - forall x y, p <= x < 1 -> p <= y < 1 -> x <= y -> pinsker_fun p c x <= pinsker_fun p c y. +Lemma pinsker_fun_increasing_on_p_to_1 (c : R) (Hc : c <= / (2 * ln 2)) + (p01 : 0 < p < 1) : + forall x y, p <= x < 1 -> p <= y < 1 -> x <= y -> + pinsker_fun p c x <= pinsker_fun p c y. Proof. -apply pderive_increasing_closed_open with (pinsker_fun_pderivable2 c Hp'). - by case: Hp'. -move=> t [Ht1 Ht2]. +apply pderive_increasing_closed_open with (pinsker_fun_pderivable2 c p01). + by case: p01. +move=> t [pt t1]. rewrite /pinsker_fun_pderivable2. -destruct Hp' as [Hp'1 Hp'2]. rewrite derive_pt_pinsker_fun //; last lra. rewrite /pinsker_fun' /div_fct. have X : 0 <= (/ (t * (1 - t) * ln 2) - 8 * c). @@ -256,8 +261,10 @@ have X : 0 <= (/ (t * (1 - t) * ln 2) - 8 * c). have /eqP Hlocal2 : t * (1 - t) <> 0 by apply/eqP/gtR_eqF/mulR_gt0; lra. apply (@leR_trans (4 / ln 2)). apply (@leR_trans (8 * / (2 * ln 2))). - apply/leRP. - rewrite leR_pmul2l'; [exact/leRP | by apply/ltRP; lra]. + apply/RleP. + rewrite 2!RmultE ler_pM2l//; last first. + by apply/RltP; rewrite (_ : 0%mcR = 0)//; lra. + exact/RleP. rewrite invRM ?mulRA; last 2 first. exact/eqP. exact/ln2_neq0. @@ -276,9 +283,7 @@ End pinsker_function_analysis. Local Open Scope reals_ext_scope. Section pinsker_fun_pos. - -Variables p q : prob . - +Variables p q : {prob R}. Variable A : finType. Hypothesis card_A : #|A| = 2%nat. Hypothesis P_dom_by_Q : @@ -288,64 +293,67 @@ Lemma pinsker_fun_pos c : 0 <= c <= / (2 * ln 2) -> 0 <= pinsker_fun p c q. Proof. move=> Hc. set a := Set2.a card_A. set b := Set2.b card_A. -have [p0|p0] := eqVneq p 0%:pr. +have [p0|p0] := eqVneq p R0%:pr. subst p. rewrite /pinsker_fun /div_fct /comp. rewrite !(mul0R,mulR0,addR0,add0R,Rminus_0_l,subR0). - have [q1|q1] := eqVneq q 1%:pr. + have [q1|q1] := eqVneq q R1%:pr. subst q. exfalso. move/dominatesP : P_dom_by_Q => /(_ a). - by rewrite !fdist_binaryE subRR eqxx subR0; lra. + by rewrite !fdist_binaryE !/onem subrr eqxx subr0 -R1E -R0E; lra. apply: leR_trans. - by apply: (@pinsker_function_spec_pos _ q Hc); rewrite -prob_lt1. + apply: (@pinsker_function_spec_pos _ q Hc); split=> //. + by apply/RltP; rewrite -prob_lt1. rewrite /pinsker_function_spec. apply Req_le. - by rewrite mul1R div1R /log LogV; [field |rewrite subR_gt0 -prob_lt1]. -have [p1|p1] := eqVneq p 1%:pr. + by rewrite mul1R div1R /log LogV; [field| + rewrite subR_gt0; apply /RltP; rewrite -prob_lt1]. +have [p1|p1] := eqVneq p 1%coqR%:pr. subst p. rewrite /pinsker_fun /div_fct /comp subRR mul0R addR0. - have [q0|q0] := eqVneq q 0%:pr. + have [q0|q0] := eqVneq q 0%coqR%:pr. subst q. exfalso. move/dominatesP : P_dom_by_Q => /(_ b). - rewrite !fdist_binaryE subRR eq_sym (negbTE (Set2.a_neq_b card_A)) => /=. + rewrite !fdist_binaryE /onem subrr eq_sym (negbTE (Set2.a_neq_b card_A)) -R0E => /=. lra. apply: leR_trans. have : 0 <= 1 - q < 1. split; first by rewrite subR_ge0. - by rewrite ltR_subl_addr -{1}(addR0 1) ltR_add2l -prob_gt0. + by rewrite ltR_subl_addr -{1}(addR0 1) ltR_add2l; apply/RltP/ prob_gt0. exact: pinsker_function_spec_pos Hc. rewrite /pinsker_function_spec. apply Req_le. - rewrite mul1R div1R /log LogV -?prob_gt0 //. + rewrite mul1R div1R /log LogV; [|by apply/RltP/prob_gt0]. rewrite /id (_ : 1 - (1 - q) = q) //; by field. -have [q0|q0] := eqVneq q 0%:pr. +have [q0|q0] := eqVneq q 0%coqR%:pr. subst q. rewrite /pinsker_fun /div_fct /comp. exfalso. move/dominatesP : P_dom_by_Q => /(_ b). rewrite !fdist_binaryE eq_sym (negbTE (Set2.a_neq_b card_A)) => /(_ erefl) p0_. by move/eqP : p0; apply; apply/val_inj; rewrite /= p0_. -have [q1|q1] := eqVneq q 1%:pr. +have [q1|q1] := eqVneq q 1%coqR%:pr. subst q. exfalso. move/dominatesP : P_dom_by_Q => /(_ a). - rewrite !fdist_binaryE subRR eqxx subR_eq0 => /(_ erefl) p1_. + rewrite !fdist_binaryE /onem subrr eqxx subR_eq0 => /(_ erefl) p1_. by move/eqP : p1; apply; apply/val_inj; rewrite /= -p1_. rewrite -(pinsker_fun_p p c). case: (Rlt_le_dec q p) => qp. apply pinsker_fun_decreasing_on_0_to_p => //. - lra. - - by split; [rewrite -prob_gt0 | rewrite -prob_lt1]. - - by split; [rewrite -prob_gt0 | exact/ltRW]. - - by split; [rewrite -prob_gt0 | exact/leRR]. + - by split; apply/RltP; [rewrite -prob_gt0 | rewrite -prob_lt1]. + - by split; [apply/RltP/prob_gt0 | exact/ltRW]. + - split; [by apply/RltP/prob_gt0 | ]. + by apply/RleP; rewrite lexx. - exact/ltRW. apply pinsker_fun_increasing_on_p_to_1 => //. - lra. -- by split; [rewrite -prob_gt0 |rewrite -prob_lt1]. -- by split; [exact/leRR |rewrite -prob_lt1]. -- by split => //; rewrite -prob_lt1. +- by split; apply/RltP; [rewrite -prob_gt0 |rewrite -prob_lt1]. +- by split; [by apply/RleP; rewrite lexx |apply/RltP/prob_lt1]. +- by split => //; apply/RltP; rewrite -prob_lt1. Qed. End pinsker_fun_pos. @@ -354,8 +362,7 @@ Local Open Scope divergence_scope. Local Open Scope variation_distance_scope. Section Pinsker_2_bdist. - -Variables p q : prob. +Variables p q : {prob R}. Variable A : finType. Hypothesis card_A : #|A| = 2%nat. @@ -387,41 +394,44 @@ transitivity (D(P || Q) - c * (`| p - q | + `| (1 - p) - (1 - q) |) ^ 2). rewrite [X in _ = _ + _ - X]mulRA. rewrite [in X in _ = _ + _ - X](mulRC c). congr (_ - _). - case/boolP : (p == 0%:pr) => [/eqP |] p0. + case/boolP : (p == 0%coqR%:pr) => [/eqP |] p0. rewrite p0 !mul0R subR0 addR0 add0R !mul1R /log (*_Log_1*) /Rdiv. - have [q1|q1] := eqVneq q 1%:pr. + have [q1|q1] := eqVneq q 1%coqR%:pr. move/dominatesP : P_dom_by_Q => /(_ (Set2.a card_A)). rewrite -/pi -/qi Hqi q1 subRR => /(_ erefl). - by rewrite Hpi p0 subR0 => ?; exfalso; lra. + by rewrite Hpi p0 subR0 -R0E => ?; exfalso; lra. rewrite /log LogM; last 2 first. lra. - by apply/invR_gt0; rewrite subR_gt0 -prob_lt1. - by rewrite LogV ?subR_gt0 -?prob_lt1 // Log_1. - have [q0|q0] := eqVneq q 0%:pr. + by apply/invR_gt0; rewrite subR_gt0; apply/RltP/prob_lt1. + rewrite LogV; last by apply/subR_gt0/RltP/prob_lt1. + by rewrite Log_1. + have [q0|q0] := eqVneq q 0%coqR%:pr. move/dominatesP : P_dom_by_Q => /(_ (Set2.b card_A)). rewrite -/pj -/qj Hqj q0 => /(_ erefl). rewrite Hpj => abs. - have : p == 0%:pr by apply/eqP/val_inj. + have : p == 0%coqR%:pr by apply/eqP/val_inj. by rewrite (negbTE p0). rewrite /div_fct /comp /= (_ : id q = q) //. - have [->|p1] := eqVneq p 1%:pr. + have [->|p1] := eqVneq p 1%coqR%:pr. rewrite subRR !mul0R /Rdiv /log LogM //; last first. - apply/invR_gt0; by rewrite -prob_gt0. - by rewrite Log_1 mul1R LogV // -?prob_gt0 // !(add0R,mul1R,addR0,sub0R). + apply/invR_gt0; by apply/RltP/prob_gt0. + rewrite Log_1 /= mul1R LogV //; last by apply/RltP/prob_gt0. + by rewrite !(add0R,mul1R,addR0,sub0R). rewrite /log LogM //; last 2 first. - by rewrite -prob_gt0. - by apply/invR_gt0; rewrite -prob_gt0. - rewrite LogV //; last by rewrite -prob_gt0. - have [q1|q1] := eqVneq q 1%:pr. + by apply/RltP/prob_gt0. + by apply/invR_gt0/RltP/prob_gt0. + rewrite LogV //; last by apply/RltP/prob_gt0. + have [q1|q1] := eqVneq q 1%coqR%:pr. move/dominatesP : P_dom_by_Q => /(_ (Set2.a card_A)). rewrite -/pi -/qi Hqi q1 subRR => /(_ erefl). rewrite Hpi subR_eq0 => abs. - have : p == 1%:pr by apply/eqP/val_inj. + have : p == 1%coqR%:pr by apply/eqP/val_inj. by rewrite (negbTE p1). rewrite /Rdiv LogM ?subR_gt0 //; last 2 first. - by rewrite -prob_lt1. - by apply/invR_gt0; rewrite subR_gt0 -prob_lt1. - by rewrite LogV ?subR_gt0 // -?prob_lt1//; ring. + by apply/RltP/prob_lt1. + by apply/invR_gt0; rewrite subR_gt0; apply/RltP/prob_lt1. + rewrite LogV; last by rewrite subR_gt0; apply/RltP/prob_lt1. + ring. congr (_ - _ * _). by rewrite /var_dist Set2sumE // -/pi -/pj -/qi -/qj Hpi Hpj Hqi Hqj addRC. Qed. @@ -432,14 +442,13 @@ set lhs := _ * _. set rhs := D(_ || _). rewrite -subR_ge0 -pinsker_fun_p_eq. apply pinsker_fun_pos with A card_A => //. -split; [exact/invR_ge0/mulR_gt0 | exact/leRR]. +by split; [exact/invR_ge0/mulR_gt0 | by apply/RleP; rewrite lexx]. Qed. End Pinsker_2_bdist. Section Pinsker_2. - -Variables (A : finType) (P Q : fdist A). +Variables (A : finType) (P Q : {fdist A}). Hypothesis card_A : #|A| = 2%nat. Hypothesis P_dom_by_Q : P `<< Q. @@ -455,20 +464,20 @@ Qed. End Pinsker_2. Section Pinsker. - -Variables (A : finType) (P Q : fdist A). +Variables (A : finType) (P Q : {fdist A}). Hypothesis P_dom_by_Q : P `<< Q. Local Notation "0" := (false). Local Notation "1" := (true). Lemma bipart_dominates : - let A_ := fun b => if b then [set a | P a if b then [set a | (P a < Q a)%mcR] + else [set a | (Q a <= P a)%mcR] in forall (cov : A_ 0 :|: A_ 1 = [set: A]) (dis : A_ 0 :&: A_ 1 = set0), bipart dis cov P `<< bipart dis cov Q. Proof. move=> A_ cov dis; apply/dominatesP => /= b. -rewrite !ffunE => /psumR_eq0P H. +rewrite !ffunE => /psumr_eq0P H. transitivity (\sum_(a | a \in A_ b) 0%R). apply eq_bigr => // a ?. by rewrite (dominatesE P_dom_by_Q) // H // => a' ?; exact/pos_ff_ge0. @@ -477,22 +486,23 @@ Qed. Lemma Pinsker_inequality : / (2 * ln 2) * d(P , Q) ^ 2 <= D(P || Q). Proof. -pose A0 := [set a | Q a match b with 0 => A0 | 1 => A1 end. have cov : A_ 0 :|: A_ 1 = setT. rewrite /= /A0 /A1. - have -> : [set x | P x a; by rewrite in_set in_setC in_set ltRNge'. + have -> : [set x | (P x < Q x)%mcR] = ~: [set x | (Q x <= P x)%mcR]. + by apply/setP => a; rewrite in_set in_setC in_set ltNge. by rewrite setUCr. have dis : A_ 0 :&: A_ 1 = set0. rewrite /A_ /A0 /A1. - have -> : [set x | P x a; by rewrite in_set in_setC in_set ltRNge'. + have -> : [set x | (P x < Q x)%mcR] = ~: [set x | (Q x <= P x)%mcR]. + by apply/setP => a; rewrite in_set in_setC in_set ltNge. by rewrite setICr. pose P_A := bipart dis cov P. pose Q_A := bipart dis cov Q. -have step1 : D(P_A || Q_A) <= D(P || Q) by apply partition_inequality; exact P_dom_by_Q. +have step1 : D(P_A || Q_A) <= D(P || Q). + by apply partition_inequality; exact P_dom_by_Q. suff : / (2 * ln 2) * d(P , Q) ^2 <= D(P_A || Q_A). move=> ?; apply (@leR_trans (D(P_A || Q_A))) => //; exact/Rge_le. have -> : d( P , Q ) = d( P_A , Q_A ). @@ -504,10 +514,11 @@ have -> : d( P , Q ) = d( P_A , Q_A ). congr (_ + _). - rewrite /P_A /Q_A /bipart /= /bipart_pmf /=. transitivity (\sum_(a | a \in A0) (P a - Q a)). - apply eq_bigr => a; rewrite /A0 in_set => /leRP Ha. + apply: eq_bigr => a; rewrite /A0 in_set => /RleP Ha. by rewrite geR0_norm ?subR_ge0. rewrite big_split /= geR0_norm; last first. - by rewrite subR_ge0; rewrite !ffunE; apply leR_sumR => ?; by rewrite inE => /leRP. + rewrite subR_ge0; rewrite !ffunE. + by apply leR_sumR => ?; rewrite inE => /RleP. by rewrite -big_morph_oppR // 2!ffunE addR_opp. - rewrite /P_A /Q_A /bipart /= !ffunE /=. have [A1_card | A1_card] : #|A1| = O \/ (0 < #|A1|)%nat. @@ -516,10 +527,10 @@ have -> : d( P , Q ) = d( P_A , Q_A ). by rewrite A1_card !big_set0 subRR normR0. + transitivity (\sum_(a | a \in A1) - (P a - Q a)). apply eq_bigr => a; rewrite /A1 in_set => Ha. - rewrite ltR0_norm // subR_lt0; exact/ltRP. + by rewrite ltR0_norm // subR_lt0; exact/RltP. rewrite -big_morph_oppR // big_split /= ltR0_norm; last first. rewrite subR_lt0; apply ltR_sumR_support => // a. - rewrite /A1 in_set; by move/ltRP. + by rewrite /A1 in_set => /RltP. by rewrite -big_morph_oppR. by rewrite big_bool /= /bipart_pmf !ffunE /=. exact/(Pinsker_2_inequality card_bool)/bipart_dominates. @@ -531,9 +542,11 @@ rewrite -(sqrt_Rsqr (d(P , Q))); last exact/pos_var_dist. apply sqrt_le_1_alt. apply (@leR_pmul2l (/ 2)); first by apply invR_gt0; lra. apply (@leR_trans (D(P || Q))); last first. - by rewrite mulRA mulVR // ?mul1R; [exact/leRR | exact/gtR_eqF]. + rewrite mulRA mulVR // ?mul1R; [| exact/gtR_eqF]. + by apply/RleP; rewrite lexx. apply: (leR_trans _ Pinsker_inequality). -rewrite (_ : forall x, Rsqr x = x ^ 2); last by move=> ?; rewrite /Rsqr /pow mulR1. +rewrite (_ : forall x, Rsqr x = x ^ 2); last first. + by move=> ?; rewrite /Rsqr /pow mulR1. apply leR_wpmul2r; first exact: pow_even_ge0. apply leR_inv => //; first exact/mulR_gt0. rewrite -[X in _ <= X]mulR1. diff --git a/probability/proba.v b/probability/proba.v index 647f2e59..594e5068 100644 --- a/probability/proba.v +++ b/probability/proba.v @@ -1,11 +1,11 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup perm finalg matrix. +From mathcomp Require Import all_ssreflect ssralg ssrnum matrix. From mathcomp Require boolp. -From mathcomp Require Import Rstruct. +From mathcomp Require Import Rstruct reals. Require Import Reals Lra. -Require Import ssrR Reals_ext logb ssr_ext ssralg_ext bigop_ext Rbigop. -Require Import fdist. +Require Import ssrR Rstruct_ext Reals_ext realType_ext logb ssr_ext ssralg_ext. +Require Import bigop_ext Rbigop fdist. (******************************************************************************) (* Probabilities over finite distributions *) @@ -126,10 +126,10 @@ Import Prenex Implicits. Local Open Scope R_scope. Local Open Scope reals_ext_scope. Local Open Scope fdist_scope. - -Declare Scope proba_scope. Local Open Scope proba_scope. +Import Order.POrderTheory Num.Theory. + (** [bigA_distr] is a specialization of [bigA_distr_bigA] and at the same time a generalized version of [GRing.exprDn] for iterated prod. *) Lemma bigA_distr (R : Type) (zero one : R) (times : Monoid.mul_law zero) @@ -183,13 +183,13 @@ Qed. Lemma m1powD k : k <> 0%nat -> (-1)^(k-1) = - (-1)^k. Proof. by case: k => [//|k _]; rewrite subn1 /= mulN1R oppRK. Qed. -Import Order.TTheory. - Notation "E `*T" := ([set x | x.1 \in E]) : proba_scope. Notation "T`* F" := ([set x | x.2 \in F]) : proba_scope. Section TsetT. -Variables (A B : finType) (P : {fdist (A * B)}). +Notation R := real_realType. + +Variables (A B : finType) (P : R.-fdist (A * B)). Implicit Types (E : {set A}) (F : {set B}). Lemma TsetT : T`* setT = setT :> {set A * B}. @@ -221,8 +221,16 @@ Proof. by apply/setP => -[a b]; rewrite !inE. Qed. End TsetT. +(* TODO: consider moving this to fdist.v *) +#[global] Hint Extern 0 (IZR Z0 <= _) => + solve [apply/RleP; exact: FDist.ge0] : core. +#[global] Hint Extern 0 (_ <= IZR (Zpos xH)) => + solve [apply/RleP; exact: FDist.le1] : core. + Section probability. -Variables (A : finType) (P : fdist A). +Notation R := Rstruct.real_realType. + +Variables (A : finType) (P : R.-fdist A). Implicit Types E : {set A}. Definition Pr E := \sum_(a in E) P a. @@ -237,7 +245,11 @@ by rewrite ltR_neqAle; split => //; exact/nesym/eqP. Qed. Lemma Pr_1 E : Pr E <= 1. -Proof. by rewrite -(FDist.f1 P); apply leR_sumRl => // a _; exact/leRR. Qed. +Proof. +rewrite (_ : 1 = GRing.one _)//. +rewrite -(FDist.f1 P); apply leR_sumRl => // a _. +by apply/RleP; rewrite lexx. +Qed. Lemma Pr_lt1 E : Pr E < 1 <-> Pr E != 1. Proof. @@ -251,7 +263,11 @@ Proof. by rewrite /Pr big_pred0 // => a; rewrite in_set0. Qed. Lemma Pr_set0P E : Pr E = 0 <-> (forall a, a \in E -> P a = 0). Proof. -by rewrite /Pr (eq_bigl (fun x => x \in E)) //; exact: (@psumR_eq0P _ (mem E)). +rewrite /Pr (eq_bigl (fun x => x \in E)) //; split => [|h]. + move/eqP; rewrite psumr_eq0// => /allP + a aE. + by move/(_ a); rewrite mem_index_enum aE implyTb => /(_ isT)/eqP. +apply/eqP; rewrite psumr_eq0 //; apply/allP => a _. +by apply/implyP => /h/eqP. Qed. Lemma Pr_setT : Pr setT = 1. @@ -263,6 +279,7 @@ Proof. by rewrite /Pr big_set1. Qed. Lemma Pr_cplt E : Pr E + Pr (~: E) = 1. Proof. rewrite /Pr -bigU /=; last by rewrite -subsets_disjoint. +rewrite (_ : 1 = GRing.one _)//. by rewrite -(FDist.f1 P); apply eq_bigl => /= a; rewrite !inE /= orbN. Qed. @@ -274,7 +291,8 @@ Proof. by rewrite -(Pr_cplt E); field. Qed. Lemma Pr_incl E E' : E \subset E' -> Pr E <= Pr E'. Proof. -by move=> H; apply leR_sumRl => a aE //; [exact/leRR | move/subsetP : H; exact]. +move=> H; apply leR_sumRl => a aE //; [ | by move/subsetP : H; exact]. +by apply/RleP; rewrite lexx. Qed. Lemma Pr_union E1 E2 : Pr (E1 :|: E2) <= Pr E1 + Pr E2. @@ -293,7 +311,7 @@ Lemma Pr_bigcup (B : finType) (p : pred B) F : Pr (\bigcup_(i | p i) F i) <= \sum_(i | p i) Pr (F i). Proof. rewrite /Pr; elim: (index_enum _) => [| h t IH]. - by rewrite big_nil; apply: sumR_ge0 => b _; rewrite big_nil; exact/leRR. + by rewrite big_nil; apply: sumR_ge0 => b _; rewrite big_nil. rewrite big_cons; case: ifP => H1. apply: leR_trans; first by eapply leR_add2l; exact: IH. rewrite [X in _ <= X](exchange_big_dep @@ -306,7 +324,7 @@ rewrite big_cons; case: ifP => H1. rewrite (_ : 1 = 1%:R) //; apply/le_INR/ssrnat.leP/card_gt0P. by case/bigcupP : H1 => b Eb hFb; exists b; rewrite -topredE /= Eb. apply/(leR_trans IH)/leR_sumR => b Eb; rewrite big_cons. -case: ifPn => hFb; last exact/leRR. +case: ifPn => hFb; last by apply/RleP; rewrite lexx. by rewrite -[X in X <= _]add0R; exact/leR_add2r. Qed. @@ -371,13 +389,16 @@ Global Hint Resolve Pr_ge0 : core. Lemma Pr_domin_setI (A : finType) (d : {fdist A}) (E F : {set A}) : Pr d E = 0 -> Pr d (E :&: F) = 0. Proof. -move=> PE0; apply/psumR_eq0P => // a; rewrite inE => /andP[aE aF]. -by move/psumR_eq0P : PE0; apply. +move=> PE0; apply/eqP; rewrite psumr_eq0//; apply/allP => a _. +apply/implyP; rewrite inE => /andP[aE aF]. +move/eqP : PE0; rewrite psumr_eq0// => /allP. +by move=> /(_ a); rewrite mem_index_enum => /(_ isT); rewrite aE implyTb. Qed. Section Pr_extra. +Notation R := real_realType. -Variables (A B : finType) (P : {fdist A * B}). +Variables (A B : finType) (P : R.-fdist (A * B)). Implicit Types (E : {set A}) (F : {set B}). Lemma Pr_XsetT E : Pr P (E `* [set: B]) = Pr (P`1) E. @@ -419,7 +440,7 @@ Lemma Pr_domin_setXN (A B : finType) (P : {fdist A * B}) E F : Pr P (E `* F) != 0 -> Pr P`1 E != 0. Proof. by apply/contra => /eqP/Pr_domin_setX => ?; exact/eqP. Qed. -Lemma Pr_fdistmap (A B : finType) (f : A -> B) (d : fdist A) (E : {set A}) : +Lemma Pr_fdistmap (A B : finType) (f : A -> B) (d : real_realType.-fdist A) (E : {set A}) : injective f -> Pr d E = Pr (fdistmap f d) (f @: E). Proof. @@ -515,21 +536,23 @@ Local Close Scope vec_ext_scope. Section random_variable. Variables (U : finType) (T : eqType). +Notation R := real_realType. -Definition RV (P : fdist U) := U -> T. +Definition RV (P : R.-fdist U) := U -> T. -Definition RV_of (P : fdist U) := +Definition RV_of (P : {fdist U}) := fun (phA : phant (Equality.sort U)) (phT : phant (Equality.sort T)) => RV P. Local Notation "{ 'RV' P -> V }" := (RV_of P (Phant _) (Phant V)). -Definition ambient_dist (P : fdist U) (X : {RV P -> T}) : fdist U := P. +Definition ambient_dist (P : {fdist U}) (X : {RV P -> T}) : {fdist U} := P. End random_variable. Notation "{ 'RV' P -> T }" := (RV_of P (Phant _) (Phant T)) : proba_scope. Section random_variable_eqType. -Variables (U : finType) (A : eqType) (P : fdist U). +Notation R := real_realType. +Variables (U : finType) (A : eqType) (P : R.-fdist U). Definition pr_eq (X : {RV P -> A}) (a : A) := locked (Pr P (finset (X @^-1 a))). Local Notation "`Pr[ X = a ]" := (pr_eq X a). @@ -544,10 +567,11 @@ Lemma pr_eq_neq0 (X : {RV P -> A}) (a : A) : `Pr[ X = a ] != 0 <-> exists i, i \in X @^-1 a /\ 0 < P i. Proof. split; rewrite pr_eqE /Pr => PXa0. - have := proj1 (@sumR_neq0 U P (enum (finset (X @^-1 a))) (FDist.ge0 _)). + have H : forall i : U, 0 <= P i by move=> ?; apply/RleP/FDist.ge0. + have := proj1 (@sumR_neq0 U P (enum (finset (X @^-1 a))) H). by rewrite !big_enum /= => /(_ PXa0) [i]; rewrite mem_enum inE => ?; exists i. case: PXa0 => i ?; rewrite -big_enum; apply/sumR_neq0; - by [move=> ?; exact: FDist.ge0 | exists i; rewrite mem_enum inE]. + by [move=> ?; exact/RleP/FDist.ge0 | exists i; rewrite mem_enum inE]. Qed. Lemma pr_eq0 (X : {RV P -> A}) (a : A) : a \notin fin_img X -> `Pr[ X = a ] = 0. @@ -562,7 +586,8 @@ Notation "`Pr[ X = a ]" := (pr_eq X a) : proba_scope. Global Hint Resolve pr_eq_ge0 : core. Section random_variable_order. -Variables (U : finType) (d : unit) (T : porderType d) (P : {fdist U}). +Notation R := real_realType. +Variables (U : finType) (d : unit) (T : porderType d) (P : R.-fdist U). Variables (X : {RV P -> T}). Definition pr_geq (X : {RV P -> T}) r := Pr P [set x | (X x >= r)%O ]. @@ -574,7 +599,8 @@ Notation "'`Pr[' X '>=' r ']'" := (pr_geq X r) : proba_scope. Notation "'`Pr[' X '<=' r ']'" := (pr_leq X r) : proba_scope. Section random_variable_finType. -Variables (U : finType) (P : fdist U) (A : finType). +Notation R := real_realType. +Variables (U : finType) (P : R.-fdist U) (A : finType). Definition pr_eq_set (X : {RV P -> A}) (E : {set A}) := locked (Pr P (X @^-1: E)). @@ -606,8 +632,9 @@ Notation "`Pr[ X '\in' E ]" := (pr_eq_set X E) : proba_scope. Notation "`p_ X" := (dist_of_RV X) : proba_scope. Section random_variables. +Notation R := real_realType. -Variables (U : finType) (P : fdist U). +Variables (U : finType) (P : R.-fdist U). Definition const_RV (T : eqType) cst : {RV P -> T} := fun=> cst. Definition comp_RV (TA TB : eqType) (f : TA -> TB) (X : {RV P -> TA}) : {RV P -> TB} := @@ -641,7 +668,8 @@ Notation "'`--' P" := (neg_RV P) : proba_scope. Notation "'`log' P" := (log_RV P) : proba_scope. Section RV_lemmas. -Variables (U : finType) (P : fdist U). +Notation R := real_realType. +Variables (U : finType) (P : R.-fdist U). Implicit Types X : {RV P -> R}. Lemma scalel_RVA k l X : scalel_RV (k * l) X = scalel_RV k (scalel_RV l X). @@ -659,7 +687,8 @@ Proof. by rewrite sq_RV_pow2; exact: pow2_ge_0. Qed. End RV_lemmas. Section pair_of_RVs. -Variables (U : finType) (P : fdist U). +Notation R := real_realType. +Variables (U : finType) (P : R.-fdist U). Variables (A : eqType) (X : {RV P -> A}) (B : eqType) (Y : {RV P -> B}). Definition RV2 : {RV P -> A * B} := fun x => (X x, Y x). End pair_of_RVs. @@ -667,7 +696,8 @@ End pair_of_RVs. Notation "'[%' x , y , .. , z ']'" := (RV2 .. (RV2 x y) .. z). Section RV2_prop. -Variables (U : finType) (P : fdist U). +Notation R := real_realType. +Variables (U : finType) (P : R.-fdist U). Variables (A B : finType) (X : {RV P -> A}) (Y : {RV P -> B}). Lemma fst_RV2 : (`p_[% X, Y])`1 = `p_X. @@ -688,7 +718,8 @@ Proof. by []. Qed. End RV2_prop. Section RV3_prop. -Variables (U : finType) (P : fdist U). +Notation R := real_realType. +Variables (U : finType) (P : R.-fdist U). Variables (A B C D : finType). Variables (X : {RV P -> A}) (Y : {RV P -> B}) (Z : {RV P -> C}) (W : {RV P -> D}). @@ -708,10 +739,10 @@ Proof. by rewrite /fdistC12 /dist_of_RV /fdistA fdistmap_comp. Qed. End RV3_prop. -Lemma pr_eq_unit (U : finType) (P : fdist U) : `Pr[ (unit_RV P) = tt ] = 1. +Lemma pr_eq_unit (U : finType) (P : real_realType.-fdist U) : `Pr[ (unit_RV P) = tt ] = 1. Proof. by rewrite pr_eqE'; apply/eqP/fdist1P; case. Qed. -Lemma Pr_fdistmap_RV2 (U : finType) (P : fdist U) (A B : finType) +Lemma Pr_fdistmap_RV2 (U : finType) (P : real_realType.-fdist U) (A B : finType) (E : {set A}) (F : {set B}) (X : {RV P -> A}) (Z : {RV P -> B}) : Pr `p_[% X, Z] (E `* F) = Pr P ([set x | preim X (mem E) x] :&: [set x | preim Z (mem F) x]). @@ -725,7 +756,8 @@ by rewrite fdistmapE. Qed. Section pr_pair. -Variables (U : finType) (P : fdist U). +Notation R := real_realType. +Variables (U : finType) (P : R.-fdist U). Variables (A B C : finType) (TA TB TC : eqType). Variables (X : {RV P -> A}) (Y : {RV P -> B}) (Z : {RV P -> C}). Variables (TX : {RV P -> TA}) (TY : {RV P -> TB}) (TZ : {RV P -> TC}). @@ -795,7 +827,8 @@ by apply/imsetP/idP => [[a aE [] ->//]|XuE]; exists (X u). Qed. Section RV_domin. -Variables (U : finType) (P : fdist U) (A B : finType) (TA TB : eqType). +Notation R := real_realType. +Variables (U : finType) (P : R.-fdist U) (A B : finType) (TA TB : eqType). Variables (X : {RV P -> A}) (Y : {RV P -> B}). Variables (TX : {RV P -> A}) (TY : {RV P -> B}). @@ -815,11 +848,11 @@ End RV_domin. Local Open Scope vec_ext_scope. -Definition cast_RV_fdist_rV1 U (P : fdist U) (T : eqType) (X : {RV P -> T}) +Definition cast_RV_fdist_rV1 (U : finType) (P : real_realType.-fdist U) (T : eqType) (X : {RV P -> T}) : {RV (P `^ 1) -> T} := fun x => X (x ``_ ord0). -Definition cast_RV_fdist_rV10 U (P : fdist U) (T : eqType) +Definition cast_RV_fdist_rV10 (U : finType) (P : real_realType.-fdist U) (T : eqType) (Xs : 'rV[{RV P -> T}]_1) : {RV (P `^ 1) -> T} := cast_RV_fdist_rV1 (Xs ``_ ord0). @@ -832,7 +865,8 @@ Definition cast_fun_rV10 U (T : eqType) (Xs : 'rV[U -> T]_1) : 'rV[U]_1 -> T := Local Close Scope vec_ext_scope. Section expected_value_def. -Variables (U : finType) (P : fdist U) (X : {RV P -> R}). +Notation R := real_realType. +Variables (U : finType) (P : R.-fdist U) (X : {RV P -> R}). Definition Ex := \sum_(u in U) X u * P u. @@ -846,7 +880,8 @@ Notation "'`E'" := (@Ex _ _) : proba_scope. (* Alternative definition of the expected value: *) Section Ex_alt. -Variables (U : finType) (P : fdist U) (X : {RV P -> R}). +Notation R := real_realType. +Variables (U : finType) (P : R.-fdist U) (X : {RV P -> R}). Definition Ex_alt := \sum_(r <- fin_img X) r * `Pr[ X = r ]. @@ -862,8 +897,9 @@ Qed. End Ex_alt. Section expected_value_prop. +Notation R := real_realType. -Variables (U : finType) (P : fdist U) (X Y : {RV P -> R}). +Variables (U : finType) (P : R.-fdist U) (X Y : {RV P -> R}). Lemma E_neg_RV : `E (`-- X) = - `E X. Proof. @@ -934,7 +970,7 @@ Proof. move=> H; by rewrite /comp_RV /= H. Qed. End expected_value_prop. -Lemma E_cast_RV_fdist_rV1 A (P : fdist A) : +Lemma E_cast_RV_fdist_rV1 (A : finType) (P : real_realType.-fdist A) : forall (X : {RV P -> R}), `E (cast_RV_fdist_rV1 X) = `E X. Proof. move=> f; rewrite /cast_RV_fdist_rV1 /=; apply big_rV_1 => // m. @@ -942,8 +978,9 @@ by rewrite -fdist_rV1. Qed. Section conditional_expectation_def. +Notation R := real_realType. -Variable (U : finType) (P : fdist U) (X : {RV P -> R}) (F : {set U}). +Variable (U : finType) (P : R.-fdist U) (X : {RV P -> R}) (F : {set U}). Definition cEx := \sum_(r <- fin_img X) r * Pr P (finset (X @^-1 r) :&: F) / Pr P F. @@ -952,8 +989,9 @@ End conditional_expectation_def. Notation "`E_[ X | F ]" := (cEx X F). Section conditional_expectation_prop. +Notation R := real_realType. -Variable (U I : finType) (P : fdist U) (X : {RV P -> R}) (F : I -> {set U}). +Variable (U I : finType) (P : R.-fdist U) (X : {RV P -> R}) (F : I -> {set U}). Hypothesis dis : forall i j, i != j -> [disjoint F i & F j]. Hypothesis cov : cover [set F i | i in I] = [set: U]. @@ -975,11 +1013,12 @@ transitivity (\sum_(i in I) Pr P (finset (X @^-1 r) :&: F i)). rewrite big_mkcond /=; apply eq_bigr => i _. case: ifPn => //; rewrite negbK => /eqP PFi0. rewrite /Pr big1 // => u; rewrite inE => /andP[uXr uFi]. - by move/psumR_eq0P : PFi0 => ->. + move/eqP : PFi0; rewrite psumr_eq0// => /allP/(_ u). + by rewrite mem_index_enum uFi implyTb => /(_ isT)/eqP. rewrite -Boole_eq; last first. move=> i j ij; rewrite -setI_eq0; apply/eqP/setP => u; rewrite !inE. apply/negbTE; rewrite !negb_and. - case/boolP : (X u != r) => // /negPn Xur //=. + have [/= Xur|//] := eqVneq (X u) r. move: (dis ij); rewrite -setI_eq0 => /eqP/setP/(_ u). by rewrite !inE => /negbT; rewrite negb_and. rewrite pr_eqE; congr Pr. @@ -1023,7 +1062,7 @@ apply (big_ind2 (R1 := {set A}) (R2 := R)); last by []. - by move=> sa a sb b Ha Hb; rewrite -Ha -Hb; apply: Ind_cap. Qed. -Lemma E_Ind (P : fdist A) s : `E (Ind s : {RV P -> R}) = Pr P s. +Lemma E_Ind (P : {fdist A}) s : `E (Ind s : {RV P -> R}) = Pr P s. Proof. rewrite /Ex /Ind /Pr (bigID (mem s)) /=. rewrite [X in _ + X = _]big1; last by move=> i /negbTE ->; rewrite mul0R. @@ -1036,7 +1075,8 @@ End Ind. contributed by Erik Martin-Dorel: the corresponding theorem is named [Pr_bigcup_incl_excl] and is more general than lemma [Pr_bigcup]. *) Section probability_inclusion_exclusion. -Variables (A : finType) (P : fdist A). +Notation R := real_realType. +Variables (A : finType) (P : R.-fdist A). Let SumIndCap (n : nat) (S : 'I_n -> {set A}) (k : nat) (x : A) := \sum_(J in {set 'I_n} | #|J| == k) (Ind (\bigcap_(j in J) S j) x). @@ -1147,12 +1187,12 @@ Hypothesis X_ge0 : forall u, 0 <= X u. Lemma Ex_lb (r : R) : r * `Pr[ X >= r] <= `E X. Proof. -rewrite /Ex (bigID [pred a' | X a' >b= r]) /= -[a in a <= _]addR0. +rewrite /Ex (bigID [pred a' | (X a' >= r)%mcR]) /= -[a in a <= _]addR0. apply leR_add; last first. by apply sumR_ge0 => a _; apply mulR_ge0 => //; exact/X_ge0. -apply (@leR_trans (\sum_(i | X i >b= r) r * P i)). +apply (@leR_trans (\sum_(i | (X i >= r)%mcR) r * P i)). by rewrite big_distrr /=; apply/Req_le/eq_bigl => a; rewrite inE. -by apply leR_sumR => u Xur; apply/leR_wpmul2r => //; exact/leRP. +by apply leR_sumR => u Xur; apply/leR_wpmul2r => //; exact/RleP. Qed. Lemma markov (r : R) : 0 < r -> `Pr[ X >= r ] <= `E X / r. @@ -1161,7 +1201,8 @@ Proof. by move=> r0; rewrite leR_pdivl_mulr // mulRC; exact/Ex_lb. Qed. End markov_inequality. Section thm61. -Variables (U : finType) (P : fdist U) (X : {RV P -> R}) (phi : R -> R). +Notation R := real_realType. +Variables (U : finType) (P : R.-fdist U) (X : {RV P -> R}) (phi : R -> R). Lemma Ex_comp_RV : `E (phi `o X) = \sum_(r <- fin_img X) phi r * `Pr[ X = r ]. Proof. @@ -1176,8 +1217,9 @@ Qed. End thm61. Section variance_def. +Notation R := real_realType. -Variables (U : finType) (P : fdist U) (X : {RV P -> R}). +Variables (U : finType) (P : R.-fdist U) (X : {RV P -> R}). (* Variance of a random variable (\sigma^2(X) = V(X) = E (X^2) - (E X)^2): *) Definition Var := let miu := `E X in `E ((X `-cst miu) `^2). @@ -1196,8 +1238,9 @@ Arguments Var {U} _ _. Notation "'`V'" := (@Var _ _) : proba_scope. Section variance_prop. +Notation R := real_realType. -Variables (U : finType) (P : fdist U) (X : {RV P -> R}). +Variables (U : finType) (P : R.-fdist U) (X : {RV P -> R}). (* The variance is not linear V (k X) = k^2 V (X) \cite[Theorem 6.7]{probook}: *) Lemma Var_scale k : `V (k `cst* X) = k ^ 2 * `V X. @@ -1218,7 +1261,7 @@ Qed. End variance_prop. -Lemma Var_cast_RV_fdist_rV1 (A : finType) (P : fdist A) (X : {RV P -> R}) : +Lemma Var_cast_RV_fdist_rV1 (A : finType) (P : {fdist A}) (X : {RV P -> R}) : `V (@cast_RV_fdist_rV1 _ P _ X) = `V X. Proof. rewrite !VarE !E_cast_RV_fdist_rV1; congr (_ - _). @@ -1229,15 +1272,16 @@ Qed. In any data sample, "nearly all" the values are "close to" the mean value: Pr[ |X - E X| \geq \epsilon] \leq V(X) / \epsilon^2 *) Section chebyshev. +Notation R := real_realType. -Variables (U : finType) (P : fdist U) (X : {RV P -> R}). +Variables (U : finType) (P : R.-fdist U) (X : {RV P -> R}). Lemma chebyshev_inequality epsilon : 0 < epsilon -> `Pr[ (Rabs `o (X `-cst `E X)) >= epsilon] <= `V X / epsilon ^ 2. Proof. move=> He; rewrite leR_pdivl_mulr; last exact/expR_gt0. rewrite mulRC /Var. -apply (@leR_trans (\sum_(a in U | `| X a - `E X | >b= epsilon) +apply (@leR_trans (\sum_(a in U | (`| X a - `E X | >= epsilon)%mcR) (((X `-cst `E X) `^2) a * P a))); last first. apply leR_sumRl_support with (Q := xpredT) => // a . by apply mulR_ge0 => //; exact: sq_RV_ge0. @@ -1246,17 +1290,18 @@ rewrite [_ ^2]lock /= -!lock. apply leR_sumRl => u; rewrite ?inE => Hu //=. - rewrite -!/(_ ^ 2). apply leR_wpmul2r => //. - apply (@leR_trans ((X u - `E X) ^ 2)); last exact/leRR. + apply (@leR_trans ((X u - `E X) ^ 2)); last by apply/RleP; rewrite lexx. rewrite -(sqR_norm (X u - `E X)). - by apply/pow_incr; split => //; [exact/ltRW | exact/leRP]. + by apply/pow_incr; split => //; [exact/ltRW | exact/RleP]. - by apply mulR_ge0 => //; exact: sq_RV_ge0. Qed. End chebyshev. Section independent_events. +Notation R := real_realType. -Variables (A : finType) (d : {fdist A}). +Variables (A : finType) (d : R.-fdist A). Definition inde_events (E F : {set A}) := Pr d (E :&: F) = Pr d E * Pr d F. @@ -1276,8 +1321,9 @@ Qed. End independent_events. Section k_wise_independence. +Notation R := real_realType. -Variables (A I : finType) (k : nat) (d : fdist A) (E : I -> {set A}). +Variables (A I : finType) (k : nat) (d : R.-fdist A) (E : I -> {set A}). Definition kwide_inde := forall (J : {set I}), (#|J| <= k)%nat -> Pr d (\bigcap_(i in J) E i) = \prod_(i in J) Pr d (E i). @@ -1285,8 +1331,9 @@ Definition kwide_inde := forall (J : {set I}), (#|J| <= k)%nat -> End k_wise_independence. Section pairwise_independence. +Notation R := real_realType. -Variables (A I : finType) (d : fdist A) (E : I -> {set A}). +Variables (A I : finType) (d : R.-fdist A) (E : I -> {set A}). Definition pairwise_inde := @kwide_inde A I 2%nat d E. @@ -1313,8 +1360,9 @@ Qed. End pairwise_independence. Section mutual_independence. +Notation R := real_realType. -Variables (A I : finType) (d : fdist A) (E : I -> {set A}). +Variables (A I : finType) (d : R.-fdist A) (E : I -> {set A}). Definition mutual_inde := (forall k, @kwide_inde A I k.+1 d E). @@ -1323,8 +1371,8 @@ Lemma mutual_indeE : Pr d (\bigcap_(i in J) E i) = \prod_(i in J) Pr d (E i)). Proof. rewrite /mutual_inde; split => [H J JI|H k J JI]. - have [/eqP->{J JI}|J0] := boolP (J == set0). - by rewrite !big_set0 Pr_setT. + have [->{J JI}|J0] := eqVneq J set0. + by rewrite !big_set0 Pr_setT. by rewrite (H #|J|.-1) ?prednK // card_gt0. by rewrite H //; apply/subsetP => i ij; rewrite inE. Qed. @@ -1333,8 +1381,8 @@ Lemma mutual_indeE' : #|I| != O -> mutual_inde <-> kwide_inde #|I| d E. Proof. move=> I0. rewrite /mutual_inde; split => [H J JI|]. - have [/eqP->{J JI}|J0] := boolP (J == set0). - by rewrite !big_set0 Pr_setT. + have [->{J JI}|J0] := eqVneq J set0. + by rewrite !big_set0 Pr_setT. by rewrite (H #|J|.-1) ?prednK // card_gt0. by move=> H k J Jk; rewrite H // max_card. Qed. @@ -1342,7 +1390,8 @@ Qed. End mutual_independence. Section conditional_probablity. -Variables (A : finType) (d : {fdist A}). +Notation R := real_realType. +Variables (A : finType) (d : R.-fdist A). Implicit Types E F : {set A}. Definition cPr E F := Pr d (E :&: F) / Pr d F. @@ -1350,8 +1399,8 @@ Local Notation "`Pr_[ E | F ]" := (cPr E F). Lemma cPr_ge0 E F : 0 <= `Pr_[E | F]. Proof. -rewrite /cPr; have [/eqP PF0|PF0] := boolP (Pr d F == 0). - by rewrite setIC (Pr_domin_setI _ PF0) div0R; exact/leRR. +rewrite /cPr; have [PF0|PF0] := eqVneq (Pr d F) 0. + by rewrite setIC (Pr_domin_setI _ PF0) div0R. by apply divR_ge0 => //; rewrite Pr_gt0. Qed. Local Hint Resolve cPr_ge0 : core. @@ -1366,11 +1415,11 @@ Qed. Lemma cPr_max E F : `Pr_[E | F] <= 1. Proof. rewrite /cPr. -have [/eqP PF0|PF0] := boolP (Pr d F == 0). +have [PF0|PF0] := eqVneq (Pr d F) 0. by rewrite setIC (Pr_domin_setI E PF0) div0R. apply leR_pdivr_mulr; first by rewrite Pr_gt0. rewrite mul1R /Pr; apply leR_sumRl => //. -by move=> a _; exact/leRR. + by move=> a _; apply/RleP; rewrite lexx. by move=> a; rewrite inE => /andP[]. Qed. @@ -1404,15 +1453,14 @@ Proof. by rewrite /cPr -divRDl -divRBl setIUl Pr_union_eq setIACA setIid. Qed. Lemma Bayes (E F : {set A}) : `Pr_[E | F] = `Pr_[F | E] * Pr d E / Pr d F. Proof. -have [/eqP PE0|PE0] := boolP (Pr d E == 0). +have [PE0|PE0] := eqVneq (Pr d E) 0. by rewrite /cPr [in RHS]setIC !(Pr_domin_setI F PE0) !(div0R,mul0R). by rewrite /cPr -mulRA mulVR // mulR1 setIC. Qed. Lemma product_rule (E F : {set A}) : Pr d (E :&: F) = `Pr_[E | F] * Pr d F. Proof. -rewrite /cPr. -have [/eqP PF0|PF0] := boolP (Pr d F == 0). +rewrite /cPr; have [PF0|PF0] := eqVneq (Pr d F) 0. by rewrite setIC (Pr_domin_setI E PF0) div0R mul0R. by rewrite -mulRA mulVR ?mulR1. Qed. @@ -1448,10 +1496,10 @@ Qed. Lemma Bayes_extended j : `Pr_[F j | E] = `Pr_[E | F j] * Pr d (F j) / \sum_(i in I) `Pr_[E | F i] * Pr d (F i). Proof. -have [/eqP PE0|PE0] := boolP (Pr d E == 0). +have [PE0|PE0] := eqVneq (Pr d E) 0. by rewrite {1 2}/cPr setIC (Pr_domin_setI (F j) PE0) !(div0R,mul0R). rewrite -total_prob_cond /cPr -!mulRA; congr (_ / _). -have [/eqP Fj0|Fj0] := boolP (Pr d (F j) == 0). +have [Fj0|Fj0] := eqVneq (Pr d (F j)) 0. by rewrite Fj0 !mulR0 (Pr_domin_setI E Fj0). by rewrite setIC mulVR ?mulR1. Qed. @@ -1463,12 +1511,13 @@ Notation "`Pr_ P [ E | F ]" := (cPr P E F) : proba_scope. Global Hint Resolve cPr_ge0 : core. Section fdist_cond. -Variables (A : finType) (P : {fdist A}) (E : {set A}). +Notation R := real_realType. +Variables (A : finType) (P : R.-fdist A) (E : {set A}). Hypothesis E0 : Pr P E != 0. Let f := [ffun a => `Pr_P [[set a] | E]]. -Let f0 a : 0 <= f a. Proof. by rewrite ffunE. Qed. +Let f0 a : (0 <= f a)%O. Proof. by apply/RleP; rewrite ffunE. Qed. Let f1 : \sum_(a in A) f a = 1. Proof. @@ -1488,7 +1537,8 @@ Definition fdist_cond : {fdist A} := locked (FDist.make f0 f1). End fdist_cond. Section fdist_cond_prop. -Variables (A : finType) (P : {fdist A}) (E : {set A}). +Notation R := real_realType. +Variables (A : finType) (P : R.-fdist A) (E : {set A}). Hypothesis E0 : Pr P E != 0. @@ -1504,7 +1554,7 @@ rewrite (_ : _ :&: _ = \bigcup_(i in G) ([set i] :&: E)); last first. rewrite [in RHS]/Pr big_bigcup_partition // => i j ij. rewrite -setI_eq0; apply/eqP/setP => a; rewrite !inE. apply/negbTE; rewrite !negb_and. -have [//|/negPn/eqP ->] := boolP (a != i). +have [->/=|//] := eqVneq a i. by rewrite ij /= orbT. Qed. @@ -1544,7 +1594,8 @@ by apply/fdist_proj23_domin/H; rewrite inE /= bF cG. Qed. Section conditionally_independent_events. -Variables (A : finType) (d : {fdist A}). +Notation R := real_realType. +Variables (A : finType) (d : R.-fdist A). Definition cinde_events (E F G : {set A}) := `Pr_d[ E :&: F | G] = `Pr_d[E | G] * `Pr_d[F | G]. @@ -1554,7 +1605,7 @@ Lemma cinde_events_alt (E F G : {set A}) : cinde_events E F G <-> Proof. split=> [|[|FG0]]; rewrite /cinde_events. - rewrite product_rule_cond => H. - have [/eqP/cPr_eq0 EG0|EG0] := boolP (`Pr_d[F | G] == 0). + have [/cPr_eq0 EG0|EG0] := eqVneq (`Pr_d[F | G]) 0. by rewrite /cPr EG0; right. by left; move/eqR_mul2r : H ; apply; apply/eqP. - by rewrite product_rule_cond => ->. @@ -1568,7 +1619,8 @@ Proof. by split; rewrite /cinde_events /inde_events !cPrET. Qed. End conditionally_independent_events. Section crandom_variable_eqType. -Variables (U : finType) (A B : eqType) (P : {fdist U}). +Notation R := real_realType. +Variables (U : finType) (A B : eqType) (P : R.-fdist U). Definition cpr_eq (X : {RV P -> A}) (a : A) (Y : {RV P -> B}) (b : B) := locked (`Pr_P[ finset (X @^-1 a) | finset (Y @^-1 b)]). @@ -1586,7 +1638,7 @@ Lemma cpr_eq_unit_RV (U : finType) (A : eqType) (P : {fdist U}) `Pr[ X = a | (unit_RV P) = tt ] = `Pr[ X = a ]. Proof. by rewrite cpr_eqE' cPrET pr_eqE. Qed. -Lemma cpr_eqE (U : finType) (P : fdist U) (TA TB : eqType) +Lemma cpr_eqE (U : finType) (P : {fdist U}) (TA TB : eqType) (X : {RV P -> TA}) (Y : {RV P -> TB}) a b : `Pr[ X = a | Y = b ] = `Pr[ [% X, Y] = (a, b) ] / `Pr[Y = b]. Proof. @@ -1595,7 +1647,8 @@ by apply/setP => u; rewrite !inE xpair_eqE. Qed. Section crandom_variable_finType. -Variables (U A B : finType) (P : {fdist U}). +Notation R := real_realType. +Variables (U A B : finType) (P : R.-fdist U). Implicit Types X : {RV P -> A}. Definition cpr_eq_set X (E : {set A}) (Y : {RV P -> B}) (F : {set B}) := @@ -1628,7 +1681,7 @@ rewrite cpr_eq_setE (_ : _ @^-1: [set tt] = setT); last first. by rewrite cPrET pr_eq_setE. Qed. -Lemma cpr_inE (U : finType) (P : fdist U) (A B : finType) +Lemma cpr_inE (U : finType) (P : {fdist U}) (A B : finType) (X : {RV P -> A}) (Z : {RV P -> B}) E F : `Pr[X \in E | Z \in F] = `Pr[ [%X, Z] \in E `* F] / `Pr[Z \in F]. Proof. @@ -1637,7 +1690,7 @@ rewrite !pr_eq_setE /cPr; congr (Pr _ _ * _). by apply/setP => u; rewrite !inE. Qed. -Lemma cpr_inE' (U : finType) (P : fdist U) (A B : finType) +Lemma cpr_inE' (U : finType) (P : {fdist U}) (A B : finType) (X : {RV P -> A}) (Y : {RV P -> B}) (E : {set A}) (F : {set B}) : `Pr[ X \in E | Y \in F ] = `Pr_(`p_ [% X, Y]) [E `*T | T`* F]. Proof. @@ -1648,7 +1701,8 @@ by rewrite setTE Pr_fdistmap_RV2; congr Pr; apply/setP => u; rewrite !inE. Qed. Section cpr_pair. -Variables (U : finType) (P : fdist U) (A B C D : finType) (TA TB TC TD : eqType). +Notation R := real_realType. +Variables (U : finType) (P : R.-fdist U) (A B C D : finType) (TA TB TC TD : eqType). Variables (X : {RV P -> A}) (Y : {RV P -> B}) (Z : {RV P -> C}) (W : {RV P -> D}). Variables (TX : {RV P -> TA}) (TY : {RV P -> TB}) (TZ : {RV P -> TC}) (TW : {RV P -> TD}). @@ -1764,7 +1818,7 @@ Qed. End cpr_pair. -Lemma cpr_eq_product_rule (U : finType) (P : fdist U) (A B C : eqType) +Lemma cpr_eq_product_rule (U : finType) (P : {fdist U}) (A B C : eqType) (X : {RV P -> A}) (Y : {RV P -> B}) (Z : {RV P -> C}) a b c : `Pr[ [% X, Y] = (a, b) | Z = c ] = `Pr[ X = a | [% Y, Z] = (b, c) ] * `Pr[ Y = b | Z = c ]. @@ -1778,7 +1832,7 @@ rewrite product_rule_cond cpr_eqE'; congr (cPr _ _ _ * _). - by rewrite cpr_eqE'. Qed. -Lemma reasoning_by_cases (U : finType) (P : fdist U) +Lemma reasoning_by_cases (U : finType) (P : {fdist U}) (A B : finType) (X : {RV P -> A}) (Y : {RV P -> B}) E : `Pr[ X \in E ] = \sum_(b <- fin_img Y) `Pr[ [% X, Y] \in (E `* [set b])]. Proof. @@ -1800,7 +1854,7 @@ transitivity (\sum_(b in B) F b). by apply eq_bigr => b _; rewrite /F pr_eq_setE /Pr partition_big_preimset. Qed. -Lemma creasoning_by_cases (U : finType) (P : fdist U) +Lemma creasoning_by_cases (U : finType) (P : {fdist U}) (A B C : finType) (X : {RV P -> A}) (Y : {RV P -> B}) (Z : {RV P -> C}) E F : `Pr[ X \in E | Z \in F ] = \sum_(b <- fin_img Y) `Pr[ [% X, Y] \in (E `* [set b]) | Z \in F]. Proof. @@ -1810,8 +1864,9 @@ by apply eq_bigr => b _; rewrite pr_in_pairAC. Qed. Section conditionnally_independent_discrete_random_variables. +Notation R := real_realType. -Variables (U : finType) (P : fdist U) (A B C : eqType). +Variables (U : finType) (P : R.-fdist U) (A B C : eqType). Variables (X : {RV P -> A}) (Y : {RV P -> B}) (Z : {RV P -> C}). Definition cinde_rv := forall a b c, @@ -1833,8 +1888,9 @@ Notation "P |= X _|_ Y | Z" := (@cinde_rv _ P _ _ _ X Y Z) : proba_scope. Notation "X _|_ Y | Z" := (cinde_rv X Y Z) : proba_scope. Section independent_rv. +Notation R := real_realType. -Variables (A : finType) (P : {fdist A}) (TA TB : eqType). +Variables (A : finType) (P : R.-fdist A) (TA TB : eqType). Variables (X : {RV P -> TA}) (Y : {RV P -> TB}). Definition inde_rv := forall (x : TA) (y : TB), @@ -2010,7 +2066,8 @@ End sum_two_rand_var. Section expected_value_of_the_product. Section thm64. -Variables (A B : finType) (P : {fdist A * B}). +Notation R := real_realType. +Variables (A B : finType) (P : R.-fdist (A * B)). Variables (X : {RV (P`1) -> R}) (Y : {RV (P`2) -> R}). Let XY : {RV P -> (R * R)%type} := (fun x => (X x.1, Y x.2)). @@ -2056,8 +2113,9 @@ End thm64. End expected_value_of_the_product. Section sum_n_rand_var_def. +Notation R := real_realType. -Variables (A : finType) (P : {fdist A}). +Variables (A : finType) (P : R.-fdist A). Inductive sum_n : forall n, {RV (P `^ n) -> R} -> 'rV[{RV P -> R}]_n -> Prop := | sum_n_1 : forall X, sum_n (cast_fun_rV10 X) X @@ -2070,8 +2128,9 @@ End sum_n_rand_var_def. Notation "X '\=sum' Xs" := (sum_n X Xs) : proba_scope. Section independent_rv_lemma. +Notation R := real_realType. -Variables (A B : finType) (P1 : {fdist A}) (P2 : {fdist B}) (TA TB : eqType). +Variables (A B : finType) (P1 : R.-fdist A) (P2 : R.-fdist B) (TA TB : eqType). Variable (X : {RV P1 -> TA}) (Y : {RV P2 -> TB}). Let P := P1 `x P2. Let X' : {RV P -> TA} := fun x => X x.1. @@ -2116,8 +2175,9 @@ Qed. Local Close Scope vec_ext_scope. Section sum_n_rand_var. +Notation R := real_realType. -Variable (A : finType) (P : {fdist A}). +Variable (A : finType) (P : R.-fdist A). Local Open Scope vec_ext_scope. @@ -2183,10 +2243,11 @@ Qed. End sum_n_rand_var. Section weak_law_of_large_numbers. +Notation R := real_realType. Local Open Scope vec_ext_scope. -Variables (A : finType) (P : {fdist A}) (n : nat). +Variables (A : finType) (P : R.-fdist A) (n : nat). Variable Xs : 'rV[{RV P -> R}]_n.+1. Variable miu : R. Hypothesis E_Xs : forall i, `E (Xs ``_ i) = miu. @@ -2207,14 +2268,16 @@ have <- : `E (X `/ n.+1) = miu. rewrite E_scalel_RV (E_sum_n X_Xs). rewrite div1R mulRC eqR_divr_mulr ?INR_eq0' // (eq_bigr (fun=> miu)) //. by rewrite big_const /= iter_addR cardE /= size_enum_ord mulRC. -by move/leR_trans: (chebyshev_inequality (X `/ n.+1) e0); apply; exact/leRR. +move/leR_trans: (chebyshev_inequality (X `/ n.+1) e0); apply. +by apply/RleP; rewrite lexx. Qed. End weak_law_of_large_numbers. (* wip*) Section vector_of_RVs. -Variables (U : finType) (P : fdist U). +Notation R := real_realType. +Variables (U : finType) (P : R.-fdist U). Variables (A : finType) (n : nat) (X : 'rV[{RV P -> A}]_n). Local Open Scope ring_scope. Local Open Scope vec_ext_scope. @@ -2222,9 +2285,10 @@ Definition RVn : {RV P -> 'rV[A]_n} := fun x => \row_(i < n) (X ``_ i) x. End vector_of_RVs. Section prob_chain_rule. -Variables (U : finType) (P : {fdist U}). -Variables (A : finType) . +Notation R := real_realType. +Variables (U : finType) (P : R.-fdist U) (A : finType). Local Open Scope vec_ext_scope. + Lemma prob_chain_rule : forall (n : nat) (X : 'rV[{RV P -> A}]_n.+1) x, `Pr[ (RVn X) = x ] = \prod_(i < n.+1) diff --git a/probability/variation_dist.v b/probability/variation_dist.v index b274e050..6aa65d29 100644 --- a/probability/variation_dist.v +++ b/probability/variation_dist.v @@ -20,12 +20,13 @@ Unset Strict Implicit. Import Prenex Implicits. Local Open Scope R_scope. +Local Open Scope fdist_scope. Section variation_distance. Variable A : finType. -Definition var_dist (P Q : fdist A) := \sum_(a : A) `| P a - Q a |. +Definition var_dist (P Q : {fdist A}) := \sum_(a : A) `| P a - Q a |. Local Notation "'d(' P ',' Q ')' " := (var_dist P Q). @@ -43,7 +44,7 @@ rewrite (bigD1 a) //= paddR_eq0 => [[] // | | ]; first exact/normR_ge0. by apply: sumR_ge0 => ? _ ; exact/normR_ge0. Qed. -Lemma leq_var_dist (p q : fdist A) x : `| p x - q x | <= d( p , q ). +Lemma leq_var_dist (p q : {fdist A}) x : `| p x - q x | <= d( p , q ). Proof. rewrite /var_dist (bigD1 x) //= -{1}(addR0 `| p x - q x |). by apply/leR_add2l/sumR_ge0 => ? _; exact/normR_ge0. diff --git a/toy_examples/conditional_entropy.v b/toy_examples/conditional_entropy.v index a7086bf1..6c5bfb0a 100644 --- a/toy_examples/conditional_entropy.v +++ b/toy_examples/conditional_entropy.v @@ -1,9 +1,9 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect ssralg fingroup finalg matrix. +From mathcomp Require Import all_ssreflect ssralg ssrnum fingroup finalg matrix. Require Import Reals Lra. From mathcomp Require Import Rstruct. -Require Import ssrR Reals_ext logb ssr_ext ssralg_ext bigop_ext Rbigop fdist. +Require Import ssrR Reals_ext realType_ext logb ssr_ext ssralg_ext bigop_ext Rbigop fdist. Require Import proba jfdist_cond entropy. (******************************************************************************) @@ -32,9 +32,10 @@ Definition f := [ffun x : 'I_4 * 'I_4 => [eta (fun=>0) with (two, zero) |-> (1/32), (two, one) |-> (1/32), (two, two) |-> (1/16), (two, three) |-> 0, (three, zero) |-> (1/32), (three, one) |-> (1/32), (three, two) |-> (1/16), (three, three) |-> 0] x]. -Lemma f0 : forall x, 0 <= f x. +Lemma f0 : forall x, (0 <= f x)%mcR. Proof. -move=> x; rewrite ffunE; move: x. +move=> x; rewrite ffunE; apply/RleP; move: x. +rewrite (_ : 0%mcR = 0)//. case => -[ [? [[|[|[|[|[]//]]]]] | [? [[|[|[|[|[]//]]]]] | [? [[|[|[|[|[]//]]]]] @@ -63,6 +64,7 @@ rewrite !big_ord_recl !big_ord0 /jcPr /Pr !(big_setX,big_set1) !dE /f /=. rewrite !fdist_sndE /=. rewrite !big_ord_recl !big_ord0 !dE /f !ffunE /=. rewrite !(addR0,add0R,div0R,mul0R). +rewrite -!RplusE !addR0. repeat (rewrite logDiv; try lra). rewrite !log1 !sub0R !log4 !log8 !log16 !log32. rewrite [X in log X](_ : _ = 1/4); last lra. diff --git a/toy_examples/expected_value_variance.v b/toy_examples/expected_value_variance.v index d710b662..a04fe828 100644 --- a/toy_examples/expected_value_variance.v +++ b/toy_examples/expected_value_variance.v @@ -1,6 +1,6 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) -From mathcomp Require Import all_ssreflect. +From mathcomp Require Import all_ssreflect ssrnum. Require Import Reals Lra. From mathcomp Require Import Rstruct. Require Import ssrR Reals_ext Rbigop fdist proba. @@ -13,8 +13,9 @@ Import Prenex Implicits. Local Open Scope reals_ext_scope. Local Open Scope R_scope. +Local Open Scope ring_scope. -Definition f : {ffun 'I_3 -> R} := [ffun i => +Definition pmf : {ffun 'I_3 -> R} := [ffun i => [fun x => 0 with inord 0 |-> 1/2, inord 1 |-> 1/3, inord 2 |-> 1/6] i]. CoInductive I3_spec : 'I_3 -> bool -> bool -> bool -> Prop := @@ -49,9 +50,9 @@ I3_neq. exact: I2_2. Qed. -Lemma f_nonneg : [forall a : 'I_3, 0 x; exact/RleP. case/I3P. - rewrite /f ffunE /= eqxx; lra. - rewrite /f ffunE /= ifF; last by I3_neq. @@ -61,13 +62,12 @@ case/I3P. rewrite eqxx; lra. Qed. -Definition pmf : [finType of 'I_3] ->R+ := mkNNFinfun f_nonneg. - Ltac I3_eq := rewrite (_ : _ == _ = true); last by apply/eqP/val_inj => /=; rewrite inordK. -Lemma pmf1 : \sum_(i in 'I_3) pmf i == 1 :> R. +Lemma pmf01 : [forall a, 0 <= pmf a] && (\sum_(a in 'I_3) pmf a == 1). Proof. +apply/andP; split; first exact: pmf_ge0. apply/eqP. do 3 rewrite big_ord_recl. rewrite big_ord0 addR0 /=. @@ -84,7 +84,7 @@ Qed. Local Open Scope fdist_scope. Local Open Scope proba_scope. -Definition d : {fdist 'I_3} := FDist.mk pmf1. +Definition d : {fdist 'I_3} := FDist.mk pmf01. Definition X : {RV d -> R} := (fun i => INR i.+1). @@ -115,7 +115,7 @@ do 3 rewrite big_ord_recl. rewrite big_ord0 addR0 /=. rewrite /sq_RV /comp_RV /=. rewrite !mul1R. -rewrite {1}/f !ffunE /=. +rewrite {1}/pmf !ffunE /=. rewrite ifT; last by I3_eq. rewrite (_ : INR _ = 2) // mulR1. rewrite /f /=. diff --git a/toy_examples/expected_value_variance_ordn.v b/toy_examples/expected_value_variance_ordn.v index 07d34251..2ea777f4 100644 --- a/toy_examples/expected_value_variance_ordn.v +++ b/toy_examples/expected_value_variance_ordn.v @@ -1,9 +1,9 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) Require Import Reals Lra. -From mathcomp Require Import all_ssreflect. +From mathcomp Require Import all_ssreflect ssrnum. From mathcomp Require Import Rstruct. -Require Import Reals_ext ssrR Rbigop fdist proba. +Require Import Reals_ext ssrR realType_ext Rbigop fdist proba. (* Coq/SSReflect/MathComp, Morikita, Sect. 7.2, without inord *) @@ -14,6 +14,7 @@ Import Prenex Implicits. Local Open Scope reals_ext_scope. Local Open Scope tuple_ext_scope. Local Open Scope R_scope. +Local Open Scope ring_scope. Definition ord1 {n} := lift ord0 (@ord0 n). Definition ord2 {n} := lift ord0 (@ord1 n). @@ -22,31 +23,27 @@ Lemma ord0E n : 0%nat = @ord0 n. Proof. done. Qed. Lemma ord1E n : 1%nat = @ord1 n. Proof. done. Qed. Lemma ord2E n : 2%nat = @ord2 n. Proof. done. Qed. -Definition p : {ffun 'I_3 -> R} := +Definition pmf : {ffun 'I_3 -> R} := finfun [fun x => 0 with ord0 |-> 1/2, ord1 |-> 1/3, ord2 |-> 1/6]. -Lemma p_nonneg : [forall a : 'I_3, 0 a. -rewrite /p ffunE /=. -apply/leRP. +rewrite /pmf ffunE /=. +apply/RleP. do! case: ifP => _; lra. Qed. -Definition p' : [finType of 'I_3] ->R+ := mkNNFinfun p_nonneg. - -Lemma p_sum1 : \sum_(i in 'I_3) p' i == 1. +Lemma pmf01 : [forall a, 0 <= pmf a] && (\sum_(a in 'I_3) pmf a == 1). Proof. -apply/eqP. -rewrite 3!big_ord_recl big_ord0 /=. -rewrite /p !ffunE /=. -by field. +apply/andP; split; first exact: pmf_ge0. +by apply/eqP; rewrite 3!big_ord_recl big_ord0 /= /pmf !ffunE /=; field. Qed. Local Open Scope fdist_scope. Local Open Scope proba_scope. -Definition P : {fdist 'I_3} := FDist.mk p_sum1. +Definition P : {fdist 'I_3} := FDist.mk pmf01. Definition X : {RV P -> R} := (fun i => INR i.+1). @@ -54,7 +51,7 @@ Lemma expected : `E X = 5/3. Proof. rewrite /Ex. rewrite 3!big_ord_recl big_ord0 /=. -rewrite /p /X !ffunE /= /bump /=. +rewrite /pmf /X !ffunE /= /bump /=. rewrite !S_INR (_ : 0%:R = 0) //. by field. Qed. diff --git a/toy_examples/expected_value_variance_tuple.v b/toy_examples/expected_value_variance_tuple.v index a5728ec4..2ce3ceea 100644 --- a/toy_examples/expected_value_variance_tuple.v +++ b/toy_examples/expected_value_variance_tuple.v @@ -1,9 +1,9 @@ (* infotheo: information theory and error-correcting codes in Coq *) (* Copyright (C) 2020 infotheo authors, license: LGPL-2.1-or-later *) Require Import Reals Lra. -From mathcomp Require Import all_ssreflect. +From mathcomp Require Import all_ssreflect ssrnum. From mathcomp Require Import Rstruct. -Require Import Reals_ext ssrR Rbigop fdist proba. +Require Import Reals_ext ssrR realType_ext Rbigop fdist proba. (* Coq/SSReflect/MathComp, Morikita, Sect. 7.2, using tuple *) @@ -14,32 +14,30 @@ Import Prenex Implicits. Local Open Scope reals_ext_scope. Local Open Scope tuple_ext_scope. Local Open Scope R_scope. +Local Open Scope ring_scope. Definition ps := [tuple 1/2; 1/3; 1/6]. Definition p : {ffun 'I_3 -> R} := [ffun i => tnth ps i]. -Lemma p_nonneg : [forall a : 'I_3, 0 a. rewrite /p ffunE. apply/all_tnthP: a => /=. -rewrite !andb_idr => * //; apply/leRP; lra. +rewrite !andb_idr => * //; apply/RleP; lra. Qed. -Definition p' : [finType of 'I_3] ->R+ := mkNNFinfun p_nonneg. - -Lemma p_sum1 : \sum_(i in 'I_3) p' i == 1. +Lemma p_sum01 : [forall a, 0 <= p a] && (\sum_(a in 'I_3) p a == 1). Proof. +apply/andP; split; first exact/p_nonneg. apply/eqP. -rewrite 3!big_ord_recl big_ord0 /=. -rewrite /p !ffunE !(tnth_nth 0) /=. -by field. +by rewrite 3!big_ord_recl big_ord0 /= /p !ffunE !(tnth_nth 0) /=; field. Qed. Local Open Scope fdist_scope. Local Open Scope proba_scope. -Definition P : {fdist 'I_3} := FDist.mk p_sum1. +Definition P : {fdist 'I_3} := FDist.mk p_sum01. Definition X : {RV P -> R} := (fun i => INR i.+1).