l3lab/ntp-mathlib huggingface dataset:
theorem liftIco_continuous [TopologicalSpace B] {f : 𝕜 → B} (hf : f a = f (a + p))
    (hc : ContinuousOn f <| Icc a (a + p)) : Continuous (liftIco p a f) := by
  rw [liftIco_eq_lift_Icc hf]
  refine' Continuous.comp _ (homeoIccQuot p a).continuous_toFun
  

Proof state:
𝕜 : Type u_1
B : Type u_2
inst✝⁴ : LinearOrderedAddCommGroup 𝕜
inst✝³ : TopologicalSpace 𝕜
inst✝² : OrderTopology 𝕜
p a : 𝕜
hp : Fact (0 < p)
inst✝¹ : Archimedean 𝕜
inst✝ : TopologicalSpace B
f : 𝕜 → B
hf : f a = f (a + p)
hc : ContinuousOn f (Icc a (a + p))
⊢ Continuous
    (Quot.lift (restrict (Icc a (a + p)) f)
      (_ :
        ∀ (a_1 b : ↑(Icc a (a + p))),
          EndpointIdent p a a_1 b → restrict (Icc a (a + p)) f a_1 = restrict (Icc a (a + p)) f b))

Next tactic:
exact continuous_coinduced_dom.mpr (continuousOn_iff_continuous_restrict.mp hc)
theorem liftIco_zero_coe_apply {f : 𝕜 → B} {x : 𝕜} (hx : x ∈ Ico 0 p) : liftIco p 0 f ↑x = f x :=
  liftIco_coe_apply (by 

Proof state:
𝕜 : Type u_1
B : Type u_2
inst✝³ : LinearOrderedAddCommGroup 𝕜
inst✝² : TopologicalSpace 𝕜
inst✝¹ : OrderTopology 𝕜
p a : 𝕜
hp : Fact (0 < p)
inst✝ : Archimedean 𝕜
f : 𝕜 → B
x : 𝕜
hx : x ∈ Ico 0 p
⊢ x ∈ Ico 0 (0 + p)

Next tactic:
rwa [zero_add]
theorem liftIco_zero_continuous [TopologicalSpace B] {f : 𝕜 → B} (hf : f 0 = f p)
    (hc : ContinuousOn f <| Icc 0 p) : Continuous (liftIco p 0 f) :=
  liftIco_continuous (by 

Proof state:
𝕜 : Type u_1
B : Type u_2
inst✝⁴ : LinearOrderedAddCommGroup 𝕜
inst✝³ : TopologicalSpace 𝕜
inst✝² : OrderTopology 𝕜
p a : 𝕜
hp : Fact (0 < p)
inst✝¹ : Archimedean 𝕜
inst✝ : TopologicalSpace B
f : 𝕜 → B
hf : f 0 = f p
hc : ContinuousOn f (Icc 0 p)
⊢ f 0 = f (0 + p)

Next tactic:
rwa [zero_add]
theorem liftIco_zero_continuous [TopologicalSpace B] {f : 𝕜 → B} (hf : f 0 = f p)
    (hc : ContinuousOn f <| Icc 0 p) : Continuous (liftIco p 0 f) :=
  liftIco_continuous (by rwa [zero_add] : f 0 = f (0 + p)) (by 

Proof state:
𝕜 : Type u_1
B : Type u_2
inst✝⁴ : LinearOrderedAddCommGroup 𝕜
inst✝³ : TopologicalSpace 𝕜
inst✝² : OrderTopology 𝕜
p a : 𝕜
hp : Fact (0 < p)
inst✝¹ : Archimedean 𝕜
inst✝ : TopologicalSpace B
f : 𝕜 → B
hf : f 0 = f p
hc : ContinuousOn f (Icc 0 p)
⊢ ContinuousOn f (Icc 0 (0 + p))

Next tactic:
rwa [zero_add]
/-- The `Finset` of `l : List α` that, given `m : Multiset α`, have the property `⟦l⟧ = m`.
-/
def lists : Multiset α → Finset (List α) := fun s =>
  Quotient.liftOn s (fun l => l.permutations.toFinset) fun l l' (h : l ~ l') => by
    

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s : Multiset α
l l' : List α
h : l ~ l'
⊢ (fun l => List.toFinset (permutations l)) l = (fun l => List.toFinset (permutations l)) l'

Next tactic:
ext sl
/-- The `Finset` of `l : List α` that, given `m : Multiset α`, have the property `⟦l⟧ = m`.
-/
def lists : Multiset α → Finset (List α) := fun s =>
  Quotient.liftOn s (fun l => l.permutations.toFinset) fun l l' (h : l ~ l') => by
    ext sl
    

Proof state:
case a
α : Type u_1
inst✝ : DecidableEq α
s : Multiset α
l l' : List α
h : l ~ l'
sl : List α
⊢ sl ∈ (fun l => List.toFinset (permutations l)) l ↔ sl ∈ (fun l => List.toFinset (permutations l)) l'

Next tactic:
simp only [mem_permutations, List.mem_toFinset]
/-- The `Finset` of `l : List α` that, given `m : Multiset α`, have the property `⟦l⟧ = m`.
-/
def lists : Multiset α → Finset (List α) := fun s =>
  Quotient.liftOn s (fun l => l.permutations.toFinset) fun l l' (h : l ~ l') => by
    ext sl
    simp only [mem_permutations, List.mem_toFinset]
    

