Module mathcomp.analysis.measure

From mathcomp Require Import all_ssreflect all_algebra finmap.
From mathcomp Require Import mathcomp_extra boolp classical_sets functions.
From mathcomp Require Import cardinality fsbigop .
Require Import reals ereal signed topology normedtype sequences esum numfun.
From HB Require Import structures.

Measure Theory

NB: See CONTRIBUTING.md for an introduction to HB concepts and commands.

This files provides a formalization of the basics of measure theory. This
includes the formalization of mathematical structures and of measures, as
well as standard theorems such as the Measure Extension theorem that
builds a measure given a function defined over a semiring of sets, the
intermediate outer measure being
infF{k=0μ(Fk)XkFk}.\inf_F\{ \sum_{k=0}^\infty \mu(F_k) | X \subseteq \bigcup_k F_k\}.

Reference:

Mathematical structures

   semiRingOfSetsType d == the type of semirings of sets                   
                           The carrier is a set of sets A_i such that      
                           "measurable A_i" holds.                         
                           "measurable A" is printed as "d.-measurable A"  
                           where d is a "display parameter" whose purpose  
                           is to distinguish different "measurable"        
                           predicates in the same context.                 
                           The HB class is SemiRingOfSets.                 
       ringOfSetsType d == the type of rings of sets                       
                           The HB class is RingOfSets.                     
    algebraOfSetsType d == the type of algebras of sets                    
                           The HB class is AlgebraOfsets.                  
         measurableType == the type of sigma-algebras                      
                           The HB class is Measurable.                     

Instances of mathematical structures

discrete_measurable_unit == the measurableType corresponding to            
                            [set: set unit]                                
discrete_measurable_bool == the measurableType corresponding to            
                            [set: set bool]                                
 discrete_measurable_nat == the measurableType corresponding to            
                            [set: set nat]                                 
               setring G == the set of sets G contains the empty set, is   
                            closed by union, and difference                
                <<r G >> := smallest setring G                             
                            <<r G >> is equipped with a structure of ring  
                            of sets.                                       
   G.-ring.-measurable A == A belongs for the ring of sets <<r G >>        
       sigma_algebra D G == the set of sets G forms a sigma algebra on D   
             <<s D, G >> == sigma-algebra generated by G on D              
                         := smallest (sigma_algebra D) G                   
                <<s G >> := <<s setT, G >>                                 
                            <<s G >> is equipped with a structure of       
                            sigma-algebra                                  
  G.-sigma.-measurable A == A is measurable for the sigma-algebra <<s G >> 
          salgebraType G == the measurableType corresponding to <<s G >>   
                            This is an HB alias.                           
   mu .-cara.-measurable == sigma-algebra of Caratheodory measurable sets  

Structures for functions on classes of sets

A few details about mixins/factories to highlight implementations
peculiarities:

{content set T -> \bar R} == type of contents                              
                           T is expected to be a semiring of sets and R a  
                           numFieldType.                                   
                           The HB class is Content.                        
{measure set T -> \bar R} == type of (non-negative) measures               
                           T is expected to be a semiring of sets and R a  
                           numFieldType.                                   
                           The HB class is Measure.                        
Content_SubSigmaAdditive_isMeasure ==                                      
                     mixin that extends a content to a measure with the    
                     proof that it is semi_sigma_additive                  
Content_isMeasure == factory that extends a content to a measure with      
                     the proof that it is sub_sigma_additive               
                isMeasure == factory corresponding to the "textbook        
                           definition" of measures                         
          sfinite_measure == predicate for s-finite measure functions      
{sfinite_measure set T -> \bar R} == type of s-finite measures             
                           The HB class is SFiniteMeasure.                 
   sfinite_measure_seq mu == the sequence of finite measures of the        
                           s-finite measure mu                             
 Measure_isSFinite_subdef == mixin for s-finite measures                   
        Measure_isSFinite == factory for s-finite measures                 
{sigma_finite_content set T -> \bar R} == contents that are also sigma     
                           finite                                          
                           The HB class is SigmaFiniteContent.             
{sigma_finite_measure set T -> \bar R} == measures that are also sigma     
                           finite                                          
                           The HB class is SigmaFiniteMeasure.             
         sigma_finite A f == the measure function f is sigma-finite on the 
                           A : set T with T a semiring of sets             
              fin_num_fun == predicate for finite function over measurable 
                           sets                                            
           FinNumFun.type == type of functions over semiring of sets       
                           returning a fin_num                             
                           The HB class is FinNumFun.                      
{finite_measure set T -> \bar R} == finite measures                        
                           The HB class is FiniteMeasure.                  
     SigmaFinite_isFinite == mixin for finite measures                     
         Measure_isFinite == factory for finite measures                   
      subprobability T R == subprobability measure over the measurableType 
                           T with values in \bar R with R : realType       
                           The HB class is SubProbability.                 
        probability T R == probability measure over the measurableType T   
                           with values in \bar with R : realType           
              probability == type of probability measures                  
                           The HB class is Probability.                    
    Measure_isProbability == factor for probability measures               
             mnormalize mu == normalization of a measure to a probability  
{outer_measure set T -> \bar R} == type of an outer measure over sets      
                           of elements of type T : Type where R is         
                           expected to be a numFieldType                   
                           The HB class is OuterMeasure.                   

Instances of measures

 pushforward mf m == pushforward/image measure of m by f, where mf is a    
                     proof that f is measurable                            
                     m has type set T -> \bar R.                           
             \d_a == Dirac measure                                         
        msum mu n == the measure corresponding to the sum of the measures  
                     mu_0, ..., mu_{n-1}                                   
       @mzero T R == the zero measure                                      
measure_add m1 m2 == the measure corresponding to the sum of the           
                     measures m1 and m2                                    
       mscale r m == the measure of corresponding to fun A => r * m A      
                     where r has type {nonneg R}                           
     mseries mu n == the measure corresponding to the sum of the           
                     measures mu_n, mu_{n+1}, ...                          
     mrestr mu mD == restriction of the measure mu to a set D; mD is a     
                     proof that D is measurable                            
     counting T R == counting measure                                      
                                                                           
     setI_closed G == the set of sets G is closed under finite             
                      intersection                                         
     setU_closed G == the set of sets G is closed under finite union       
     setC_closed G == the set of sets G is closed under complement         
     setD_closed G == the set of sets G is closed under difference         
    ndseq_closed G == the set of sets G is closed under non-decreasing     
                      countable union                                      
 trivIset_closed G == the set of sets G is closed under pairwise-disjoint  
                      countable union                                      

Hierarchy of s-finite, sigma-finite, finite measures

                  sfinite_measure == predicate for s-finite measure        
                                     functions                             
         Measure_isSFinite_subdef == mixin for s-finite measures           
                   SFiniteMeasure == structure of s-finite measures        
{sfinite_measure set T -> \bar R} == type of s-finite measures             
                Measure_isSFinite == factory for s-finite measures         
           sfinite_measure_seq mu == the sequence of finite measures of    
                                     the s-finite measure mu               
                                                                           
                      sigma_finite A f == the measure function f is        
                                          sigma-finite on the set A:set T  
                                          with T : semiRingOfSetsType      
                         isSigmaFinite == mixin corresponding to           
                                          sigma finiteness                 
{sigma_finite_content set T -> \bar R} == contents that are also sigma     
                                          finite                           
{sigma_finite_measure set T -> \bar R} == measures that are also sigma     
                                          finite                           
                                                                           
         fin_num_fun == predicate for finite function over measurable sets 
SigmaFinite_isFinite == mixin for finite measures                          
       FiniteMeasure == structure of finite measures                       
    Measure_isFinite == factory for finite measures                        
                                                                           
    mfrestr mD muDoo == finite measure corresponding to the restriction of 
                        the measure mu over D with mu D < +oo,             
                        mD : measurable D, muDoo : mu D < +oo              
                                                                           
FiniteMeasure_isSubProbability == mixin corresponding to subprobability    
                SubProbability == structure of subprobability              
            subprobability T R == subprobability measure over the          
                                  measurableType T with value              
                                  in R : realType                          
      Measure_isSubProbability == factory for subprobability measures      
                                                                           
          isProbability == mixin corresponding to probability measures     
            Probability == structure of probability measures               
        probability T R == probability measure over the                    
                           measurableType T with value in R : realType     
  Measure_isProbability == factor for probability measures                 
                                                                           
     monotone_class D G == G is a monotone class of subsets of D           
            <<m D, G >> == monotone class generated by G on D              
               <<m G >> := <<m setT, G >>                                  
               dynkin G == G is a set of sets that form a Dynkin           
                           (or a lambda) system                            
               <<d G >> == Dynkin system generated by G, i.e.,             
                           smallest dynkin G                               
                                                                           
     measurable_fun D f == the function f with domain D is measurable      
   preimage_class D f G == class of the preimages by f of sets in G        
      image_class D f G == class of the sets with a preimage by f in G     
                                                                           
       mu.-negligible A == A is mu negligible                              
 measure_is_complete mu == the measure mu is complete                      
 {ae mu, forall x, P x} == P holds almost everywhere for the measure mu,   
                           declared as an instance of the type of filters  
            ae_eq D f g == f is equal to g almost everywhere               

Measure extension theorem

From a premeasure to an outer measure (Measure Extension Theorem part 1):

     measurable_cover X == the set of sequences F such that                
                           - forall k, F k is measurable                   
                           - X `<=` \bigcup_k (F k)                        
                   mu^* == extension of the measure mu over a semiring of  
                           sets (it is an outer measure)                   

