l3lab/ntp-mathlib huggingface dataset:
@[measurability]
theorem Finset.measurable_range_sup'' {f : ℕ → δ → α} {n : ℕ} (hf : ∀ k ≤ n, Measurable (f k)) :
    Measurable fun x => (range (n + 1)).sup' nonempty_range_succ fun k => f k x := by
  convert Finset.measurable_range_sup' hf using 1
  

Proof state:
case h.e'_5
M : Type u_1
inst✝³ : MeasurableSpace M
α : Type u_2
m : MeasurableSpace α
μ : Measure α
f✝ g : α → M
δ : Type u_3
inst✝² : MeasurableSpace δ
inst✝¹ : SemilatticeSup α
inst✝ : MeasurableSup₂ α
f : ℕ → δ → α
n : ℕ
hf : ∀ k ≤ n, Measurable (f k)
⊢ (fun x => sup' (range (n + 1)) (_ : Finset.Nonempty (range (n + 1))) fun k => f k x) =
    sup' (range (n + 1)) (_ : Finset.Nonempty (range (n + 1))) fun k => f k

Next tactic:
ext x
@[measurability]
theorem Finset.measurable_range_sup'' {f : ℕ → δ → α} {n : ℕ} (hf : ∀ k ≤ n, Measurable (f k)) :
    Measurable fun x => (range (n + 1)).sup' nonempty_range_succ fun k => f k x := by
  convert Finset.measurable_range_sup' hf using 1
  ext x
  

Proof state:
case h.e'_5.h
M : Type u_1
inst✝³ : MeasurableSpace M
α : Type u_2
m : MeasurableSpace α
μ : Measure α
f✝ g : α → M
δ : Type u_3
inst✝² : MeasurableSpace δ
inst✝¹ : SemilatticeSup α
inst✝ : MeasurableSup₂ α
f : ℕ → δ → α
n : ℕ
hf : ∀ k ≤ n, Measurable (f k)
x : δ
⊢ (sup' (range (n + 1)) (_ : Finset.Nonempty (range (n + 1))) fun k => f k x) =
    sup' (range (n + 1)) (_ : Finset.Nonempty (range (n + 1))) (fun k => f k) x

Next tactic:
simp
/-- Pullback a `Distrib` instance along an injective function.
See note [reducible non-instances]. -/
@[reducible]
protected def Function.Injective.distrib {S} [Mul R] [Add R] [Distrib S] (f : R → S)
    (hf : Injective f) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) :
    Distrib R where
  mul := (· * ·)
  add := (· + ·)
  left_distrib x y z := hf <| by 

Proof state:
α : Type u
β : Type v
γ : Type w
R : Type x
S : Type ?u.27
inst✝² : Mul R
inst✝¹ : Add R
inst✝ : Distrib S
f : R → S
hf : Injective f
add : ∀ (x y : R), f (x + y) = f x + f y
mul : ∀ (x y : R), f (x * y) = f x * f y
x y z : R
⊢ f (x * (y + z)) = f (x * y + x * z)

Next tactic:
simp only [*, left_distrib]
/-- Pullback a `Distrib` instance along an injective function.
See note [reducible non-instances]. -/
@[reducible]
protected def Function.Injective.distrib {S} [Mul R] [Add R] [Distrib S] (f : R → S)
    (hf : Injective f) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) :
    Distrib R where
  mul := (· * ·)
  add := (· + ·)
  left_distrib x y z := hf <| by simp only [*, left_distrib]
  right_distrib x y z := hf <| by 

Proof state:
α : Type u
β : Type v
γ : Type w
R : Type x
S : Type ?u.27
inst✝² : Mul R
inst✝¹ : Add R
inst✝ : Distrib S
f : R → S
hf : Injective f
add : ∀ (x y : R), f (x + y) = f x + f y
mul : ∀ (x y : R), f (x * y) = f x * f y
x y z : R
⊢ f ((x + y) * z) = f (x * z + y * z)

Next tactic:
simp only [*, right_distrib]
/-- Pushforward a `Distrib` instance along a surjective function.
See note [reducible non-instances]. -/
@[reducible]
protected def Function.Surjective.distrib {S} [Distrib R] [Add S] [Mul S] (f : R → S)
    (hf : Surjective f) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) :
    Distrib S where
  mul := (· * ·)
  add := (· + ·)
  left_distrib := hf.forall₃.2 fun x y z => by 

