Library discprob.prob.countable

From discprob.basic Require Import base Series_Ext.
Require Import Reals Fourier Omega Psatz.
From mathcomp Require Import ssreflect ssrbool ssrfun eqtype choice fintype bigop.
From Coquelicot Require Import Rcomplements Rbar Series Lim_seq Hierarchy Markov.


Definition support {X} (v: X → R) := { x : X | is_true (Rgt_dec (v x) 0) }.

Definition countable_sum {A: countType} (f: A → R) :=
  λ n: nat, oapp f R0 (@pickle_inv A n).

Lemma countable_sum_ext {A: countType} (f f': A → R) n :
  (∀ n, f n = f' n) → countable_sum f n = countable_sum f' n.

Lemma countable_sum_le {A: countType} (f f': A → R) n :
  (∀ n, f n ≤ f' n) → countable_sum f n ≤ countable_sum f' n.

Lemma LPO_count {A: countType} (P: A → Prop):
      (∀ a, P a ∨ ¬ P a) → {a : A | P a} + {(∀ a, ¬ P a)}.

Lemma LPO_countb {A: countType} (P: A → bool):
      {a : A | P a} + {(∀ a, ¬ P a)}.

Definition exC {A: countType} (B: pred A) : bool := LPO_countb B.

Lemma exCP {A: countType} (B: pred A) : reflect (∃ x, B x) (exC B).

Lemma pickle_inv_some_inv {A: countType} n a':
  @pickle_inv A n = Some a' →
  pickle a' = n.

Lemma pickle_inv_some_inj {A: countType} n n' a':
  @pickle_inv A n = Some a' →
  @pickle_inv A n = @pickle_inv A n' →
  n = n'.

Lemma pickle_inj {A: countType} (a a': A):
  pickle a = pickle a' → a = a'.


Definition img {A: countType} {B: eqType} (f: A → B ) : pred B := λ y, exC (λ x, f x == y).
Definition imgT {A: countType} {B: eqType} (f: A → B) := {y | y \in img f}.

Definition img_pickle {A: countType} {B: eqType} (f: A → B) : { y | exC (λ x, f x == y) } → nat.

Definition img_unpickle {A: countType} {B: eqType} (f: A → B) (n: nat)
  : option { y | exC (λ x, f x == y) } :=
 (match unpickle n with
 | Some a ⇒
     Some (exist (λ y : B, exC (λ x : A, f x == y)) (f a)
          (introT (exCP (λ x : A, f x == f a)) (ex_intro (λ x : A, f x == f a) a (eqxx (T:=B) (f a)))))
 | None ⇒ None
 end).

Lemma pickle_imgK {A: countType} {B: eqType} (f: A → B):
  pcancel (img_pickle f) (img_unpickle f).

Definition img_choiceMixin {A: countType} {B: eqType} (f: A → B) :=
  PcanChoiceMixin (pickle_imgK f).
Canonical img_choiceType {A: countType} {B: eqType} {f: A → B} :=
  Eval hnf in ChoiceType (imgT f) (@img_choiceMixin A B f).

Definition img_countMixin {A: countType} {B: eqType} (f: A → B) :=
  PcanCountMixin (pickle_imgK f).
Canonical img_countType {A: countType} {B: eqType} (f: A → B) :=
  Eval hnf in CountType (imgT f) (@img_countMixin A B f).


Section countable_series_facts.
Variable (A: countType).
Implicit Types (a b: A → R).


Lemma countable_sum_scal c a:
  ∀ n, countable_sum (λ x, scal c (a x)) n = (λ n, scal c (countable_sum a n)) n.

Lemma is_seriesC_0 a: (∀ n, a n = 0) → is_series (countable_sum a) 0.

Lemma is_seriesC_ext a b l:
  (∀ n, a n = b n) → is_series (countable_sum a) l → is_series (countable_sum b) l.

Lemma ex_seriesC_ext a b:
  (∀ n, a n = b n) → ex_series (countable_sum a) → ex_series (countable_sum b).

Global Instance is_series_Proper:
  Proper (pointwise_relation nat (@eq R) ==> @eq R ==> iff) is_series.

Global Instance ex_series_Proper:
  Proper (pointwise_relation nat (@eq R) ==> iff) ex_series.

Global Instance Series_Proper:
  Proper (pointwise_relation nat (@eq R) ==> eq) Series.

Global Instance countable_sum_Proper:
  Proper (pointwise_relation A (@eq R) ==> pointwise_relation nat (@eq R)) countable_sum.

Global Instance countable_sum_Proper' {B: countType}:
  Proper (pointwise_relation B (@eq R) ==> eq ==> eq) countable_sum.

Lemma is_seriesC_filter_pos a (P: pred A) (v: R):
  (∀ n, a n ≥ 0) →
  is_series (countable_sum a) v → ex_series (countable_sum (λ n, if P n then a n else 0)).

Lemma is_seriesC_filter_PQ a (P Q: pred A) (v: R):
  (∀ n, a n ≥ 0) →
  is_series (countable_sum (λ n, if P n then a n else 0)) v →
  (∀ n, Q n → P n) →
  ex_series (countable_sum (λ n, if Q n then a n else 0)).

Lemma ex_seriesC_filter_PQ a (P Q: pred A):
  (∀ n, a n ≥ 0) →
  ex_series (countable_sum (λ n, if P n then a n else 0)) →
  (∀ n, Q n → P n) →
  ex_series (countable_sum (λ n, if Q n then a n else 0)).

Lemma ex_seriesC_filter_P a (Q: pred A):
  (∀ n, a n ≥ 0) →
  ex_series (countable_sum a) →
  ex_series (countable_sum (λ n, if Q n then a n else 0)).

Lemma is_seriesC_filter_split a (P: pred A) (v: R):
  (∀ n, a n ≥ 0) →
  is_series (countable_sum a) v →
  Series (countable_sum (λ n, if P n then a n else 0)) +
  Series (countable_sum (λ n, if ~~ P n then a n else 0)) = v.

Lemma is_seriesC_filter_union a (P Q: pred A) (v: R):
  (∀ n, a n ≥ 0) →
  is_series (countable_sum (λ n, if P n || Q n then a n else 0)) v →
  Series (countable_sum (λ n, if P n then a n else 0)) +
  Series (countable_sum (λ n, if Q n then a n else 0))
    - Series (countable_sum (λ n, if P n && Q n then a n else 0)) = v.

Lemma SeriesC_ext a b:
  (∀ n, a n = b n) →
  Series (countable_sum a) = Series (countable_sum b).

Lemma SeriesC_le a b:
  (∀ n, 0 ≤ a n ≤ b n) → ex_series (countable_sum b) →
  Series (countable_sum a) ≤ Series (countable_sum b).

Lemma SeriesC_le' a b:
  (∀ n, a n ≤ b n) →
  ex_series (countable_sum a) → ex_series (countable_sum b) →
  Series (countable_sum a) ≤ Series (countable_sum b).

Lemma countable_sum_plus a b:
  ∀ n, (countable_sum (λ x, a x + b x) n = (λ n, countable_sum a n + countable_sum b n) n).

Lemma countable_sum_Rabs a:
  ∀ n, (countable_sum (λ x, Rabs (a x)) n) = (λ n, Rabs (countable_sum a n)) n.

Lemma ex_seriesC_le a b:
  (∀ n, 0 ≤ a n ≤ b n) → ex_series (countable_sum b) →
  ex_series (countable_sum a).

Lemma countable_sum_scal_l c a:
  ∀ n, (countable_sum (λ x, c × a x) n = (λ n, c × (countable_sum a n)) n).

Lemma countable_sum_scal_r c a:
  ∀ n, (countable_sum (λ x, a x × c) n = (λ n, (countable_sum a n) × c) n).

Lemma SeriesC_scal_l (c : R) a:
  Series (λ n, countable_sum (λ x, c × a x) n) = c × Series (countable_sum a).

Lemma SeriesC_scal_r (c : R) a:
  Series (λ n, countable_sum (λ x, a x × c) n) = Series (countable_sum a) × c.

Lemma ex_seriesC_scal_l (c : R) a:
  ex_series (countable_sum a) →
  ex_series (countable_sum (λ x, c × a x)).

Lemma ex_seriesC_scal_r (c : R) a:
  ex_series (countable_sum a) →
  ex_series (countable_sum (λ x, a x × c)).

Lemma ex_seriesC_plus a b:
  ex_series (countable_sum a) →
  ex_series (countable_sum b) →
  ex_series (countable_sum (λ x, a x + b x)).

Lemma is_seriesC_scal_l (c : R) a v:
  is_series (countable_sum a) v →
  is_series (countable_sum (λ x, c × a x)) (c × v).

Lemma is_seriesC_scal_r (c : R) a v:
  is_series (countable_sum a) v →
  is_series (countable_sum (λ x, a x × c)) (v × c).

Lemma is_seriesC_plus a b v1 v2:
  is_series (countable_sum a) v1 →
  is_series (countable_sum b) v2 →
  is_series (countable_sum (λ x, a x + b x)) (v1 + v2).

Lemma is_seriesC_bump (x' : A) v:
  is_series (countable_sum (λ x, if x == x' then v else 0)) v.

Lemma ex_seriesC_Rabs a:
  ex_series (countable_sum (λ x, Rabs (a x))) →
  ex_series (countable_sum a).

Lemma SeriesC_bump (x' : A) v:
  Series (countable_sum (λ x, if x == x' then v else 0)) = v.

Lemma SeriesC_0 a:
  (∀ x, a x = 0) →
  Series (countable_sum a) = 0.

End countable_series_facts.