From an outer measure to a measure (Measure Extension Theorem part 2):

    mu.-caratheodory == the set of Caratheodory measurable sets for the    
                        outer measure mu, i.e., sets A such that           
                        forall B, mu A = mu (A `&` B) + mu (A `&` ~` B)    
caratheodory_type mu := T, where mu : {outer_measure set T -> \bar R}      
                        It is a canonical mesurableType copy of T.         
                        The restriction of the outer measure mu to the     
                        sigma algebra of Caratheodory measurable sets is a 
                        measure.                                           
                        Remark: sets that are negligible for               
                        this measure are Caratheodory measurable.          

Measure Extension Theorem:

   measure_extension mu == extension of the content mu over a semiring of  
                           sets to a measure over the generated            
                           sigma algebra (requires a proof of              
                           sigma-sub-additivity)                           

Product of measurable spaces

        preimage_classes f1 f2 == sigma-algebra generated by the union of  
                                  the preimages by f1 and the preimages by 
                                  f2 with f1 : T -> T1 and f : T -> T2, T1 
                                  and T2 being measurableType's            
  (d1, d2).-prod.-measurable A == A is measurable for the sigma-algebra    
                                  generated from T1 x T2, with T1 and T2   
                                  measurableType's with resp. display d1   
                                  and d2                                   

Others

 m1 `<< m2 == m1 is absolutely continuous w.r.t. m2 or m2 dominates m1     
 ess_sup f == essential supremum of the function f : T -> R where T is a   
              measurableType and R is a realType                           

Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Import Order.TTheory GRing.Theory Num.Def Num.Theory.

Reserved Notation "'s<|' D , G '|>'" (at level 40, G, D at next level).
Reserved Notation "'s<<' A '>>'".
Reserved Notation "'d<<' D '>>'".
Reserved Notation "mu .-negligible" (at level 2, format "mu .-negligible").
Reserved Notation "{ 'ae' m , P }" (at level 0, format "{ 'ae'  m ,  P }").
Reserved Notation "mu .-measurable" (at level 2, format "mu .-measurable").
Reserved Notation "'\d_' a" (at level 8, a at level 2, format "'\d_' a").
Reserved Notation "G .-sigma" (at level 1, format "G .-sigma").
Reserved Notation "G .-sigma.-measurable"
 (at level 2, format "G .-sigma.-measurable").
Reserved Notation "d .-ring" (at level 1, format "d .-ring").
Reserved Notation "d .-ring.-measurable"
 (at level 2, format "d .-ring.-measurable").
Reserved Notation "mu .-cara" (at level 1, format "mu .-cara").
Reserved Notation "mu .-cara.-measurable"
 (at level 2, format "mu .-cara.-measurable").
Reserved Notation "mu .-caratheodory"
  (at level 2, format "mu .-caratheodory").
Reserved Notation "'<<m' D , G '>>'"
  (at level 2, format "'<<m'  D ,  G  '>>'").
Reserved Notation "'<<m' G '>>'"
  (at level 2, format "'<<m'  G  '>>'").
Reserved Notation "'<<d' G '>>'"
  (at level 2, format "'<<d'  G '>>'").
Reserved Notation "'<<s' D , G '>>'"
  (at level 2, format "'<<s'  D ,  G  '>>'").
Reserved Notation "'<<s' G '>>'"
  (at level 2, format "'<<s'  G  '>>'").
Reserved Notation "'<<r' G '>>'"
  (at level 2, format "'<<r'  G '>>'").
Reserved Notation "{ 'content' fUV }" (at level 0, format "{ 'content'  fUV }").
Reserved Notation "[ 'content' 'of' f 'as' g ]"
  (at level 0, format "[ 'content'  'of'  f  'as'  g ]").
Reserved Notation "[ 'content' 'of' f ]"
  (at level 0, format "[ 'content'  'of'  f ]").
Reserved Notation "{ 'measure' fUV }"
  (at level 0, format "{ 'measure'  fUV }").
Reserved Notation "[ 'measure' 'of' f 'as' g ]"
  (at level 0, format "[ 'measure'  'of'  f  'as'  g ]").
Reserved Notation "[ 'measure' 'of' f ]"
  (at level 0, format "[ 'measure'  'of'  f ]").
Reserved Notation "{ 'outer_measure' fUV }"
  (at level 0, format "{ 'outer_measure'  fUV }").
Reserved Notation "[ 'outer_measure' 'of' f 'as' g ]"
  (at level 0, format "[ 'outer_measure'  'of'  f  'as'  g ]").
Reserved Notation "[ 'outer_measure' 'of' f ]"
  (at level 0, format "[ 'outer_measure'  'of'  f ]").
Reserved Notation "p .-prod" (at level 1, format "p .-prod").
Reserved Notation "p .-prod.-measurable"
 (at level 2, format "p .-prod.-measurable").
Reserved Notation "m1 `<< m2" (at level 51).

Inductive measure_display := default_measure_display .
Declare Scope measure_display_scope.
Delimit Scope measure_display_scope with mdisp.
Bind Scope measure_display_scope with measure_display.

Local Open Scope classical_set_scope.
Local Open Scope ring_scope.

Section classes .
Context {T} ( C : set (set T) -> Prop) ( D : set T) ( G : set (set T)).

Definition setC_closed := forall A, G A -> G (~` A).
Definition setI_closed := forall A B, G A -> G B -> G (A `&` B).
Definition setU_closed := forall A B, G A -> G B -> G (A `|` B).
Definition setD_closed := forall A B, B `<=` A -> G A -> G B -> G (A `\` B).
Definition setDI_closed := forall A B, G A -> G B -> G (A `\` B).

Definition fin_bigcap_closed :=
    forall I ( D : set I) A_, finite_set D -> (forall i, D i -> G (A_ i)) ->
  G (\bigcap_( i in D) (A_ i)).

Definition finN0_bigcap_closed :=
    forall I ( D : set I) A_, finite_set D -> D !=set0 ->
    (forall i, D i -> G (A_ i)) ->
  G (\bigcap_( i in D) (A_ i)).

Definition fin_bigcup_closed :=
    forall I ( D : set I) A_, finite_set D -> (forall i, D i -> G (A_ i)) ->
  G (\bigcup_( i in D) (A_ i)).

Definition semi_setD_closed := forall A B, G A -> G B -> exists D,
  [/\ finite_set D, D `<=` G, A `\` B = \bigcup_( X in D) X & trivIset D id].

Definition ndseq_closed :=
 forall F, nondecreasing_seq F -> (forall i, G (F i)) -> G (\bigcup_i (F i)).

Definition trivIset_closed :=
  forall F : (set T)^nat, trivIset setT F -> (forall n, G (F n)) ->
                    G (\bigcup_k F k).

Definition fin_trivIset_closed :=
  forall I ( D : set I) ( F : I -> set T), finite_set D -> trivIset D F ->
   (forall i, D i -> G (F i)) -> G (\bigcup_( k in D) F k).

Definition setring := [/\ G set0, setU_closed & setDI_closed].

Definition sigma_algebra :=
  [/\ G set0, (forall A, G A -> G (D `\` A)) &
     (forall A : (set T)^nat, (forall n, G (A n)) -> G (\bigcup_k A k))].

Definition dynkin := [/\ G setT, setC_closed & trivIset_closed].

Definition monotone_class :=
  [/\ forall A, G A -> A `<=` D, G D, setD_closed & ndseq_closed].

End classes.

Notation "'<<m' D , G '>>'" := (smallest (monotone_class D) G) :
  classical_set_scope.
Notation "'<<m' G '>>'" := (<<m setT, G>>) : classical_set_scope.
Notation "'<<d' G '>>'" := (smallest dynkin G) : classical_set_scope.
Notation "'<<s' D , G '>>'" := (smallest (sigma_algebra D) G) :
  classical_set_scope.
Notation "'<<s' G '>>'" := (<<s setT, G>>) : classical_set_scope.
Notation "'<<r' G '>>'" := (smallest setring G) : classical_set_scope.

Lemma fin_bigcup_closedP T ( G : set (set T)) :
  (G set0 /\ setU_closed G) <-> fin_bigcup_closed G.
Proof.

Lemma finN0_bigcap_closedP T ( G : set (set T)) :
  setI_closed G <-> finN0_bigcap_closed G.
Proof.

Lemma sedDI_closedP T ( G : set (set T)) :
  setDI_closed G <-> (setI_closed G /\ setD_closed G).
Proof.

Lemma sigma_algebra_bigcap T ( I : choiceType) ( D : set T)
    ( F : I -> set (set T)) ( J : set I) :
  (forall n, J n -> sigma_algebra D (F n)) ->
  sigma_algebra D (\bigcap_( i in J) F i).
Proof.

Lemma sigma_algebraP T U ( C : set (set T)) :
  (forall X, C X -> X `<=` U) ->
  sigma_algebra U C <->
  [/\ C U, setD_closed C, ndseq_closed C & setI_closed C].
Proof.

Section generated_sigma_algebra .
Context {T : Type} ( D : set T) ( G : set (set T)).
Implicit Types (M : set (set T)).

Lemma smallest_sigma_algebra : sigma_algebra D <<s D, G >>.
Proof.
Hint Resolve smallest_sigma_algebra : core.

Lemma sub_sigma_algebra2 M : M `<=` G -> <<s D, M >> `<=` <<s D, G >>.
Proof.

Lemma sigma_algebra_id : sigma_algebra D G -> <<s D, G >> = G.
Proof.

Lemma sub_sigma_algebra : G `<=` <<s D, G >>
Proof.

Lemma sigma_algebra0 : <<s D, G >> set0.
Proof.

Lemma sigma_algebraCD : forall A, <<s D, G >> A -> <<s D, G >> (D `\` A).
Proof.

Lemma sigma_algebra_bigcup ( A : (set T)^nat) :
  (forall i, <<s D, G >> (A i)) -> <<s D, G >> (\bigcup_i (A i)).
Proof.

End generated_sigma_algebra.
#[global] Hint Resolve smallest_sigma_algebra : core.

Section generated_setring .
Context {T : Type} ( G : set (set T)).
Implicit Types (M : set (set T)).

Lemma smallest_setring : setring <<r G >>.
Proof.
Hint Resolve smallest_setring : core.

Lemma sub_setring2 M : M `<=` G -> <<r M >> `<=` <<r G >>.
Proof.

Lemma setring_id : setring G -> <<r G >> = G.
Proof.

Lemma sub_setring : G `<=` <<r G >>
Proof.

Lemma setring0 : <<r G >> set0.
Proof.

Lemma setringDI : setDI_closed <<r G>>.
Proof.

Lemma setringU : setU_closed <<r G>>.
Proof.

Lemma setring_fin_bigcup : fin_bigcup_closed <<r G>>.
Proof.

End generated_setring.
#[global] Hint Resolve smallest_setring setring0 : core.

Lemma monotone_class_g_salgebra T ( G : set (set T)) ( D : set T) :
  (forall X, <<s D, G >> X -> X `<=` D) -> G D ->
  monotone_class D (<<s D, G >>).
Proof.

Section smallest_monotone_classE .
Variables ( T : Type) ( G : set (set T)) ( setIG : setI_closed G).
Variables ( D : set T) ( GD : G D).
Variables ( H : set (set T)) ( monoH : monotone_class D H) ( GH : G `<=` H).

Lemma smallest_monotone_classE : (forall X, <<s D, G >> X -> X `<=` D) ->
  (forall E, monotone_class D E -> G `<=` E -> H `<=` E) ->
  H = <<s D, G >>.
Proof.

End smallest_monotone_classE.

Section monotone_class_subset .
Variables ( T : Type) ( G : set (set T)) ( setIG : setI_closed G).
Variables ( D : set T) ( GD : G D).
Variables ( H : set (set T)) ( monoH : monotone_class D H) ( GH : G `<=` H).

Lemma monotone_class_subset : (forall X, (<<s D, G >>) X -> X `<=` D) ->
  <<s D, G >> `<=` H.
Proof.

End monotone_class_subset.

Section dynkin .
Variable T : Type.
Implicit Types G D : set (set T).

Lemma dynkinT G : dynkin G -> G setT
Proof.

Lemma dynkinC G : dynkin G -> setC_closed G
Proof.

Lemma dynkinU G : dynkin G -> (forall F : (set T)^nat, trivIset setT F ->
  (forall n, G (F n)) -> G (\bigcup_k F k))
Proof.

End dynkin.

Section dynkin_lemmas .
Variable T : Type.
Implicit Types D G : set (set T).

Lemma dynkin_monotone G : dynkin G <-> monotone_class setT G.
Proof.

Lemma dynkin_g_dynkin G : dynkin (<<d G >>).
Proof.

Lemma sigma_algebra_dynkin G : sigma_algebra setT G -> dynkin G.
Proof.

Lemma dynkin_setI_bigsetI G ( F : (set T)^nat) : dynkin G -> setI_closed G ->
  (forall n, G (F n)) -> forall n, G (\big[setI/setT]_( i < n) F i).
Proof.

Lemma dynkin_setI_sigma_algebra G : dynkin G -> setI_closed G ->
  sigma_algebra setT G.
Proof.

Lemma setI_closed_gdynkin_salgebra G : setI_closed G -> <<d G >> = <<s G >>.
Proof.

End dynkin_lemmas.

HB.mixin Record isSemiRingOfSets ( d : measure_display) T := {
   ptclass : Pointed.class_of T;
   measurable : set (set T) ;
   measurable0 : measurable set0 ;
   measurableI : setI_closed measurable;
   semi_measurableD : semi_setD_closed measurable;
}.

#[short(type=semiRingOfSetsType)]
HB.structure Definition SemiRingOfSets d := {T of isSemiRingOfSets d T}.

Arguments measurable {d}%measure_display_scope {s} _%classical_set_scope.

Canonical semiRingOfSets_eqType d ( T : semiRingOfSetsType d) := EqType T ptclass.
Canonical semiRingOfSets_choiceType d ( T : semiRingOfSetsType d) :=
  ChoiceType T ptclass.
Canonical semiRingOfSets_ptType d ( T : semiRingOfSetsType d) :=
  PointedType T ptclass.

Lemma measurable_curry ( T1 T2 : Type) d ( T : semiRingOfSetsType d)
    ( G : T1 * T2 -> set T) ( x : T1 * T2) :
  measurable (G x) <-> measurable (curry G x.1 x.2).
Proof.

Notation "d .-measurable" := (@measurable d%mdisp) : classical_set_scope.
Notation "'measurable" :=
  (@measurable default_measure_display) : classical_set_scope.

HB.mixin Record SemiRingOfSets_isRingOfSets d T of isSemiRingOfSets d T := {
   measurableU : setU_closed (@measurable d [the semiRingOfSetsType d of T]) }.

#[short(type=ringOfSetsType)]
HB.structure Definition RingOfSets d :=
  {T of SemiRingOfSets_isRingOfSets d T & SemiRingOfSets d T}.

Canonical ringOfSets_eqType d ( T : ringOfSetsType d) := EqType T ptclass.
Canonical ringOfSets_choiceType d ( T : ringOfSetsType d) := ChoiceType T ptclass.
Canonical ringOfSets_ptType d ( T : ringOfSetsType d) := PointedType T ptclass.

HB.mixin Record RingOfSets_isAlgebraOfSets d T of RingOfSets d T := {
   measurableT : measurable [set: T]
}.

#[short(type=algebraOfSetsType)]
HB.structure Definition AlgebraOfSets d :=
  {T of RingOfSets_isAlgebraOfSets d T & RingOfSets d T}.

Canonical algebraOfSets_eqType d ( T : algebraOfSetsType d) := EqType T ptclass.
Canonical algebraOfSets_choiceType d ( T : algebraOfSetsType d) :=
  ChoiceType T ptclass.
Canonical algebraOfSets_ptType d ( T : algebraOfSetsType d) :=
  PointedType T ptclass.

HB.mixin Record AlgebraOfSets_isMeasurable d T of AlgebraOfSets d T := {
   bigcupT_measurable : forall F : (set T)^nat, (forall i, measurable (F i)) ->
    measurable (\bigcup_i (F i))
}.

#[short(type=measurableType)]
HB.structure Definition Measurable d :=
  {T of AlgebraOfSets_isMeasurable d T & AlgebraOfSets d T}.

Canonical measurable_eqType d ( T : measurableType d) := EqType T ptclass.
Canonical measurable_choiceType d ( T : measurableType d) := ChoiceType T ptclass.
Canonical measurable_ptType d ( T : measurableType d) := PointedType T ptclass.

HB.factory Record isRingOfSets ( d : measure_display) T := {
   ptclass : Pointed.class_of T;
   measurable : set (set T) ;
   measurable0 : measurable set0 ;
   measurableU : setU_closed measurable;
   measurableD : setDI_closed measurable;
}.

HB.builders Context d T of isRingOfSets d T.
Implicit Types (A B C D : set T).

Lemma mI : setI_closed measurable.
Proof.

Lemma mD : semi_setD_closed measurable.
Proof.

HB.instance Definition _ :=
  @isSemiRingOfSets.Build d T ptclass measurable measurable0 mI mD.

HB.instance Definition _ := SemiRingOfSets_isRingOfSets.Build d T measurableU.

HB.end.

HB.factory Record isAlgebraOfSets ( d : measure_display) T := {
   ptclass : Pointed.class_of T;
   measurable : set (set T) ;
   measurable0 : measurable set0 ;
   measurableU : setU_closed measurable;
   measurableC : setC_closed measurable
}.

HB.builders Context d T of isAlgebraOfSets d T.

Lemma mD : setDI_closed measurable.
Proof.

HB.instance Definition _ :=
  @isRingOfSets.Build d T ptclass measurable measurable0 measurableU mD.

Lemma measurableT : measurable [set: T].
Proof.

HB.instance Definition _ := RingOfSets_isAlgebraOfSets.Build d T measurableT.

HB.end.

HB.factory Record isMeasurable ( d : measure_display) T := {
   ptclass : Pointed.class_of T;
   measurable : set (set T) ;
   measurable0 : measurable set0 ;
   measurableC : forall A, measurable A -> measurable (~` A) ;
   measurable_bigcup : forall F : (set T)^nat, (forall i, measurable (F i)) ->
    measurable (\bigcup_i (F i))
}.

HB.builders Context d T of isMeasurable d T.

Obligation Tactic := idtac.

Lemma mU : setU_closed measurable.
Proof.

Lemma mC : setC_closed measurable
Proof.

HB.instance Definition _ :=
  @isAlgebraOfSets.Build d T ptclass measurable measurable0 mU mC.

HB.instance Definition _ :=
  @AlgebraOfSets_isMeasurable.Build d T measurable_bigcup.

HB.end.

#[global] Hint Extern 0 (measurable set0) => solve [apply: measurable0] : core.
#[global] Hint Extern 0 (measurable setT) => solve [apply: measurableT] : core.

Section ringofsets_lemmas .
Context d ( T : ringOfSetsType d).
Implicit Types A B : set T.

Lemma bigsetU_measurable I r ( P : pred I) ( F : I -> set T) :
  (forall i, P i -> measurable (F i)) ->
  measurable (\big[setU/set0]_( i <- r | P i) F i).
Proof.

Lemma fin_bigcup_measurable I ( D : set I) ( F : I -> set T) :
    finite_set D ->
    (forall i, D i -> measurable (F i)) ->
  measurable (\bigcup_( i in D) F i).