Proof state:
α : Type u
β : Type v
γ : Type w
R : Type x
S : Type ?u.1571
inst✝² : Distrib R
inst✝¹ : Add S
inst✝ : Mul S
f : R → S
hf : Surjective f
add : ∀ (x y : R), f (x + y) = f x + f y
mul : ∀ (x y : R), f (x * y) = f x * f y
x y z : R
⊢ f x * (f y + f z) = f x * f y + f x * f z

Next tactic:
simp only [← add, ← mul, left_distrib]
/-- Pushforward a `Distrib` instance along a surjective function.
See note [reducible non-instances]. -/
@[reducible]
protected def Function.Surjective.distrib {S} [Distrib R] [Add S] [Mul S] (f : R → S)
    (hf : Surjective f) (add : ∀ x y, f (x + y) = f x + f y) (mul : ∀ x y, f (x * y) = f x * f y) :
    Distrib S where
  mul := (· * ·)
  add := (· + ·)
  left_distrib := hf.forall₃.2 fun x y z => by simp only [← add, ← mul, left_distrib]
  right_distrib := hf.forall₃.2 fun x y z => by 

Proof state:
α : Type u
β : Type v
γ : Type w
R : Type x
S : Type ?u.1571
inst✝² : Distrib R
inst✝¹ : Add S
inst✝ : Mul S
f : R → S
hf : Surjective f
add : ∀ (x y : R), f (x + y) = f x + f y
mul : ∀ (x y : R), f (x * y) = f x * f y
x y z : R
⊢ (f x + f y) * f z = f x * f z + f y * f z

