Module infotheo.lib.realType_ext
From HB Require Import structures.From mathcomp Require Import all_ssreflect ssralg archimedean ssrnum ssrint.
From mathcomp Require Import reals normedtype sequences exp.
From mathcomp Require Import unstable mathcomp_extra boolp interval_inference.
From mathcomp Require Import ring lra.
Declare Scope reals_ext_scope.
Reserved Notation "+| r |" (at level 0, r at level 99, format "+| r |").
Reserved Notation "p '.~'" (format "p .~", at level 1).
Reserved Notation "P '`<<' Q" (at level 51).
Reserved Notation "P '`< (at level 51).
Reserved Notation "{ 'prob' T }" (at level 0, format "{ 'prob' T }").
Reserved Notation "x %:pr" (at level 1, format "x %:pr").
Reserved Notation "x %:opr" (at level 1, format "x %:opr").
Reserved Notation "[ 's_of' p , q ]" (format "[ 's_of' p , q ]").
Reserved Notation "[ 'r_of' p , q ]" (format "[ 'r_of' p , q ]").
Reserved Notation "[ 'p_of' r , s ]" (format "[ 'p_of' r , s ]").
Reserved Notation "[ 'q_of' r , s ]" (format "[ 'q_of' r , s ]").
Set Implicit Arguments.
Set SsrOldRewriteGoalsOrder.
Unset Strict Implicit.
Import Prenex Implicits.
Local Open Scope ring_scope.
Import Order.POrderTheory Order.TotalTheory GRing.Theory Num.Theory.
Definition
ex2C not a defined object.
Proof.
Lemma asboolTE : `[< True >] = true.
Proof.
Notation "+| r |" := (Num.Def.maxr 0 r) : reals_ext_scope.
Section num_ext.
Lemma wpmulr_lgt0 (R : numDomainType) (x y : R) : 0 <= x -> 0 < y * x -> 0 < y.
Lemma wpmulr_rgt0 (R : numDomainType) (x y : R) : 0 <= x -> 0 < x * y -> 0 < y.
Proof.
Lemma eqr_divrMr {R : realType} (z x y : R) : z != 0 ->
y / z = x <-> y = x * z.
Proof.
Lemma prodr_gt0 (R : numDomainType) (A : finType) (F : A -> R) :
(forall a, 0 < F a) -> 0 < \prod_(a : A) F a.
Notation "p '.~'" := (onem p).
Section onem.
Variable R : realFieldType.
Implicit Types r s : R.
Lemma onem_le r s : (r <= s) = (s.~ <= r.~).
Lemma onem_lt r s : (r < s) = (s.~ < r.~).
Proof.
Lemma onemE r : r.~ = 1 - r
Proof.
Lemma onem_div r s : s != 0 -> (r / s).~ = (s - r) / s.
Lemma onem_prob r : 0 <= r <= 1 -> 0 <= r.~ <= 1.
Lemma onem_eq0 r : (r.~ = 0) <-> (r = 1).
Lemma onem_neq0 (r : R) : (r.~ != 0) <-> (r != 1).
Lemma onem_eq1 r : r.~ = 1 <-> r = 0
Proof.
Lemma onem_oprob r : 0 < r < 1 -> 0 < r.~ < 1.
Lemma subr_onem r s : r - s.~ = r + s - 1.
End onem.
Section about_the_pow_function.
Lemma x_x2_eq {R : realFieldType} (q : R) :
q * (1 - q) = 4^-1 - 4^-1 * (2 * q - 1) ^+ 2.
Proof.
Lemma x_x2_max {R : realFieldType} (q : R) : q * (1 - q) <= 4^-1.
Proof.
Lemma x_x2_pos {R : realFieldType} (q : R) : 0 < q < 1 -> 0 < q * (1 - q).
Proof.
Lemma x_x2_nneg {R : realFieldType} (q : R) : 0 <= q <= 1 -> 0 <= q * (1 - q).
Proof.
End about_the_pow_function.
Lemma expR1_gt2 {R : realType} : 2 < expR 1 :> R.
Proof.
Section dominance_defs.
Definition
dominates not a defined object.
locked (forall a, Q a = 0 -> P a = 0).
Local Notation "P '`<<' Q" := (dominates Q P).
Lemma dominatesP {R : realType} A (Q P : A -> R) :
P `<< Q <-> forall a, Q a = 0 -> P a = 0.
Proof.
End dominance_defs.
Notation "P '`<<' Q" := (dominates Q P).
Section dominance.
Context {R : realType}.
Lemma dominatesxx A (P : A -> R) : P `<< P.
Proof.
Let dominatesN A (Q P : A -> R) : P `<< Q -> forall a, P a != 0 -> Q a != 0.
Proof.
Lemma dominatesE A (Q P : A -> R) a : P `<< Q -> Q a = 0 -> P a = 0.
Proof.
Lemma dominatesEN A (Q P : A -> R) a : P `<< Q -> P a != 0 -> Q a != 0.
Proof.
Lemma dominates_scale (A : finType) (Q P : A -> R) : P `<< Q ->
forall k : R, k != 0 -> P `<< [ffun a : A => k * Q a].
Proof.
by rewrite ffunE mulf_eq0 (negbTE k0)/= => /eqP/(dominatesE PQ).
Qed.
Definition
dominatesb not a defined object.
[forall b, (Q b == 0) ==> (P b == 0)].
End dominance.
Notation "P '`<<' Q" := (dominates Q P) : reals_ext_scope.
Notation "P '`< := (dominatesb Q P) : reals_ext_scope.
Module Prob.
Section prob.
Context {R : realType}.
Lemma O1 (p : {i01 R}) : 0 <= p%:num <= 1.
Proof.
Prob.mk not a defined object.
Itv01 (andP O1).1 (andP O1).2.
#[deprecated(since="infotheo 0.9.7", note="use %:num instead")]
Definition
Prob.p not a defined object.
End prob.
End Prob.
Notation "q %:pr" := (@Prob.mk _ q (@Prob.O1 _ _)).
#[deprecated(since="infotheo 0.9.7", note="use {i01 _} instead")]
Notation "'prob' R" := {i01 R} (at level 1).
Notation "{ 'prob' R }" := {i01 R}.
Section prob_lemmas.
Variable R : realType.
Implicit Types p q : {prob R}.
#[deprecated(since="infotheo 0.9.7", note="use 0%:i01 instead")]
Definition
prob0 not a defined object.
#[deprecated(since="infotheo 0.9.7", note="use 1%:i01 instead")]
Definition
prob1 not a defined object.
Canonical
probcplt not a defined object.
Eval hnf in Prob.mk (onem_prob (Prob.O1 p)).
#[deprecated(since="infotheo 0.9.7", note="use ge0 instead")]
Lemma prob_ge0 (p : {prob R}) : 0 <= p%:num.
Proof.
#[deprecated(since="infotheo 0.9.7", note="use le1 instead")]
Lemma prob_le1 (p : {prob R}) : p%:num <= 1.
Proof.
Lemma prob_gt0 (p : {prob R}) : p != 0%:i01 <-> 0 < p%:num.
Proof.
Lemma prob_lt1 (p : {prob R}) : p != 1%:i01 <-> p%:num < 1.
Proof.
Lemma prob_trichotomy p : p = 0%:i01 \/ p = 1%:i01 \/ 0 < p%:num < 1.
Proof.
Lemma probK p : p = (p%:num.~).~%:i01.
Lemma probKC (p : {prob R}) : p%:num + p%:num.~ = 1 :> R.
Proof.
Lemma probadd_eq0 p q : p%:num + q%:num = 0 <-> p = 0%:i01 /\ q = 0%:i01.
Proof.
Lemma probadd_neq0 p q : p%:num + q%:num != 0 <-> p != 0%:i01 \/ q != 0%:i01.
Proof.
Lemma probmul_eq1 p q : p%:num * q%:num = 1 <-> p = 1%:i01 /\ q = 1%:i01.
Proof.
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 < p%:num by rewrite lt_neqAle 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 (@Order.le ring_display _ _ _)) =>
exact/prob_le1 : core.
#[export] Hint Extern 0 (is_true (@Order.le ring_display _ _ _)) =>
exact/prob_ge0 : core.
Lemma prob_invn {R : realType} (m : nat) :
0 <= ((1 + m)%:R^-1 : R) <= 1.
Canonical
probinvn not a defined object.
Eval hnf in @Prob.mk _ ((1 + n)%:R^-1) (@prob_invn R n).
Module OProb.
Section def.
Record t (R: realType):= mk {
p :> {prob R};
Op1 : 0 < p%:num < 1 }.
Definition
OProb.O1 not a defined object.
Arguments O1 : simpl never.
End def.
Module Exports.
Notation oprob := t.
Notation "q %:opr" := (@mk _ q (@O1 _ _)).
OProb.Exports.OProb_t__canonical__eqtype_SubType not a defined object.
OProb.Exports.OProb_t__canonical__eqtype_SubType not a defined object.
OProb.Exports.OProb_t__canonical__eqtype_SubType not a defined object.
OProb.Exports.OProb_t__canonical__eqtype_SubType not a defined object.
OProb.Exports.OProb_t__canonical__eqtype_SubType not a defined object.
OProb.Exports.OProb_t__canonical__eqtype_SubType not a defined object.
OProb.Exports.OProb_t__canonical__eqtype_SubType not a defined object.
OProb.Exports.OProb_t__canonical__eqtype_SubEquality not a defined object.
OProb.Exports.OProb_t__canonical__eqtype_SubEquality not a defined object.
OProb.Exports.OProb_t__canonical__eqtype_SubEquality not a defined object.
OProb.Exports.OProb_t__canonical__eqtype_SubEquality not a defined object.
OProb.Exports.OProb_t__canonical__eqtype_SubEquality not a defined object.
OProb.Exports.OProb_t__canonical__eqtype_SubEquality not a defined object.
OProb.Exports.OProb_t__canonical__eqtype_SubEquality not a defined object.
End Exports.
End OProb.
Export OProb.Exports.
Canonical
oprobcplt not a defined object.
Eval hnf in OProb.mk (onem_oprob (OProb.O1 p)).
Reserved Notation "{ 'oprob' T }" (at level 0, format "{ 'oprob' T }").
Notation "{ 'oprob' T }" := (@oprob T).
Notation oprob_to_real o := (OProb.p o)%:num.
Section oprob_lemmas.
Variable R : realType.
Implicit Types p q : {oprob R}.
Lemma oprob_gt0 p : 0 < oprob_to_real p.
Proof.
Lemma oprob_lt1 p : oprob_to_real p < 1.
Proof.
Import Order.POrderTheory Order.TotalTheory.
Lemma oprob_neq0 p : oprob_to_real p != 0 :> R.
Lemma oprob_neq1 p : oprob_to_real p != 1 :> R.
Lemma oprob_onemK (p : {oprob R}) : p = ((oprob_to_real p).~).~%:pr%:opr.
Lemma prob_trichotomy' (p : {prob R}) (P : {prob R} -> Prop) :
P 0%:i01 -> P 1%:i01 -> (forall o : {oprob R}, P (OProb.p o)) -> P p.
Proof.
Lemma oprobadd_gt0 p q : 0 < oprob_to_real p + oprob_to_real q.
Lemma oprobadd_neq0 p q : oprob_to_real p + oprob_to_real q != 0.
End oprob_lemmas.
Section prob_lemmas2.
Variable R : realType.
Implicit Types p q : {prob R}.
Definition
divrnnm not a defined object.
Lemma prob_divrnnm_subproof n m : (0 <= divrnnm n m <= 1)%O.
Proof.
Canonical
probdivrnnm not a defined object.
Eval hnf in @Prob.mk _ (divrnnm n m) (prob_divrnnm_subproof n m).
Lemma prob_invprob_subproof (p : {prob R}) : (0 <= 1 / (1 + p%:num) <= 1)%O.
Proof.
Definition
prob_invprob not a defined object.
Lemma prob_mulr_subproof (p q : {prob R}) : 0 <= p%:num * q%:num <= 1.
Canonical
probmulr not a defined object.
Eval hnf in @Prob.mk _ (p%:num * q%:num) (prob_mulr_subproof p q).
End prob_lemmas2.
Definition
s_of_pq not a defined object.
locked (p%:num.~ * q%:num.~).~%:i01.
Declare Scope reals_ext_scope.
Notation "[ 's_of' p , q ]" := (s_of_pq p q) : reals_ext_scope.
Local Open Scope reals_ext_scope.
Section s_of_pq_lemmas.
Variable R : realType.
Implicit Types p q : {prob R}.
Lemma s_of_pqE p q : [s_of p, q]%:num = (p%:num.~ * q%:num.~).~ :> R.
Proof.
Lemma s_of_0q q : [s_of 0%:i01, q] = q.
Lemma s_of_1q q : [s_of 1%:i01, q] = 1%:i01.
Lemma s_of_p0 p : [s_of p, 0%:i01] = p.
Lemma s_of_p1 p : [s_of p, 1%:i01] = 1%:i01.
Lemma s_of_gt0 p q : p != 0%:i01 -> 0 < [s_of p, q]%:num.
Proof.
Lemma ge_s_of p q : p%:num <= [s_of p, q]%:num.
End s_of_pq_lemmas.
Lemma r_of_pq_subproof {R : realType} (p q : {prob R}) :
0 <= p%:num / [s_of p, q]%:num <= 1.
Proof.
Definition
r_of_pq not a defined object.
locked (Prob.mk (r_of_pq_subproof p q)).
Notation "[ 'r_of' p , q ]" := (r_of_pq p q) : reals_ext_scope.
Section r_of_pq_lemmas.
Variable R : realType.
Implicit Types p q : {prob R}.
Lemma r_of_pqE p q : [r_of p, q]%:num = p%:num / [s_of p, q]%:num :> R.
Proof.
Lemma r_of_p0 p : p != 0%:i01 -> [r_of p, 0%:i01] = 1%:i01.
Lemma r_of_0q q : [r_of 0%:i01, q] = 0%:i01.
Lemma r_of_p1 p : [r_of p, 1%:i01] = p.
Lemma r_of_1q q : [r_of 1%:i01, q] = 1%:i01.
End r_of_pq_lemmas.
Lemma p_is_rs {R : realType} (p q : {prob R}) :
p%:num = [r_of p, q]%:num * [s_of p, q]%:num :> R.
Proof.
Lemma p_of_rs_subproof {R : realType} (r s : {prob R}) :
0 <= r%:num * s%:num <= 1.
Definition
p_of_rs not a defined object.
locked (Prob.mk (p_of_rs_subproof r s)).
Notation "[ 'p_of' r , s ]" := (p_of_rs r s) : reals_ext_scope.
Section p_of_rs_lemmas.
Variable R : realType.
Implicit Types r s : {prob R}.
Lemma p_of_rsE r s : [p_of r, s]%:num = r%:num * s%:num :> R.
Proof.
Lemma p_of_r1 r : [p_of r, 1%:i01] = r.
Lemma p_of_1s s : [p_of 1%:i01, s] = s.
Lemma p_of_r0 r : [p_of r, 0%:i01] = 0%:i01.
Lemma p_of_0s s : [p_of 0%:i01, s] = 0%:i01.
Lemma p_of_rsC r s : [p_of r, s] = [p_of s, r].
Lemma p_of_neq1 r s : 0 < s%:num < 1 -> [p_of r, s] != 1%:i01.
Proof.
Lemma p_of_rs1 r s :
([p_of r, s] == 1%:i01 :> {prob R}) = ((r == 1%:i01) && (s == 1%:i01)).
Proof.
Lemma p_of_rs1P r s : reflect (r = 1%:i01 /\ s = 1%:i01) ([p_of r, s] == 1%:i01).
Proof.
End p_of_rs_lemmas.
Lemma q_of_rs_prob {R : realType} (r s : {prob R}) :
0 <= (r%:num.~ * s%:num) / [p_of r, s]%:num.~ <= 1.
Proof.
by rewrite onem1 !mul0r lexx ler01.
have [->|s1] := eqVneq s 1%:i01.
rewrite mulr1 p_of_r1 divff ?onem_neq0//.
by rewrite ler01// lexx.
apply/andP; split.
by rewrite divr_ge0// mulr_ge0.
rewrite ler_pdivrMr// ?mul1r.
by rewrite p_of_rsE {2}/onem lerBrDr -mulrDl addrC add_onemK mul1r.
rewrite onem_gt0// -prob_lt1.
apply/p_of_rs1P/not_andP; left.
exact/eqP.
Qed.
Lemma r_of_pq_is_r {R : realType} (p q r s : {prob R}) :
r != 0%:i01 -> s != 0%:i01 ->
p%:num = r%:num * s%:num :> R ->
(s%:num).~ = (p%:num).~ * (q%:num).~ -> [r_of p, q] = r.
Proof.
Definition
q_of_rs not a defined object.
locked (Prob.mk (q_of_rs_prob r s)).
Notation "[ 'q_of' r , s ]" := (q_of_rs r s) : reals_ext_scope.
Section q_of_rs_lemmas.
Variable R : realType.
Implicit Types r s : {prob R}.
Lemma q_of_rsE r s :
[q_of r, s]%:num = (r%:num.~ * s%:num) / [p_of r, s]%:num.~ :> R.
Proof.
Lemma q_of_r0 r : [q_of r, 0%:i01] = 0%:i01.
Lemma q_of_r1 r : r != 1%:i01 -> [q_of r, 1%:i01] = 1%:i01.
Proof.
Lemma q_of_1s s : [q_of 1%:i01, s] = 0%:i01.
End q_of_rs_lemmas.
Lemma pq_is_rs {R : realType} (p q : {prob R}) :
p%:num.~ * q%:num = [r_of p, q]%:num.~ * [s_of p, q]%:num.
Proof.
Lemma s_of_pqK {R : realType} (r s : {prob R}) : [p_of r, s] != 1%:i01 ->
[s_of [p_of r, s], [q_of r, s]] = s.
Proof.
Lemma r_of_pqK {R : realType} (r s : {prob R}) :
[p_of r, s] != 1%:i01 -> s != 0%:i01 ->
[r_of [p_of r, s], [q_of r, s]] = r.
Proof.
rewrite !(r_of_pqE,s_of_pqE,q_of_rsE,p_of_rsE) /onem.
suff rs_neq1 : 1 - r%:num * s%:num != 0.
(field; do ?[apply/andP; split]) => //.
by rewrite mulrBl mul1r !opprB -!addrA addrC !addrA !subrK ?subrr ?add0r.
rewrite subr_eq0.
apply: contra H1 => /eqP H1.
by apply/eqP/val_inj; rewrite /= p_of_rsE.
Qed.
Lemma oprob_divrposxxy {R : realType} (x y : {posnum R}) :
0 < x%:num / (x%:num + y%:num) < 1.
Proof.
Lemma prob_divrposxxy {R : realType} (x y : {posnum R}) :
0 <= x%:num / (x%:num + y%:num) <= 1.
Proof.
Canonical
divrposxxy not a defined object.
Eval hnf in Prob.mk (prob_divrposxxy x y).
Lemma s_of_rpos_probA {R : realType} (p q r : {posnum R}) :
[s_of divrposxxy p ((q%:num + r%:num)%:pos), divrposxxy q r] =
divrposxxy (p%:num + q%:num)%:pos r.
Proof.
Lemma r_of_rpos_probA {R : realType} (p q r : {posnum R}) :
[r_of divrposxxy p (q%:num + r%:num)%:pos, divrposxxy q r] =
divrposxxy p q.
Proof.
Lemma r_of_p0_oprob {R : realType} (p : {oprob R}) :
[r_of (OProb.p p), 0%:i01] = 1%:i01.
Proof.
Lemma onem_divrxxy {R : realType} (r q : {posnum R}) :
(r%:num / (r%:num + q%:num)).~ = q%:num / (q%:num + r%:num).
Section leR_ltR_sumR_finType.
Context {R : realType}.
Variables (A : finType) (f g : A -> R) (P Q : pred A).
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.
Lemma leR_sumRl : (forall i, P i -> f i <= g i) ->
(forall i, Q i -> 0 <= g i) -> (forall i, P i -> Q i) ->
\sum_(i | P i) f i <= \sum_(i | Q i) g i.
Proof.
Lemma leR_sumRl_support (U : pred A) :
(forall a, 0 <= f a) -> (forall i, P i -> Q i) ->
\sum_(i in U | P i) f i <= \sum_(i in U | Q i) f i.
Proof.
Lemma ltR_sumR_support (X : {set A}) : (0 < #|X|)%N ->
(forall i, i \in X -> f i < g i) ->
\sum_(i in X) f i < \sum_(i in X) g i.
Proof.
move: (ltn0Sn n); rewrite -Hn card_gt0; case/set0Pn => a0 Ha0.
rewrite (@big_setD1 _ _ _ _ a0 _ f) //= (@big_setD1 _ _ _ _ a0 _ g) //=.
case: n => [|n] in IH Hn.
rewrite (_ : X :\ a0 = set0); first by rewrite !big_set0 2!addr0; exact: H.
move: Hn.
by rewrite (cardsD1 a0) Ha0 /= add1n => -[] /eqP; rewrite cards_eq0 => /eqP.
apply: ltrD; first exact/H.
apply: IH => //.
- by move: Hn; rewrite (cardsD1 a0) Ha0 /= add1n => -[].
- by move=> a; rewrite in_setD inE => /andP[_ ?]; exact: H.
Qed.
Lemma ltR_sumR : (O < #|A|)%N -> (forall i, f i < g i) ->
\sum_(i in A) f i < \sum_(i in A) g i.
Proof.
have : forall i : A, i \in [set: A] -> f i < g i by move=> a _; exact/H0.
move/ltR_sumR_support; rewrite cardsT => /(_ A0).
rewrite big_mkcond /= [in X in _ < X]big_mkcond /=.
rewrite (eq_bigr f) //; last by move=> *; rewrite inE.
by rewrite [in X in _ < X](eq_bigr g) // => *; rewrite inE.
Qed.
End leR_ltR_sumR_finType.
Lemma leR_sumR_eq {R : realType} (A : finType) (f g : A -> R) (P : pred A) :
(forall a, P a -> f a <= g a) ->
\sum_(a | P a) g a = \sum_(a | P a) f a ->
forall a, P a -> g a = f a.
Proof.
Definition
frac_part not a defined object.
x - (Num.floor x)%:~R.
Section oprob_lemmas2.
Variable R : realType.
Implicit Types p q : {oprob R}.
Lemma oprob_mulr_subproof p q :
(0 < (OProb.p p)%:num * (OProb.p q)%:num < 1)%O.
Proof.
Canonical
oprobmulr not a defined object.
Eval hnf in @OProb.mk R (probmulr (OProb.p p) (OProb.p q)) (oprob_mulr_subproof p q).
Lemma s_of_pq_oprob_subproof p q : (0 < [s_of (OProb.p p), (OProb.p q)]%:num < 1)%O.
Proof.
Canonical
oprob_of_s_of_pq not a defined object.
Eval hnf in OProb.mk (s_of_pq_oprob_subproof p q).
Lemma r_of_pq_oprob_subproof p q : (0 < [r_of (OProb.p p), (OProb.p q)]%:num < 1)%O.
Proof.
by rewrite divr_gt0// oprob_gt0.
rewrite ltr_pdivrMr ?mul1r ?oprob_gt0//.
rewrite lt_neqAle; apply/andP; split; last exact/ge_s_of.
rewrite s_of_pqE lt_eqF//.
rewrite onemM !onemK -addrA ltrDl.
rewrite -[X in 0 < X - _]mul1r -mulrBl -onemE.
by rewrite mulr_gt0// oprob_gt0.
Qed.
Canonical
oprob_of_r_of_pq not a defined object.
Eval hnf in OProb.mk (r_of_pq_oprob_subproof p q).
Lemma s_of_gt0_oprob p q : 0 < [s_of (OProb.p p), (OProb.p q)]%:num.
Proof.
End oprob_lemmas2.