File: Mathlib/Probability/ProbabilityMassFunction/Monad.lean

full_name: PMF.pure
code: /-- The pure `PMF` is the `PMF` where all the mass lies in one point.
  The value of `pure a` is `1` at `a` and `0` elsewhere. -/
def pure (a : α) : PMF α 
goal: PMF α

full_name: PMF.pure_apply
code: @[simp]
theorem pure_apply : pure a a' = if a' = a then 1 else 0 
goal: (PMF.pure a) a' = if a' = a then 1 else 0

full_name: PMF.support_pure
code: @[simp]
theorem support_pure : (pure a).support = {a} 
goal: (PMF.pure a).support = {a}

full_name: PMF.mem_support_pure_iff
code: theorem mem_support_pure_iff : a' ∈ (pure a).support ↔ a' = a 
goal: a' ∈ (PMF.pure a).support ↔ a' = a

full_name: PMF.pure_apply_self
code: theorem pure_apply_self : pure a a = 1 
goal: (PMF.pure a) a = 1

full_name: PMF.pure_apply_of_ne
code: theorem pure_apply_of_ne (h : a' ≠ a) : pure a a' = 0 
goal: (PMF.pure a) a' = 0

full_name: PMF.instInhabited
code: instance [Inhabited α] : Inhabited (PMF α) 
goal: Inhabited (PMF α)

full_name: PMF.toOuterMeasure_pure_apply
code: @[simp]
theorem toOuterMeasure_pure_apply : (pure a).toOuterMeasure s = if a ∈ s then 1 else 0 
goal: (PMF.pure a).toOuterMeasure s = if a ∈ s then 1 else 0

full_name: PMF.toMeasure_pure_apply
code: /-- The measure of a set under `pure a` is `1` for sets containing `a` and `0` otherwise. -/
@[simp]
theorem toMeasure_pure_apply (hs : MeasurableSet s) :
    (pure a).toMeasure s = if a ∈ s then 1 else 0 
goal: (PMF.pure a).toMeasure s = if a ∈ s then 1 else 0

full_name: PMF.toMeasure_pure
code: theorem toMeasure_pure : (pure a).toMeasure = Measure.dirac a 
goal: (PMF.pure a).toMeasure = MeasureTheory.Measure.dirac a

full_name: PMF.toPMF_dirac
code: @[simp]
theorem toPMF_dirac [Countable α] [h : MeasurableSingletonClass α] :
    (Measure.dirac a).toPMF = pure a 
goal: (MeasureTheory.Measure.dirac a).toPMF = PMF.pure a

full_name: PMF.bind
code: /-- The monadic bind operation for `PMF`. -/
def bind (p : PMF α) (f : α → PMF β) : PMF β 
goal: PMF β

full_name: PMF.bind_apply
code: @[simp]
theorem bind_apply (b : β) : p.bind f b = ∑' a, p a * f a b 
goal: (p.bind f) b = ∑' (a : α), p a * (f a) b

full_name: PMF.support_bind
code: @[simp]
theorem support_bind : (p.bind f).support = ⋃ a ∈ p.support, (f a).support 
goal: (p.bind f).support = ⋃ a ∈ p.support, (f a).support

full_name: PMF.mem_support_bind_iff
code: theorem mem_support_bind_iff (b : β) :
    b ∈ (p.bind f).support ↔ ∃ a ∈ p.support, b ∈ (f a).support 
goal: b ∈ (p.bind f).support ↔ ∃ a ∈ p.support, b ∈ (f a).support

full_name: PMF.pure_bind
code: @[simp]
theorem pure_bind (a : α) (f : α → PMF β) : (pure a).bind f = f a 
goal: (PMF.pure a).bind f = f a

full_name: PMF.bind_pure
code: @[simp]
theorem bind_pure : p.bind pure = p 
goal: p.bind PMF.pure = p

full_name: PMF.bind_const
code: @[simp]
theorem bind_const (p : PMF α) (q : PMF β) : (p.bind fun _ => q) = q 
goal: (p.bind fun x => q) = q

full_name: PMF.bind_bind
code: @[simp]
theorem bind_bind : (p.bind f).bind g = p.bind fun a => (f a).bind g 
goal: (p.bind f).bind g = p.bind fun a => (f a).bind g

full_name: PMF.bind_comm
code: theorem bind_comm (p : PMF α) (q : PMF β) (f : α → β → PMF γ) :
    (p.bind fun a => q.bind (f a)) = q.bind fun b => p.bind fun a => f a b 
goal: (p.bind fun a => q.bind (f a)) = q.bind fun b => p.bind fun a => f a b

full_name: PMF.toOuterMeasure_bind_apply
code: @[simp]
theorem toOuterMeasure_bind_apply :
    (p.bind f).toOuterMeasure s = ∑' a, p a * (f a).toOuterMeasure s 
goal: (p.bind f).toOuterMeasure s = ∑' (a : α), p a * (f a).toOuterMeasure s

full_name: PMF.toMeasure_bind_apply
code: /-- The measure of a set under `p.bind f` is the sum over `a : α`
  of the probability of `a` under `p` times the measure of the set under `f a`. -/
@[simp]
theorem toMeasure_bind_apply [MeasurableSpace β] (hs : MeasurableSet s) :
    (p.bind f).toMeasure s = ∑' a, p a * (f a).toMeasure s 
goal: (p.bind f).toMeasure s = ∑' (a : α), p a * (f a).toMeasure s

full_name: PMF.instMonad
code: instance : Monad PMF 
goal: Monad PMF

full_name: PMF.bindOnSupport
code: /-- Generalized version of `bind` allowing `f` to only be defined on the support of `p`.
  `p.bind f` is equivalent to `p.bindOnSupport (fun a _ ↦ f a)`, see `bindOnSupport_eq_bind`. -/
def bindOnSupport (p : PMF α) (f : ∀ a ∈ p.support, PMF β) : PMF β 
goal: PMF β

full_name: PMF.bindOnSupport_apply
code: @[simp]
theorem bindOnSupport_apply (b : β) :
    p.bindOnSupport f b = ∑' a, p a * if h : p a = 0 then 0 else f a h b 
goal: (p.bindOnSupport f) b = ∑' (a : α), p a * if h : p a = 0 then 0 else (f a h) b

full_name: PMF.support_bindOnSupport
code: @[simp]
theorem support_bindOnSupport :
    (p.bindOnSupport f).support = ⋃ (a : α) (h : a ∈ p.support), (f a h).support 
goal: (p.bindOnSupport f).support = ⋃ a, ⋃ (h : a ∈ p.support), (f a h).support

full_name: PMF.mem_support_bindOnSupport_iff
code: theorem mem_support_bindOnSupport_iff (b : β) :
    b ∈ (p.bindOnSupport f).support ↔ ∃ (a : α) (h : a ∈ p.support), b ∈ (f a h).support 
goal: b ∈ (p.bindOnSupport f).support ↔ ∃ a, ∃ (h : a ∈ p.support), b ∈ (f a h).support

full_name: PMF.bindOnSupport_eq_bind
code: /-- `bindOnSupport` reduces to `bind` if `f` doesn't depend on the additional hypothesis. -/
@[simp]
theorem bindOnSupport_eq_bind (p : PMF α) (f : α → PMF β) :
    (p.bindOnSupport fun a _ => f a) = p.bind f 
goal: (p.bindOnSupport fun a x => f a) = p.bind f

full_name: PMF.bindOnSupport_eq_zero_iff
code: theorem bindOnSupport_eq_zero_iff (b : β) :
    p.bindOnSupport f b = 0 ↔ ∀ (a) (ha : p a ≠ 0), f a ha b = 0 
goal: (p.bindOnSupport f) b = 0 ↔ ∀ (a : α) (ha : p a ≠ 0), (f a ha) b = 0

full_name: PMF.pure_bindOnSupport
code: @[simp]
theorem pure_bindOnSupport (a : α) (f : ∀ (a' : α) (_ : a' ∈ (pure a).support), PMF β) :
    (pure a).bindOnSupport f = f a ((mem_support_pure_iff a a).mpr rfl) 
goal: (PMF.pure a).bindOnSupport f = f a ⋯

full_name: PMF.bindOnSupport_pure
code: theorem bindOnSupport_pure (p : PMF α) : (p.bindOnSupport fun a _ => pure a) = p 
goal: (p.bindOnSupport fun a x => PMF.pure a) = p

full_name: PMF.bindOnSupport_bindOnSupport
code: @[simp]
theorem bindOnSupport_bindOnSupport (p : PMF α) (f : ∀ a ∈ p.support, PMF β)
    (g : ∀ b ∈ (p.bindOnSupport f).support, PMF γ) :
    (p.bindOnSupport f).bindOnSupport g =
      p.bindOnSupport fun a ha =>
        (f a ha).bindOnSupport fun b hb =>
          g b ((mem_support_bindOnSupport_iff f b).mpr ⟨a, ha, hb⟩) 
goal: (p.bindOnSupport f).bindOnSupport g = p.bindOnSupport fun a ha => (f a ha).bindOnSupport fun b hb => g b ⋯

full_name: PMF.bindOnSupport_comm
code: theorem bindOnSupport_comm (p : PMF α) (q : PMF β) (f : ∀ a ∈ p.support, ∀ b ∈ q.support, PMF γ) :
    (p.bindOnSupport fun a ha => q.bindOnSupport (f a ha)) =
      q.bindOnSupport fun b hb => p.bindOnSupport fun a ha => f a ha b hb 
goal: (p.bindOnSupport fun a ha => q.bindOnSupport (f a ha)) =
  q.bindOnSupport fun b hb => p.bindOnSupport fun a ha => f a ha b hb

full_name: PMF.toOuterMeasure_bindOnSupport_apply
code: @[simp]
theorem toOuterMeasure_bindOnSupport_apply :
    (p.bindOnSupport f).toOuterMeasure s =
      ∑' a, p a * if h : p a = 0 then 0 else (f a h).toOuterMeasure s 
goal: (p.bindOnSupport f).toOuterMeasure s = ∑' (a : α), p a * if h : p a = 0 then 0 else (f a h).toOuterMeasure s

full_name: PMF.toMeasure_bindOnSupport_apply
code: /-- The measure of a set under `p.bindOnSupport f` is the sum over `a : α`
  of the probability of `a` under `p` times the measure of the set under `f a _`.
  The additional if statement is needed since `f` is only a partial function. -/
@[simp]
theorem toMeasure_bindOnSupport_apply [MeasurableSpace β] (hs : MeasurableSet s) :
    (p.bindOnSupport f).toMeasure s =
      ∑' a, p a * if h : p a = 0 then 0 else (f a h).toMeasure s 
goal: (p.bindOnSupport f).toMeasure s = ∑' (a : α), p a * if h : p a = 0 then 0 else (f a h).toMeasure s