Proof state:
case a
α : Type u_1
inst✝ : DecidableEq α
s : Multiset α
l l' : List α
h : l ~ l'
sl : List α
⊢ sl ~ l ↔ sl ~ l'

Next tactic:
exact ⟨fun hs => hs.trans h, fun hs => hs.trans h.symm⟩
@[simp]
theorem mem_lists_iff (s : Multiset α) (l : List α) : l ∈ lists s ↔ s = ⟦l⟧ := by
  

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s : Multiset α
l : List α
⊢ l ∈ lists s ↔ s = ⟦l⟧

Next tactic:
induction s using Quotient.inductionOn
@[simp]
theorem mem_lists_iff (s : Multiset α) (l : List α) : l ∈ lists s ↔ s = ⟦l⟧ := by
  induction s using Quotient.inductionOn
  

Proof state:
case h
α : Type u_1
inst✝ : DecidableEq α
l a✝ : List α
⊢ l ∈ lists ⟦a✝⟧ ↔ ⟦a✝⟧ = ⟦l⟧

Next tactic:
simpa using perm_comm
instance fintypeNodupList [Fintype α] : Fintype { l : List α // l.Nodup } :=
  Fintype.subtype ((Finset.univ : Finset α).powerset.biUnion fun s => s.val.lists) fun l => by
    

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
l : List α
⊢ (l ∈ Finset.biUnion (Finset.powerset Finset.univ) fun s => Multiset.lists s.val) ↔ Nodup l

Next tactic:
suffices (∃ a : Finset α, a.val = ↑l) ↔ l.Nodup by simpa
instance fintypeNodupList [Fintype α] : Fintype { l : List α // l.Nodup } :=
  Fintype.subtype ((Finset.univ : Finset α).powerset.biUnion fun s => s.val.lists) fun l => by
    suffices (∃ a : Finset α, a.val = ↑l) ↔ l.Nodup by 

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
l : List α
this : (∃ a, a.val = ↑l) ↔ Nodup l
⊢ (l ∈ Finset.biUnion (Finset.powerset Finset.univ) fun s => Multiset.lists s.val) ↔ Nodup l

Next tactic:
simpa
instance fintypeNodupList [Fintype α] : Fintype { l : List α // l.Nodup } :=
  Fintype.subtype ((Finset.univ : Finset α).powerset.biUnion fun s => s.val.lists) fun l => by
    suffices (∃ a : Finset α, a.val = ↑l) ↔ l.Nodup by simpa
    

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
l : List α
⊢ (∃ a, a.val = ↑l) ↔ Nodup l

Next tactic:
constructor
instance fintypeNodupList [Fintype α] : Fintype { l : List α // l.Nodup } :=
  Fintype.subtype ((Finset.univ : Finset α).powerset.biUnion fun s => s.val.lists) fun l => by
    suffices (∃ a : Finset α, a.val = ↑l) ↔ l.Nodup by simpa
    constructor
    · 

Proof state:
case mp
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
l : List α
⊢ (∃ a, a.val = ↑l) → Nodup l

Next tactic:
rintro ⟨s, hs⟩
instance fintypeNodupList [Fintype α] : Fintype { l : List α // l.Nodup } :=
  Fintype.subtype ((Finset.univ : Finset α).powerset.biUnion fun s => s.val.lists) fun l => by
    suffices (∃ a : Finset α, a.val = ↑l) ↔ l.Nodup by simpa
    constructor
    · rintro ⟨s, hs⟩
      

Proof state:
case mp.intro
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
l : List α
s : Finset α
hs : s.val = ↑l
⊢ Nodup l

Next tactic:
simpa [← Multiset.coe_nodup, ← hs] using s.nodup
instance fintypeNodupList [Fintype α] : Fintype { l : List α // l.Nodup } :=
  Fintype.subtype ((Finset.univ : Finset α).powerset.biUnion fun s => s.val.lists) fun l => by
    suffices (∃ a : Finset α, a.val = ↑l) ↔ l.Nodup by simpa
    constructor
    · rintro ⟨s, hs⟩
      simpa [← Multiset.coe_nodup, ← hs] using s.nodup
    · 

Proof state:
case mpr
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
l : List α
⊢ Nodup l → ∃ a, a.val = ↑l

Next tactic:
intro hl
instance fintypeNodupList [Fintype α] : Fintype { l : List α // l.Nodup } :=
  Fintype.subtype ((Finset.univ : Finset α).powerset.biUnion fun s => s.val.lists) fun l => by
    suffices (∃ a : Finset α, a.val = ↑l) ↔ l.Nodup by simpa
    constructor
    · rintro ⟨s, hs⟩
      simpa [← Multiset.coe_nodup, ← hs] using s.nodup
    · intro hl
      

Proof state:
case mpr
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
l : List α
hl : Nodup l
⊢ ∃ a, a.val = ↑l

Next tactic:
refine' ⟨⟨↑l, hl⟩, _⟩
instance fintypeNodupList [Fintype α] : Fintype { l : List α // l.Nodup } :=
  Fintype.subtype ((Finset.univ : Finset α).powerset.biUnion fun s => s.val.lists) fun l => by
    suffices (∃ a : Finset α, a.val = ↑l) ↔ l.Nodup by simpa
    constructor
    · rintro ⟨s, hs⟩
      simpa [← Multiset.coe_nodup, ← hs] using s.nodup
    · intro hl
      refine' ⟨⟨↑l, hl⟩, _⟩
      

Proof state:
case mpr
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
l : List α
hl : Nodup l
⊢ { val := ↑l, nodup := hl }.val = ↑l

Next tactic:
simp
lemma prod_apply (s : Set (α × β)) (s_mble : MeasurableSet s) :
    μ.prod ν s = ENNReal.toNNReal (∫⁻ x, ν.toMeasure (Prod.mk x ⁻¹' s) ∂μ) := by
  

Proof state:
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
s : Set (α × β)
s_mble : MeasurableSet s
⊢ (fun s => ENNReal.toNNReal (↑↑↑(prod μ ν) s)) s = ENNReal.toNNReal (∫⁻ (x : α), ↑↑↑ν (Prod.mk x ⁻¹' s) ∂↑μ)

Next tactic:
simp [Measure.prod_apply s_mble]
lemma prod_apply_symm (s : Set (α × β)) (s_mble : MeasurableSet s) :
    μ.prod ν s = ENNReal.toNNReal (∫⁻ y, μ.toMeasure ((fun x ↦ ⟨x, y⟩) ⁻¹' s) ∂ν) := by
  

Proof state:
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
s : Set (α × β)
s_mble : MeasurableSet s
⊢ (fun s => ENNReal.toNNReal (↑↑↑(prod μ ν) s)) s = ENNReal.toNNReal (∫⁻ (y : β), ↑↑↑μ ((fun x => (x, y)) ⁻¹' s) ∂↑ν)

Next tactic:
simp [Measure.prod_apply_symm s_mble]
lemma prod_prod (s : Set α) (t : Set β) : μ.prod ν (s ×ˢ t) = μ s * ν t := by 

Proof state:
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
s : Set α
t : Set β
⊢ (fun s => ENNReal.toNNReal (↑↑↑(prod μ ν) s)) (s ×ˢ t) =
    (fun s => ENNReal.toNNReal (↑↑↑μ s)) s * (fun s => ENNReal.toNNReal (↑↑↑ν s)) t

Next tactic:
simp
@[simp] lemma mass_prod : (μ.prod ν).mass = μ.mass * ν.mass := by
  

Proof state:
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
⊢ mass (prod μ ν) = mass μ * mass ν

Next tactic:
simp only [mass, univ_prod_univ.symm, toMeasure_prod]
@[simp] lemma mass_prod : (μ.prod ν).mass = μ.mass * ν.mass := by
  simp only [mass, univ_prod_univ.symm, toMeasure_prod]
  

Proof state:
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
⊢ ENNReal.toNNReal (↑↑(Measure.prod ↑μ ↑ν) (univ ×ˢ univ)) = ENNReal.toNNReal (↑↑↑μ univ) * ENNReal.toNNReal (↑↑↑ν univ)

Next tactic:
rw [← ENNReal.toNNReal_mul]
@[simp] lemma mass_prod : (μ.prod ν).mass = μ.mass * ν.mass := by
  simp only [mass, univ_prod_univ.symm, toMeasure_prod]
  rw [← ENNReal.toNNReal_mul]
  

Proof state:
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
⊢ ENNReal.toNNReal (↑↑(Measure.prod ↑μ ↑ν) (univ ×ˢ univ)) = ENNReal.toNNReal (↑↑↑μ univ * ↑↑↑ν univ)

Next tactic:
exact congr_arg ENNReal.toNNReal (Measure.prod_prod univ univ)
@[simp] lemma zero_prod : (0 : FiniteMeasure α).prod ν = 0 := by
  

Proof state:
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
⊢ prod 0 ν = 0

Next tactic:
rw [← mass_zero_iff, mass_prod, zero_mass, zero_mul]
@[simp] lemma prod_zero : μ.prod (0 : FiniteMeasure β) = 0 := by
  

Proof state:
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
⊢ prod μ 0 = 0

Next tactic:
rw [← mass_zero_iff, mass_prod, zero_mass, mul_zero]
@[simp] lemma map_fst_prod : (μ.prod ν).map Prod.fst = ν univ • μ := by
  

Proof state:
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
⊢ map (prod μ ν) Prod.fst = (fun s => ENNReal.toNNReal (↑↑↑ν s)) univ • μ

Next tactic:
apply Subtype.ext
@[simp] lemma map_fst_prod : (μ.prod ν).map Prod.fst = ν univ • μ := by
  apply Subtype.ext
  

Proof state:
case a
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
⊢ ↑(map (prod μ ν) Prod.fst) = ↑((fun s => ENNReal.toNNReal (↑↑↑ν s)) univ • μ)

Next tactic:
simp only [val_eq_toMeasure, toMeasure_map, toMeasure_prod, Measure.map_fst_prod]
@[simp] lemma map_fst_prod : (μ.prod ν).map Prod.fst = ν univ • μ := by
  apply Subtype.ext
  simp only [val_eq_toMeasure, toMeasure_map, toMeasure_prod, Measure.map_fst_prod]
  

Proof state:
case a
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
⊢ ↑↑↑ν univ • ↑μ = ↑(ENNReal.toNNReal (↑↑↑ν univ) • μ)

Next tactic:
ext s _
@[simp] lemma map_fst_prod : (μ.prod ν).map Prod.fst = ν univ • μ := by
  apply Subtype.ext
  simp only [val_eq_toMeasure, toMeasure_map, toMeasure_prod, Measure.map_fst_prod]
  ext s _
  

Proof state:
case a.h
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
s : Set α
a✝ : MeasurableSet s
⊢ ↑↑(↑↑↑ν univ • ↑μ) s = ↑↑↑(ENNReal.toNNReal (↑↑↑ν univ) • μ) s

Next tactic:
simp only [Measure.smul_toOuterMeasure, OuterMeasure.coe_smul, Pi.smul_apply, smul_eq_mul]
@[simp] lemma map_fst_prod : (μ.prod ν).map Prod.fst = ν univ • μ := by
  apply Subtype.ext
  simp only [val_eq_toMeasure, toMeasure_map, toMeasure_prod, Measure.map_fst_prod]
  ext s _
  simp only [Measure.smul_toOuterMeasure, OuterMeasure.coe_smul, Pi.smul_apply, smul_eq_mul]
  

Proof state:
case a.h
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
s : Set α
a✝ : MeasurableSet s
⊢ ↑↑↑ν univ * ↑↑↑μ s = ↑↑↑(ENNReal.toNNReal (↑↑↑ν univ) • μ) s

Next tactic:
have aux := coeFn_smul_apply (ν univ) μ s
@[simp] lemma map_fst_prod : (μ.prod ν).map Prod.fst = ν univ • μ := by
  apply Subtype.ext
  simp only [val_eq_toMeasure, toMeasure_map, toMeasure_prod, Measure.map_fst_prod]
  ext s _
  simp only [Measure.smul_toOuterMeasure, OuterMeasure.coe_smul, Pi.smul_apply, smul_eq_mul]
  have aux := coeFn_smul_apply (ν univ) μ s
  

Proof state:
case a.h
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
s : Set α
a✝ : MeasurableSet s
aux :
  (fun s => ENNReal.toNNReal (↑↑↑((fun s => ENNReal.toNNReal (↑↑↑ν s)) univ • μ) s)) s =
    (fun s => ENNReal.toNNReal (↑↑↑ν s)) univ • (fun s => ENNReal.toNNReal (↑↑↑μ s)) s
⊢ ↑↑↑ν univ * ↑↑↑μ s = ↑↑↑(ENNReal.toNNReal (↑↑↑ν univ) • μ) s

Next tactic:
simpa using congr_arg ENNReal.ofNNReal aux.symm
@[simp] lemma map_snd_prod : (μ.prod ν).map Prod.snd = μ univ • ν := by
  

Proof state:
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
⊢ map (prod μ ν) Prod.snd = (fun s => ENNReal.toNNReal (↑↑↑μ s)) univ • ν

Next tactic:
apply Subtype.ext
@[simp] lemma map_snd_prod : (μ.prod ν).map Prod.snd = μ univ • ν := by
  apply Subtype.ext
  

Proof state:
case a
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
⊢ ↑(map (prod μ ν) Prod.snd) = ↑((fun s => ENNReal.toNNReal (↑↑↑μ s)) univ • ν)

Next tactic:
simp only [val_eq_toMeasure, toMeasure_map, toMeasure_prod, Measure.map_fst_prod]
@[simp] lemma map_snd_prod : (μ.prod ν).map Prod.snd = μ univ • ν := by
  apply Subtype.ext
  simp only [val_eq_toMeasure, toMeasure_map, toMeasure_prod, Measure.map_fst_prod]
  

Proof state:
case a
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
⊢ Measure.map Prod.snd (Measure.prod ↑μ ↑ν) = ↑(ENNReal.toNNReal (↑↑↑μ univ) • ν)

Next tactic:
ext s _
@[simp] lemma map_snd_prod : (μ.prod ν).map Prod.snd = μ univ • ν := by
  apply Subtype.ext
  simp only [val_eq_toMeasure, toMeasure_map, toMeasure_prod, Measure.map_fst_prod]
  ext s _
  

Proof state:
case a.h
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
s : Set β
a✝ : MeasurableSet s
⊢ ↑↑(Measure.map Prod.snd (Measure.prod ↑μ ↑ν)) s = ↑↑↑(ENNReal.toNNReal (↑↑↑μ univ) • ν) s

Next tactic:
simp only [Measure.map_snd_prod, Measure.smul_toOuterMeasure, OuterMeasure.coe_smul,
    Pi.smul_apply, smul_eq_mul]
@[simp] lemma map_snd_prod : (μ.prod ν).map Prod.snd = μ univ • ν := by
  apply Subtype.ext
  simp only [val_eq_toMeasure, toMeasure_map, toMeasure_prod, Measure.map_fst_prod]
  ext s _
  simp only [Measure.map_snd_prod, Measure.smul_toOuterMeasure, OuterMeasure.coe_smul,
    Pi.smul_apply, smul_eq_mul]
  

Proof state:
case a.h
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
s : Set β
a✝ : MeasurableSet s
⊢ ↑↑↑μ univ * ↑↑↑ν s = ↑↑↑(ENNReal.toNNReal (↑↑↑μ univ) • ν) s

Next tactic:
have aux := coeFn_smul_apply (μ univ) ν s
@[simp] lemma map_snd_prod : (μ.prod ν).map Prod.snd = μ univ • ν := by
  apply Subtype.ext
  simp only [val_eq_toMeasure, toMeasure_map, toMeasure_prod, Measure.map_fst_prod]
  ext s _
  simp only [Measure.map_snd_prod, Measure.smul_toOuterMeasure, OuterMeasure.coe_smul,
    Pi.smul_apply, smul_eq_mul]
  have aux := coeFn_smul_apply (μ univ) ν s
  

Proof state:
case a.h
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
s : Set β
a✝ : MeasurableSet s
aux :
  (fun s => ENNReal.toNNReal (↑↑↑((fun s => ENNReal.toNNReal (↑↑↑μ s)) univ • ν) s)) s =
    (fun s => ENNReal.toNNReal (↑↑↑μ s)) univ • (fun s => ENNReal.toNNReal (↑↑↑ν s)) s
⊢ ↑↑↑μ univ * ↑↑↑ν s = ↑↑↑(ENNReal.toNNReal (↑↑↑μ univ) • ν) s

Next tactic:
simpa using congr_arg ENNReal.ofNNReal aux.symm
lemma map_prod_map {α' : Type*} [MeasurableSpace α'] {β' : Type*} [MeasurableSpace β']
    {f : α → α'} {g : β → β'}  (f_mble : Measurable f) (g_mble : Measurable g):
    (μ.map f).prod (ν.map g) = (μ.prod ν).map (Prod.map f g) := by
  

Proof state:
α : Type u_1
inst✝³ : MeasurableSpace α
β : Type u_2
inst✝² : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
α' : Type u_3
inst✝¹ : MeasurableSpace α'
β' : Type u_4
inst✝ : MeasurableSpace β'
f : α → α'
g : β → β'
f_mble : Measurable f
g_mble : Measurable g
⊢ prod (map μ f) (map ν g) = map (prod μ ν) (Prod.map f g)

Next tactic:
apply Subtype.ext
lemma map_prod_map {α' : Type*} [MeasurableSpace α'] {β' : Type*} [MeasurableSpace β']
    {f : α → α'} {g : β → β'}  (f_mble : Measurable f) (g_mble : Measurable g):
    (μ.map f).prod (ν.map g) = (μ.prod ν).map (Prod.map f g) := by
  apply Subtype.ext
  

Proof state:
case a
α : Type u_1
inst✝³ : MeasurableSpace α
β : Type u_2
inst✝² : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
α' : Type u_3
inst✝¹ : MeasurableSpace α'
β' : Type u_4
inst✝ : MeasurableSpace β'
f : α → α'
g : β → β'
f_mble : Measurable f
g_mble : Measurable g
⊢ ↑(prod (map μ f) (map ν g)) = ↑(map (prod μ ν) (Prod.map f g))

Next tactic:
simp only [val_eq_toMeasure, toMeasure_prod, toMeasure_map]
lemma map_prod_map {α' : Type*} [MeasurableSpace α'] {β' : Type*} [MeasurableSpace β']
    {f : α → α'} {g : β → β'}  (f_mble : Measurable f) (g_mble : Measurable g):
    (μ.map f).prod (ν.map g) = (μ.prod ν).map (Prod.map f g) := by
  apply Subtype.ext
  simp only [val_eq_toMeasure, toMeasure_prod, toMeasure_map]
  

Proof state:
case a
α : Type u_1
inst✝³ : MeasurableSpace α
β : Type u_2
inst✝² : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
α' : Type u_3
inst✝¹ : MeasurableSpace α'
β' : Type u_4
inst✝ : MeasurableSpace β'
f : α → α'
g : β → β'
f_mble : Measurable f
g_mble : Measurable g
⊢ Measure.prod (Measure.map f ↑μ) (Measure.map g ↑ν) = Measure.map (Prod.map f g) (Measure.prod ↑μ ↑ν)

Next tactic:
rw [Measure.map_prod_map _ _ f_mble g_mble]
lemma prod_swap : (μ.prod ν).map Prod.swap = ν.prod μ := by
  

Proof state:
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
⊢ map (prod μ ν) Prod.swap = prod ν μ

Next tactic:
apply Subtype.ext
lemma prod_swap : (μ.prod ν).map Prod.swap = ν.prod μ := by
  apply Subtype.ext
  

Proof state:
case a
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : FiniteMeasure α
ν : FiniteMeasure β
⊢ ↑(map (prod μ ν) Prod.swap) = ↑(prod ν μ)

Next tactic:
simp [Measure.prod_swap]
/-- The binary product of probability measures. -/
noncomputable def prod (μ : ProbabilityMeasure α) (ν : ProbabilityMeasure β) :
    ProbabilityMeasure (α × β) :=
  ⟨μ.toMeasure.prod ν.toMeasure, by 

Proof state:
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : ProbabilityMeasure α
ν : ProbabilityMeasure β
⊢ IsProbabilityMeasure (Measure.prod ↑μ ↑ν)

Next tactic:
infer_instance
lemma prod_apply (s : Set (α × β)) (s_mble : MeasurableSet s) :
    μ.prod ν s = ENNReal.toNNReal (∫⁻ x, ν.toMeasure (Prod.mk x ⁻¹' s) ∂μ) := by
  

Proof state:
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : ProbabilityMeasure α
ν : ProbabilityMeasure β
s : Set (α × β)
s_mble : MeasurableSet s
⊢ (fun s => ENNReal.toNNReal (↑↑↑(prod μ ν) s)) s = ENNReal.toNNReal (∫⁻ (x : α), ↑↑↑ν (Prod.mk x ⁻¹' s) ∂↑μ)

Next tactic:
simp [Measure.prod_apply s_mble]
lemma prod_apply_symm (s : Set (α × β)) (s_mble : MeasurableSet s) :
    μ.prod ν s = ENNReal.toNNReal (∫⁻ y, μ.toMeasure ((fun x ↦ ⟨x, y⟩) ⁻¹' s) ∂ν) := by
  

Proof state:
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : ProbabilityMeasure α
ν : ProbabilityMeasure β
s : Set (α × β)
s_mble : MeasurableSet s
⊢ (fun s => ENNReal.toNNReal (↑↑↑(prod μ ν) s)) s = ENNReal.toNNReal (∫⁻ (y : β), ↑↑↑μ ((fun x => (x, y)) ⁻¹' s) ∂↑ν)

Next tactic:
simp [Measure.prod_apply_symm s_mble]
lemma prod_prod (s : Set α) (t : Set β) : μ.prod ν (s ×ˢ t) = μ s * ν t := by 

Proof state:
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : ProbabilityMeasure α
ν : ProbabilityMeasure β
s : Set α
t : Set β
⊢ (fun s => ENNReal.toNNReal (↑↑↑(prod μ ν) s)) (s ×ˢ t) =
    (fun s => ENNReal.toNNReal (↑↑↑μ s)) s * (fun s => ENNReal.toNNReal (↑↑↑ν s)) t

Next tactic:
simp
/-- The first marginal of a product probability measure is the first probability measure. -/
@[simp] lemma map_fst_prod : (μ.prod ν).map measurable_fst.aemeasurable = μ := by
  

Proof state:
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : ProbabilityMeasure α
ν : ProbabilityMeasure β
⊢ map (prod μ ν) (_ : AEMeasurable Prod.fst) = μ

Next tactic:
apply Subtype.ext
/-- The first marginal of a product probability measure is the first probability measure. -/
@[simp] lemma map_fst_prod : (μ.prod ν).map measurable_fst.aemeasurable = μ := by
  apply Subtype.ext
  

Proof state:
case a
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : ProbabilityMeasure α
ν : ProbabilityMeasure β
⊢ ↑(map (prod μ ν) (_ : AEMeasurable Prod.fst)) = ↑μ

Next tactic:
simp only [val_eq_to_measure, toMeasure_map, toMeasure_prod, Measure.map_fst_prod,
             measure_univ, one_smul]
/-- The second marginal of a product probability measure is the second probability measure. -/
@[simp] lemma map_snd_prod : (μ.prod ν).map measurable_snd.aemeasurable = ν := by
  

Proof state:
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : ProbabilityMeasure α
ν : ProbabilityMeasure β
⊢ map (prod μ ν) (_ : AEMeasurable Prod.snd) = ν

Next tactic:
apply Subtype.ext
/-- The second marginal of a product probability measure is the second probability measure. -/
@[simp] lemma map_snd_prod : (μ.prod ν).map measurable_snd.aemeasurable = ν := by
  apply Subtype.ext
  

Proof state:
case a
α : Type u_1
inst✝¹ : MeasurableSpace α
β : Type u_2
inst✝ : MeasurableSpace β
μ : ProbabilityMeasure α
ν : ProbabilityMeasure β
⊢ ↑(map (prod μ ν) (_ : AEMeasurable Prod.snd)) = ↑ν

Next tactic:
simp only [val_eq_to_measure, toMeasure_map, toMeasure_prod, Measure.map_snd_prod,
             measure_univ, one_smul]
lemma map_prod_map {α' : Type*} [MeasurableSpace α'] {β' : Type*} [MeasurableSpace β']
    {f : α → α'} {g : β → β'} (f_mble : Measurable f) (g_mble : Measurable g) :
    (μ.map f_mble.aemeasurable).prod (ν.map g_mble.aemeasurable)
      = (μ.prod ν).map (f_mble.prod_map g_mble).aemeasurable := by
  

Proof state:
α : Type u_1
inst✝³ : MeasurableSpace α
β : Type u_2
inst✝² : MeasurableSpace β
μ : ProbabilityMeasure α
ν : ProbabilityMeasure β
α' : Type u_3
inst✝¹ : MeasurableSpace α'
β' : Type u_4
inst✝ : MeasurableSpace β'
f : α → α'
g : β → β'
f_mble : Measurable f
g_mble : Measurable g
⊢ prod (map μ (_ : AEMeasurable f)) (map ν (_ : AEMeasurable g)) = map (prod μ ν) (_ : AEMeasurable (Prod.map f g))

Next tactic:
apply Subtype.ext