l3lab/ntp-mathlib huggingface dataset:
/-- Simple function defined on the empty type. -/
def ofIsEmpty [IsEmpty α] : α →ₛ β where
  toFun := isEmptyElim
  measurableSet_fiber' x := Subsingleton.measurableSet
  finite_range' := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝¹ : MeasurableSpace α
inst✝ : IsEmpty α
⊢ Set.Finite (range fun a => isEmptyElim a)

Next tactic:
simp [range_eq_empty]
theorem forall_range_iff {f : α →ₛ β} {p : β → Prop} : (∀ y ∈ f.range, p y) ↔ ∀ x, p (f x) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
f : α →ₛ β
p : β → Prop
⊢ (∀ y ∈ SimpleFunc.range f, p y) ↔ ∀ (x : α), p (↑f x)

Next tactic:
simp only [mem_range, Set.forall_range_iff]
theorem exists_range_iff {f : α →ₛ β} {p : β → Prop} : (∃ y ∈ f.range, p y) ↔ ∃ x, p (f x) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
f : α →ₛ β
p : β → Prop
⊢ (∃ y ∈ SimpleFunc.range f, p y) ↔ ∃ x, p (↑f x)

Next tactic:
simpa only [mem_range, exists_prop] using Set.exists_range_iff
@[simp]
theorem range_const (α) [MeasurableSpace α] [Nonempty α] (b : β) : (const α b).range = {b} :=
  Finset.coe_injective <| by 

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : MeasurableSpace α✝
α : Type u_5
inst✝¹ : MeasurableSpace α
inst✝ : Nonempty α
b : β
⊢ ↑(SimpleFunc.range (const α b)) = ↑{b}

Next tactic:
simp (config := { unfoldPartialApp := true }) [Function.const]
theorem range_const_subset (α) [MeasurableSpace α] (b : β) : (const α b).range ⊆ {b} :=
  Finset.coe_subset.1 <| by 

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝¹ : MeasurableSpace α✝
α : Type u_5
inst✝ : MeasurableSpace α
b : β
⊢ ↑(SimpleFunc.range (const α b)) ⊆ ↑{b}

Next tactic:
simp
theorem simpleFunc_bot {α} (f : @SimpleFunc α ⊥ β) [Nonempty β] : ∃ c, ∀ x, f x = c := by
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝¹ : MeasurableSpace α✝
α : Type u_5
f : α →ₛ β
inst✝ : Nonempty β
⊢ ∃ c, ∀ (x : α), ↑f x = c

