Documentation

ToMathlib.ProbabilityTheory.FinRatPMF

Probability mass functions with finite support and non-negative rational weights #

This is a special case of PMF that suffices for denotational semantics of OracleComp with finite oracle specifications.

Design #

We use a two-layer approach:

For computation, use FinRatPMF.Raw. For reasoning about distributional equality, use FinRatPMF. Both connect to Mathlib's PMF via toPMF.

Raw representation #

structure FinRatPMF.Raw (α : Type u) :

Raw probability mass function with finite support and non-negative rational weights.

Stores an array of (outcome, weight) pairs whose weights sum to 1. This representation is computable but not canonical: many different FinRatPMF.Raw values can represent the same probability distribution.

Instances For
    def FinRatPMF.Raw.toList {α : Type u} (p : Raw α) :

    View the raw array representation as a list, which is convenient for proofs.

    Instances For
      def FinRatPMF.Raw.probOfList {α : Type u} [DecidableEq α] (l : List (α × ℚ≥0)) (x : α) :
      Instances For
        Instances For
          theorem FinRatPMF.Raw.ext {α : Type u} {p q : Raw α} (h : p.data = q.data) :
          p = q
          theorem FinRatPMF.Raw.ext_iff {α : Type u} {p q : Raw α} :
          p = q p.data = q.data
          theorem FinRatPMF.Raw.ext_toList {α : Type u} {p q : Raw α} (h : p.toList = q.toList) :
          p = q

          Bind sum auxiliary lemma #

          Monad operations #

          def FinRatPMF.Raw.pure {α : Type u} (a : α) :
          Raw α
          Instances For
            @[implicit_reducible]
            @[implicit_reducible]
            instance FinRatPMF.Raw.instRepr {α : Type u} [Repr α] :
            Repr (Raw α)
            @[implicit_reducible]
            def FinRatPMF.Raw.bind {α β : Type u} (f : Raw α) (g : αRaw β) :
            Raw β
            Instances For
              @[implicit_reducible]
              @[simp]
              theorem FinRatPMF.Raw.pure_toList {α : Type u} (a : α) :
              @[simp]
              theorem FinRatPMF.Raw.bind_toList {α β : Type u} (f : Raw α) (g : αRaw β) :
              (f >>= g).toList = List.flatMap (fun (x : α × ℚ≥0) => match x with | (a, p) => List.map (fun (x : β × ℚ≥0) => match x with | (b, q) => (b, p * q)) (g a).toList) f.toList
              def FinRatPMF.Raw.uniformList {α : Type u} (l : List α) (hl : l []) :
              Raw α

              Uniform distribution over a nonempty list, treating repeated entries as repeated tickets.

              Instances For
                def FinRatPMF.Raw.uniform {α : Type u} [FinEnum α] [Inhabited α] :
                Raw α

                Uniform distribution over a finite inhabited type.

                Instances For

                  Fair coin.

                  Instances For

                    Bernoulli distribution with probability p of true.

                    Instances For

                      Probability and support #

                      def FinRatPMF.Raw.prob {α : Type u} [DecidableEq α] (p : Raw α) (x : α) :

                      The probability assigned to x by the raw PMF: sum of weights for all entries with key x.

                      Instances For
                        theorem FinRatPMF.Raw.prob_eq_prob {α : Type u} (inst1 inst2 : DecidableEq α) (p : Raw α) (x : α) :
                        p.prob x = p.prob x

                        prob is independent of the DecidableEq instance, since decide (a = b) gives the same Bool for any Decidable instance on the same Prop.

                        def FinRatPMF.Raw.support {α : Type u} [DecidableEq α] (p : Raw α) :

                        The finite support: the set of outcomes appearing in the array.

                        Instances For
                          theorem FinRatPMF.Raw.prob_eq_zero_of_not_mem_support {α : Type u} [DecidableEq α] (p : Raw α) {x : α} (hx : xp.support) :
                          p.prob x = 0
                          theorem FinRatPMF.Raw.mem_support_iff {α : Type u} [DecidableEq α] (p : Raw α) (x : α) :
                          x p.support p.prob x 0

                          Sum of prob over the support recovers the total weight.

                          @[simp]
                          theorem FinRatPMF.Raw.prob_pure {α : Type u} [DecidableEq α] (a x : α) :
                          (Raw.pure a).prob x = if x = a then 1 else 0
                          @[simp]
                          theorem FinRatPMF.Raw.support_pure {α : Type u} [DecidableEq α] (a : α) :
                          theorem FinRatPMF.Raw.prob_uniformList_of_nodup {α : Type u} [DecidableEq α] {l : List α} (hl : l []) (hnd : l.Nodup) (x : α) :

                          Point probabilities for uniformList on a duplicate-free list.

                          theorem FinRatPMF.Raw.support_uniformList_of_nodup {α : Type u} [DecidableEq α] {l : List α} (hl : l []) (hnd : l.Nodup) :

                          Uniform distributions over duplicate-free lists have support exactly the listed elements.

                          @[simp]
                          theorem FinRatPMF.Raw.prob_uniform {α : Type u} [FinEnum α] [Inhabited α] (x : α) :

                          Point probabilities of Raw.uniform.

                          @[simp]

                          Raw.uniform has full finite support.

                          @[simp]

                          Point probabilities of Raw.coin.

                          @[simp]
                          @[simp]
                          theorem FinRatPMF.Raw.prob_le_one {α : Type u} [DecidableEq α] (p : Raw α) (x : α) :
                          p.prob x 1
                          @[simp]
                          theorem FinRatPMF.Raw.prob_bind {α β : Type u} [DecidableEq α] [DecidableEq β] (m : Raw α) (f : αRaw β) (y : β) :
                          (m >>= f).prob y = am.support, m.prob a * (f a).prob y
                          theorem FinRatPMF.Raw.mem_support_bind_iff {α β : Type u} [DecidableEq α] [DecidableEq β] (m : Raw α) (f : αRaw β) (y : β) :
                          y (m >>= f).support xm.support, y (f x).support
                          @[simp]
                          theorem FinRatPMF.Raw.support_bind {α β : Type u} [DecidableEq α] [DecidableEq β] (m : Raw α) (f : αRaw β) :
                          (m >>= f).support = m.support.biUnion fun (x : α) => (f x).support
                          Instances For
                            Instances For
                              Instances For
                                def FinRatPMF.Raw.normalize {α : Type u} [DecidableEq α] [BEq α] [Hashable α] [LawfulBEq α] [LawfulHashable α] (p : Raw α) :
                                Raw α

                                Merge duplicate outcomes and discard zero-weight entries. This implementation is linear in the number of raw entries up to hash-map operations, so it avoids the repeated support/prob rescans that would make normalization quadratic.

                                Instances For
                                  @[simp]
                                  theorem FinRatPMF.Raw.prob_normalize {α : Type u} [DecidableEq α] [BEq α] [Hashable α] [LawfulBEq α] [LawfulHashable α] (p : Raw α) (x : α) :
                                  noncomputable def FinRatPMF.Raw.toPMF {α : Type u} [DecidableEq α] (p : Raw α) :
                                  PMF α

                                  Convert to a PMF by mapping weights through ℚ≥0 → ℝ≥0 → ℝ≥0∞.

                                  Instances For
                                    @[simp]
                                    theorem FinRatPMF.Raw.toPMF_apply {α : Type u} [DecidableEq α] (p : Raw α) (x : α) :
                                    p.toPMF x = (p.prob x)
                                    @[simp]
                                    theorem FinRatPMF.Raw.toPMF_pure {α : Type u} [DecidableEq α] (a : α) :
                                    @[simp]
                                    theorem FinRatPMF.Raw.toPMF_bind {α β : Type u} [DecidableEq α] [DecidableEq β] (m : Raw α) (f : αRaw β) :
                                    (m >>= f).toPMF = do let am.toPMF (f a).toPMF
                                    Instances For

                                      Distributional equality and quotient #

                                      def FinRatPMF.SameDist {α : Type u} (p q : Raw α) :

                                      Two raw PMFs represent the same distribution if they assign the same probability to every outcome. Uses classical decidable equality since this is a Prop.

                                      Instances For
                                        theorem FinRatPMF.SameDist.refl {α : Type u} (p : Raw α) :
                                        theorem FinRatPMF.SameDist.symm {α : Type u} {p q : Raw α} (h : SameDist p q) :
                                        theorem FinRatPMF.SameDist.trans {α : Type u} {p q r : Raw α} (hpq : SameDist p q) (hqr : SameDist q r) :
                                        theorem FinRatPMF.SameDist.prob_eq {α : Type u} [DecidableEq α] {p q : Raw α} (h : SameDist p q) (x : α) :
                                        p.prob x = q.prob x
                                        theorem FinRatPMF.SameDist.support_eq {α : Type u} [DecidableEq α] {p q : Raw α} (h : SameDist p q) :
                                        theorem FinRatPMF.SameDist.bind_congr {α β : Type u} {p q : Raw α} {f g : αRaw β} (hpq : SameDist p q) (hfg : ∀ (x : α), SameDist (f x) (g x)) :
                                        SameDist (p >>= f) (q >>= g)
                                        theorem FinRatPMF.SameDist.map_congr {α β : Type u} {p q : Raw α} (hpq : SameDist p q) (f : αβ) :
                                        SameDist (f <$> p) (f <$> q)
                                        @[implicit_reducible]
                                        instance FinRatPMF.Raw.instSetoid {α : Type u} :
                                        Setoid (Raw α)
                                        def FinRatPMF (α : Type u) :

                                        Probability mass function with finite support and rational weights, with canonical equality.

                                        Defined as the quotient of FinRatPMF.Raw by distributional equality. Two values are equal iff they assign the same probability to every outcome.

                                        Instances For
                                          def FinRatPMF.mk {α : Type u} (p : Raw α) :

                                          Construct from a raw PMF.

                                          Instances For
                                            theorem FinRatPMF.eq_iff {α : Type u} {p q : Raw α} :
                                            mk p = mk q SameDist p q

                                            FinRatPMF equality is distributional equality.

                                            Monad operations #

                                            @[implicit_reducible]
                                            noncomputable instance FinRatPMF.instMonad :

                                            bind lifts Raw.bind across the quotient in the first argument. The codomain remains noncomputable because the Kleisli function returns quotient values, so we still choose a raw representative for each branch.

                                            theorem FinRatPMF.bind_eq_out {α β : Type u} (ma : FinRatPMF α) (f : αFinRatPMF β) :
                                            ma >>= f = mk ((Quotient.out ma).bind fun (a : α) => Quotient.out (f a))
                                            @[simp]
                                            theorem FinRatPMF.bind_mk {α β : Type u} (p : Raw α) (f : αFinRatPMF β) :
                                            mk p >>= f = mk (p.bind fun (a : α) => Quotient.out (f a))

                                            Connection to PMF #

                                            noncomputable def FinRatPMF.toPMF {α : Type u} (p : FinRatPMF α) :
                                            PMF α

                                            Convert a FinRatPMF to a PMF. Well-defined since SameDist implies equal toPMF.

                                            Instances For
                                              @[simp]
                                              theorem FinRatPMF.toPMF_mk {α : Type u} (p : Raw α) :
                                              (mk p).toPMF = p.toPMF
                                              @[simp]
                                              theorem FinRatPMF.toPMF_pure {α : Type u} (a : α) :
                                              @[simp]
                                              theorem FinRatPMF.toPMF_bind {α β : Type u} (ma : FinRatPMF α) (f : αFinRatPMF β) :
                                              (ma >>= f).toPMF = do let ama.toPMF (f a).toPMF
                                              Instances For
                                                @[implicit_reducible]
                                                instance FinRatPMF.instDecidableSameDist {α : Type u} [DecidableEq α] (p q : Raw α) :
                                                @[implicit_reducible]
                                                @[simp]
                                                theorem FinRatPMF.beq_iff_sameDist {α : Type u} [DecidableEq α] (p q : Raw α) :
                                                (p == q) = true SameDist p q