Next tactic:
simp only [← add, ← mul, right_distrib]
/-- A type endowed with `-` and `*` has distributive negation, if it admits an injective map that
preserves `-` and `*` to a type which has distributive negation. -/
@[reducible]
protected def Function.Injective.hasDistribNeg [Neg β] [Mul β] (f : β → α) (hf : Injective f)
    (neg : ∀ a, f (-a) = -f a) (mul : ∀ a b, f (a * b) = f a * f b) : HasDistribNeg β :=
  { hf.involutiveNeg _ neg, ‹Mul β› with
    neg_mul := fun x y => hf <| by 

Proof state:
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝³ : Mul α
inst✝² : HasDistribNeg α
inst✝¹ : Neg β
inst✝ : Mul β
f : β → α
hf : Injective f
neg : ∀ (a : β), f (-a) = -f a
mul : ∀ (a b : β), f (a * b) = f a * f b
src✝¹ : InvolutiveNeg β := Injective.involutiveNeg f hf neg
src✝ : Mul β := inst✝
x y : β
⊢ f (-x * y) = f (-(x * y))

Next tactic:
erw [neg, mul, neg, neg_mul, mul]
/-- A type endowed with `-` and `*` has distributive negation, if it admits an injective map that
preserves `-` and `*` to a type which has distributive negation. -/
@[reducible]
protected def Function.Injective.hasDistribNeg [Neg β] [Mul β] (f : β → α) (hf : Injective f)
    (neg : ∀ a, f (-a) = -f a) (mul : ∀ a b, f (a * b) = f a * f b) : HasDistribNeg β :=
  { hf.involutiveNeg _ neg, ‹Mul β› with
    neg_mul := fun x y => hf <| by erw [neg, mul, neg, neg_mul, mul],
    mul_neg := fun x y => hf <| by 

Proof state:
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝³ : Mul α
inst✝² : HasDistribNeg α
inst✝¹ : Neg β
inst✝ : Mul β
f : β → α
hf : Injective f
neg : ∀ (a : β), f (-a) = -f a
mul : ∀ (a b : β), f (a * b) = f a * f b
src✝¹ : InvolutiveNeg β := Injective.involutiveNeg f hf neg
src✝ : Mul β := inst✝
x y : β
⊢ f (x * -y) = f (-(x * y))

Next tactic:
erw [neg, mul, neg, mul_neg, mul]
/-- A type endowed with `-` and `*` has distributive negation, if it admits a surjective map that
preserves `-` and `*` from a type which has distributive negation. -/
@[reducible]
protected def Function.Surjective.hasDistribNeg [Neg β] [Mul β] (f : α → β) (hf : Surjective f)
    (neg : ∀ a, f (-a) = -f a) (mul : ∀ a b, f (a * b) = f a * f b) : HasDistribNeg β :=
  { hf.involutiveNeg _ neg, ‹Mul β› with
    neg_mul := hf.forall₂.2 fun x y => by 

Proof state:
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝³ : Mul α
inst✝² : HasDistribNeg α
inst✝¹ : Neg β
inst✝ : Mul β
f : α → β
hf : Surjective f
neg : ∀ (a : α), f (-a) = -f a
mul : ∀ (a b : α), f (a * b) = f a * f b
src✝¹ : InvolutiveNeg β := Surjective.involutiveNeg f hf neg
src✝ : Mul β := inst✝
x y : α
⊢ -f x * f y = -(f x * f y)

Next tactic:
erw [← neg, ← mul, neg_mul, neg, mul]
/-- A type endowed with `-` and `*` has distributive negation, if it admits a surjective map that
preserves `-` and `*` from a type which has distributive negation. -/
@[reducible]
protected def Function.Surjective.hasDistribNeg [Neg β] [Mul β] (f : α → β) (hf : Surjective f)
    (neg : ∀ a, f (-a) = -f a) (mul : ∀ a b, f (a * b) = f a * f b) : HasDistribNeg β :=
  { hf.involutiveNeg _ neg, ‹Mul β› with
    neg_mul := hf.forall₂.2 fun x y => by erw [← neg, ← mul, neg_mul, neg, mul]
    mul_neg := hf.forall₂.2 fun x y => by 

Proof state:
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝³ : Mul α
inst✝² : HasDistribNeg α
inst✝¹ : Neg β
inst✝ : Mul β
f : α → β
hf : Surjective f
neg : ∀ (a : α), f (-a) = -f a
mul : ∀ (a b : α), f (a * b) = f a * f b
src✝¹ : InvolutiveNeg β := Surjective.involutiveNeg f hf neg
src✝ : Mul β := inst✝
x y : α
⊢ f x * -f y = -(f x * f y)

Next tactic:
erw [← neg, ← mul, mul_neg, neg, mul]
theorem lfp_induction {p : α → Prop} (step : ∀ a, p a → a ≤ lfp f → p (f a))
    (hSup : ∀ s, (∀ a ∈ s, p a) → p (sSup s)) : p (lfp f) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝ : CompleteLattice α
f : α →o α
p : α → Prop
step : ∀ (a : α), p a → a ≤ lfp f → p (f a)
hSup : ∀ (s : Set α), (∀ a ∈ s, p a) → p (sSup s)
⊢ p (lfp f)

Next tactic:
set s := { a | a ≤ lfp f ∧ p a }
theorem lfp_induction {p : α → Prop} (step : ∀ a, p a → a ≤ lfp f → p (f a))
    (hSup : ∀ s, (∀ a ∈ s, p a) → p (sSup s)) : p (lfp f) := by
  set s := { a | a ≤ lfp f ∧ p a }
  

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝ : CompleteLattice α
f : α →o α
p : α → Prop
step : ∀ (a : α), p a → a ≤ lfp f → p (f a)
hSup : ∀ (s : Set α), (∀ a ∈ s, p a) → p (sSup s)
s : Set α := {a | a ≤ lfp f ∧ p a}
⊢ p (lfp f)

Next tactic:
specialize hSup s fun a => And.right
theorem lfp_induction {p : α → Prop} (step : ∀ a, p a → a ≤ lfp f → p (f a))
    (hSup : ∀ s, (∀ a ∈ s, p a) → p (sSup s)) : p (lfp f) := by
  set s := { a | a ≤ lfp f ∧ p a }
  specialize hSup s fun a => And.right
  

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝ : CompleteLattice α
f : α →o α
p : α → Prop
step : ∀ (a : α), p a → a ≤ lfp f → p (f a)
s : Set α := {a | a ≤ lfp f ∧ p a}
hSup : p (sSup s)
⊢ p (lfp f)

Next tactic:
suffices sSup s = lfp f from this ▸ hSup
theorem lfp_induction {p : α → Prop} (step : ∀ a, p a → a ≤ lfp f → p (f a))
    (hSup : ∀ s, (∀ a ∈ s, p a) → p (sSup s)) : p (lfp f) := by
  set s := { a | a ≤ lfp f ∧ p a }
  specialize hSup s fun a => And.right
  suffices sSup s = lfp f from this ▸ hSup
  

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝ : CompleteLattice α
f : α →o α
p : α → Prop
step : ∀ (a : α), p a → a ≤ lfp f → p (f a)
s : Set α := {a | a ≤ lfp f ∧ p a}
hSup : p (sSup s)
⊢ sSup s = lfp f

Next tactic:
have h : sSup s ≤ lfp f := sSup_le fun b => And.left
theorem lfp_induction {p : α → Prop} (step : ∀ a, p a → a ≤ lfp f → p (f a))
    (hSup : ∀ s, (∀ a ∈ s, p a) → p (sSup s)) : p (lfp f) := by
  set s := { a | a ≤ lfp f ∧ p a }
  specialize hSup s fun a => And.right
  suffices sSup s = lfp f from this ▸ hSup
  have h : sSup s ≤ lfp f := sSup_le fun b => And.left
  

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝ : CompleteLattice α
f : α →o α
p : α → Prop
step : ∀ (a : α), p a → a ≤ lfp f → p (f a)
s : Set α := {a | a ≤ lfp f ∧ p a}
hSup : p (sSup s)
h : sSup s ≤ lfp f
⊢ sSup s = lfp f

Next tactic:
have hmem : f (sSup s) ∈ s := ⟨f.map_le_lfp h, step _ hSup h⟩
theorem lfp_induction {p : α → Prop} (step : ∀ a, p a → a ≤ lfp f → p (f a))
    (hSup : ∀ s, (∀ a ∈ s, p a) → p (sSup s)) : p (lfp f) := by
  set s := { a | a ≤ lfp f ∧ p a }
  specialize hSup s fun a => And.right
  suffices sSup s = lfp f from this ▸ hSup
  have h : sSup s ≤ lfp f := sSup_le fun b => And.left
  have hmem : f (sSup s) ∈ s := ⟨f.map_le_lfp h, step _ hSup h⟩
  

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝ : CompleteLattice α
f : α →o α
p : α → Prop
step : ∀ (a : α), p a → a ≤ lfp f → p (f a)
s : Set α := {a | a ≤ lfp f ∧ p a}
hSup : p (sSup s)
h : sSup s ≤ lfp f
hmem : f (sSup s) ∈ s
⊢ sSup s = lfp f

Next tactic:
exact h.antisymm (f.lfp_le <| le_sSup hmem)
theorem lfp_lfp (h : α →o α →o α) : lfp (lfp.comp h) = lfp h.onDiag := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝¹ : CompleteLattice α
inst✝ : CompleteLattice β
f : β →o α
g : α →o β
h : α →o α →o α
⊢ lfp (comp lfp h) = lfp (onDiag h)

Next tactic:
let a := lfp (lfp.comp h)
theorem lfp_lfp (h : α →o α →o α) : lfp (lfp.comp h) = lfp h.onDiag := by
  let a := lfp (lfp.comp h)
  

Proof state:
α : Type u
β : Type v
γ : Type w
inst✝¹ : CompleteLattice α
inst✝ : CompleteLattice β
f : β →o α
g : α →o β
h : α →o α →o α
a : α := lfp (comp lfp h)
⊢ lfp (comp lfp h) = lfp (onDiag h)

Next tactic:
refine' (lfp_le _ _).antisymm (lfp_le _ (Eq.le _))
theorem lfp_lfp (h : α →o α →o α) : lfp (lfp.comp h) = lfp h.onDiag := by
  let a := lfp (lfp.comp h)
  refine' (lfp_le _ _).antisymm (lfp_le _ (Eq.le _))
  · 

Proof state:
case refine'_1
α : Type u
β : Type v
γ : Type w
inst✝¹ : CompleteLattice α
inst✝ : CompleteLattice β
f : β →o α
g : α →o β
h : α →o α →o α
a : α := lfp (comp lfp h)
⊢ (comp lfp h) (lfp (onDiag h)) ≤ lfp (onDiag h)

Next tactic:
exact lfp_le _ h.onDiag.map_lfp.le
theorem lfp_lfp (h : α →o α →o α) : lfp (lfp.comp h) = lfp h.onDiag := by
  let a := lfp (lfp.comp h)
  refine' (lfp_le _ _).antisymm (lfp_le _ (Eq.le _))
  · exact lfp_le _ h.onDiag.map_lfp.le
  

Proof state:
case refine'_2
α : Type u
β : Type v
γ : Type w
inst✝¹ : CompleteLattice α
inst✝ : CompleteLattice β
f : β →o α
g : α →o β
h : α →o α →o α
a : α := lfp (comp lfp h)
⊢ (onDiag h) (lfp (comp lfp h)) = lfp (comp lfp h)

Next tactic:
have ha : (lfp ∘ h) a = a := (lfp.comp h).map_lfp
theorem lfp_lfp (h : α →o α →o α) : lfp (lfp.comp h) = lfp h.onDiag := by
  let a := lfp (lfp.comp h)
  refine' (lfp_le _ _).antisymm (lfp_le _ (Eq.le _))
  · exact lfp_le _ h.onDiag.map_lfp.le
  have ha : (lfp ∘ h) a = a := (lfp.comp h).map_lfp
  

Proof state:
case refine'_2
α : Type u
β : Type v
γ : Type w
inst✝¹ : CompleteLattice α
inst✝ : CompleteLattice β
f : β →o α
g : α →o β
h : α →o α →o α
a : α := lfp (comp lfp h)
ha : (⇑lfp ∘ ⇑h) a = a
⊢ (onDiag h) (lfp (comp lfp h)) = lfp (comp lfp h)

Next tactic:
calc
    h a a = h a (lfp (h a)) := congr_arg (h a) ha.symm
    _ = lfp (h a) := (h a).map_lfp
    _ = a := ha
/-- An equality `X = Y` gives us a morphism `X ⟶ Y`.

It is typically better to use this, rather than rewriting by the equality then using `𝟙 _`
which usually leads to dependent type theory hell.
-/
def eqToHom {X Y : C} (p : X = Y) : X ⟶ Y := by 

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y : C
p : X = Y
⊢ X ⟶ Y

Next tactic:
rw [p]
/-- An equality `X = Y` gives us a morphism `X ⟶ Y`.

It is typically better to use this, rather than rewriting by the equality then using `𝟙 _`
which usually leads to dependent type theory hell.
-/
def eqToHom {X Y : C} (p : X = Y) : X ⟶ Y := by rw [p]; 

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y : C
p : X = Y
⊢ Y ⟶ Y

Next tactic:
exact 𝟙 _
@[reassoc (attr := simp)]
theorem eqToHom_trans {X Y Z : C} (p : X = Y) (q : Y = Z) :
    eqToHom p ≫ eqToHom q = eqToHom (p.trans q) := by
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y Z : C
p : X = Y
q : Y = Z
⊢ eqToHom p ≫ eqToHom q = eqToHom (_ : X = Z)

Next tactic:
cases p
@[reassoc (attr := simp)]
theorem eqToHom_trans {X Y Z : C} (p : X = Y) (q : Y = Z) :
    eqToHom p ≫ eqToHom q = eqToHom (p.trans q) := by
  cases p
  

Proof state:
case refl
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Z : C
q : X = Z
⊢ eqToHom (_ : X = X) ≫ eqToHom q = eqToHom (_ : X = Z)

Next tactic:
cases q
@[reassoc (attr := simp)]
theorem eqToHom_trans {X Y Z : C} (p : X = Y) (q : Y = Z) :
    eqToHom p ≫ eqToHom q = eqToHom (p.trans q) := by
  cases p
  cases q
  

Proof state:
case refl.refl
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X : C
⊢ eqToHom (_ : X = X) ≫ eqToHom (_ : X = X) = eqToHom (_ : X = X)

Next tactic:
simp
theorem comp_eqToHom_iff {X Y Y' : C} (p : Y = Y') (f : X ⟶ Y) (g : X ⟶ Y') :
    f ≫ eqToHom p = g ↔ f = g ≫ eqToHom p.symm :=
  { mp := fun h => h ▸ by 

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y Y' : C
p : Y = Y'
f : X ⟶ Y
g : X ⟶ Y'
h : f ≫ eqToHom p = g
⊢ f = (f ≫ eqToHom p) ≫ eqToHom (_ : Y' = Y)

Next tactic:
simp
theorem comp_eqToHom_iff {X Y Y' : C} (p : Y = Y') (f : X ⟶ Y) (g : X ⟶ Y') :
    f ≫ eqToHom p = g ↔ f = g ≫ eqToHom p.symm :=
  { mp := fun h => h ▸ by simp
    mpr := fun h => by 

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y Y' : C
p : Y = Y'
f : X ⟶ Y
g : X ⟶ Y'
h : f = g ≫ eqToHom (_ : Y' = Y)
⊢ f ≫ eqToHom p = g

Next tactic:
simp [eq_whisker h (eqToHom p)]
theorem eqToHom_comp_iff {X X' Y : C} (p : X = X') (f : X ⟶ Y) (g : X' ⟶ Y) :
    eqToHom p ≫ g = f ↔ g = eqToHom p.symm ≫ f :=
  { mp := fun h => h ▸ by 

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X X' Y : C
p : X = X'
f : X ⟶ Y
g : X' ⟶ Y
h : eqToHom p ≫ g = f
⊢ g = eqToHom (_ : X' = X) ≫ eqToHom p ≫ g

Next tactic:
simp
theorem eqToHom_comp_iff {X X' Y : C} (p : X = X') (f : X ⟶ Y) (g : X' ⟶ Y) :
    eqToHom p ≫ g = f ↔ g = eqToHom p.symm ≫ f :=
  { mp := fun h => h ▸ by simp
    mpr := fun h => h ▸ by 

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X X' Y : C
p : X = X'
f : X ⟶ Y
g : X' ⟶ Y
h : g = eqToHom (_ : X' = X) ≫ f
⊢ eqToHom p ≫ eqToHom (_ : X' = X) ≫ f = f

Next tactic:
simp [whisker_eq _ h]
/-- We can push `eqToHom` to the left through families of morphisms. -/
-- The simpNF linter incorrectly claims that this will never apply.
-- https://github.com/leanprover-community/mathlib4/issues/5049
@[reassoc (attr := simp, nolint simpNF)]
theorem eqToHom_naturality {f g : β → C} (z : ∀ b, f b ⟶ g b) {j j' : β} (w : j = j') :
    z j ≫ eqToHom (by 

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
β : Sort ?u.2361
f g : β → C
z : (b : β) → f b ⟶ g b
j j' : β
w : j = j'
⊢ g j = g j'

Next tactic:
simp [w]
/-- We can push `eqToHom` to the left through families of morphisms. -/
-- The simpNF linter incorrectly claims that this will never apply.
-- https://github.com/leanprover-community/mathlib4/issues/5049
@[reassoc (attr := simp, nolint simpNF)]
theorem eqToHom_naturality {f g : β → C} (z : ∀ b, f b ⟶ g b) {j j' : β} (w : j = j') :
    z j ≫ eqToHom (by simp [w]) = eqToHom (by 

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
β : Sort ?u.2361
f g : β → C
z : (b : β) → f b ⟶ g b
j j' : β
w : j = j'
⊢ f j = f j'

Next tactic:
simp [w]
/-- We can push `eqToHom` to the left through families of morphisms. -/
-- The simpNF linter incorrectly claims that this will never apply.
-- https://github.com/leanprover-community/mathlib4/issues/5049
@[reassoc (attr := simp, nolint simpNF)]
theorem eqToHom_naturality {f g : β → C} (z : ∀ b, f b ⟶ g b) {j j' : β} (w : j = j') :
    z j ≫ eqToHom (by simp [w]) = eqToHom (by simp [w]) ≫ z j' := by
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
β : Sort u_1
f g : β → C
z : (b : β) → f b ⟶ g b
j j' : β
w : j = j'
⊢ z j ≫ eqToHom (_ : g j = g j') = eqToHom (_ : f j = f j') ≫ z j'

Next tactic:
cases w
/-- We can push `eqToHom` to the left through families of morphisms. -/
-- The simpNF linter incorrectly claims that this will never apply.
-- https://github.com/leanprover-community/mathlib4/issues/5049
@[reassoc (attr := simp, nolint simpNF)]
theorem eqToHom_naturality {f g : β → C} (z : ∀ b, f b ⟶ g b) {j j' : β} (w : j = j') :
    z j ≫ eqToHom (by simp [w]) = eqToHom (by simp [w]) ≫ z j' := by
  cases w
  

Proof state:
case refl
C : Type u₁
inst✝ : Category.{v₁, u₁} C
β : Sort u_1
f g : β → C
z : (b : β) → f b ⟶ g b
j : β
⊢ z j ≫ eqToHom (_ : g j = g j) = eqToHom (_ : f j = f j) ≫ z j

Next tactic:
simp
/-- A variant on `eqToHom_naturality` that helps Lean identify the families `f` and `g`. -/
-- The simpNF linter incorrectly claims that this will never apply.
-- https://github.com/leanprover-community/mathlib4/issues/5049
@[reassoc (attr := simp, nolint simpNF)]
theorem eqToHom_iso_hom_naturality {f g : β → C} (z : ∀ b, f b ≅ g b) {j j' : β} (w : j = j') :
    (z j).hom ≫ eqToHom (by 

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
β : Sort ?u.3391
f g : β → C
z : (b : β) → f b ≅ g b
j j' : β
w : j = j'
⊢ g j = g j'

Next tactic:
simp [w]
/-- A variant on `eqToHom_naturality` that helps Lean identify the families `f` and `g`. -/
-- The simpNF linter incorrectly claims that this will never apply.
-- https://github.com/leanprover-community/mathlib4/issues/5049
@[reassoc (attr := simp, nolint simpNF)]
theorem eqToHom_iso_hom_naturality {f g : β → C} (z : ∀ b, f b ≅ g b) {j j' : β} (w : j = j') :
    (z j).hom ≫ eqToHom (by simp [w]) = eqToHom (by 

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
β : Sort ?u.3391
f g : β → C
z : (b : β) → f b ≅ g b
j j' : β
w : j = j'
⊢ f j = f j'

Next tactic:
simp [w]
/-- A variant on `eqToHom_naturality` that helps Lean identify the families `f` and `g`. -/
-- The simpNF linter incorrectly claims that this will never apply.
-- https://github.com/leanprover-community/mathlib4/issues/5049
@[reassoc (attr := simp, nolint simpNF)]
theorem eqToHom_iso_hom_naturality {f g : β → C} (z : ∀ b, f b ≅ g b) {j j' : β} (w : j = j') :
    (z j).hom ≫ eqToHom (by simp [w]) = eqToHom (by simp [w]) ≫ (z j').hom := by
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
β : Sort u_1
f g : β → C
z : (b : β) → f b ≅ g b
j j' : β
w : j = j'
⊢ (z j).hom ≫ eqToHom (_ : g j = g j') = eqToHom (_ : f j = f j') ≫ (z j').hom

Next tactic:
cases w
/-- A variant on `eqToHom_naturality` that helps Lean identify the families `f` and `g`. -/
-- The simpNF linter incorrectly claims that this will never apply.
-- https://github.com/leanprover-community/mathlib4/issues/5049
@[reassoc (attr := simp, nolint simpNF)]
theorem eqToHom_iso_hom_naturality {f g : β → C} (z : ∀ b, f b ≅ g b) {j j' : β} (w : j = j') :
    (z j).hom ≫ eqToHom (by simp [w]) = eqToHom (by simp [w]) ≫ (z j').hom := by
  cases w
  

Proof state:
case refl
C : Type u₁
inst✝ : Category.{v₁, u₁} C
β : Sort u_1
f g : β → C
z : (b : β) → f b ≅ g b
j : β
⊢ (z j).hom ≫ eqToHom (_ : g j = g j) = eqToHom (_ : f j = f j) ≫ (z j).hom

Next tactic:
simp
/-- A variant on `eqToHom_naturality` that helps Lean identify the families `f` and `g`. -/
-- The simpNF linter incorrectly claims that this will never apply.
-- https://github.com/leanprover-community/mathlib4/issues/5049
@[reassoc (attr := simp, nolint simpNF)]
theorem eqToHom_iso_inv_naturality {f g : β → C} (z : ∀ b, f b ≅ g b) {j j' : β} (w : j = j') :
    (z j).inv ≫ eqToHom (by 

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
β : Sort ?u.4451
f g : β → C
z : (b : β) → f b ≅ g b
j j' : β
w : j = j'
⊢ f j = f j'

Next tactic:
simp [w]
/-- A variant on `eqToHom_naturality` that helps Lean identify the families `f` and `g`. -/
-- The simpNF linter incorrectly claims that this will never apply.
-- https://github.com/leanprover-community/mathlib4/issues/5049
@[reassoc (attr := simp, nolint simpNF)]
theorem eqToHom_iso_inv_naturality {f g : β → C} (z : ∀ b, f b ≅ g b) {j j' : β} (w : j = j') :
    (z j).inv ≫ eqToHom (by simp [w]) = eqToHom (by 

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
β : Sort ?u.4451
f g : β → C
z : (b : β) → f b ≅ g b
j j' : β
w : j = j'
⊢ g j = g j'

Next tactic:
simp [w]
/-- A variant on `eqToHom_naturality` that helps Lean identify the families `f` and `g`. -/
-- The simpNF linter incorrectly claims that this will never apply.
-- https://github.com/leanprover-community/mathlib4/issues/5049
@[reassoc (attr := simp, nolint simpNF)]
theorem eqToHom_iso_inv_naturality {f g : β → C} (z : ∀ b, f b ≅ g b) {j j' : β} (w : j = j') :
    (z j).inv ≫ eqToHom (by simp [w]) = eqToHom (by simp [w]) ≫ (z j').inv := by
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
β : Sort u_1
f g : β → C
z : (b : β) → f b ≅ g b
j j' : β
w : j = j'
⊢ (z j).inv ≫ eqToHom (_ : f j = f j') = eqToHom (_ : g j = g j') ≫ (z j').inv

Next tactic:
cases w
/-- A variant on `eqToHom_naturality` that helps Lean identify the families `f` and `g`. -/
-- The simpNF linter incorrectly claims that this will never apply.
-- https://github.com/leanprover-community/mathlib4/issues/5049
@[reassoc (attr := simp, nolint simpNF)]
theorem eqToHom_iso_inv_naturality {f g : β → C} (z : ∀ b, f b ≅ g b) {j j' : β} (w : j = j') :
    (z j).inv ≫ eqToHom (by simp [w]) = eqToHom (by simp [w]) ≫ (z j').inv := by
  cases w
  

Proof state:
case refl
C : Type u₁
inst✝ : Category.{v₁, u₁} C
β : Sort u_1
f g : β → C
z : (b : β) → f b ≅ g b
j : β
⊢ (z j).inv ≫ eqToHom (_ : f j = f j) = eqToHom (_ : g j = g j) ≫ (z j).inv

Next tactic:
simp
/-- Reducible form of congrArg_mpr_hom_left -/
@[simp, nolint simpNF]
theorem congrArg_cast_hom_left {X Y Z : C} (p : X = Y) (q : Y ⟶ Z) :
    cast (congrArg (fun W : C => W ⟶ Z) p.symm) q = eqToHom p ≫ q := by
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y Z : C
p : X = Y
q : Y ⟶ Z
⊢ cast (_ : (Y ⟶ Z) = (X ⟶ Z)) q = eqToHom p ≫ q

Next tactic:
cases p
/-- Reducible form of congrArg_mpr_hom_left -/
@[simp, nolint simpNF]
theorem congrArg_cast_hom_left {X Y Z : C} (p : X = Y) (q : Y ⟶ Z) :
    cast (congrArg (fun W : C => W ⟶ Z) p.symm) q = eqToHom p ≫ q := by
  cases p
  

Proof state:
case refl
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Z : C
q : X ⟶ Z
⊢ cast (_ : (X ⟶ Z) = (X ⟶ Z)) q = eqToHom (_ : X = X) ≫ q

Next tactic:
simp