l3lab/ntp-mathlib huggingface dataset:
/-- The infimum of the Rayleigh quotient of a symmetric operator `T` on a nontrivial
finite-dimensional vector space is an eigenvalue for that operator. -/
theorem hasEigenvalue_iInf_of_finiteDimensional (hT : T.IsSymmetric) :
    HasEigenvalue T ↑(⨅ x : { x : E // x ≠ 0 }, IsROrC.re ⟪T x, x⟫ / ‖(x : E)‖ ^ 2 : ℝ) := by
  haveI := FiniteDimensional.proper_isROrC 𝕜 E
  let T' := hT.toSelfAdjoint
  obtain ⟨x, hx⟩ : ∃ x : E, x ≠ 0 := exists_ne 0
  have H₁ : IsCompact (sphere (0 : E) ‖x‖) := isCompact_sphere _ _
  have H₂ : (sphere (0 : E) ‖x‖).Nonempty := ⟨x, by simp⟩
  -- key point: in finite dimension, a continuous function on the sphere has a min
  obtain ⟨x₀, hx₀', hTx₀⟩ :=
    H₁.exists_forall_le H₂ T'.val.reApplyInnerSelf_continuous.continuousOn
  have hx₀ : ‖x₀‖ = ‖x‖ := by 

Proof state:
𝕜 : Type u_1
inst✝³ : IsROrC 𝕜
E : Type u_2
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
inst✝ : FiniteDimensional 𝕜 E
_i : Nontrivial E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
this : ProperSpace E
T' : ↥(selfAdjoint (E →L[𝕜] E)) := toSelfAdjoint hT
x : E
hx : x ≠ 0
H₁ : IsCompact (sphere 0 ‖x‖)
H₂ : Set.Nonempty (sphere 0 ‖x‖)
x₀ : E
hx₀' : x₀ ∈ sphere 0 ‖x‖
hTx₀ : ∀ y ∈ sphere 0 ‖x‖, ContinuousLinearMap.reApplyInnerSelf (↑T') x₀ ≤ ContinuousLinearMap.reApplyInnerSelf (↑T') y
⊢ ‖x₀‖ = ‖x‖

Next tactic:
simpa using hx₀'
/-- The infimum of the Rayleigh quotient of a symmetric operator `T` on a nontrivial
finite-dimensional vector space is an eigenvalue for that operator. -/
theorem hasEigenvalue_iInf_of_finiteDimensional (hT : T.IsSymmetric) :
    HasEigenvalue T ↑(⨅ x : { x : E // x ≠ 0 }, IsROrC.re ⟪T x, x⟫ / ‖(x : E)‖ ^ 2 : ℝ) := by
  haveI := FiniteDimensional.proper_isROrC 𝕜 E
  let T' := hT.toSelfAdjoint
  obtain ⟨x, hx⟩ : ∃ x : E, x ≠ 0 := exists_ne 0
  have H₁ : IsCompact (sphere (0 : E) ‖x‖) := isCompact_sphere _ _
  have H₂ : (sphere (0 : E) ‖x‖).Nonempty := ⟨x, by simp⟩
  -- key point: in finite dimension, a continuous function on the sphere has a min
  obtain ⟨x₀, hx₀', hTx₀⟩ :=
    H₁.exists_forall_le H₂ T'.val.reApplyInnerSelf_continuous.continuousOn
  have hx₀ : ‖x₀‖ = ‖x‖ := by simpa using hx₀'
  

Proof state:
case intro.intro.intro
𝕜 : Type u_1
inst✝³ : IsROrC 𝕜
E : Type u_2
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
inst✝ : FiniteDimensional 𝕜 E
_i : Nontrivial E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
this : ProperSpace E
T' : ↥(selfAdjoint (E →L[𝕜] E)) := toSelfAdjoint hT
x : E
hx : x ≠ 0
H₁ : IsCompact (sphere 0 ‖x‖)
H₂ : Set.Nonempty (sphere 0 ‖x‖)
x₀ : E
hx₀' : x₀ ∈ sphere 0 ‖x‖
hTx₀ : ∀ y ∈ sphere 0 ‖x‖, ContinuousLinearMap.reApplyInnerSelf (↑T') x₀ ≤ ContinuousLinearMap.reApplyInnerSelf (↑T') y
hx₀ : ‖x₀‖ = ‖x‖
⊢ HasEigenvalue T ↑(⨅ x, IsROrC.re (inner (T ↑x) ↑x) / ‖↑x‖ ^ 2)

Next tactic:
have : IsMinOn T'.val.reApplyInnerSelf (sphere 0 ‖x₀‖) x₀ := by simpa only [← hx₀] using hTx₀
/-- The infimum of the Rayleigh quotient of a symmetric operator `T` on a nontrivial
finite-dimensional vector space is an eigenvalue for that operator. -/
theorem hasEigenvalue_iInf_of_finiteDimensional (hT : T.IsSymmetric) :
    HasEigenvalue T ↑(⨅ x : { x : E // x ≠ 0 }, IsROrC.re ⟪T x, x⟫ / ‖(x : E)‖ ^ 2 : ℝ) := by
  haveI := FiniteDimensional.proper_isROrC 𝕜 E
  let T' := hT.toSelfAdjoint
  obtain ⟨x, hx⟩ : ∃ x : E, x ≠ 0 := exists_ne 0
  have H₁ : IsCompact (sphere (0 : E) ‖x‖) := isCompact_sphere _ _
  have H₂ : (sphere (0 : E) ‖x‖).Nonempty := ⟨x, by simp⟩
  -- key point: in finite dimension, a continuous function on the sphere has a min
  obtain ⟨x₀, hx₀', hTx₀⟩ :=
    H₁.exists_forall_le H₂ T'.val.reApplyInnerSelf_continuous.continuousOn
  have hx₀ : ‖x₀‖ = ‖x‖ := by simpa using hx₀'
  have : IsMinOn T'.val.reApplyInnerSelf (sphere 0 ‖x₀‖) x₀ := by 

Proof state:
𝕜 : Type u_1
inst✝³ : IsROrC 𝕜
E : Type u_2
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
inst✝ : FiniteDimensional 𝕜 E
_i : Nontrivial E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
this : ProperSpace E
T' : ↥(selfAdjoint (E →L[𝕜] E)) := toSelfAdjoint hT
x : E
hx : x ≠ 0
H₁ : IsCompact (sphere 0 ‖x‖)
H₂ : Set.Nonempty (sphere 0 ‖x‖)
x₀ : E
hx₀' : x₀ ∈ sphere 0 ‖x‖
hTx₀ : ∀ y ∈ sphere 0 ‖x‖, ContinuousLinearMap.reApplyInnerSelf (↑T') x₀ ≤ ContinuousLinearMap.reApplyInnerSelf (↑T') y
hx₀ : ‖x₀‖ = ‖x‖
⊢ IsMinOn (ContinuousLinearMap.reApplyInnerSelf ↑T') (sphere 0 ‖x₀‖) x₀

Next tactic:
simpa only [← hx₀] using hTx₀
/-- The infimum of the Rayleigh quotient of a symmetric operator `T` on a nontrivial
finite-dimensional vector space is an eigenvalue for that operator. -/
theorem hasEigenvalue_iInf_of_finiteDimensional (hT : T.IsSymmetric) :
    HasEigenvalue T ↑(⨅ x : { x : E // x ≠ 0 }, IsROrC.re ⟪T x, x⟫ / ‖(x : E)‖ ^ 2 : ℝ) := by
  haveI := FiniteDimensional.proper_isROrC 𝕜 E
  let T' := hT.toSelfAdjoint
  obtain ⟨x, hx⟩ : ∃ x : E, x ≠ 0 := exists_ne 0
  have H₁ : IsCompact (sphere (0 : E) ‖x‖) := isCompact_sphere _ _
  have H₂ : (sphere (0 : E) ‖x‖).Nonempty := ⟨x, by simp⟩
  -- key point: in finite dimension, a continuous function on the sphere has a min
  obtain ⟨x₀, hx₀', hTx₀⟩ :=
    H₁.exists_forall_le H₂ T'.val.reApplyInnerSelf_continuous.continuousOn
  have hx₀ : ‖x₀‖ = ‖x‖ := by simpa using hx₀'
  have : IsMinOn T'.val.reApplyInnerSelf (sphere 0 ‖x₀‖) x₀ := by simpa only [← hx₀] using hTx₀
  

Proof state:
case intro.intro.intro
𝕜 : Type u_1
inst✝³ : IsROrC 𝕜
E : Type u_2
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
inst✝ : FiniteDimensional 𝕜 E
_i : Nontrivial E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
this✝ : ProperSpace E
T' : ↥(selfAdjoint (E →L[𝕜] E)) := toSelfAdjoint hT
x : E
hx : x ≠ 0
H₁ : IsCompact (sphere 0 ‖x‖)
H₂ : Set.Nonempty (sphere 0 ‖x‖)
x₀ : E
hx₀' : x₀ ∈ sphere 0 ‖x‖
hTx₀ : ∀ y ∈ sphere 0 ‖x‖, ContinuousLinearMap.reApplyInnerSelf (↑T') x₀ ≤ ContinuousLinearMap.reApplyInnerSelf (↑T') y
hx₀ : ‖x₀‖ = ‖x‖
this : IsMinOn (ContinuousLinearMap.reApplyInnerSelf ↑T') (sphere 0 ‖x₀‖) x₀
⊢ HasEigenvalue T ↑(⨅ x, IsROrC.re (inner (T ↑x) ↑x) / ‖↑x‖ ^ 2)

Next tactic:
have hx₀_ne : x₀ ≠ 0 := by
    have : ‖x₀‖ ≠ 0 := by simp only [hx₀, norm_eq_zero, hx, Ne.def, not_false_iff]
    simpa [← norm_eq_zero, Ne.def]
/-- The infimum of the Rayleigh quotient of a symmetric operator `T` on a nontrivial
finite-dimensional vector space is an eigenvalue for that operator. -/
theorem hasEigenvalue_iInf_of_finiteDimensional (hT : T.IsSymmetric) :
    HasEigenvalue T ↑(⨅ x : { x : E // x ≠ 0 }, IsROrC.re ⟪T x, x⟫ / ‖(x : E)‖ ^ 2 : ℝ) := by
  haveI := FiniteDimensional.proper_isROrC 𝕜 E
  let T' := hT.toSelfAdjoint
  obtain ⟨x, hx⟩ : ∃ x : E, x ≠ 0 := exists_ne 0
  have H₁ : IsCompact (sphere (0 : E) ‖x‖) := isCompact_sphere _ _
  have H₂ : (sphere (0 : E) ‖x‖).Nonempty := ⟨x, by simp⟩
  -- key point: in finite dimension, a continuous function on the sphere has a min
  obtain ⟨x₀, hx₀', hTx₀⟩ :=
    H₁.exists_forall_le H₂ T'.val.reApplyInnerSelf_continuous.continuousOn
  have hx₀ : ‖x₀‖ = ‖x‖ := by simpa using hx₀'
  have : IsMinOn T'.val.reApplyInnerSelf (sphere 0 ‖x₀‖) x₀ := by simpa only [← hx₀] using hTx₀
  have hx₀_ne : x₀ ≠ 0 := by
    

Proof state:
𝕜 : Type u_1
inst✝³ : IsROrC 𝕜
E : Type u_2
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
inst✝ : FiniteDimensional 𝕜 E
_i : Nontrivial E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
this✝ : ProperSpace E
T' : ↥(selfAdjoint (E →L[𝕜] E)) := toSelfAdjoint hT
x : E
hx : x ≠ 0
H₁ : IsCompact (sphere 0 ‖x‖)
H₂ : Set.Nonempty (sphere 0 ‖x‖)
x₀ : E
hx₀' : x₀ ∈ sphere 0 ‖x‖
hTx₀ : ∀ y ∈ sphere 0 ‖x‖, ContinuousLinearMap.reApplyInnerSelf (↑T') x₀ ≤ ContinuousLinearMap.reApplyInnerSelf (↑T') y
hx₀ : ‖x₀‖ = ‖x‖
this : IsMinOn (ContinuousLinearMap.reApplyInnerSelf ↑T') (sphere 0 ‖x₀‖) x₀
⊢ x₀ ≠ 0

Next tactic:
have : ‖x₀‖ ≠ 0 := by simp only [hx₀, norm_eq_zero, hx, Ne.def, not_false_iff]
/-- The infimum of the Rayleigh quotient of a symmetric operator `T` on a nontrivial
finite-dimensional vector space is an eigenvalue for that operator. -/
theorem hasEigenvalue_iInf_of_finiteDimensional (hT : T.IsSymmetric) :
    HasEigenvalue T ↑(⨅ x : { x : E // x ≠ 0 }, IsROrC.re ⟪T x, x⟫ / ‖(x : E)‖ ^ 2 : ℝ) := by
  haveI := FiniteDimensional.proper_isROrC 𝕜 E
  let T' := hT.toSelfAdjoint
  obtain ⟨x, hx⟩ : ∃ x : E, x ≠ 0 := exists_ne 0
  have H₁ : IsCompact (sphere (0 : E) ‖x‖) := isCompact_sphere _ _
  have H₂ : (sphere (0 : E) ‖x‖).Nonempty := ⟨x, by simp⟩
  -- key point: in finite dimension, a continuous function on the sphere has a min
  obtain ⟨x₀, hx₀', hTx₀⟩ :=
    H₁.exists_forall_le H₂ T'.val.reApplyInnerSelf_continuous.continuousOn
  have hx₀ : ‖x₀‖ = ‖x‖ := by simpa using hx₀'
  have : IsMinOn T'.val.reApplyInnerSelf (sphere 0 ‖x₀‖) x₀ := by simpa only [← hx₀] using hTx₀
  have hx₀_ne : x₀ ≠ 0 := by
    have : ‖x₀‖ ≠ 0 := by 

Proof state:
𝕜 : Type u_1
inst✝³ : IsROrC 𝕜
E : Type u_2
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
inst✝ : FiniteDimensional 𝕜 E
_i : Nontrivial E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
this✝ : ProperSpace E
T' : ↥(selfAdjoint (E →L[𝕜] E)) := toSelfAdjoint hT
x : E
hx : x ≠ 0
H₁ : IsCompact (sphere 0 ‖x‖)
H₂ : Set.Nonempty (sphere 0 ‖x‖)
x₀ : E
hx₀' : x₀ ∈ sphere 0 ‖x‖
hTx₀ : ∀ y ∈ sphere 0 ‖x‖, ContinuousLinearMap.reApplyInnerSelf (↑T') x₀ ≤ ContinuousLinearMap.reApplyInnerSelf (↑T') y
hx₀ : ‖x₀‖ = ‖x‖
this : IsMinOn (ContinuousLinearMap.reApplyInnerSelf ↑T') (sphere 0 ‖x₀‖) x₀
⊢ ‖x₀‖ ≠ 0

Next tactic:
simp only [hx₀, norm_eq_zero, hx, Ne.def, not_false_iff]
/-- The infimum of the Rayleigh quotient of a symmetric operator `T` on a nontrivial
finite-dimensional vector space is an eigenvalue for that operator. -/
theorem hasEigenvalue_iInf_of_finiteDimensional (hT : T.IsSymmetric) :
    HasEigenvalue T ↑(⨅ x : { x : E // x ≠ 0 }, IsROrC.re ⟪T x, x⟫ / ‖(x : E)‖ ^ 2 : ℝ) := by
  haveI := FiniteDimensional.proper_isROrC 𝕜 E
  let T' := hT.toSelfAdjoint
  obtain ⟨x, hx⟩ : ∃ x : E, x ≠ 0 := exists_ne 0
  have H₁ : IsCompact (sphere (0 : E) ‖x‖) := isCompact_sphere _ _
  have H₂ : (sphere (0 : E) ‖x‖).Nonempty := ⟨x, by simp⟩
  -- key point: in finite dimension, a continuous function on the sphere has a min
  obtain ⟨x₀, hx₀', hTx₀⟩ :=
    H₁.exists_forall_le H₂ T'.val.reApplyInnerSelf_continuous.continuousOn
  have hx₀ : ‖x₀‖ = ‖x‖ := by simpa using hx₀'
  have : IsMinOn T'.val.reApplyInnerSelf (sphere 0 ‖x₀‖) x₀ := by simpa only [← hx₀] using hTx₀
  have hx₀_ne : x₀ ≠ 0 := by
    have : ‖x₀‖ ≠ 0 := by simp only [hx₀, norm_eq_zero, hx, Ne.def, not_false_iff]
    

Proof state:
𝕜 : Type u_1
inst✝³ : IsROrC 𝕜
E : Type u_2
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
inst✝ : FiniteDimensional 𝕜 E
_i : Nontrivial E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
this✝¹ : ProperSpace E
T' : ↥(selfAdjoint (E →L[𝕜] E)) := toSelfAdjoint hT
x : E
hx : x ≠ 0
H₁ : IsCompact (sphere 0 ‖x‖)
H₂ : Set.Nonempty (sphere 0 ‖x‖)
x₀ : E
hx₀' : x₀ ∈ sphere 0 ‖x‖
hTx₀ : ∀ y ∈ sphere 0 ‖x‖, ContinuousLinearMap.reApplyInnerSelf (↑T') x₀ ≤ ContinuousLinearMap.reApplyInnerSelf (↑T') y
hx₀ : ‖x₀‖ = ‖x‖
this✝ : IsMinOn (ContinuousLinearMap.reApplyInnerSelf ↑T') (sphere 0 ‖x₀‖) x₀
this : ‖x₀‖ ≠ 0
⊢ x₀ ≠ 0

Next tactic:
simpa [← norm_eq_zero, Ne.def]
/-- The infimum of the Rayleigh quotient of a symmetric operator `T` on a nontrivial
finite-dimensional vector space is an eigenvalue for that operator. -/
theorem hasEigenvalue_iInf_of_finiteDimensional (hT : T.IsSymmetric) :
    HasEigenvalue T ↑(⨅ x : { x : E // x ≠ 0 }, IsROrC.re ⟪T x, x⟫ / ‖(x : E)‖ ^ 2 : ℝ) := by
  haveI := FiniteDimensional.proper_isROrC 𝕜 E
  let T' := hT.toSelfAdjoint
  obtain ⟨x, hx⟩ : ∃ x : E, x ≠ 0 := exists_ne 0
  have H₁ : IsCompact (sphere (0 : E) ‖x‖) := isCompact_sphere _ _
  have H₂ : (sphere (0 : E) ‖x‖).Nonempty := ⟨x, by simp⟩
  -- key point: in finite dimension, a continuous function on the sphere has a min
  obtain ⟨x₀, hx₀', hTx₀⟩ :=
    H₁.exists_forall_le H₂ T'.val.reApplyInnerSelf_continuous.continuousOn
  have hx₀ : ‖x₀‖ = ‖x‖ := by simpa using hx₀'
  have : IsMinOn T'.val.reApplyInnerSelf (sphere 0 ‖x₀‖) x₀ := by simpa only [← hx₀] using hTx₀
  have hx₀_ne : x₀ ≠ 0 := by
    have : ‖x₀‖ ≠ 0 := by simp only [hx₀, norm_eq_zero, hx, Ne.def, not_false_iff]
    simpa [← norm_eq_zero, Ne.def]
  

Proof state:
case intro.intro.intro
𝕜 : Type u_1
inst✝³ : IsROrC 𝕜
E : Type u_2
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
inst✝ : FiniteDimensional 𝕜 E
_i : Nontrivial E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
this✝ : ProperSpace E
T' : ↥(selfAdjoint (E →L[𝕜] E)) := toSelfAdjoint hT
x : E
hx : x ≠ 0
H₁ : IsCompact (sphere 0 ‖x‖)
H₂ : Set.Nonempty (sphere 0 ‖x‖)
x₀ : E
hx₀' : x₀ ∈ sphere 0 ‖x‖
hTx₀ : ∀ y ∈ sphere 0 ‖x‖, ContinuousLinearMap.reApplyInnerSelf (↑T') x₀ ≤ ContinuousLinearMap.reApplyInnerSelf (↑T') y
hx₀ : ‖x₀‖ = ‖x‖
this : IsMinOn (ContinuousLinearMap.reApplyInnerSelf ↑T') (sphere 0 ‖x₀‖) x₀
hx₀_ne : x₀ ≠ 0
⊢ HasEigenvalue T ↑(⨅ x, IsROrC.re (inner (T ↑x) ↑x) / ‖↑x‖ ^ 2)

Next tactic:
exact hasEigenvalue_of_hasEigenvector (T'.prop.hasEigenvector_of_isMinOn hx₀_ne this)
/-- A `forget₂ C D` forgetful functor between concrete categories `C` and `D`
where `forget C` reflects isomorphisms, itself reflects isomorphisms.
-/
theorem reflectsIsomorphisms_forget₂ [HasForget₂ C D] [ReflectsIsomorphisms (forget C)] :
    ReflectsIsomorphisms (forget₂ C D) :=
  { reflects := fun X Y f {i} => by
      

Proof state:
C : Type (u + 1)
inst✝⁵ : Category.{u_1, u + 1} C
inst✝⁴ : ConcreteCategory C
D : Type (u + 1)
inst✝³ : Category.{u_2, u + 1} D
inst✝² : ConcreteCategory D
inst✝¹ : HasForget₂ C D
inst✝ : ReflectsIsomorphisms (forget C)
X Y : C
f : X ⟶ Y
i : IsIso ((forget₂ C D).map f)
⊢ IsIso f

Next tactic:
skip
/-- A `forget₂ C D` forgetful functor between concrete categories `C` and `D`
where `forget C` reflects isomorphisms, itself reflects isomorphisms.
-/
theorem reflectsIsomorphisms_forget₂ [HasForget₂ C D] [ReflectsIsomorphisms (forget C)] :
    ReflectsIsomorphisms (forget₂ C D) :=
  { reflects := fun X Y f {i} => by
      skip
      

Proof state:
C : Type (u + 1)
inst✝⁵ : Category.{u_1, u + 1} C
inst✝⁴ : ConcreteCategory C
D : Type (u + 1)
inst✝³ : Category.{u_2, u + 1} D
inst✝² : ConcreteCategory D
inst✝¹ : HasForget₂ C D
inst✝ : ReflectsIsomorphisms (forget C)
X Y : C
f : X ⟶ Y
i : IsIso ((forget₂ C D).map f)
⊢ IsIso f

Next tactic:
haveI i' : IsIso ((forget D).map ((forget₂ C D).map f)) := Functor.map_isIso (forget D) _
/-- A `forget₂ C D` forgetful functor between concrete categories `C` and `D`
where `forget C` reflects isomorphisms, itself reflects isomorphisms.
-/
theorem reflectsIsomorphisms_forget₂ [HasForget₂ C D] [ReflectsIsomorphisms (forget C)] :
    ReflectsIsomorphisms (forget₂ C D) :=
  { reflects := fun X Y f {i} => by
      skip
      haveI i' : IsIso ((forget D).map ((forget₂ C D).map f)) := Functor.map_isIso (forget D) _
      

Proof state:
C : Type (u + 1)
inst✝⁵ : Category.{u_1, u + 1} C
inst✝⁴ : ConcreteCategory C
D : Type (u + 1)
inst✝³ : Category.{u_2, u + 1} D
inst✝² : ConcreteCategory D
inst✝¹ : HasForget₂ C D
inst✝ : ReflectsIsomorphisms (forget C)
X Y : C
f : X ⟶ Y
i : IsIso ((forget₂ C D).map f)
i' : IsIso ((forget D).map ((forget₂ C D).map f))
⊢ IsIso f

Next tactic:
haveI : IsIso ((forget C).map f) := by
        have := @HasForget₂.forget_comp C D
        rw [← this]
        exact i'
/-- A `forget₂ C D` forgetful functor between concrete categories `C` and `D`
where `forget C` reflects isomorphisms, itself reflects isomorphisms.
-/
theorem reflectsIsomorphisms_forget₂ [HasForget₂ C D] [ReflectsIsomorphisms (forget C)] :
    ReflectsIsomorphisms (forget₂ C D) :=
  { reflects := fun X Y f {i} => by
      skip
      haveI i' : IsIso ((forget D).map ((forget₂ C D).map f)) := Functor.map_isIso (forget D) _
      haveI : IsIso ((forget C).map f) := by
        

Proof state:
C : Type (u + 1)
inst✝⁵ : Category.{u_1, u + 1} C
inst✝⁴ : ConcreteCategory C
D : Type (u + 1)
inst✝³ : Category.{u_2, u + 1} D
inst✝² : ConcreteCategory D
inst✝¹ : HasForget₂ C D
inst✝ : ReflectsIsomorphisms (forget C)
X Y : C
f : X ⟶ Y
i : IsIso ((forget₂ C D).map f)
i' : IsIso ((forget D).map ((forget₂ C D).map f))
⊢ IsIso ((forget C).map f)

Next tactic:
have := @HasForget₂.forget_comp C D
/-- A `forget₂ C D` forgetful functor between concrete categories `C` and `D`
where `forget C` reflects isomorphisms, itself reflects isomorphisms.
-/
theorem reflectsIsomorphisms_forget₂ [HasForget₂ C D] [ReflectsIsomorphisms (forget C)] :
    ReflectsIsomorphisms (forget₂ C D) :=
  { reflects := fun X Y f {i} => by
      skip
      haveI i' : IsIso ((forget D).map ((forget₂ C D).map f)) := Functor.map_isIso (forget D) _
      haveI : IsIso ((forget C).map f) := by
        have := @HasForget₂.forget_comp C D
        

Proof state:
C : Type (u + 1)
inst✝⁵ : Category.{u_1, u + 1} C
inst✝⁴ : ConcreteCategory C
D : Type (u + 1)
inst✝³ : Category.{u_2, u + 1} D
inst✝² : ConcreteCategory D
inst✝¹ : HasForget₂ C D
inst✝ : ReflectsIsomorphisms (forget C)
X Y : C
f : X ⟶ Y
i : IsIso ((forget₂ C D).map f)
i' : IsIso ((forget D).map ((forget₂ C D).map f))
this :
  ∀ [inst : Category.{?u.1896, u + 1} C] [inst_1 : ConcreteCategory C] [inst_2 : Category.{?u.1895, u + 1} D]
    [inst_3 : ConcreteCategory D] [self : HasForget₂ C D], HasForget₂.forget₂ ⋙ forget D = forget C
⊢ IsIso ((forget C).map f)

Next tactic:
rw [← this]
/-- A `forget₂ C D` forgetful functor between concrete categories `C` and `D`
where `forget C` reflects isomorphisms, itself reflects isomorphisms.
-/
theorem reflectsIsomorphisms_forget₂ [HasForget₂ C D] [ReflectsIsomorphisms (forget C)] :
    ReflectsIsomorphisms (forget₂ C D) :=
  { reflects := fun X Y f {i} => by
      skip
      haveI i' : IsIso ((forget D).map ((forget₂ C D).map f)) := Functor.map_isIso (forget D) _
      haveI : IsIso ((forget C).map f) := by
        have := @HasForget₂.forget_comp C D
        rw [← this]
        

Proof state:
C : Type (u + 1)
inst✝⁵ : Category.{u_1, u + 1} C
inst✝⁴ : ConcreteCategory C
D : Type (u + 1)
inst✝³ : Category.{u_2, u + 1} D
inst✝² : ConcreteCategory D
inst✝¹ : HasForget₂ C D
inst✝ : ReflectsIsomorphisms (forget C)
X Y : C
f : X ⟶ Y
i : IsIso ((forget₂ C D).map f)
i' : IsIso ((forget D).map ((forget₂ C D).map f))
this :
  ∀ [inst : Category.{u_1, u + 1} C] [inst_1 : ConcreteCategory C] [inst_2 : Category.{u_2, u + 1} D]
    [inst_3 : ConcreteCategory D] [self : HasForget₂ C D], HasForget₂.forget₂ ⋙ forget D = forget C
⊢ IsIso ((HasForget₂.forget₂ ⋙ forget D).map f)

Next tactic:
exact i'
/-- A `forget₂ C D` forgetful functor between concrete categories `C` and `D`
where `forget C` reflects isomorphisms, itself reflects isomorphisms.
-/
theorem reflectsIsomorphisms_forget₂ [HasForget₂ C D] [ReflectsIsomorphisms (forget C)] :
    ReflectsIsomorphisms (forget₂ C D) :=
  { reflects := fun X Y f {i} => by
      skip
      haveI i' : IsIso ((forget D).map ((forget₂ C D).map f)) := Functor.map_isIso (forget D) _
      haveI : IsIso ((forget C).map f) := by
        have := @HasForget₂.forget_comp C D
        rw [← this]
        exact i'
      

Proof state:
C : Type (u + 1)
inst✝⁵ : Category.{u_1, u + 1} C
inst✝⁴ : ConcreteCategory C
D : Type (u + 1)
inst✝³ : Category.{u_2, u + 1} D
inst✝² : ConcreteCategory D
inst✝¹ : HasForget₂ C D
inst✝ : ReflectsIsomorphisms (forget C)
X Y : C
f : X ⟶ Y
i : IsIso ((forget₂ C D).map f)
i' : IsIso ((forget D).map ((forget₂ C D).map f))
this : IsIso ((forget C).map f)
⊢ IsIso f

Next tactic:
apply isIso_of_reflects_iso f (forget C)
theorem I_isProper : IsProper IF.I := by
  

Proof state:
P : Type u_1
inst✝ : Preorder P
IF : PrimePair P
⊢ IsProper IF.I

Next tactic:
cases' IF.F.nonempty with w h
theorem I_isProper : IsProper IF.I := by
  cases' IF.F.nonempty with w h
  

Proof state:
case intro
P : Type u_1
inst✝ : Preorder P
IF : PrimePair P
w : P
h : w ∈ ↑IF.F
⊢ IsProper IF.I

Next tactic:
apply isProper_of_not_mem (_ : w ∉ IF.I)
theorem I_isProper : IsProper IF.I := by
  cases' IF.F.nonempty with w h
  apply isProper_of_not_mem (_ : w ∉ IF.I)
  

Proof state:
P : Type u_1
inst✝ : Preorder P
IF : PrimePair P
w : P
h : w ∈ ↑IF.F
⊢ w ∉ IF.I

Next tactic:
rwa [← IF.compl_I_eq_F] at h
theorem PrimePair.I_isPrime (IF : PrimePair P) : IsPrime IF.I :=
  { IF.I_isProper with
    compl_filter := by
      

Proof state:
P : Type u_1
inst✝ : Preorder P
IF : PrimePair P
src✝ : IsProper IF.I := I_isProper IF
⊢ IsPFilter (↑IF.I)ᶜ

Next tactic:
rw [IF.compl_I_eq_F]
theorem PrimePair.I_isPrime (IF : PrimePair P) : IsPrime IF.I :=
  { IF.I_isProper with
    compl_filter := by
      rw [IF.compl_I_eq_F]
      

Proof state:
P : Type u_1
inst✝ : Preorder P
IF : PrimePair P
src✝ : IsProper IF.I := I_isProper IF
⊢ IsPFilter ↑IF.F

Next tactic:
exact IF.F.isPFilter
theorem IsPrime.mem_or_mem (hI : IsPrime I) {x y : P} : x ⊓ y ∈ I → x ∈ I ∨ y ∈ I := by
  

Proof state:
P : Type u_1
inst✝ : SemilatticeInf P
x✝ y✝ : P
I : Ideal P
hI : IsPrime I
x y : P
⊢ x ⊓ y ∈ I → x ∈ I ∨ y ∈ I

Next tactic:
contrapose!
theorem IsPrime.mem_or_mem (hI : IsPrime I) {x y : P} : x ⊓ y ∈ I → x ∈ I ∨ y ∈ I := by
  contrapose!
  

Proof state:
P : Type u_1
inst✝ : SemilatticeInf P
x✝ y✝ : P
I : Ideal P
hI : IsPrime I
x y : P
⊢ x ∉ I ∧ y ∉ I → x ⊓ y ∉ I

Next tactic:
let F := hI.compl_filter.toPFilter
theorem IsPrime.mem_or_mem (hI : IsPrime I) {x y : P} : x ⊓ y ∈ I → x ∈ I ∨ y ∈ I := by
  contrapose!
  let F := hI.compl_filter.toPFilter
  

Proof state:
P : Type u_1
inst✝ : SemilatticeInf P
x✝ y✝ : P
I : Ideal P
hI : IsPrime I
x y : P
F : PFilter P := IsPFilter.toPFilter (_ : IsPFilter (↑I)ᶜ)
⊢ x ∉ I ∧ y ∉ I → x ⊓ y ∉ I

Next tactic:
show x ∈ F ∧ y ∈ F → x ⊓ y ∈ F
theorem IsPrime.mem_or_mem (hI : IsPrime I) {x y : P} : x ⊓ y ∈ I → x ∈ I ∨ y ∈ I := by
  contrapose!
  let F := hI.compl_filter.toPFilter
  show x ∈ F ∧ y ∈ F → x ⊓ y ∈ F
  

Proof state:
P : Type u_1
inst✝ : SemilatticeInf P
x✝ y✝ : P
I : Ideal P
hI : IsPrime I
x y : P
F : PFilter P := IsPFilter.toPFilter (_ : IsPFilter (↑I)ᶜ)
⊢ x ∈ F ∧ y ∈ F → x ⊓ y ∈ F

Next tactic:
exact fun h => inf_mem h.1 h.2
theorem IsPrime.of_mem_or_mem [IsProper I] (hI : ∀ {x y : P}, x ⊓ y ∈ I → x ∈ I ∨ y ∈ I) :
    IsPrime I := by
  

Proof state:
P : Type u_1
inst✝¹ : SemilatticeInf P
x y : P
I : Ideal P
inst✝ : IsProper I
hI : ∀ {x y : P}, x ⊓ y ∈ I → x ∈ I ∨ y ∈ I
⊢ IsPrime I

Next tactic:
rw [IsPrime_iff]
theorem IsPrime.of_mem_or_mem [IsProper I] (hI : ∀ {x y : P}, x ⊓ y ∈ I → x ∈ I ∨ y ∈ I) :
    IsPrime I := by
  rw [IsPrime_iff]
  

Proof state:
P : Type u_1
inst✝¹ : SemilatticeInf P
x y : P
I : Ideal P
inst✝ : IsProper I
hI : ∀ {x y : P}, x ⊓ y ∈ I → x ∈ I ∨ y ∈ I
⊢ IsProper I ∧ IsPFilter (↑I)ᶜ

Next tactic:
use ‹_›
theorem IsPrime.of_mem_or_mem [IsProper I] (hI : ∀ {x y : P}, x ⊓ y ∈ I → x ∈ I ∨ y ∈ I) :
    IsPrime I := by
  rw [IsPrime_iff]
  use ‹_›
  

Proof state:
case right
P : Type u_1
inst✝¹ : SemilatticeInf P
x y : P
I : Ideal P
inst✝ : IsProper I
hI : ∀ {x y : P}, x ⊓ y ∈ I → x ∈ I ∨ y ∈ I
⊢ IsPFilter (↑I)ᶜ

Next tactic:
refine .of_def ?_ ?_ ?_
theorem IsPrime.of_mem_or_mem [IsProper I] (hI : ∀ {x y : P}, x ⊓ y ∈ I → x ∈ I ∨ y ∈ I) :
    IsPrime I := by
  rw [IsPrime_iff]
  use ‹_›
  refine .of_def ?_ ?_ ?_
  · 

Proof state:
case right.refine_1
P : Type u_1
inst✝¹ : SemilatticeInf P
x y : P
I : Ideal P
inst✝ : IsProper I
hI : ∀ {x y : P}, x ⊓ y ∈ I → x ∈ I ∨ y ∈ I
⊢ Set.Nonempty (↑I)ᶜ

Next tactic:
exact Set.nonempty_compl.2 (I.IsProper_iff.1 ‹_›)
theorem IsPrime.of_mem_or_mem [IsProper I] (hI : ∀ {x y : P}, x ⊓ y ∈ I → x ∈ I ∨ y ∈ I) :
    IsPrime I := by
  rw [IsPrime_iff]
  use ‹_›
  refine .of_def ?_ ?_ ?_
  · exact Set.nonempty_compl.2 (I.IsProper_iff.1 ‹_›)
  · 

Proof state:
case right.refine_2
P : Type u_1
inst✝¹ : SemilatticeInf P
x y : P
I : Ideal P
inst✝ : IsProper I
hI : ∀ {x y : P}, x ⊓ y ∈ I → x ∈ I ∨ y ∈ I
⊢ DirectedOn (fun x x_1 => x ≥ x_1) (↑I)ᶜ

Next tactic:
intro x hx y hy
theorem IsPrime.of_mem_or_mem [IsProper I] (hI : ∀ {x y : P}, x ⊓ y ∈ I → x ∈ I ∨ y ∈ I) :
    IsPrime I := by
  rw [IsPrime_iff]
  use ‹_›
  refine .of_def ?_ ?_ ?_
  · exact Set.nonempty_compl.2 (I.IsProper_iff.1 ‹_›)
  · intro x hx y hy
    

Proof state:
case right.refine_2
P : Type u_1
inst✝¹ : SemilatticeInf P
x✝ y✝ : P
I : Ideal P
inst✝ : IsProper I
hI : ∀ {x y : P}, x ⊓ y ∈ I → x ∈ I ∨ y ∈ I
x : P
hx : x ∈ (↑I)ᶜ
y : P
hy : y ∈ (↑I)ᶜ
⊢ ∃ z ∈ (↑I)ᶜ, (fun x x_1 => x ≥ x_1) x z ∧ (fun x x_1 => x ≥ x_1) y z

Next tactic:
exact ⟨x ⊓ y, fun h => (hI h).elim hx hy, inf_le_left, inf_le_right⟩