Proof.

Lemma measurableD : setDI_closed (@measurable d T).
Proof.

End ringofsets_lemmas.

Section algebraofsets_lemmas .
Context d ( T : algebraOfSetsType d).
Implicit Types A B : set T.

Lemma measurableC A : measurable A -> measurable (~` A).
Proof.

Lemma bigsetI_measurable I r ( P : pred I) ( F : I -> set T) :
  (forall i, P i -> measurable (F i)) ->
  measurable (\big[setI/setT]_( i <- r | P i) F i).
Proof.

Lemma fin_bigcap_measurable I ( D : set I) ( F : I -> set T) :
    finite_set D ->
    (forall i, D i -> measurable (F i)) ->
  measurable (\bigcap_( i in D) F i).
Proof.

End algebraofsets_lemmas.

Section measurable_lemmas .
Context d ( T : measurableType d).
Implicit Types (A B : set T) (F : (set T)^nat) (P : set nat).

Lemma sigma_algebra_measurable : sigma_algebra setT (@measurable d T).
Proof.

Lemma bigcup_measurable F P :
  (forall k, P k -> measurable (F k)) -> measurable (\bigcup_( i in P) F i).
Proof.

Lemma bigcap_measurable F P :
  (forall k, P k -> measurable (F k)) -> measurable (\bigcap_( i in P) F i).
Proof.

Lemma bigcapT_measurable F : (forall i, measurable (F i)) ->
  measurable (\bigcap_i (F i)).
Proof.

End measurable_lemmas.

Lemma bigcupT_measurable_rat d ( T : measurableType d) ( F : rat -> set T) :
  (forall i, measurable (F i)) -> measurable (\bigcup_i F i).
Proof.

Section discrete_measurable_unit .

Definition discrete_measurable_unit : set (set unit) := [set: set unit].

Let discrete_measurable0 : discrete_measurable_unit set0
Proof.

Let discrete_measurableC X :
  discrete_measurable_unit X -> discrete_measurable_unit (~` X).
Proof.

Let discrete_measurableU ( F : (set unit)^nat) :
  (forall i, discrete_measurable_unit (F i)) ->
  discrete_measurable_unit (\bigcup_i F i).
Proof.

HB.instance Definition _ := @isMeasurable.Build default_measure_display unit
  (Pointed.class _) discrete_measurable_unit discrete_measurable0
  discrete_measurableC discrete_measurableU.

End discrete_measurable_unit.

Section discrete_measurable_bool .

Definition discrete_measurable_bool : set (set bool) := [set: set bool].

Let discrete_measurable0 : discrete_measurable_bool set0
Proof.

Let discrete_measurableC X :
  discrete_measurable_bool X -> discrete_measurable_bool (~` X).
Proof.

Let discrete_measurableU ( F : (set bool)^nat) :
  (forall i, discrete_measurable_bool (F i)) ->
  discrete_measurable_bool (\bigcup_i F i).
Proof.

HB.instance Definition _ := @isMeasurable.Build default_measure_display bool
  (Pointed.class _) discrete_measurable_bool discrete_measurable0
  discrete_measurableC discrete_measurableU.

End discrete_measurable_bool.

Section discrete_measurable_nat .

Definition discrete_measurable_nat : set (set nat) := [set: set nat].

Let discrete_measurable_nat0 : discrete_measurable_nat set0
Proof.

Let discrete_measurable_natC X :
  discrete_measurable_nat X -> discrete_measurable_nat (~` X).
Proof.

Let discrete_measurable_natU ( F : (set nat)^nat) :
  (forall i, discrete_measurable_nat (F i)) ->
  discrete_measurable_nat (\bigcup_i F i).
Proof.

HB.instance Definition _ := @isMeasurable.Build default_measure_display nat
  (Pointed.class _) discrete_measurable_nat discrete_measurable_nat0
  discrete_measurable_natC discrete_measurable_natU.

End discrete_measurable_nat.

Definition sigma_display {T} : set (set T) -> measure_display.
Proof.

Definition salgebraType {T} ( G : set (set T)) := T.

Section g_salgebra_instance .
Variables ( T : pointedType) ( G : set (set T)).

Lemma sigma_algebraC ( A : set T) : <<s G >> A -> <<s G >> (~` A).
Proof.

Canonical salgebraType_eqType := EqType (salgebraType G) (Equality.class T).
Canonical salgebraType_choiceType := ChoiceType (salgebraType G) (Choice.class T).
Canonical salgebraType_ptType := PointedType (salgebraType G) (Pointed.class T).
HB.instance Definition _ := @isMeasurable.Build (sigma_display G)
  (salgebraType G) (Pointed.class T)
  <<s G >> (@sigma_algebra0 _ setT G) (@sigma_algebraC)
  (@sigma_algebra_bigcup _ setT G).

End g_salgebra_instance.

Notation "G .-sigma" := (sigma_display G) : measure_display_scope.
Notation "G .-sigma.-measurable" :=
  (measurable : set (set (salgebraType G))) : classical_set_scope.

Lemma measurable_g_measurableTypeE ( T : pointedType) ( G : set (set T)) :
  sigma_algebra setT G -> G.-sigma.-measurable = G.
Proof.

Definition measurable_fun d d' ( T : measurableType d) ( U : measurableType d')
    ( D : set T) ( f : T -> U) :=
  measurable D -> forall Y, measurable Y -> measurable (D `&` f @^-1` Y).

Section measurable_fun .
Context d1 d2 d3 ( T1 : measurableType d1) ( T2 : measurableType d2)
        ( T3 : measurableType d3).
Implicit Type D E : set T1.

Lemma measurable_id D : measurable_fun D id.
Proof.

Lemma measurable_comp F ( f : T2 -> T3) E ( g : T1 -> T2) :
  measurable F -> g @` E `<=` F ->
  measurable_fun F f -> measurable_fun E g -> measurable_fun E (f \o g).
Proof.

Lemma measurableT_comp ( f : T2 -> T3) E ( g : T1 -> T2) :
  measurable_fun setT f -> measurable_fun E g -> measurable_fun E (f \o g).
Proof.

Lemma eq_measurable_fun D ( f g : T1 -> T2) :
  {in D, f =1 g} -> measurable_fun D f -> measurable_fun D g.
Proof.

Lemma measurable_cst D ( r : T2) : measurable_fun D (cst r : T1 -> _).
Proof.

Lemma measurable_fun_bigcup ( E : (set T1)^nat) ( f : T1 -> T2) :
  (forall i, measurable (E i)) ->
  measurable_fun (\bigcup_i E i) f <-> (forall i, measurable_fun (E i) f).
Proof.

Lemma measurable_funU D E ( f : T1 -> T2) : measurable D -> measurable E ->
  measurable_fun (D `|` E) f <-> measurable_fun D f /\ measurable_fun E f.
Proof.

Lemma measurable_funS E D ( f : T1 -> T2) :
    measurable E -> D `<=` E -> measurable_fun E f ->
  measurable_fun D f.
Proof.

Lemma measurable_funTS D ( f : T1 -> T2) :
  measurable_fun setT f -> measurable_fun D f.
Proof.

Lemma measurable_restrict D E ( f : T1 -> T2) :
  measurable D -> measurable E -> D `<=` E ->
  measurable_fun D f <-> measurable_fun E (f \_ D).
Proof.

Lemma measurable_fun_if ( g h : T1 -> T2) D ( mD : measurable D)
    ( f : T1 -> bool) ( mf : measurable_fun D f) :
  measurable_fun (D `&` (f @^-1` [set true])) g ->
  measurable_fun (D `&` (f @^-1` [set false])) h ->
  measurable_fun D (fun t => if f t then g t else h t).
Proof.

Lemma measurable_fun_ifT ( g h : T1 -> T2) ( f : T1 -> bool)
    ( mf : measurable_fun setT f) :
  measurable_fun setT g -> measurable_fun setT h ->
  measurable_fun setT (fun t => if f t then g t else h t).
Proof.

Lemma measurable_fun_bool D ( f : T1 -> bool) b :
  measurable (f @^-1` [set b]) -> measurable_fun D f.
Proof.

End measurable_fun.
#[global] Hint Extern 0 (measurable_fun _ (fun=> _)) =>
  solve [apply: measurable_cst] : core.
#[global] Hint Extern 0 (measurable_fun _ (cst _)) =>
  solve [apply: measurable_cst] : core.
#[global] Hint Extern 0 (measurable_fun _ id) =>
  solve [apply: measurable_id] : core.
Arguments eq_measurable_fun {d1 d2 T1 T2 D} f {g}.
Arguments measurable_fun_bool {d1 T1 D f} b.
#[deprecated(since="mathcomp-analysis 0.6.2", note="renamed `eq_measurable_fun`")]
Notation measurable_fun_ext := eq_measurable_fun (only parsing).
#[deprecated(since="mathcomp-analysis 0.6.3", note="renamed `measurable_id`")]
Notation measurable_fun_id := measurable_id (only parsing).
#[deprecated(since="mathcomp-analysis 0.6.3", note="renamed `measurable_cst`")]
Notation measurable_fun_cst := measurable_cst (only parsing).
#[deprecated(since="mathcomp-analysis 0.6.3", note="renamed `measurable_comp`")]
Notation measurable_fun_comp := measurable_comp (only parsing).
#[deprecated(since="mathcomp-analysis 0.6.3", note="renamed `measurableT_comp`")]
Notation measurable_funT_comp := measurableT_comp (only parsing).

Section measurability .

Definition preimage_class ( aT rT : Type) ( D : set aT) ( f : aT -> rT)
    ( G : set (set rT)) : set (set aT) :=
  [set D `&` f @^-1` B | B in G].

Lemma preimage_class_measurable_fun d ( aT : pointedType) ( rT : measurableType d)
  ( D : set aT) ( f : aT -> rT) :
  measurable_fun (D : set (salgebraType (preimage_class D f measurable))) f.
Proof.

Lemma sigma_algebra_preimage_class ( aT rT : Type) ( G : set (set rT))
    ( D : set aT) ( f : aT -> rT) :
  sigma_algebra setT G -> sigma_algebra D (preimage_class D f G).
Proof.

Definition image_class ( aT rT : Type) ( D : set aT) ( f : aT -> rT)
    ( G : set (set aT)) : set (set rT) :=
  [set B : set rT | G (D `&` f @^-1` B)].

Lemma sigma_algebra_image_class ( aT rT : Type) ( D : set aT) ( f : aT -> rT)
    ( G : set (set aT)) :
  sigma_algebra D G -> sigma_algebra setT (image_class D f G).
Proof.