Next tactic:
have hf_meas := @SimpleFunc.measurableSet_fiber α _ ⊥ f
theorem simpleFunc_bot {α} (f : @SimpleFunc α ⊥ β) [Nonempty β] : ∃ c, ∀ x, f x = c := by
  have hf_meas := @SimpleFunc.measurableSet_fiber α _ ⊥ f
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝¹ : MeasurableSpace α✝
α : Type u_5
f : α →ₛ β
inst✝ : Nonempty β
hf_meas : ∀ (x : β), MeasurableSet (↑f ⁻¹' {x})
⊢ ∃ c, ∀ (x : α), ↑f x = c

Next tactic:
simp_rw [MeasurableSpace.measurableSet_bot_iff] at hf_meas
theorem simpleFunc_bot {α} (f : @SimpleFunc α ⊥ β) [Nonempty β] : ∃ c, ∀ x, f x = c := by
  have hf_meas := @SimpleFunc.measurableSet_fiber α _ ⊥ f
  simp_rw [MeasurableSpace.measurableSet_bot_iff] at hf_meas
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝¹ : MeasurableSpace α✝
α : Type u_5
f : α →ₛ β
inst✝ : Nonempty β
hf_meas : ∀ (x : β), ↑f ⁻¹' {x} = ∅ ∨ ↑f ⁻¹' {x} = univ
⊢ ∃ c, ∀ (x : α), ↑f x = c

Next tactic:
exact (exists_eq_const_of_preimage_singleton hf_meas).imp fun c hc ↦ congr_fun hc
theorem measurableSet_cut (r : α → β → Prop) (f : α →ₛ β) (h : ∀ b, MeasurableSet { a | r a b }) :
    MeasurableSet { a | r a (f a) } := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
r : α → β → Prop
f : α →ₛ β
h : ∀ (b : β), MeasurableSet {a | r a b}
⊢ MeasurableSet {a | r a (↑f a)}

Next tactic:
have : { a | r a (f a) } = ⋃ b ∈ range f, { a | r a b } ∩ f ⁻¹' {b} := by
    ext a
    suffices r a (f a) ↔ ∃ i, r a (f i) ∧ f a = f i by simpa
    exact ⟨fun h => ⟨a, ⟨h, rfl⟩⟩, fun ⟨a', ⟨h', e⟩⟩ => e.symm ▸ h'⟩
theorem measurableSet_cut (r : α → β → Prop) (f : α →ₛ β) (h : ∀ b, MeasurableSet { a | r a b }) :
    MeasurableSet { a | r a (f a) } := by
  have : { a | r a (f a) } = ⋃ b ∈ range f, { a | r a b } ∩ f ⁻¹' {b} := by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
r : α → β → Prop
f : α →ₛ β
h : ∀ (b : β), MeasurableSet {a | r a b}
⊢ {a | r a (↑f a)} = ⋃ b ∈ range ↑f, {a | r a b} ∩ ↑f ⁻¹' {b}

Next tactic:
ext a
theorem measurableSet_cut (r : α → β → Prop) (f : α →ₛ β) (h : ∀ b, MeasurableSet { a | r a b }) :
    MeasurableSet { a | r a (f a) } := by
  have : { a | r a (f a) } = ⋃ b ∈ range f, { a | r a b } ∩ f ⁻¹' {b} := by
    ext a
    

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
r : α → β → Prop
f : α →ₛ β
h : ∀ (b : β), MeasurableSet {a | r a b}
a : α
⊢ a ∈ {a | r a (↑f a)} ↔ a ∈ ⋃ b ∈ range ↑f, {a | r a b} ∩ ↑f ⁻¹' {b}

Next tactic:
suffices r a (f a) ↔ ∃ i, r a (f i) ∧ f a = f i by simpa
theorem measurableSet_cut (r : α → β → Prop) (f : α →ₛ β) (h : ∀ b, MeasurableSet { a | r a b }) :
    MeasurableSet { a | r a (f a) } := by
  have : { a | r a (f a) } = ⋃ b ∈ range f, { a | r a b } ∩ f ⁻¹' {b} := by
    ext a
    suffices r a (f a) ↔ ∃ i, r a (f i) ∧ f a = f i by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
r : α → β → Prop
f : α →ₛ β
h : ∀ (b : β), MeasurableSet {a | r a b}
a : α
this : r a (↑f a) ↔ ∃ i, r a (↑f i) ∧ ↑f a = ↑f i
⊢ a ∈ {a | r a (↑f a)} ↔ a ∈ ⋃ b ∈ range ↑f, {a | r a b} ∩ ↑f ⁻¹' {b}

Next tactic:
simpa
theorem measurableSet_cut (r : α → β → Prop) (f : α →ₛ β) (h : ∀ b, MeasurableSet { a | r a b }) :
    MeasurableSet { a | r a (f a) } := by
  have : { a | r a (f a) } = ⋃ b ∈ range f, { a | r a b } ∩ f ⁻¹' {b} := by
    ext a
    suffices r a (f a) ↔ ∃ i, r a (f i) ∧ f a = f i by simpa
    

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
r : α → β → Prop
f : α →ₛ β
h : ∀ (b : β), MeasurableSet {a | r a b}
a : α
⊢ r a (↑f a) ↔ ∃ i, r a (↑f i) ∧ ↑f a = ↑f i

Next tactic:
exact ⟨fun h => ⟨a, ⟨h, rfl⟩⟩, fun ⟨a', ⟨h', e⟩⟩ => e.symm ▸ h'⟩
theorem measurableSet_cut (r : α → β → Prop) (f : α →ₛ β) (h : ∀ b, MeasurableSet { a | r a b }) :
    MeasurableSet { a | r a (f a) } := by
  have : { a | r a (f a) } = ⋃ b ∈ range f, { a | r a b } ∩ f ⁻¹' {b} := by
    ext a
    suffices r a (f a) ↔ ∃ i, r a (f i) ∧ f a = f i by simpa
    exact ⟨fun h => ⟨a, ⟨h, rfl⟩⟩, fun ⟨a', ⟨h', e⟩⟩ => e.symm ▸ h'⟩
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
r : α → β → Prop
f : α →ₛ β
h : ∀ (b : β), MeasurableSet {a | r a b}
this : {a | r a (↑f a)} = ⋃ b ∈ range ↑f, {a | r a b} ∩ ↑f ⁻¹' {b}
⊢ MeasurableSet {a | r a (↑f a)}

Next tactic:
rw [this]
theorem measurableSet_cut (r : α → β → Prop) (f : α →ₛ β) (h : ∀ b, MeasurableSet { a | r a b }) :
    MeasurableSet { a | r a (f a) } := by
  have : { a | r a (f a) } = ⋃ b ∈ range f, { a | r a b } ∩ f ⁻¹' {b} := by
    ext a
    suffices r a (f a) ↔ ∃ i, r a (f i) ∧ f a = f i by simpa
    exact ⟨fun h => ⟨a, ⟨h, rfl⟩⟩, fun ⟨a', ⟨h', e⟩⟩ => e.symm ▸ h'⟩
  rw [this]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
r : α → β → Prop
f : α →ₛ β
h : ∀ (b : β), MeasurableSet {a | r a b}
this : {a | r a (↑f a)} = ⋃ b ∈ range ↑f, {a | r a b} ∩ ↑f ⁻¹' {b}
⊢ MeasurableSet (⋃ b ∈ range ↑f, {a | r a b} ∩ ↑f ⁻¹' {b})

Next tactic:
exact
    MeasurableSet.biUnion f.finite_range.countable fun b _ =>
      MeasurableSet.inter (h b) (f.measurableSet_fiber _)
theorem sum_range_measure_preimage_singleton (f : α →ₛ β) (μ : Measure α) :
    (∑ y in f.range, μ (f ⁻¹' {y})) = μ univ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
f : α →ₛ β
μ : Measure α
⊢ ∑ y in SimpleFunc.range f, ↑↑μ (↑f ⁻¹' {y}) = ↑↑μ univ

Next tactic:
rw [f.sum_measure_preimage_singleton, coe_range, preimage_range]
@[simp]
theorem piecewise_compl {s : Set α} (hs : MeasurableSet sᶜ) (f g : α →ₛ β) :
    piecewise sᶜ hs f g = piecewise s hs.of_compl g f :=
  coe_injective <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
s : Set α
hs : MeasurableSet sᶜ
f g : α →ₛ β
⊢ ↑(piecewise sᶜ hs f g) = ↑(piecewise s (_ : MeasurableSet s) g f)

Next tactic:
simp [hs]
@[simp]
theorem piecewise_compl {s : Set α} (hs : MeasurableSet sᶜ) (f g : α →ₛ β) :
    piecewise sᶜ hs f g = piecewise s hs.of_compl g f :=
  coe_injective <| by simp [hs]; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
s : Set α
hs : MeasurableSet sᶜ
f g : α →ₛ β
⊢ Set.piecewise sᶜ ↑f ↑g = Set.piecewise s ↑g ↑f

Next tactic:
convert Set.piecewise_compl s f g
@[simp]
theorem piecewise_univ (f g : α →ₛ β) : piecewise univ MeasurableSet.univ f g = f :=
  coe_injective <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
f g : α →ₛ β
⊢ ↑(piecewise univ (_ : MeasurableSet univ) f g) = ↑f

Next tactic:
simp
@[simp]
theorem piecewise_univ (f g : α →ₛ β) : piecewise univ MeasurableSet.univ f g = f :=
  coe_injective <| by simp; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
f g : α →ₛ β
⊢ Set.piecewise univ ↑f ↑g = ↑f

Next tactic:
convert Set.piecewise_univ f g
@[simp]
theorem piecewise_empty (f g : α →ₛ β) : piecewise ∅ MeasurableSet.empty f g = g :=
  coe_injective <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
f g : α →ₛ β
⊢ ↑(piecewise ∅ (_ : MeasurableSet ∅) f g) = ↑g

Next tactic:
simp
@[simp]
theorem piecewise_empty (f g : α →ₛ β) : piecewise ∅ MeasurableSet.empty f g = g :=
  coe_injective <| by simp; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
f g : α →ₛ β
⊢ Set.piecewise ∅ ↑f ↑g = ↑g

Next tactic:
convert Set.piecewise_empty f g
theorem range_indicator {s : Set α} (hs : MeasurableSet s) (hs_nonempty : s.Nonempty)
    (hs_ne_univ : s ≠ univ) (x y : β) :
    (piecewise s hs (const α x) (const α y)).range = {x, y} := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
s : Set α
hs : MeasurableSet s
hs_nonempty : Set.Nonempty s
hs_ne_univ : s ≠ univ
x y : β
⊢ SimpleFunc.range (piecewise s hs (const α x) (const α y)) = {x, y}

Next tactic:
simp only [← Finset.coe_inj, coe_range, coe_piecewise, range_piecewise, coe_const,
    Finset.coe_insert, Finset.coe_singleton, hs_nonempty.image_const,
    (nonempty_compl.2 hs_ne_univ).image_const, singleton_union, Function.const]
/-- If `f : α →ₛ β` is a simple function and `g : β → α →ₛ γ` is a family of simple functions,
then `f.bind g` binds the first argument of `g` to `f`. In other words, `f.bind g a = g (f a) a`. -/
def bind (f : α →ₛ β) (g : β → α →ₛ γ) : α →ₛ γ :=
  ⟨fun a => g (f a) a, fun c =>
    f.measurableSet_cut (fun a b => g b a = c) fun b => (g b).measurableSet_preimage {c},
    (f.finite_range.biUnion fun b _ => (g b).finite_range).subset <| by
      

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
f : α →ₛ β
g : β → α →ₛ γ
⊢ (range fun a => ↑(g (↑f a)) a) ⊆ ⋃ i ∈ range ↑f, range ↑(g i)

Next tactic:
rintro _ ⟨a, rfl⟩
/-- If `f : α →ₛ β` is a simple function and `g : β → α →ₛ γ` is a family of simple functions,
then `f.bind g` binds the first argument of `g` to `f`. In other words, `f.bind g a = g (f a) a`. -/
def bind (f : α →ₛ β) (g : β → α →ₛ γ) : α →ₛ γ :=
  ⟨fun a => g (f a) a, fun c =>
    f.measurableSet_cut (fun a b => g b a = c) fun b => (g b).measurableSet_preimage {c},
    (f.finite_range.biUnion fun b _ => (g b).finite_range).subset <| by
      rintro _ ⟨a, rfl⟩; 

Proof state:
case intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
f : α →ₛ β
g : β → α →ₛ γ
a : α
⊢ (fun a => ↑(g (↑f a)) a) a ∈ ⋃ i ∈ range ↑f, range ↑(g i)

Next tactic:
simp
/-- If `f : α →ₛ β` is a simple function and `g : β → α →ₛ γ` is a family of simple functions,
then `f.bind g` binds the first argument of `g` to `f`. In other words, `f.bind g a = g (f a) a`. -/
def bind (f : α →ₛ β) (g : β → α →ₛ γ) : α →ₛ γ :=
  ⟨fun a => g (f a) a, fun c =>
    f.measurableSet_cut (fun a b => g b a = c) fun b => (g b).measurableSet_preimage {c},
    (f.finite_range.biUnion fun b _ => (g b).finite_range).subset <| by
      rintro _ ⟨a, rfl⟩; simp; 

Proof state:
case intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
f : α →ₛ β
g : β → α →ₛ γ
a : α
⊢ ∃ i y, ↑(g (↑f i)) y = ↑(g (↑f a)) a

Next tactic:
exact ⟨a, a, rfl⟩
@[simp]
theorem range_map [DecidableEq γ] (g : β → γ) (f : α →ₛ β) : (f.map g).range = f.range.image g :=
  Finset.coe_injective <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝¹ : MeasurableSpace α
inst✝ : DecidableEq γ
g : β → γ
f : α →ₛ β
⊢ ↑(SimpleFunc.range (map g f)) = ↑(Finset.image g (SimpleFunc.range f))

Next tactic:
simp only [coe_range, coe_map, Finset.coe_image, range_comp]
theorem map_preimage (f : α →ₛ β) (g : β → γ) (s : Set γ) :
    f.map g ⁻¹' s = f ⁻¹' ↑(f.range.filter fun b => g b ∈ s) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
f : α →ₛ β
g : β → γ
s : Set γ
⊢ ↑(map g f) ⁻¹' s = ↑f ⁻¹' ↑(Finset.filter (fun b => g b ∈ s) (SimpleFunc.range f))

Next tactic:
simp only [coe_range, sep_mem_eq, coe_map, Finset.coe_filter,
    ← mem_preimage, inter_comm, preimage_inter_range, ← Finset.mem_coe]
theorem map_preimage (f : α →ₛ β) (g : β → γ) (s : Set γ) :
    f.map g ⁻¹' s = f ⁻¹' ↑(f.range.filter fun b => g b ∈ s) := by
  simp only [coe_range, sep_mem_eq, coe_map, Finset.coe_filter,
    ← mem_preimage, inter_comm, preimage_inter_range, ← Finset.mem_coe]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
f : α →ₛ β
g : β → γ
s : Set γ
⊢ g ∘ ↑f ⁻¹' s = ↑f ⁻¹' (g ⁻¹' s)

Next tactic:
exact preimage_comp
theorem range_comp_subset_range [MeasurableSpace β] (f : β →ₛ γ) {g : α → β} (hgm : Measurable g) :
    (f.comp g hgm).range ⊆ f.range :=
  Finset.coe_subset.1 <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
f : β →ₛ γ
g : α → β
hgm : Measurable g
⊢ ↑(SimpleFunc.range (comp f g hgm)) ⊆ ↑(SimpleFunc.range f)

Next tactic:
simp only [coe_range, coe_comp, Set.range_comp_subset_range]
/-- Extend a `SimpleFunc` along a measurable embedding: `f₁.extend g hg f₂` is the function
`F : β →ₛ γ` such that `F ∘ g = f₁` and `F y = f₂ y` whenever `y ∉ range g`. -/
def extend [MeasurableSpace β] (f₁ : α →ₛ γ) (g : α → β) (hg : MeasurableEmbedding g)
    (f₂ : β →ₛ γ) : β →ₛ γ where
  toFun := Function.extend g f₁ f₂
  finite_range' :=
    (f₁.finite_range.union <| f₂.finite_range.subset (image_subset_range _ _)).subset
      (range_extend_subset _ _ _)
  measurableSet_fiber' := by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
f₁ : α →ₛ γ
g : α → β
hg : MeasurableEmbedding g
f₂ : β →ₛ γ
⊢ ∀ (x : γ), MeasurableSet (Function.extend g ↑f₁ ↑f₂ ⁻¹' {x})

Next tactic:
letI : MeasurableSpace γ := ⊤
/-- Extend a `SimpleFunc` along a measurable embedding: `f₁.extend g hg f₂` is the function
`F : β →ₛ γ` such that `F ∘ g = f₁` and `F y = f₂ y` whenever `y ∉ range g`. -/
def extend [MeasurableSpace β] (f₁ : α →ₛ γ) (g : α → β) (hg : MeasurableEmbedding g)
    (f₂ : β →ₛ γ) : β →ₛ γ where
  toFun := Function.extend g f₁ f₂
  finite_range' :=
    (f₁.finite_range.union <| f₂.finite_range.subset (image_subset_range _ _)).subset
      (range_extend_subset _ _ _)
  measurableSet_fiber' := by
    letI : MeasurableSpace γ := ⊤; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
f₁ : α →ₛ γ
g : α → β
hg : MeasurableEmbedding g
f₂ : β →ₛ γ
this : MeasurableSpace γ := ⊤
⊢ ∀ (x : γ), MeasurableSet (Function.extend g ↑f₁ ↑f₂ ⁻¹' {x})

Next tactic:
haveI : MeasurableSingletonClass γ := ⟨fun _ => trivial⟩
/-- Extend a `SimpleFunc` along a measurable embedding: `f₁.extend g hg f₂` is the function
`F : β →ₛ γ` such that `F ∘ g = f₁` and `F y = f₂ y` whenever `y ∉ range g`. -/
def extend [MeasurableSpace β] (f₁ : α →ₛ γ) (g : α → β) (hg : MeasurableEmbedding g)
    (f₂ : β →ₛ γ) : β →ₛ γ where
  toFun := Function.extend g f₁ f₂
  finite_range' :=
    (f₁.finite_range.union <| f₂.finite_range.subset (image_subset_range _ _)).subset
      (range_extend_subset _ _ _)
  measurableSet_fiber' := by
    letI : MeasurableSpace γ := ⊤; haveI : MeasurableSingletonClass γ := ⟨fun _ => trivial⟩
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
f₁ : α →ₛ γ
g : α → β
hg : MeasurableEmbedding g
f₂ : β →ₛ γ
this✝ : MeasurableSpace γ := ⊤
this : MeasurableSingletonClass γ
⊢ ∀ (x : γ), MeasurableSet (Function.extend g ↑f₁ ↑f₂ ⁻¹' {x})

Next tactic:
exact fun x => hg.measurable_extend f₁.measurable f₂.measurable (measurableSet_singleton _)
theorem pair_preimage_singleton (f : α →ₛ β) (g : α →ₛ γ) (b : β) (c : γ) :
    pair f g ⁻¹' {(b, c)} = f ⁻¹' {b} ∩ g ⁻¹' {c} := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
f : α →ₛ β
g : α →ₛ γ
b : β
c : γ
⊢ ↑(pair f g) ⁻¹' {(b, c)} = ↑f ⁻¹' {b} ∩ ↑g ⁻¹' {c}

Next tactic:
rw [← singleton_prod_singleton]
theorem pair_preimage_singleton (f : α →ₛ β) (g : α →ₛ γ) (b : β) (c : γ) :
    pair f g ⁻¹' {(b, c)} = f ⁻¹' {b} ∩ g ⁻¹' {c} := by
  rw [← singleton_prod_singleton]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
f : α →ₛ β
g : α →ₛ γ
b : β
c : γ
⊢ ↑(pair f g) ⁻¹' {b} ×ˢ {c} = ↑f ⁻¹' {b} ∩ ↑g ⁻¹' {c}

Next tactic:
exact pair_preimage _ _ _ _
theorem bind_const (f : α →ₛ β) : f.bind (const α) = f := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
f : α →ₛ β
⊢ bind f (const α) = f

Next tactic:
ext
theorem bind_const (f : α →ₛ β) : f.bind (const α) = f := by ext; 

Proof state:
case H
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
f : α →ₛ β
a✝ : α
⊢ ↑(bind f (const α)) a✝ = ↑f a✝

Next tactic:
simp
@[to_additive (attr := simp)]
theorem range_one [Nonempty α] [One β] : (1 : α →ₛ β).range = {1} :=
  Finset.ext fun x => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : MeasurableSpace α
inst✝¹ : Nonempty α
inst✝ : One β
x : β
⊢ x ∈ SimpleFunc.range 1 ↔ x ∈ {1}

Next tactic:
simp [eq_comm]
@[simp]
theorem range_eq_empty_of_isEmpty {β} [hα : IsEmpty α] (f : α →ₛ β) : f.range = ∅ := by
  

Proof state:
α : Type u_1
β✝ : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
β : Type u_5
hα : IsEmpty α
f : α →ₛ β
⊢ SimpleFunc.range f = ∅

Next tactic:
rw [← Finset.not_nonempty_iff_eq_empty]
@[simp]
theorem range_eq_empty_of_isEmpty {β} [hα : IsEmpty α] (f : α →ₛ β) : f.range = ∅ := by
  rw [← Finset.not_nonempty_iff_eq_empty]
  

Proof state:
α : Type u_1
β✝ : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
β : Type u_5
hα : IsEmpty α
f : α →ₛ β
⊢ ¬Finset.Nonempty (SimpleFunc.range f)

Next tactic:
by_contra h
@[simp]
theorem range_eq_empty_of_isEmpty {β} [hα : IsEmpty α] (f : α →ₛ β) : f.range = ∅ := by
  rw [← Finset.not_nonempty_iff_eq_empty]
  by_contra h
  

Proof state:
α : Type u_1
β✝ : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
β : Type u_5
hα : IsEmpty α
f : α →ₛ β
h : Finset.Nonempty (SimpleFunc.range f)
⊢ False

Next tactic:
obtain ⟨y, hy_mem⟩ := h
@[simp]
theorem range_eq_empty_of_isEmpty {β} [hα : IsEmpty α] (f : α →ₛ β) : f.range = ∅ := by
  rw [← Finset.not_nonempty_iff_eq_empty]
  by_contra h
  obtain ⟨y, hy_mem⟩ := h
  

Proof state:
case intro
α : Type u_1
β✝ : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
β : Type u_5
hα : IsEmpty α
f : α →ₛ β
y : β
hy_mem : y ∈ SimpleFunc.range f
⊢ False

Next tactic:
rw [SimpleFunc.mem_range, Set.mem_range] at hy_mem
@[simp]
theorem range_eq_empty_of_isEmpty {β} [hα : IsEmpty α] (f : α →ₛ β) : f.range = ∅ := by
  rw [← Finset.not_nonempty_iff_eq_empty]
  by_contra h
  obtain ⟨y, hy_mem⟩ := h
  rw [SimpleFunc.mem_range, Set.mem_range] at hy_mem
  

Proof state:
case intro
α : Type u_1
β✝ : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
β : Type u_5
hα : IsEmpty α
f : α →ₛ β
y : β
hy_mem : ∃ y_1, ↑f y_1 = y
⊢ False

Next tactic:
obtain ⟨x, hxy⟩ := hy_mem
@[simp]
theorem range_eq_empty_of_isEmpty {β} [hα : IsEmpty α] (f : α →ₛ β) : f.range = ∅ := by
  rw [← Finset.not_nonempty_iff_eq_empty]
  by_contra h
  obtain ⟨y, hy_mem⟩ := h
  rw [SimpleFunc.mem_range, Set.mem_range] at hy_mem
  obtain ⟨x, hxy⟩ := hy_mem
  

Proof state:
case intro.intro
α : Type u_1
β✝ : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
β : Type u_5
hα : IsEmpty α
f : α →ₛ β
y : β
x : α
hxy : ↑f x = y
⊢ False

Next tactic:
rw [isEmpty_iff] at hα
@[simp]
theorem range_eq_empty_of_isEmpty {β} [hα : IsEmpty α] (f : α →ₛ β) : f.range = ∅ := by
  rw [← Finset.not_nonempty_iff_eq_empty]
  by_contra h
  obtain ⟨y, hy_mem⟩ := h
  rw [SimpleFunc.mem_range, Set.mem_range] at hy_mem
  obtain ⟨x, hxy⟩ := hy_mem
  rw [isEmpty_iff] at hα
  

Proof state:
case intro.intro
α : Type u_1
β✝ : Type u_2
γ : Type u_3
δ : Type u_4
inst✝ : MeasurableSpace α
β : Type u_5
hα : α → False
f : α →ₛ β
y : β
x : α
hxy : ↑f x = y
⊢ False

Next tactic:
exact hα x
theorem finset_sup_apply [SemilatticeSup β] [OrderBot β] {f : γ → α →ₛ β} (s : Finset γ) (a : α) :
    s.sup f a = s.sup fun c => f c a := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : MeasurableSpace α
K : Type u_5
inst✝¹ : SemilatticeSup β
inst✝ : OrderBot β
f : γ → α →ₛ β
s : Finset γ
a : α
⊢ ↑(Finset.sup s f) a = Finset.sup s fun c => ↑(f c) a

Next tactic:
refine' Finset.induction_on s rfl _
theorem finset_sup_apply [SemilatticeSup β] [OrderBot β] {f : γ → α →ₛ β} (s : Finset γ) (a : α) :
    s.sup f a = s.sup fun c => f c a := by
  refine' Finset.induction_on s rfl _
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : MeasurableSpace α
K : Type u_5
inst✝¹ : SemilatticeSup β
inst✝ : OrderBot β
f : γ → α →ₛ β
s : Finset γ
a : α
⊢ ∀ ⦃a_1 : γ⦄ {s : Finset γ},
    a_1 ∉ s →
      (↑(Finset.sup s f) a = Finset.sup s fun c => ↑(f c) a) →
        ↑(Finset.sup (insert a_1 s) f) a = Finset.sup (insert a_1 s) fun c => ↑(f c) a

Next tactic:
intro a s _ ih
theorem finset_sup_apply [SemilatticeSup β] [OrderBot β] {f : γ → α →ₛ β} (s : Finset γ) (a : α) :
    s.sup f a = s.sup fun c => f c a := by
  refine' Finset.induction_on s rfl _
  intro a s _ ih
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : MeasurableSpace α
K : Type u_5
inst✝¹ : SemilatticeSup β
inst✝ : OrderBot β
f : γ → α →ₛ β
s✝ : Finset γ
a✝¹ : α
a : γ
s : Finset γ
a✝ : a ∉ s
ih : ↑(Finset.sup s f) a✝¹ = Finset.sup s fun c => ↑(f c) a✝¹
⊢ ↑(Finset.sup (insert a s) f) a✝¹ = Finset.sup (insert a s) fun c => ↑(f c) a✝¹

Next tactic:
rw [Finset.sup_insert, Finset.sup_insert, sup_apply, ih]
@[simp]
theorem coe_restrict (f : α →ₛ β) {s : Set α} (hs : MeasurableSet s) :
    ⇑(restrict f s) = indicator s f := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝¹ : MeasurableSpace α
K : Type u_5
inst✝ : Zero β
f : α →ₛ β
s : Set α
hs : MeasurableSet s
⊢ ↑(restrict f s) = indicator s ↑f

Next tactic:
rw [restrict, dif_pos hs, coe_piecewise, coe_zero, piecewise_eq_indicator]
@[simp]
theorem restrict_univ (f : α →ₛ β) : restrict f univ = f := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝¹ : MeasurableSpace α
K : Type u_5
inst✝ : Zero β
f : α →ₛ β
⊢ restrict f univ = f

Next tactic:
simp [restrict]
@[simp]
theorem restrict_empty (f : α →ₛ β) : restrict f ∅ = 0 := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝¹ : MeasurableSpace α
K : Type u_5
inst✝ : Zero β
f : α →ₛ β
⊢ restrict f ∅ = 0

Next tactic:
simp [restrict]
theorem map_restrict_of_zero [Zero γ] {g : β → γ} (hg : g 0 = 0) (f : α →ₛ β) (s : Set α) :
    (f.restrict s).map g = (f.map g).restrict s :=
  ext fun x =>
    if hs : MeasurableSet s then by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
inst✝² : MeasurableSpace α
K : Type u_5
inst✝¹ : Zero β
inst✝ : Zero γ
g : β → γ
hg : g 0 = 0
f : α →ₛ β
s : Set α
x : α
hs : MeasurableSet s
⊢ ↑(map g (restrict f s)) x = ↑(restrict (map g f) s) x

Next tactic:
simp [hs, Set.indicator_comp_of_zero hg]