Lemma sigma_algebra_preimage_classE aT ( rT : pointedType) ( D : set aT)
    ( f : aT -> rT) ( G' : set (set rT)) :
  <<s D, preimage_class D f G' >> =
    preimage_class D f (G'.-sigma.-measurable).
Proof.

Lemma measurability d d' ( aT : measurableType d) ( rT : measurableType d')
    ( D : set aT) ( f : aT -> rT)
    ( G' : set (set rT)) :
  @measurable _ rT = <<s G' >> -> preimage_class D f G' `<=` @measurable _ aT ->
  measurable_fun D f.
Proof.

End measurability.

Local Open Scope ereal_scope.

Section additivity .
Context d ( R : numFieldType) ( T : semiRingOfSetsType d)
        ( mu : set T -> \bar R).

Definition semi_additive2 := forall A B, measurable A -> measurable B ->
  measurable (A `|` B) ->
  A `&` B = set0 -> mu (A `|` B) = mu A + mu B.

Definition semi_additive := forall F n,
 (forall k : nat, measurable (F k)) -> trivIset setT F ->
  measurable (\big[setU/set0]_( k < n) F k) ->
  mu (\big[setU/set0]_( i < n) F i) = \sum_( i < n) mu (F i).

Definition semi_sigma_additive :=
  forall F, (forall i : nat, measurable (F i)) -> trivIset setT F ->
  measurable (\bigcup_n F n) ->
  (fun n => \sum_(0 <= i < n) mu (F i)) --> mu (\bigcup_n F n).

Definition additive2 := forall A B, measurable A -> measurable B ->
  A `&` B = set0 -> mu (A `|` B) = mu A + mu B.

Definition additive :=
  forall F, (forall i : nat, measurable (F i)) -> trivIset setT F ->
  forall n, mu (\big[setU/set0]_( i < n) F i) = \sum_( i < n) mu (F i).

Definition sigma_additive :=
  forall F, (forall i : nat, measurable (F i)) -> trivIset setT F ->
  (fun n => \sum_(0 <= i < n) mu (F i)) --> mu (\bigcup_n F n).

Definition sub_additive := forall ( A : set T) ( F : nat -> set T) n,
 (forall k, `I_n k -> measurable (F k)) -> measurable A ->
  A `<=` \big[setU/set0]_( k < n) F k ->
  mu A <= \sum_( k < n) mu (F k).

Definition sigma_sub_additive := forall ( A : set T) ( F : nat -> set T),
 (forall n, measurable (F n)) -> measurable A ->
  A `<=` \bigcup_n F n ->
  mu A <= \sum_( n <oo) mu (F n).

Lemma semi_additiveW : mu set0 = 0 -> semi_additive -> semi_additive2.
Proof.

End additivity.

Section ring_additivity .
Context d ( R : numFieldType) ( T : ringOfSetsType d) ( mu : set T -> \bar R).

Lemma semi_additiveE : semi_additive mu = additive mu.
Proof.

Lemma semi_additive2E : semi_additive2 mu = additive2 mu.
Proof.

Lemma additive2P : mu set0 = 0 -> semi_additive mu <-> additive2 mu.
Proof.

End ring_additivity.

Lemma semi_sigma_additive_is_additive d ( T : semiRingOfSetsType d)
    ( R : realFieldType) ( mu : set T -> \bar R) :
  mu set0 = 0 -> semi_sigma_additive mu -> semi_additive mu.
Proof.

Lemma semi_sigma_additiveE
  ( R : numFieldType) d ( T : measurableType d) ( mu : set T -> \bar R) :
  semi_sigma_additive mu = sigma_additive mu.
Proof.

Lemma sigma_additive_is_additive
  ( R : realFieldType) d ( T : measurableType d) ( mu : set T -> \bar R) :
  mu set0 = 0 -> sigma_additive mu -> additive mu.
Proof.

HB.mixin Record isContent d
    ( T : semiRingOfSetsType d) ( R : numFieldType) ( mu : set T -> \bar R) := {
   measure_ge0 : forall x, 0 <= mu x ;
   measure_semi_additive : semi_additive mu }.

HB.structure Definition Content d
    ( T : semiRingOfSetsType d) ( R : numFieldType) := {
   mu & isContent d T R mu }.

Notation content := Content.type.
Notation "{ 'content' 'set' T '->' '\bar' R }" :=
  (content T R) (at level 36, T, R at next level,
    format "{ 'content'  'set'  T  '->'  '\bar'  R }") : ring_scope.

Arguments measure_ge0 {d T R} _.

Section content_signed .
Context d ( T : semiRingOfSetsType d) ( R : numFieldType).

Variable mu : {content set T -> \bar R}.

Lemma content_snum_subproof S : Signed.spec 0 ?=0 >=0 (mu S).
Proof.

Canonical content_snum S := Signed.mk (content_snum_subproof S).

End content_signed.

Section content_on_semiring_of_sets .
Context d ( T : semiRingOfSetsType d) ( R : numFieldType)
        ( mu : {content set T -> \bar R}).

Lemma measure0 : mu set0 = 0.
Proof.

Hint Resolve measure0 : core.

Hint Resolve measure_ge0 : core.

Hint Resolve measure_semi_additive : core.

Lemma measure_semi_additive_ord ( n : nat) ( F : 'I_n -> set T) :
  (forall ( k : 'I_n), measurable (F k)) ->
  trivIset setT F ->
  measurable (\big[setU/set0]_( k < n) F k) ->
  mu (\big[setU/set0]_( i < n) F i) = \sum_( i < n) mu (F i).
Proof.

Lemma measure_semi_additive_ord_I ( F : nat -> set T) ( n : nat) :
  (forall k, (k < n)%N -> measurable (F k)) ->
  trivIset `I_n F ->
  measurable (\big[setU/set0]_( k < n) F k) ->
  mu (\big[setU/set0]_( i < n) F i) = \sum_( i < n) mu (F i).
Proof.

Lemma content_fin_bigcup ( I : choiceType) ( D : set I) ( F : I -> set T) :
    finite_set D ->
    trivIset D F ->
    (forall i, D i -> measurable (F i)) ->
    measurable (\bigcup_( i in D) F i) ->
  mu (\bigcup_( i in D) F i) = \sum_( i \in D) mu (F i).
Proof.

Lemma measure_semi_additive2 : semi_additive2 mu.
Proof.
Hint Resolve measure_semi_additive2 : core.

End content_on_semiring_of_sets.
Arguments measure0 {d T R} _.

#[global] Hint Extern 0
  (is_true (0 <= (_ : {content set _ -> \bar _}) _)%E) =>
  solve [apply: measure_ge0] : core.

#[global]
Hint Resolve measure0 measure_semi_additive2 measure_semi_additive : core.

Section content_on_ring_of_sets .
Context d ( R : realFieldType)( T : ringOfSetsType d)
        ( mu : {content set T -> \bar R}).

Lemma measureU : additive2 mu.
Proof.

Lemma measure_bigsetU : additive mu.
Proof.

Lemma measure_fin_bigcup ( I : choiceType) ( D : set I) ( F : I -> set T) :
    finite_set D ->
    trivIset D F ->
    (forall i, D i -> measurable (F i)) ->
  mu (\bigcup_( i in D) F i) = \sum_( i \in D) mu (F i).
Proof.

Lemma measure_bigsetU_ord_cond n ( P : {pred 'I_n}) ( F : 'I_n -> set T) :
  (forall i : 'I_n, P i -> measurable (F i)) -> trivIset P F ->
  mu (\big[setU/set0]_( i < n | P i) F i) = (\sum_( i < n | P i) mu (F i))%E.
Proof.

Lemma measure_bigsetU_ord n ( P : {pred 'I_n}) ( F : 'I_n -> set T) :
  (forall i : 'I_n, measurable (F i)) -> trivIset setT F ->
  mu (\big[setU/set0]_( i < n | P i) F i) = (\sum_( i < n | P i) mu (F i))%E.
Proof.

Lemma measure_fbigsetU ( I : choiceType) ( A : {fset I}) ( F : I -> set T) :
  (forall i, i \in A -> measurable (F i)) -> trivIset [set` A] F ->
  mu (\big[setU/set0]_( i <- A) F i) = (\sum_( i <- A) mu (F i))%E.
Proof.

End content_on_ring_of_sets.

#[global]
Hint Resolve measureU measure_bigsetU : core.

HB.mixin Record Content_isMeasure d ( T : semiRingOfSetsType d)
    ( R : numFieldType) ( mu : set T -> \bar R) of Content d mu := {
   measure_semi_sigma_additive : semi_sigma_additive mu }.

#[short(type=measure)]
HB.structure Definition Measure d ( T : semiRingOfSetsType d)
    ( R : numFieldType) :=
  {mu of Content_isMeasure d T R mu & Content d mu}.

Notation "{ 'measure' 'set' T '->' '\bar' R }" := (measure T%type R)
  (at level 36, T, R at next level,
    format "{ 'measure'  'set'  T  '->'  '\bar'  R }") : ring_scope.

Section measure_signed .
Context d ( R : numFieldType) ( T : semiRingOfSetsType d).

Variable mu : {measure set T -> \bar R}.

Lemma measure_snum_subproof S : Signed.spec 0 ?=0 >=0 (mu S).
Proof.

Canonical measure_snum S := Signed.mk (measure_snum_subproof S).

End measure_signed.

HB.factory Record isMeasure d ( T : semiRingOfSetsType d) ( R : realFieldType)
    ( mu : set T -> \bar R) := {
   measure0 : mu set0 = 0 ;
   measure_ge0 : forall x, 0 <= mu x ;
   measure_semi_sigma_additive : semi_sigma_additive mu }.

HB.builders Context d ( T : semiRingOfSetsType d) ( R : realFieldType)
  ( mu : set T -> \bar R) of isMeasure _ T R mu.

Let semi_additive_mu : semi_additive mu.
Proof.

HB.instance Definition _ := isContent.Build d T R mu
  measure_ge0 semi_additive_mu.
HB.instance Definition _ := Content_isMeasure.Build d T R mu
  measure_semi_sigma_additive.
HB.end.

Lemma eq_measure d ( T : measurableType d) ( R : realFieldType)
  ( m1 m2 : {measure set T -> \bar R}) :
  (m1 = m2 :> (set T -> \bar R)) -> m1 = m2.
Proof.

Section measure_lemmas .
Context d ( R : realFieldType) ( T : semiRingOfSetsType d).

Variable mu : {measure set T -> \bar R}.

Lemma measure_semi_bigcup A : (forall i : nat, measurable (A i)) ->
    trivIset setT A -> measurable (\bigcup_n A n) ->
  mu (\bigcup_n A n) = \sum_( i <oo) mu (A i).
Proof.

End measure_lemmas.

#[global] Hint Extern 0 (_ set0 = 0) => solve [apply: measure0] : core.
#[global] Hint Extern 0 (is_true (0 <= _)) => solve [apply: measure_ge0] : core.

Section measure_lemmas .
Context d ( R : realFieldType) ( T : measurableType d).
Variable mu : {measure set T -> \bar R}.

Lemma measure_sigma_additive : sigma_additive mu.
Proof.

Lemma measure_bigcup ( D : set nat) F : (forall i, D i -> measurable (F i)) ->
  trivIset D F -> mu (\bigcup_( n in D) F n) = \sum_( i <oo | i \in D) mu (F i).
Proof.

End measure_lemmas.
Arguments measure_bigcup {d R T} _ _.

#[global] Hint Extern 0 (sigma_additive _) =>
  solve [apply: measure_sigma_additive] : core.

Definition pushforward d1 d2 ( T1 : measurableType d1) ( T2 : measurableType d2)
  ( R : realFieldType) ( m : set T1 -> \bar R) ( f : T1 -> T2)
  of measurable_fun setT f := fun A => m (f @^-1` A).
Arguments pushforward {d1 d2 T1 T2 R} m {f}.

Section pushforward_measure .
Local Open Scope ereal_scope.
Context d d' ( T1 : measurableType d) ( T2 : measurableType d')
        ( R : realFieldType).
Variables ( m : {measure set T1 -> \bar R}) ( f : T1 -> T2).
Hypothesis mf : measurable_fun setT f.

Let pushforward0 : pushforward m mf set0 = 0.
Proof.

Let pushforward_ge0 A : 0 <= pushforward m mf A.
Proof.

Let pushforward_sigma_additive : semi_sigma_additive (pushforward m mf).
Proof.

HB.instance Definition _ := isMeasure.Build _ _ _
  (pushforward m mf) pushforward0 pushforward_ge0 pushforward_sigma_additive.

End pushforward_measure.

Section dirac_measure .
Local Open Scope ereal_scope.
Context d ( T : measurableType d) ( a : T) ( R : realFieldType).

Definition dirac ( A : set T) : \bar R := (\1_A a)%:E.

Let dirac0 : dirac set0 = 0
Proof.

Let dirac_ge0 B : 0 <= dirac B
Proof.

Let dirac_sigma_additive : semi_sigma_additive dirac.
Proof.

HB.instance Definition _ := isMeasure.Build _ _ _
  dirac dirac0 dirac_ge0 dirac_sigma_additive.

End dirac_measure.
Arguments dirac {d T} _ {R}.

Notation "\d_ a" := (dirac a) : ring_scope.

Section dirac_lemmas_realFieldType .
Local Open Scope ereal_scope.
Context d ( T : measurableType d) ( R : realFieldType).

Lemma diracE a ( A : set T) : \d_a A = (a \in A)%:R%:E :> \bar R.
Proof.

Lemma dirac0 ( a : T) : \d_a set0 = 0 :> \bar R.
Proof.

Lemma diracT ( a : T) : \d_a setT = 1 :> \bar R.
Proof.

End dirac_lemmas_realFieldType.

Section dirac_lemmas .
Local Open Scope ereal_scope.
Context d ( T : measurableType d) ( R : realType).

Lemma finite_card_sum ( A : set T) : finite_set A ->
  \esum_( i in A) 1 = (#|` fset_set A|%:R)%:E :> \bar R.
Proof.

Lemma finite_card_dirac ( A : set T) : finite_set A ->
  \esum_( i in A) \d_ i A = (#|` fset_set A|%:R)%:E :> \bar R.
Proof.

Lemma infinite_card_dirac ( A : set T) : infinite_set A ->
  \esum_( i in A) \d_ i A = +oo :> \bar R.
Proof.

End dirac_lemmas.

Section measure_sum .
Local Open Scope ereal_scope.
Context d ( T : measurableType d) ( R : realType).
Variables ( m : {measure set T -> \bar R}^nat) ( n : nat).

Definition msum ( A : set T) : \bar R := \sum_( k < n) m k A.

Let msum0 : msum set0 = 0
Proof.

Let msum_ge0 B : 0 <= msum B
Proof.

Let msum_sigma_additive : semi_sigma_additive msum.
Proof.

HB.instance Definition _ := isMeasure.Build _ _ _ msum
  msum0 msum_ge0 msum_sigma_additive.

End measure_sum.
Arguments msum {d T R}.

Section measure_zero .
Local Open Scope ereal_scope.
Context d ( T : measurableType d) ( R : realType).

Definition mzero ( A : set T) : \bar R := 0.

Let mzero0 : mzero set0 = 0
Proof.

Let mzero_ge0 B : 0 <= mzero B
Proof.

Let mzero_sigma_additive : semi_sigma_additive mzero.
Proof.

HB.instance Definition _ := isMeasure.Build _ _ _ mzero
  mzero0 mzero_ge0 mzero_sigma_additive.

End measure_zero.
Arguments mzero {d T R}.

Lemma msum_mzero d ( T : measurableType d) ( R : realType)
    ( m_ : {measure set T -> \bar R}^nat) :
  msum m_ 0 = mzero.
Proof.

Section measure_add .
Local Open Scope ereal_scope.
Context d ( T : measurableType d) ( R : realType).
Variables ( m1 m2 : {measure set T -> \bar R}).

Definition measure_add := msum (fun n => if n is 0%N then m1 else m2) 2.

Lemma measure_addE A : measure_add A = m1 A + m2 A.
Proof.

End measure_add.

Section measure_scale .
Local Open Scope ereal_scope.
Context d ( T : measurableType d) ( R : realFieldType).
Variables ( r : {nonneg R}) ( m : {measure set T -> \bar R}).

Definition mscale ( A : set T) : \bar R := r%:num%:E * m A.

Let mscale0 : mscale set0 = 0
Proof.

Let mscale_ge0 B : 0 <= mscale B.
Proof.

Let mscale_sigma_additive : semi_sigma_additive mscale.
Proof.

HB.instance Definition _ := isMeasure.Build _ _ _ mscale
  mscale0 mscale_ge0 mscale_sigma_additive.

End measure_scale.
Arguments mscale {d T R}.

Section measure_series .
Local Open Scope ereal_scope.
Context d ( T : measurableType d) ( R : realType).
Variables ( m : {measure set T -> \bar R}^nat) ( n : nat).

Definition mseries ( A : set T) : \bar R := \sum_(n <= k <oo) m k A.

Let mseries0 : mseries set0 = 0.
Proof.

Let mseries_ge0 B : 0 <= mseries B.
Proof.

Let mseries_sigma_additive : semi_sigma_additive mseries.
Proof.

HB.instance Definition _ := isMeasure.Build _ _ _ mseries
  mseries0 mseries_ge0 mseries_sigma_additive.

End measure_series.
Arguments mseries {d T R}.

Definition mrestr d ( T : measurableType d) ( R : realFieldType) ( D : set T)
  ( f : set T -> \bar R) ( mD : measurable D) := fun X => f (X `&` D).

Section measure_restr .
Context d ( T : measurableType d) ( R : realFieldType).
Variables ( mu : {measure set T -> \bar R}) ( D : set T) ( mD : measurable D).

Local Notation restr := (mrestr mu mD).

Let restr0 : restr set0 = 0%E
Proof.

Let restr_ge0 ( A : set _) : (0 <= restr A)%E.
Proof.

Let restr_sigma_additive : semi_sigma_additive restr.
Proof.

HB.instance Definition _ := isMeasure.Build _ _ _ restr
  restr0 restr_ge0 restr_sigma_additive.

End measure_restr.

Definition counting ( T : choiceType) ( R : realType) ( X : set T) : \bar R :=
  if `[< finite_set X >] then (#|` fset_set X |)%:R%:E else +oo.
Arguments counting {T R}.

Section measure_count .
Context d ( T : measurableType d) ( R : realType).
Variables ( D : set T) ( mD : measurable D).

Local Notation counting := (@counting [choiceType of T] R).

Let counting0 : counting set0 = 0.
Proof.

Let counting_ge0 ( A : set T) : 0 <= counting A.
Proof.

Let counting_sigma_additive : semi_sigma_additive counting.
Proof.

HB.instance Definition _ := isMeasure.Build _ _ _ counting
  counting0 counting_ge0 counting_sigma_additive.

End measure_count.

Lemma big_trivIset ( I : choiceType) D T ( R : Type) ( idx : R)
   ( op : Monoid.com_law idx) ( A : I -> set T) ( F : set T -> R) :
    finite_set D -> trivIset D A -> F set0 = idx ->
  \big[op/idx]_( i <- fset_set D) F (A i) =
  \big[op/idx]_( X <- (A @` fset_set D)%fset) F X.
Proof.

Section covering .
Context {T : Type}.
Implicit Type (C : forall I, set (set I)).
Implicit Type (P : forall I, set I -> set (I -> set T)).

Definition covered_by C P :=
  [set X : set T | exists I D A, [/\ C I D, P I D A & X = \bigcup_( i in D) A i]].

Lemma covered_bySr C P P' : (forall I D A, P I D A -> P' I D A) ->
  covered_by C P `<=` covered_by C P'.
Proof.

Lemma covered_byP C P I D A : C I D -> P I D A ->
  covered_by C P (\bigcup_( i in D) A i).
Proof.

Lemma covered_by_finite P :
    (forall I ( D : set I) A, (forall i, D i -> A i = set0) -> P I D A) ->
    (forall ( I : pointedType) D A, finite_set D -> P I D A ->
       P nat `I_#|` fset_set D| (A \o nth point (fset_set D))) ->
  covered_by (@finite_set) P =
    [set X : set T | exists n A, [/\ P nat `I_n A & X = \bigcup_( i < n) A i]].
Proof.

Lemma covered_by_countable P :
    (forall I ( D : set I) A, (forall i, D i -> A i = set0) -> P I D A) ->
    (forall ( I : choiceType) ( D : set I) ( A : I -> set T) ( f : nat -> I),
       set_surj [set: nat] D f ->
       P I D A -> P nat [set: nat] (A \o f)) ->
  covered_by (@countable) P =
    [set X : set T | exists A, [/\ P nat [set: nat] A & X = \bigcup_i A i]].
Proof.

End covering.

Module SetRing .
Definition type ( T : Type) := T.
Definition display : measure_display -> measure_display
Proof.

Section SetRing .
Context d {T : semiRingOfSetsType d}.

Notation rT := (type T).
Canonical ring_eqType := EqType rT ptclass.
Canonical ring_choiceType := ChoiceType rT ptclass.
Canonical ring_ptType := PointedType rT ptclass.
#[export]
HB.instance Definition _ := isRingOfSets.Build (display d) rT ptclass
  (@setring0 T measurable) (@setringU T measurable) (@setringDI T measurable).

Local Notation "d .-ring" := (display d) (at level 1, format "d .-ring" ).
Local Notation "d .-ring.-measurable" :=
  ((d%mdisp.-ring).-measurable : set (set (type _))).

Local Definition measurable_fin_trivIset : set (set T) :=
  [set A | exists B : set (set T),
    [/\ A = \bigcup_( X in B) X, forall X : set T, B X -> measurable X,
      finite_set B & trivIset B id]].

Lemma ring_measurableE : d.-ring.-measurable = measurable_fin_trivIset.
Proof.

Lemma measurable_subring : (d.-measurable : set (set T)) `<=` d.-ring.-measurable.
Proof.

Lemma ring_finite_set ( A : set rT) : measurable A -> exists B : set (set T),
  [/\ finite_set B,
      (forall X, B X -> X !=set0),
      trivIset B id,
      (forall X : set T, X \in B -> measurable X) &
      A = \bigcup_( X in B) X].
Proof.

Definition decomp ( A : set rT) : set (set T) :=
  if A == set0 then [set set0] else
  if pselect (measurable A) is left mA then projT1 (cid (ring_finite_set mA))
  else [set A].

Lemma decomp_finite_set ( A : set rT) : finite_set (decomp A).
Proof.

Lemma decomp_triv ( A : set rT) : trivIset (decomp A) id.
Proof.
Hint Resolve decomp_triv : core.

Lemma all_decomp_neq0 ( A : set rT) :
  A !=set0 -> (forall X, decomp A X -> X !=set0).
Proof.

Lemma decomp_neq0 ( A : set rT) X : A !=set0 -> X \in decomp A -> X !=set0.
Proof.

Lemma decomp_measurable ( A : set rT) ( X : set T) :
  measurable A -> X \in decomp A -> measurable X.
Proof.

Lemma cover_decomp ( A : set rT) : \bigcup_( X in decomp A) X = A.
Proof.

Lemma decomp_sub ( A : set rT) ( X : set T) : X \in decomp A -> X `<=` A.
Proof.

Lemma decomp_set0 : decomp set0 = [set set0].
Proof.

Lemma decompN0 ( A : set rT) : decomp A != set0.
Proof.

Definition measure ( R : numDomainType) ( mu : set T -> \bar R)
  ( A : set rT) : \bar R := \sum_( X \in decomp A) mu X.

Section content .
Context {R : realFieldType} ( mu : {content set T -> \bar R}).
Local Notation Rmu := (measure mu).
Arguments big_trivIset {I D T R idx op} A F.

Lemma Rmu_fin_bigcup ( I : choiceType) ( D : set I) ( F : I -> set T) :
    finite_set D -> trivIset D F -> (forall i, i \in D -> measurable (F i)) ->
  Rmu (\bigcup_( i in D) F i) = \sum_( i \in D) mu (F i).
Proof.

Lemma RmuE ( A : set T) : measurable A -> Rmu A = mu A.
Proof.

Let Rmu0 : Rmu set0 = 0.
Proof.

Lemma Rmu_ge0 A : Rmu A >= 0.
Proof.

Lemma Rmu_additive : semi_additive Rmu.
Proof.

#[export]
HB.instance Definition _ := isContent.Build _ _ _ Rmu Rmu_ge0 Rmu_additive.

End content.

End SetRing.
Module Exports .
Canonical ring_eqType.
Canonical ring_choiceType.
Canonical ring_ptType.
HB.reexport SetRing.
End Exports.
End SetRing.
Export SetRing.Exports.

Notation "d .-ring" := (SetRing.display d)
  (at level 1, format "d .-ring") : measure_display_scope.
Notation "d .-ring.-measurable" :=
  ((d%mdisp.-ring).-measurable : set (set (SetRing.type _))) : classical_set_scope.

Lemma le_measure d ( R : realFieldType) ( T : semiRingOfSetsType d)
    ( mu : {content set T -> \bar R}) :
  {in measurable &, {homo mu : A B / A `<=` B >-> (A <= B)%E}}.
Proof.

Lemma measure_le0 d ( T : semiRingOfSetsType d) ( R : realFieldType)
  ( mu : {content set T -> \bar R}) ( A : set T) :
  (mu A <= 0)%E = (mu A == 0)%E.
Proof.

Section more_content_semiring_lemmas .
Context d ( R : realFieldType) ( T : semiRingOfSetsType d).
Variable mu : {content set T -> \bar R}.

Lemma content_sub_additive : sub_additive mu.
Proof.

Lemma content_sub_fsum ( I : choiceType) D ( A : set T) ( A_ : I -> set T) :
  finite_set D ->
  (forall i, D i -> measurable (A_ i)) ->
  measurable A ->
  A `<=` \bigcup_( i in D) A_ i -> mu A <= \sum_( i \in D) mu (A_ i).
Proof.


End more_content_semiring_lemmas.

Section content_ring_lemmas .
Context d ( R : realType) ( T : ringOfSetsType d).
Variable mu : {content set T -> \bar R}.

Lemma content_ring_sup_sigma_additive ( A : nat -> set T) :
  (forall i, measurable (A i)) -> measurable (\bigcup_i A i) ->
  trivIset [set: nat] A -> \sum_( i <oo) mu (A i) <= mu (\bigcup_i A i).
Proof.

Lemma content_ring_sigma_additive : sigma_sub_additive mu -> semi_sigma_additive mu.
Proof.

End content_ring_lemmas.

Section ring_sigma_sub_additive_content .
Context d ( R : realType) ( T : semiRingOfSetsType d)
        ( mu : {content set T -> \bar R}).
Local Notation Rmu := (SetRing.measure mu).
Import SetRing.

Lemma ring_sigma_sub_additive : sigma_sub_additive mu -> sigma_sub_additive Rmu.
Proof.

Lemma ring_semi_sigma_additive : sigma_sub_additive mu -> semi_sigma_additive Rmu.
Proof.

Lemma semiring_sigma_additive : sigma_sub_additive mu -> semi_sigma_additive mu.
Proof.

End ring_sigma_sub_additive_content.

#[key="mu"]
HB.factory Record Content_SubSigmaAdditive_isMeasure d
    ( R : realType) ( T : semiRingOfSetsType d) ( mu : set T -> \bar R) of Content d mu := {
   measure_sigma_sub_additive : sigma_sub_additive mu }.

HB.builders Context d ( R : realType) ( T : semiRingOfSetsType d)
  ( mu : set T -> \bar R) of Content_SubSigmaAdditive_isMeasure d R T mu.
  HB.instance Definition _ := Content_isMeasure.Build d T R mu
    (semiring_sigma_additive (measure_sigma_sub_additive)).
HB.end.

Section more_premeasure_ring_lemmas .
Context d ( R : realType) ( T : semiRingOfSetsType d).
Variable mu : {measure set T -> \bar R}.
Import SetRing.

Lemma measure_sigma_sub_additive : sigma_sub_additive mu.
Proof.

End more_premeasure_ring_lemmas.

Lemma measure_sigma_sub_additive_tail d ( R : realType) ( T : semiRingOfSetsType d)
  ( mu : {measure set T -> \bar R}) ( A : set T) ( F : nat -> set T) N :
    (forall n, measurable (F n)) -> measurable A ->
    A `<=` \bigcup_( n in ~` `I_N) F n ->
  (mu A <= \sum_(N <= n <oo) mu (F n))%E.
Proof.

Section ring_sigma_content .
Context d ( R : realType) ( T : semiRingOfSetsType d)
        ( mu : {measure set T -> \bar R}).
Local Notation Rmu := (SetRing.measure mu).
Import SetRing.

Let ring_sigma_content : semi_sigma_additive Rmu.
Proof.

HB.instance Definition _ := Content_isMeasure.Build _ _ _ Rmu
  ring_sigma_content.

End ring_sigma_content.

Definition fin_num_fun d ( T : semiRingOfSetsType d) ( R : numDomainType)
  ( mu : set T -> \bar R) := forall U, measurable U -> mu U \is a fin_num.

Lemma fin_num_fun_lty d ( T : algebraOfSetsType d) ( R : realFieldType)
  ( mu : set T -> \bar R) : fin_num_fun mu -> mu setT < +oo.
Proof.

Lemma lty_fin_num_fun d ( T : algebraOfSetsType d)
    ( R : realFieldType) ( mu : {measure set T -> \bar R}) :
  mu setT < +oo -> fin_num_fun mu.
Proof.

Definition sfinite_measure d ( T : measurableType d) ( R : realType)
    ( mu : set T -> \bar R) :=
  exists2 s : {measure set T -> \bar R}^nat,
    forall n, fin_num_fun (s n) &
    forall U, measurable U -> mu U = mseries s 0 U.

Definition sigma_finite d ( T : semiRingOfSetsType d) ( R : numDomainType)
    ( A : set T) ( mu : set T -> \bar R) :=
  exists2 F : (set T)^nat, A = \bigcup_( i : nat) F i &
      forall i, measurable (F i) /\ mu (F i) < +oo.

Lemma fin_num_fun_sigma_finite d ( T : algebraOfSetsType d)
    ( R : realFieldType) ( mu : set T -> \bar R) : mu set0 < +oo ->
  fin_num_fun mu -> sigma_finite setT mu.
Proof.

Lemma sfinite_measure_sigma_finite d ( T : measurableType d)
    ( R : realType) ( mu : {measure set T -> \bar R}) :
  sigma_finite setT mu -> sfinite_measure mu.
Proof.

HB.mixin Record Measure_isSFinite_subdef d ( T : measurableType d)
    ( R : realType) ( mu : set T -> \bar R) := {
   sfinite_measure_subdef : sfinite_measure mu }.

HB.structure Definition SFiniteMeasure
     d ( T : measurableType d) ( R : realType) :=
  {mu of @Measure _ T R mu & Measure_isSFinite_subdef _ T R mu }.
Arguments sfinite_measure_subdef {d T R} _.

Notation "{ 'sfinite_measure' 'set' T '->' '\bar' R }" :=
  (SFiniteMeasure.type T R) (at level 36, T, R at next level,
    format "{ 'sfinite_measure'  'set'  T  '->'  '\bar'  R }") : ring_scope.

HB.mixin Record isSigmaFinite d ( T : semiRingOfSetsType d) ( R : numFieldType)
  ( mu : set T -> \bar R) := { sigma_finiteT : sigma_finite setT mu }.

#[short(type="sigma_finite_content")]
HB.structure Definition SigmaFiniteContent d T R :=
  { mu of isSigmaFinite d T R mu & @Content d T R mu }.

Arguments sigma_finiteT {d T R} s.
#[global] Hint Resolve sigma_finiteT : core.

Notation "{ 'sigma_finite_content' 'set' T '->' '\bar' R }" :=
  (sigma_finite_content T R) (at level 36, T, R at next level,
    format "{ 'sigma_finite_content'  'set'  T  '->'  '\bar'  R }")
  : ring_scope.

#[short(type="sigma_finite_measure")]
HB.structure Definition SigmaFiniteMeasure d T R :=
  { mu of @SFiniteMeasure d T R mu & isSigmaFinite d T R mu }.

Notation "{ 'sigma_finite_measure' 'set' T '->' '\bar' R }" :=
  (sigma_finite_measure T R) (at level 36, T, R at next level,
    format "{ 'sigma_finite_measure'  'set'  T  '->'  '\bar'  R }")
  : ring_scope.

HB.factory Record Measure_isSigmaFinite d ( T : measurableType d) ( R : realType)
    ( mu : set T -> \bar R) of isMeasure _ _ _ mu :=
  { sigma_finiteT : sigma_finite setT mu }.

HB.builders Context d ( T : measurableType d) ( R : realType)
   mu of @Measure_isSigmaFinite d T R mu.

Lemma sfinite : sfinite_measure mu.
Proof.

HB.instance Definition _ := @Measure_isSFinite_subdef.Build _ _ _ mu sfinite.

HB.instance Definition _ := @isSigmaFinite.Build _ _ _ mu sigma_finiteT.

HB.end.

Lemma sigma_finite_mzero d ( T : measurableType d) ( R : realType) :
  sigma_finite setT (@mzero d T R).
Proof.

HB.instance Definition _ d ( T : measurableType d) ( R : realType) :=
  @isSigmaFinite.Build d T R mzero (@sigma_finite_mzero d T R).

Lemma sfinite_mzero d ( T : measurableType d) ( R : realType) :
  sfinite_measure (@mzero d T R).
Proof.

HB.instance Definition _ d ( T : measurableType d) ( R : realType) :=
  @Measure_isSFinite_subdef.Build d T R mzero (@sfinite_mzero d T R).

HB.mixin Record SigmaFinite_isFinite d ( T : semiRingOfSetsType d)
    ( R : numDomainType) ( k : set T -> \bar R) :=
  { fin_num_measure : fin_num_fun k }.

HB.structure Definition FinNumFun d ( T : semiRingOfSetsType d)
    ( R : numFieldType) := { k of SigmaFinite_isFinite _ T R k }.

HB.structure Definition FiniteMeasure d ( T : measurableType d) ( R : realType) :=
  { k of @SigmaFiniteMeasure _ _ _ k & SigmaFinite_isFinite _ T R k }.
Arguments fin_num_measure {d T R} _.

Notation "{ 'finite_measure' 'set' T '->' '\bar' R }" :=
  (FiniteMeasure.type T R) (at level 36, T, R at next level,
    format "{ 'finite_measure'  'set'  T  '->'  '\bar'  R }") : ring_scope.

HB.factory Record Measure_isFinite d ( T : measurableType d)
    ( R : realType) ( k : set T -> \bar R)
  of isMeasure _ _ _ k := { fin_num_measure : fin_num_fun k }.

HB.builders Context d ( T : measurableType d) ( R : realType) k
  of Measure_isFinite d T R k.

Let sfinite : sfinite_measure k.
Proof.

HB.instance Definition _ := @Measure_isSFinite_subdef.Build d T R k sfinite.

Let sigma_finite : sigma_finite setT k.
Proof.

HB.instance Definition _ := @isSigmaFinite.Build d T R k sigma_finite.

Let finite : fin_num_fun k
Proof.

HB.instance Definition _ := @SigmaFinite_isFinite.Build d T R k finite.

HB.end.

HB.factory Record Measure_isSFinite d ( T : measurableType d)
    ( R : realType) ( k : set T -> \bar R) of isMeasure _ _ _ k := {
   sfinite_measure_subdef : exists s : {finite_measure set T -> \bar R}^nat,
    forall U, measurable U -> k U = mseries s 0 U }.

HB.builders Context d ( T : measurableType d) ( R : realType)
   k of Measure_isSFinite d T R k.

Let sfinite : sfinite_measure k.
Proof.

HB.instance Definition _ := @Measure_isSFinite_subdef.Build d T R k sfinite.

HB.end.

Section sfinite_measure .
Context d ( T : measurableType d) ( R : realType)
        ( mu : {sfinite_measure set T -> \bar R}).

Let s : (set T -> \bar R)^nat :=
  let: exist2 x _ _ := cid2 (sfinite_measure_subdef mu) in x.

Let s0 n : s n set0 = 0.
Proof.

Let s_ge0 n x : 0 <= s n x.
Proof.

Let s_semi_sigma_additive n : semi_sigma_additive (s n).
Proof.

HB.instance Definition _ n := @isMeasure.Build _ _ _ (s n) (s0 n) (s_ge0 n)
  (@s_semi_sigma_additive n).

Let s_fin n : fin_num_fun (s n).
Proof.

HB.instance Definition _ n := @Measure_isFinite.Build d T R (s n) (s_fin n).

Definition sfinite_measure_seq : {finite_measure set T -> \bar R}^nat :=
  fun n => [the {finite_measure set T -> \bar R} of s n].

Lemma sfinite_measure_seqP U : measurable U ->
  mu U = mseries sfinite_measure_seq O U.
Proof.

End sfinite_measure.

Definition mfrestr d ( T : measurableType d) ( R : realFieldType) ( D : set T)
    ( f : set T -> \bar R) ( mD : measurable D) of f D < +oo :=
  mrestr f mD.

Section measure_frestr .
Context d ( T : measurableType d) ( R : realType).
Variables ( mu : {measure set T -> \bar R}) ( D : set T) ( mD : measurable D).
Hypothesis moo : mu D < +oo.

Local Notation restr := (mfrestr mD moo).

HB.instance Definition _ := Measure.on restr.

Let restr_fin : fin_num_fun restr.
Proof.

HB.instance Definition _ := Measure_isFinite.Build _ _ _ restr
  restr_fin.

End measure_frestr.

HB.mixin Record FiniteMeasure_isSubProbability d ( T : measurableType d)
    ( R : realType) ( P : set T -> \bar R) :=
  { sprobability_setT : P setT <= 1%E }.

#[short(type=subprobability)]
HB.structure Definition SubProbability d ( T : measurableType d) ( R : realType)
  := {mu of @FiniteMeasure d T R mu & FiniteMeasure_isSubProbability d T R mu }.

HB.factory Record Measure_isSubProbability d ( T : measurableType d)
    ( R : realType) ( P : set T -> \bar R) of isMeasure _ _ _ P :=
  { sprobability_setT : P setT <= 1%E }.

HB.builders Context d ( T : measurableType d) ( R : realType)
   P of Measure_isSubProbability d T R P.

Let finite : @Measure_isFinite d T R P.
Proof.

HB.instance Definition _ := finite.

HB.instance Definition _ :=
  @FiniteMeasure_isSubProbability.Build _ _ _ P sprobability_setT.

HB.end.

HB.mixin Record isProbability d ( T : measurableType d) ( R : realType)
  ( P : set T -> \bar R) := { probability_setT : P setT = 1%E }.

#[short(type=probability)]
HB.structure Definition Probability d ( T : measurableType d) ( R : realType) :=
  {P of @SubProbability d T R P & isProbability d T R P }.

Section probability_lemmas .
Context d ( T : measurableType d) ( R : realType) ( P : probability T R).

Lemma probability_le1 ( A : set T) : measurable A -> P A <= 1.
Proof.

Lemma probability_setC ( A : set T) : measurable A -> P (~` A) = 1 - P A.
Proof.

End probability_lemmas.

HB.factory Record Measure_isProbability d ( T : measurableType d)
    ( R : realType) ( P : set T -> \bar R) of isMeasure _ _ _ P :=
  { probability_setT : P setT = 1%E }.

HB.builders Context d ( T : measurableType d) ( R : realType)
   P of Measure_isProbability d T R P.

Let subprobability : @Measure_isSubProbability d T R P.
Proof.

HB.instance Definition _ := subprobability.

HB.instance Definition _ := @isProbability.Build _ _ _ P probability_setT.

HB.end.

Section mnormalize .
Context d ( T : measurableType d) ( R : realType).
Variables ( mu : {measure set T -> \bar R}) ( P : probability T R).

Definition mnormalize :=
  let evidence := mu [set: T] in
  if (evidence == 0) || (evidence == +oo) then fun U => P U
  else fun U => mu U * (fine evidence)^-1%:E.

Let mnormalize0 : mnormalize set0 = 0.
Proof.

Let mnormalize_ge0 U : 0 <= mnormalize U.
Proof.

Let mnormalize_sigma_additive : semi_sigma_additive mnormalize.
Proof.

HB.instance Definition _ := isMeasure.Build _ _ _ mnormalize
  mnormalize0 mnormalize_ge0 mnormalize_sigma_additive.

Let mnormalize1 : mnormalize [set: T] = 1.
Proof.

HB.instance Definition _ :=
  Measure_isProbability.Build _ _ _ mnormalize mnormalize1.

End mnormalize.

Section pdirac .
Context d ( T : measurableType d) ( R : realType).

HB.instance Definition _ x :=
  Measure_isProbability.Build _ _ _ (@dirac _ T x R) (diracT R x).

End pdirac.

Lemma sigma_finite_counting ( R : realType) :
  sigma_finite [set: nat] (@counting _ R).
Proof.
HB.instance Definition _ R :=
  @isSigmaFinite.Build _ _ _ (@counting _ R) (sigma_finite_counting R).

Section content_semiRingOfSetsType .
Context d ( T : semiRingOfSetsType d) ( R : realFieldType).
Variables ( mu : {content set T -> \bar R}) ( A B : set T).
Hypotheses ( mA : measurable A) ( mB : measurable B).

Lemma measureIl : mu (A `&` B) <= mu A.
Proof.

Lemma measureIr : mu (A `&` B) <= mu B.
Proof.

Lemma subset_measure0 : A `<=` B -> mu B = 0 -> mu A = 0.
Proof.

End content_semiRingOfSetsType.

Section content_ringOfSetsType .
Context d ( T : ringOfSetsType d) ( R : realFieldType).
Variable mu : {content set T -> \bar R}.
Implicit Types A B : set T.

Lemma measureDI A B : measurable A -> measurable B ->
  mu A = mu (A `\` B) + mu (A `&` B).
Proof.

Lemma measureD A B : measurable A -> measurable B ->
  mu A < +oo -> mu (A `\` B) = mu A - mu (A `&` B).
Proof.

Lemma measureU2 A B : measurable A -> measurable B ->
  mu (A `|` B) <= mu A + mu B.
Proof.

End content_ringOfSetsType.

Section measureU .
Context d ( T : ringOfSetsType d) ( R : realFieldType).
Variable mu : {measure set T -> \bar R}.

Lemma measureUfinr A B : measurable A -> measurable B -> mu B < +oo ->
  mu (A `|` B) = mu A + mu B - mu (A `&` B).
Proof.

Lemma measureUfinl A B : measurable A -> measurable B -> mu A < +oo ->
  mu (A `|` B) = mu A + mu B - mu (A `&` B).
Proof.

Lemma null_set_setU A B : measurable A -> measurable B ->
  mu A = 0 -> mu B = 0 -> mu (A `|` B) = 0.
Proof.

Lemma measureU0 A B : measurable A -> measurable B -> mu B = 0 ->
  mu (A `|` B) = mu A.
Proof.

End measureU.

Lemma eq_measureU d ( T : ringOfSetsType d) ( R : realFieldType) ( A B : set T)
   ( mu mu' : {measure set T -> \bar R}):
    measurable A -> measurable B ->
  mu A = mu' A -> mu B = mu' B -> mu (A `&` B) = mu' (A `&` B) ->
  mu (A `|` B) = mu' (A `|` B).
Proof.

Section measure_continuity .

Local Open Scope ereal_scope.

Lemma nondecreasing_cvg_mu d ( T : ringOfSetsType d) ( R : realFieldType)
  ( mu : {measure set T -> \bar R}) ( F : (set T) ^nat) :
  (forall i, measurable (F i)) -> measurable (\bigcup_n F n) ->
  nondecreasing_seq F ->
  mu \o F --> mu (\bigcup_n F n).
Proof.

Lemma nonincreasing_cvg_mu d ( T : algebraOfSetsType d) ( R : realFieldType)
  ( mu : {measure set T -> \bar R}) ( F : (set T) ^nat) :
  mu (F 0%N) < +oo ->
  (forall i, measurable (F i)) -> measurable (\bigcap_n F n) ->
  nonincreasing_seq F -> mu \o F --> mu (\bigcap_n F n).
Proof.

End measure_continuity.

Section boole_inequality .
Context d ( R : realFieldType) ( T : ringOfSetsType d).
Variable mu : {content set T -> \bar R}.

Theorem Boole_inequality ( A : (set T) ^nat) n :
    (forall i, `I_n i -> measurable (A i)) ->
  mu (\big[setU/set0]_( i < n) A i) <= \sum_( i < n) mu (A i).
Proof.

End boole_inequality.
Notation le_mu_bigsetU := Boole_inequality.

Section sigma_finite_lemma .
Context d ( T : ringOfSetsType d) ( R : realFieldType) ( A : set T)
        ( mu : {content set T -> \bar R}).

Lemma sigma_finiteP : sigma_finite A mu ->
  exists2 F, A = \bigcup_i F i &
    nondecreasing_seq F /\ forall i, measurable (F i) /\ mu (F i) < +oo.
Proof.

End sigma_finite_lemma.

Section generalized_boole_inequality .
Context d ( T : ringOfSetsType d) ( R : realType).
Variable mu : {measure set T -> \bar R}.

Theorem generalized_Boole_inequality ( A : (set T) ^nat) :
  (forall i, measurable (A i)) -> measurable (\bigcup_n A n) ->
  mu (\bigcup_n A n) <= \sum_( i <oo) mu (A i).
Proof.

End generalized_boole_inequality.
Notation le_mu_bigcup := generalized_Boole_inequality.

Section negligible .
Context d ( T : semiRingOfSetsType d) ( R : realFieldType).

Definition negligible ( mu : set T -> \bar R) N :=
  exists A, [/\ measurable A, mu A = 0 & N `<=` A].

Local Notation "mu .-negligible" := (negligible mu).

Variable mu : {content set T -> \bar R}.

Lemma negligibleP A : measurable A -> mu.-negligible A <-> mu A = 0.
Proof.

Lemma negligible_set0 : mu.-negligible set0.
Proof.

Lemma measure_negligible ( A : set T) :
  measurable A -> mu.-negligible A -> mu A = 0%E.
Proof.

Lemma negligibleS A B : B `<=` A -> mu.-negligible A -> mu.-negligible B.
Proof.

Lemma negligibleI A B :
  mu.-negligible A -> mu.-negligible B -> mu.-negligible (A `&` B).
Proof.

End negligible.
Notation "mu .-negligible" := (negligible mu) : type_scope.

Definition measure_is_complete d ( T : semiRingOfSetsType d) ( R : realFieldType)
    ( mu : set T -> \bar R) :=
  mu.-negligible `<=` measurable.

Section negligible_ringOfSetsType .
Context d ( T : ringOfSetsType d) ( R : realFieldType).
Variable mu : {content set T -> \bar R}.

Lemma negligibleU A B :
  mu.-negligible A -> mu.-negligible B -> mu.-negligible (A `|` B).
Proof.

Lemma negligible_bigsetU ( F : (set T)^nat) s ( P : pred nat) :
  (forall k, P k -> mu.-negligible (F k)) ->
  mu.-negligible (\big[setU/set0]_( k <- s | P k) F k).
Proof.

End negligible_ringOfSetsType.

Lemma negligible_bigcup d ( T : measurableType d) ( R : realFieldType)
    ( mu : {measure set T -> \bar R}) ( F : (set T)^nat) :
  (forall k, mu.-negligible (F k)) -> mu.-negligible (\bigcup_k F k).
Proof.

Section ae .

Definition almost_everywhere d ( T : semiRingOfSetsType d) ( R : realFieldType)
  ( mu : set T -> \bar R) ( P : T -> Prop) := mu.-negligible (~` [set x | P x]).

Let almost_everywhereT d ( T : semiRingOfSetsType d) ( R : realFieldType)
    ( mu : {content set T -> \bar R}) : almost_everywhere mu setT.
Proof.

Let almost_everywhereS d ( T : semiRingOfSetsType d) ( R : realFieldType)
    ( mu : {measure set T -> \bar R}) A B : A `<=` B ->
  almost_everywhere mu A -> almost_everywhere mu B.
Proof.

Let almost_everywhereI d ( T : ringOfSetsType d) ( R : realFieldType)
    ( mu : {measure set T -> \bar R}) A B :
  almost_everywhere mu A -> almost_everywhere mu B ->
  almost_everywhere mu (A `&` B).
Proof.

#[global]
Instance ae_filter_ringOfSetsType d {T : ringOfSetsType d} ( R : realFieldType)
  ( mu : {measure set T -> \bar R}) : Filter (almost_everywhere mu).
Proof.

#[global]
Instance ae_properfilter_algebraOfSetsType d {T : algebraOfSetsType d}
    ( R : realFieldType) ( mu : {measure set T -> \bar R}) :
  mu [set: T] > 0 -> ProperFilter (almost_everywhere mu).
Proof.

End ae.

#[global] Hint Extern 0 (Filter (almost_everywhere _)) =>
  (apply: ae_filter_ringOfSetsType) : typeclass_instances.

#[global] Hint Extern 0 (ProperFilter (almost_everywhere _)) =>
  (apply: ae_properfilter_algebraOfSetsType) : typeclass_instances.

Definition almost_everywhere_notation d ( T : semiRingOfSetsType d)
    ( R : realFieldType) ( mu : set T -> \bar R) ( P : T -> Prop)
  & (phantom Prop (forall x, P x)) := almost_everywhere mu P.
Notation "{ 'ae' m , P }" :=
  (almost_everywhere_notation m (inPhantom P)) : type_scope.

Lemma aeW {d} {T : semiRingOfSetsType d} {R : realFieldType}
    ( mu : {measure set _ -> \bar R}) ( P : T -> Prop) :
  (forall x, P x) -> {ae mu, forall x, P x}.
Proof.

Section ae_eq .
Local Open Scope ereal_scope.
Context d ( T : measurableType d) ( R : realType).
Variables ( mu : {measure set T -> \bar R}) ( D : set T).
Implicit Types f g h i : T -> \bar R.

Definition ae_eq f g := {ae mu, forall x, D x -> f x = g x}.

Lemma ae_eq0 f g : measurable D -> mu D = 0 -> ae_eq f g.
Proof.

Lemma ae_eq_comp ( j : \bar R -> \bar R) f g :
  ae_eq f g -> ae_eq (j \o f) (j \o g).
Proof.

Lemma ae_eq_funeposneg f g : ae_eq f g <-> ae_eq f^\+ g^\+ /\ ae_eq f^\- g^\-.
Proof.

Lemma ae_eq_refl f : ae_eq f f
Proof.

Lemma ae_eq_sym f g : ae_eq f g -> ae_eq g f.
Proof.

Lemma ae_eq_trans f g h : ae_eq f g -> ae_eq g h -> ae_eq f h.
Proof.

Lemma ae_eq_sub f g h i : ae_eq f g -> ae_eq h i -> ae_eq (f \- h) (g \- i).
Proof.

Lemma ae_eq_mul2r f g h : ae_eq f g -> ae_eq (f \* h) (g \* h).
Proof.

Lemma ae_eq_mul2l f g h : ae_eq f g -> ae_eq (h \* f) (h \* g).
Proof.

Lemma ae_eq_mul1l f g : ae_eq f (cst 1) -> ae_eq g (g \* f).
Proof.

Lemma ae_eq_abse f g : ae_eq f g -> ae_eq (abse \o f) (abse \o g).
Proof.

End ae_eq.

Section ae_eq_lemmas .
Context d ( T : measurableType d) ( R : realType).
Implicit Types mu : {measure set T -> \bar R}.

Lemma ae_eq_subset mu A B f g : B `<=` A -> ae_eq mu A f g -> ae_eq mu B f g.
Proof.

End ae_eq_lemmas.

Definition sigma_subadditive {T} {R : numFieldType}
  ( mu : set T -> \bar R) := forall ( F : (set T) ^nat),
  mu (\bigcup_n (F n)) <= \sum_( i <oo) mu (F i).

HB.mixin Record isOuterMeasure
    ( R : numFieldType) ( T : Type) ( mu : set T -> \bar R) := {
   outer_measure0 : mu set0 = 0 ;
   outer_measure_ge0 : forall x, 0 <= mu x ;
   le_outer_measure : {homo mu : A B / A `<=` B >-> A <= B} ;
   outer_measure_sigma_subadditive : sigma_subadditive mu }.

#[short(type=outer_measure)]
HB.structure Definition OuterMeasure ( R : numFieldType) ( T : Type) :=
  {mu & isOuterMeasure R T mu}.

Notation "{ 'outer_measure' 'set' T '->' '\bar' R }" := (outer_measure R T)
  (at level 36, T, R at next level,
    format "{ 'outer_measure'  'set'  T  '->'  '\bar'  R }") : ring_scope.

#[global] Hint Extern 0 (_ set0 = 0) => solve [apply: outer_measure0] : core.
#[global] Hint Extern 0 (sigma_subadditive _) =>
  solve [apply: outer_measure_sigma_subadditive] : core.

Arguments outer_measure0 {R T} _.
Arguments outer_measure_ge0 {R T} _.
Arguments le_outer_measure {R T} _.
Arguments outer_measure_sigma_subadditive {R T} _.

Lemma outer_measure_sigma_subadditive_tail ( T : Type) ( R : realType)
    ( mu : {outer_measure set T -> \bar R}) N ( F : (set T) ^nat) :
  (mu (\bigcup_( n in ~` `I_N) (F n)) <= \sum_(N <= i <oo) mu (F i))%E.
Proof.

Section outer_measureU .
Context d ( T : semiRingOfSetsType d) ( R : realType).
Variable mu : {outer_measure set T -> \bar R}.
Local Open Scope ereal_scope.

Lemma outer_measure_subadditive ( F : nat -> set T) n :
  mu (\big[setU/set0]_( i < n) F i) <= \sum_( i < n) mu (F i).
Proof.

Lemma outer_measureU2 A B : mu (A `|` B) <= mu A + mu B.
Proof.

End outer_measureU.

Lemma le_outer_measureIC ( R : realFieldType) T
  ( mu : {outer_measure set T -> \bar R}) ( A X : set T) :
  mu X <= mu (X `&` A) + mu (X `&` ~` A).
Proof.

Definition caratheodory_measurable ( R : realType) ( T : Type)
  ( mu : set T -> \bar R) ( A : set T) := forall X,
  mu X = mu (X `&` A) + mu (X `&` ~` A).

Local Notation "mu .-caratheodory" :=
   (caratheodory_measurable mu) : classical_set_scope.

Lemma le_caratheodory_measurable ( R : realType) T
  ( mu : {outer_measure set T -> \bar R}) ( A : set T) :
  (forall X, mu (X `&` A) + mu (X `&` ~` A) <= mu X) ->
  mu.-caratheodory A.
Proof.

Section caratheodory_theorem_sigma_algebra .
Variables ( R : realType) ( T : Type) ( mu : {outer_measure set T -> \bar R}).

Lemma outer_measure_bigcup_lim ( A : (set T) ^nat) X :
  mu (X `&` \bigcup_k A k) <= \sum_( k <oo) mu (X `&` A k).
Proof.

Let M := mu.-caratheodory.

Lemma caratheodory_measurable_set0 : M set0.
Proof.

Lemma caratheodory_measurable_setC A : M A -> M (~` A).
Proof.

Lemma caratheodory_measurable_setU_le ( X A B : set T) :
  mu.-caratheodory A -> mu.-caratheodory B ->
  mu (X `&` (A `|` B)) + mu (X `&` ~` (A `|` B)) <= mu X.
Proof.

Lemma caratheodory_measurable_setU A B : M A -> M B -> M (A `|` B).
Proof.

Lemma caratheodory_measurable_bigsetU ( A : (set T) ^nat) :
  (forall n, M (A n)) -> forall n, M (\big[setU/set0]_( i < n) A i).
Proof.

Lemma caratheodory_measurable_setI A B : M A -> M B -> M (A `&` B).
Proof.

Lemma caratheodory_measurable_setD A B : M A -> M B -> M (A `\` B).
Proof.

Section additive_ext_lemmas .
Variable A B : set T.
Hypothesis ( mA : M A) ( mB : M B).

Let caratheodory_decomp X :
  mu X = mu (X `&` A `&` B) + mu (X `&` A `&` ~` B) +
         mu (X `&` ~` A `&` B) + mu (X `&` ~` A `&` ~` B).
Proof.

Let caratheorody_decompIU X : mu (X `&` (A `|` B)) =
  mu (X `&` A `&` B) + mu (X `&` ~` A `&` B) + mu (X `&` A `&` ~` B).
Proof.

Lemma disjoint_caratheodoryIU X : [disjoint A & B] ->
  mu (X `&` (A `|` B)) = mu (X `&` A) + mu (X `&` B).
Proof.
End additive_ext_lemmas.

Lemma caratheodory_additive ( A : (set T) ^nat) : (forall n, M (A n)) ->
  trivIset setT A -> forall n X,
    mu (X `&` \big[setU/set0]_( i < n) A i) = \sum_( i < n) mu (X `&` A i).
Proof.

Lemma caratheodory_lime_le ( A : (set T) ^nat) : (forall n, M (A n)) ->
  trivIset setT A -> forall X,
  \sum_( k <oo) mu (X `&` A k) + mu (X `&` ~` \bigcup_k A k) <= mu X.
Proof.
#[deprecated(since="mathcomp-analysis 0.6.0",
      note="renamed `caratheodory_lime_le`")]
Notation caratheodory_lim_lee := caratheodory_lime_le (only parsing).

Lemma caratheodory_measurable_trivIset_bigcup ( A : (set T) ^nat) :
  (forall n, M (A n)) -> trivIset setT A -> M (\bigcup_k (A k)).
Proof.

Lemma caratheodory_measurable_bigcup ( A : (set T) ^nat) : (forall n, M (A n)) ->
  M (\bigcup_k (A k)).
Proof.

End caratheodory_theorem_sigma_algebra.

Definition caratheodory_type ( R : realType) ( T : Type)
  ( mu : set T -> \bar R) := T.

Definition caratheodory_display R T : (set T -> \bar R) -> measure_display.
Proof.

Section caratheodory_sigma_algebra .
Variables ( R : realType) ( T : pointedType) ( mu : {outer_measure set T -> \bar R}).

HB.instance Definition _ := @isMeasurable.Build (caratheodory_display mu)
  (caratheodory_type mu) (Pointed.class T) mu.-caratheodory
    (caratheodory_measurable_set0 mu)
    (@caratheodory_measurable_setC _ _ mu)
    (@caratheodory_measurable_bigcup _ _ mu).

End caratheodory_sigma_algebra.

Notation "mu .-cara" := (caratheodory_display mu) : measure_display_scope.
Notation "mu .-cara.-measurable" :=
  (measurable : set (set (caratheodory_type mu))) : classical_set_scope.

Section caratheodory_measure .
Variables ( R : realType) ( T : pointedType).
Variable mu : {outer_measure set T -> \bar R}.
Let U := caratheodory_type mu.

Lemma caratheodory_measure0 : mu (set0 : set U) = 0.
Proof.

Lemma caratheodory_measure_ge0 ( A : set U) : 0 <= mu A.
Proof.

Lemma caratheodory_measure_sigma_additive :
  semi_sigma_additive (mu : set U -> _).
Proof.

HB.instance Definition _ := isMeasure.Build _ _ _
  (mu : set (caratheodory_type mu) -> _)
  caratheodory_measure0 caratheodory_measure_ge0
  caratheodory_measure_sigma_additive.

Lemma measure_is_complete_caratheodory :
  measure_is_complete (mu : set (caratheodory_type mu) -> _).
Proof.

End caratheodory_measure.

Lemma epsilon_trick ( R : realType) ( A : (\bar R)^nat) e
    ( P : pred nat) : (forall n, 0 <= A n) -> (0 <= e)%R ->
  \sum_( i <oo | P i) (A i + (e / (2 ^ i.+1)%:R)%:E) <=
  \sum_( i <oo | P i) A i + e%:E.
Proof.

Lemma epsilon_trick0 ( R : realType) ( eps : R) ( P : pred nat) :
  (0 <= eps)%R -> \sum_( i <oo | P i) (eps / (2 ^ i.+1)%:R)%:E <= eps%:E.
Proof.

Section measurable_cover .
Context d ( T : semiRingOfSetsType d).
Implicit Types (X : set T) (F : (set T)^nat).

Definition measurable_cover X := [set F : (set T)^nat |
  (forall i, measurable (F i)) /\ X `<=` \bigcup_k (F k)].

Lemma cover_measurable X F : measurable_cover X F -> forall k, measurable (F k).
Proof.

Lemma cover_subset X F : measurable_cover X F -> X `<=` \bigcup_k (F k).
Proof.

End measurable_cover.

Lemma measurable_uncurry ( T1 T2 : Type) d ( T : semiRingOfSetsType d)
    ( G : T1 -> T2 -> set T) ( x : T1 * T2) :
  measurable (G x.1 x.2) <-> measurable (uncurry G x).
Proof.

Section outer_measure_construction .
Context d ( T : semiRingOfSetsType d) ( R : realType).
Variable mu : set T -> \bar R.
Hypothesis ( measure0 : mu set0 = 0) ( measure_ge0 : forall X, mu X >= 0).
Hint Resolve measure_ge0 measure0 : core.

Definition mu_ext ( X : set T) : \bar R :=
  ereal_inf [set \sum_( k <oo) mu (A k) | A in measurable_cover X].
Local Notation "mu^*" := mu_ext.

Lemma le_mu_ext : {homo mu^* : A B / A `<=` B >-> A <= B}.
Proof.

Lemma mu_ext_ge0 A : 0 <= mu^* A.
Proof.

Lemma mu_ext0 : mu^* set0 = 0.
Proof.

Lemma mu_ext_sigma_subadditive : sigma_subadditive mu^*.
Proof.

End outer_measure_construction.
Declare Scope measure_scope.
Delimit Scope measure_scope with mu.
Notation "mu ^*" := (mu_ext mu) : measure_scope.
Local Open Scope measure_scope.

Section outer_measure_of_content .
Context d ( R : realType) ( T : semiRingOfSetsType d).
Variable mu : {content set T -> \bar R}.

HB.instance Definition _ := isOuterMeasure.Build
  R T _ (@mu_ext0 _ _ _ _ (measure0 mu) (measure_ge0 mu))
      (mu_ext_ge0 (measure_ge0 mu))
      (le_mu_ext mu)
      (mu_ext_sigma_subadditive (measure_ge0 mu)).

End outer_measure_of_content.

Section g_salgebra_measure_unique_trace .
Context d ( R : realType) ( T : measurableType d).
Variables ( G : set (set T)) ( D : set T) ( mD : measurable D).
Let H := [set X | G X /\ X `<=` D] .
Hypotheses ( Hm : H `<=` measurable) ( setIH : setI_closed H) ( HD : H D).
Variables m1 m2 : {measure set T -> \bar R}.
Hypotheses ( m1m2 : forall A, H A -> m1 A = m2 A) ( m1oo : (m1 D < +oo)%E).

Lemma g_salgebra_measure_unique_trace :
  (forall X, (<<s D, H >>) X -> X `<=` D) -> forall X, <<s D, H >> X ->
  m1 X = m2 X.
Proof.

End g_salgebra_measure_unique_trace.

Section g_salgebra_measure_unique .
Context d ( R : realType) ( T : measurableType d).
Variable G : set (set T).
Hypothesis Gm : G `<=` measurable.
Variable g : (set T)^nat.
Hypotheses Gg : forall i, G (g i).
Hypothesis g_cover : \bigcup_k (g k) = setT.
Variables m1 m2 : {measure set T -> \bar R}.

Lemma g_salgebra_measure_unique_cover :
  (forall n A, <<s G >> A -> m1 (g n `&` A) = m2 (g n `&` A)) ->
  forall A, <<s G >> A -> m1 A = m2 A.
Proof.

Hypothesis setIG : setI_closed G.
Hypothesis m1m2 : forall A, G A -> m1 A = m2 A.
Hypothesis m1goo : forall k, (m1 (g k) < +oo)%E.

Lemma g_salgebra_measure_unique : forall E, <<s G >> E -> m1 E = m2 E.
Proof.

End g_salgebra_measure_unique.

Section measure_unique .
Context d ( R : realType) ( T : measurableType d).
Variables ( G : set (set T)) ( g : (set T)^nat).
Hypotheses ( mG : measurable = <<s G >>) ( setIG : setI_closed G).
Hypothesis Gg : forall i, G (g i).
Hypothesis g_cover : \bigcup_k (g k) = setT.
Variables m1 m2 : {measure set T -> \bar R}.
Hypothesis m1m2 : forall A, G A -> m1 A = m2 A.
Hypothesis m1goo : forall k, (m1 (g k) < +oo)%E.

Lemma measure_unique A : measurable A -> m1 A = m2 A.
Proof.

End measure_unique.
Arguments measure_unique {d R T} G g.

Lemma measurable_mu_extE d ( R : realType) ( T : semiRingOfSetsType d)
    ( mu : {measure set T -> \bar R}) X :
  measurable X -> mu^* X = mu X.
Proof.

Section Rmu_ext .
Import SetRing.

Lemma Rmu_ext d ( R : realType) ( T : semiRingOfSetsType d)
    ( mu : {content set T -> \bar R}) :
  (measure mu)^* = mu^*.
Proof.

End Rmu_ext.

Lemma measurable_Rmu_extE d ( R : realType) ( T : semiRingOfSetsType d)
    ( mu : {measure set T -> \bar R}) X :
  d.-ring.-measurable X -> mu^* X = SetRing.measure mu X.
Proof.

Section measure_extension .
Context d ( T : semiRingOfSetsType d) ( R : realType).
Variable mu : {measure set T -> \bar R}.
Let Rmu := SetRing.measure mu.
Notation rT := (SetRing.type T).

Lemma sub_caratheodory :
  (d.-measurable).-sigma.-measurable `<=` mu^*.-cara.-measurable.
Proof.

Let I := [the measurableType _ of salgebraType (@measurable _ T)].

Definition measure_extension : set I -> \bar R := mu^*.

Local Lemma measure_extension0 : measure_extension set0 = 0.
Proof.

Local Lemma measure_extension_ge0 ( A : set I) : 0 <= measure_extension A.
Proof.

Local Lemma measure_extension_semi_sigma_additive :
  semi_sigma_additive measure_extension.
Proof.

HB.instance Definition _ := isMeasure.Build _ _ _ measure_extension
  measure_extension0 measure_extension_ge0
  measure_extension_semi_sigma_additive.

Lemma measure_extension_sigma_finite : @sigma_finite _ T _ setT mu ->
  @sigma_finite _ _ _ setT measure_extension.
Proof.

Lemma measure_extension_unique : sigma_finite [set: T] mu ->
  (forall mu' : {measure set I -> \bar R},
    (forall X, d.-measurable X -> mu X = mu' X) ->
    (forall X, (d.-measurable).-sigma.-measurable X ->
      measure_extension X = mu' X)).
Proof.

End measure_extension.

Lemma caratheodory_measurable_mu_ext d ( R : realType) ( T : measurableType d)
    ( mu : {measure set T -> \bar R}) A :
  d.-measurable A -> mu^*.-cara.-measurable A.
Proof.

Definition preimage_classes d1 d2
    ( T1 : measurableType d1) ( T2 : measurableType d2) ( T : Type)
    ( f1 : T -> T1) ( f2 : T -> T2) :=
  <<s preimage_class setT f1 measurable `|`
      preimage_class setT f2 measurable >>.

Section product_lemma .
Context d1 d2 ( T1 : measurableType d1) ( T2 : measurableType d2).
Variables ( T : pointedType) ( f1 : T -> T1) ( f2 : T -> T2).
Variables ( T3 : Type) ( g : T3 -> T).

Lemma preimage_classes_comp : preimage_classes (f1 \o g) (f2 \o g) =
                              preimage_class setT g (preimage_classes f1 f2).
Proof.

End product_lemma.

Definition measure_prod_display :
  (measure_display * measure_display) -> measure_display.
Proof.

Section product_salgebra_instance .
Context d1 d2 ( T1 : measurableType d1) ( T2 : measurableType d2).
Let f1 := @fst T1 T2.
Let f2 := @snd T1 T2.

Lemma prod_salgebra_set0 : preimage_classes f1 f2 (set0 : set (T1 * T2)).
Proof.

Lemma prod_salgebra_setC A : preimage_classes f1 f2 A ->
  preimage_classes f1 f2 (~` A).
Proof.

Lemma prod_salgebra_bigcup ( F : _^nat) : (forall i, preimage_classes f1 f2 (F i)) ->
  preimage_classes f1 f2 (\bigcup_i (F i)).
Proof.

HB.instance Definition prod_salgebra_mixin :=
  @isMeasurable.Build (measure_prod_display (d1, d2))
    (T1 * T2)%type (Pointed.class _) (preimage_classes f1 f2)
    (prod_salgebra_set0) (prod_salgebra_setC) (prod_salgebra_bigcup).

End product_salgebra_instance.
Notation "p .-prod" := (measure_prod_display p) : measure_display_scope.
Notation "p .-prod.-measurable" :=
  ((p.-prod).-measurable : set (set (_ * _))) :
    classical_set_scope.

Lemma measurableM d1 d2 ( T1 : measurableType d1) ( T2 : measurableType d2)
    ( A : set T1) ( B : set T2) :
  measurable A -> measurable B -> measurable (A `*` B).
Proof.

Section product_salgebra_measurableType .
Context d1 d2 ( T1 : measurableType d1) ( T2 : measurableType d2).
Let M1 := @measurable _ T1.
Let M2 := @measurable _ T2.
Let M1xM2 := [set A `*` B | A in M1 & B in M2].

Lemma measurable_prod_measurableType :
  (d1, d2).-prod.-measurable = <<s M1xM2 >>.
Proof.

End product_salgebra_measurableType.

Section product_salgebra_g_measurableTypeR .
Context d1 ( T1 : measurableType d1) ( T2 : pointedType) ( C2 : set (set T2)).
Hypothesis setTC2 : setT `<=` C2.

Lemma measurable_prod_g_measurableTypeR :
  @measurable _ [the measurableType _ of T1 * salgebraType C2 : Type]
  = <<s [set A `*` B | A in measurable & B in C2] >>.
Proof.

End product_salgebra_g_measurableTypeR.

Section product_salgebra_g_measurableType .
Variables ( T1 T2 : pointedType) ( C1 : set (set T1)) ( C2 : set (set T2)).
Hypotheses ( setTC1 : setT `<=` C1) ( setTC2 : setT `<=` C2).

Lemma measurable_prod_g_measurableType :
  @measurable _ [the measurableType _ of salgebraType C1 * salgebraType C2 : Type]
  = <<s [set A `*` B | A in C1 & B in C2] >>.
Proof.

End product_salgebra_g_measurableType.

Section prod_measurable_fun .
Context d d1 d2 ( T : measurableType d) ( T1 : measurableType d1)
        ( T2 : measurableType d2).

Lemma prod_measurable_funP ( h : T -> T1 * T2) : measurable_fun setT h <->
  measurable_fun setT (fst \o h) /\ measurable_fun setT (snd \o h).
Proof.

Lemma measurable_fun_prod ( f : T -> T1) ( g : T -> T2) :
  measurable_fun setT f -> measurable_fun setT g ->
  measurable_fun setT (fun x => (f x, g x)).
Proof.

End prod_measurable_fun.
#[deprecated(since="mathcomp-analysis 0.6.3", note="renamed `measurable_fun_prod`")]
Notation measurable_fun_pair := measurable_fun_prod (only parsing).

Section prod_measurable_proj .
Context d1 d2 ( T1 : measurableType d1) ( T2 : measurableType d2).

Lemma measurable_fst : measurable_fun [set: T1 * T2] fst.
Proof.
#[local] Hint Resolve measurable_fst : core.

Lemma measurable_snd : measurable_fun [set: T1 * T2] snd.
Proof.
#[local] Hint Resolve measurable_snd : core.

Lemma measurable_swap : measurable_fun [set: _] (@swap T1 T2).
Proof.

End prod_measurable_proj.
Arguments measurable_fst {d1 d2 T1 T2}.
Arguments measurable_snd {d1 d2 T1 T2}.
#[deprecated(since="mathcomp-analysis 0.6.3", note="renamed `measurable_fst`")]
Notation measurable_fun_fst := measurable_fst (only parsing).
#[deprecated(since="mathcomp-analysis 0.6.3", note="renamed `measurable_snd`")]
Notation measurable_fun_snd := measurable_snd (only parsing).
#[deprecated(since="mathcomp-analysis 0.6.3", note="renamed `measurable_swap`")]
Notation measurable_fun_swap := measurable_swap (only parsing).
#[global] Hint Extern 0 (measurable_fun _ fst) =>
  solve [apply: measurable_fst] : core.
#[global] Hint Extern 0 (measurable_fun _ snd) =>
  solve [apply: measurable_snd] : core.

Lemma measurable_fun_if_pair d d' ( X : measurableType d)
    ( Y : measurableType d') ( x y : X -> Y) :
  measurable_fun setT x -> measurable_fun setT y ->
  measurable_fun setT (fun tb => if tb.2 then x tb.1 else y tb.1).
Proof.

Section partial_measurable_fun .
Context d d1 d2 ( T : measurableType d) ( T1 : measurableType d1)
  ( T2 : measurableType d2).
Variable f : T1 * T2 -> T.

Lemma measurable_pair1 ( x : T1) : measurable_fun [set: T2] (pair x).
Proof.

Lemma measurable_pair2 ( y : T2) : measurable_fun [set: T1] (pair^~ y).
Proof.

End partial_measurable_fun.
#[global] Hint Extern 0 (measurable_fun _ (pair _)) =>
  solve [apply: measurable_pair1] : core.
#[global] Hint Extern 0 (measurable_fun _ (pair^~ _)) =>
  solve [apply: measurable_pair2] : core.

Section absolute_continuity .
Context d ( T : measurableType d) ( R : realType).
Implicit Types m : set T -> \bar R.

Definition measure_dominates m1 m2 :=
  forall A, measurable A -> m2 A = 0 -> m1 A = 0.

Local Notation "m1 `<< m2" := (measure_dominates m1 m2).

Lemma measure_dominates_trans m1 m2 m3 : m1 `<< m2 -> m2 `<< m3 -> m1 `<< m3.
Proof.

End absolute_continuity.
Notation "m1 `<< m2" := (measure_dominates m1 m2).

Section absolute_continuity_lemmas .
Context d ( T : measurableType d) ( R : realType).
Implicit Types m : {measure set T -> \bar R}.

Lemma measure_dominates_ae_eq m1 m2 f g E : measurable E ->
    m2 `<< m1 -> ae_eq m1 E f g -> ae_eq m2 E f g.
Proof.

End absolute_continuity_lemmas.

Section essential_supremum .
Context d {T : measurableType d} {R : realType}.
Variable mu : {measure set T -> \bar R}.
Implicit Types f : T -> R.

Definition ess_sup f :=
  ereal_inf (EFin @` [set r | mu (f @^-1` `]r, +oo[) = 0]).

Lemma ess_sup_ge0 f : 0 < mu [set: T] -> (forall t, 0 <= f t)%R ->
  0 <= ess_sup f.
Proof.

End essential_supremum.