l3lab/ntp-mathlib huggingface dataset:
/-- The loop space at x carries a structure of an H-space. Note that the field `eHmul`
(resp. `hmulE`) neither implies nor is implied by `Path.Homotopy.reflTrans`
(resp. `Path.Homotopy.transRefl`).
-/
instance (x : X) : HSpace (Path x x) where
  hmul := ⟨fun ρ => ρ.1.trans ρ.2, continuous_trans⟩
  e := refl x
  hmul_e_e := refl_trans_refl
  eHmul :=
    { toHomotopy :=
        ⟨⟨fun p : I × Path x x ↦ delayReflLeft p.1 p.2, continuous_delayReflLeft⟩,
          delayReflLeft_zero, delayReflLeft_one⟩
      prop' := by 

Proof state:
X : Type u
inst✝ : TopologicalSpace X
x✝ y x : X
⊢ ∀ (t : ↑I),
    ∀ x_1 ∈ {refl x},
      (ContinuousMap.mk fun x_2 =>
            ContinuousMap.toFun
              { toContinuousMap := ContinuousMap.mk fun p => delayReflLeft p.1 p.2,
                  map_zero_left := (_ : ∀ (γ : Path x x), delayReflLeft 0 γ = trans (refl x) γ),
                  map_one_left := (_ : ∀ (γ : Path x x), delayReflLeft 1 γ = γ) }.toContinuousMap
              (t, x_2))
          x_1 =
        (comp (ContinuousMap.mk fun ρ => trans ρ.1 ρ.2)
            (prodMk (const (Path x x) (refl x)) (ContinuousMap.id (Path x x))))
          x_1

Next tactic:
rintro t _ rfl
/-- The loop space at x carries a structure of an H-space. Note that the field `eHmul`
(resp. `hmulE`) neither implies nor is implied by `Path.Homotopy.reflTrans`
(resp. `Path.Homotopy.transRefl`).
-/
instance (x : X) : HSpace (Path x x) where
  hmul := ⟨fun ρ => ρ.1.trans ρ.2, continuous_trans⟩
  e := refl x
  hmul_e_e := refl_trans_refl
  eHmul :=
    { toHomotopy :=
        ⟨⟨fun p : I × Path x x ↦ delayReflLeft p.1 p.2, continuous_delayReflLeft⟩,
          delayReflLeft_zero, delayReflLeft_one⟩
      prop' := by rintro t _ rfl; 

Proof state:
X : Type u
inst✝ : TopologicalSpace X
x✝ y x : X
t : ↑I
⊢ (ContinuousMap.mk fun x_1 =>
        ContinuousMap.toFun
          { toContinuousMap := ContinuousMap.mk fun p => delayReflLeft p.1 p.2,
              map_zero_left := (_ : ∀ (γ : Path x x), delayReflLeft 0 γ = trans (refl x) γ),
              map_one_left := (_ : ∀ (γ : Path x x), delayReflLeft 1 γ = γ) }.toContinuousMap
          (t, x_1))
      (refl x) =
    (comp (ContinuousMap.mk fun ρ => trans ρ.1 ρ.2) (prodMk (const (Path x x) (refl x)) (ContinuousMap.id (Path x x))))
      (refl x)

Next tactic:
exact refl_trans_refl.symm
/-- The loop space at x carries a structure of an H-space. Note that the field `eHmul`
(resp. `hmulE`) neither implies nor is implied by `Path.Homotopy.reflTrans`
(resp. `Path.Homotopy.transRefl`).
-/
instance (x : X) : HSpace (Path x x) where
  hmul := ⟨fun ρ => ρ.1.trans ρ.2, continuous_trans⟩
  e := refl x
  hmul_e_e := refl_trans_refl
  eHmul :=
    { toHomotopy :=
        ⟨⟨fun p : I × Path x x ↦ delayReflLeft p.1 p.2, continuous_delayReflLeft⟩,
          delayReflLeft_zero, delayReflLeft_one⟩
      prop' := by rintro t _ rfl; exact refl_trans_refl.symm }
  hmulE :=
    { toHomotopy :=
        ⟨⟨fun p : I × Path x x ↦ delayReflRight p.1 p.2, continuous_delayReflRight⟩,
          delayReflRight_zero, delayReflRight_one⟩
      prop' := by 

Proof state:
X : Type u
inst✝ : TopologicalSpace X
x✝ y x : X
⊢ ∀ (t : ↑I),
    ∀ x_1 ∈ {refl x},
      (ContinuousMap.mk fun x_2 =>
            ContinuousMap.toFun
              { toContinuousMap := ContinuousMap.mk fun p => delayReflRight p.1 p.2,
                  map_zero_left := (_ : ∀ (γ : Path x x), delayReflRight 0 γ = trans γ (refl x)),
                  map_one_left := (_ : ∀ (γ : Path x x), delayReflRight 1 γ = γ) }.toContinuousMap
              (t, x_2))
          x_1 =
        (comp (ContinuousMap.mk fun ρ => trans ρ.1 ρ.2)
            (prodMk (ContinuousMap.id (Path x x)) (const (Path x x) (refl x))))
          x_1

Next tactic:
rintro t _ rfl
/-- The loop space at x carries a structure of an H-space. Note that the field `eHmul`
(resp. `hmulE`) neither implies nor is implied by `Path.Homotopy.reflTrans`
(resp. `Path.Homotopy.transRefl`).
-/
instance (x : X) : HSpace (Path x x) where
  hmul := ⟨fun ρ => ρ.1.trans ρ.2, continuous_trans⟩
  e := refl x
  hmul_e_e := refl_trans_refl
  eHmul :=
    { toHomotopy :=
        ⟨⟨fun p : I × Path x x ↦ delayReflLeft p.1 p.2, continuous_delayReflLeft⟩,
          delayReflLeft_zero, delayReflLeft_one⟩
      prop' := by rintro t _ rfl; exact refl_trans_refl.symm }
  hmulE :=
    { toHomotopy :=
        ⟨⟨fun p : I × Path x x ↦ delayReflRight p.1 p.2, continuous_delayReflRight⟩,
          delayReflRight_zero, delayReflRight_one⟩
      prop' := by rintro t _ rfl; 

Proof state:
X : Type u
inst✝ : TopologicalSpace X
x✝ y x : X
t : ↑I
⊢ (ContinuousMap.mk fun x_1 =>
        ContinuousMap.toFun
          { toContinuousMap := ContinuousMap.mk fun p => delayReflRight p.1 p.2,
              map_zero_left := (_ : ∀ (γ : Path x x), delayReflRight 0 γ = trans γ (refl x)),
              map_one_left := (_ : ∀ (γ : Path x x), delayReflRight 1 γ = γ) }.toContinuousMap
          (t, x_1))
      (refl x) =
    (comp (ContinuousMap.mk fun ρ => trans ρ.1 ρ.2) (prodMk (ContinuousMap.id (Path x x)) (const (Path x x) (refl x))))
      (refl x)

Next tactic:
exact refl_trans_refl.symm
/-- A self-adjoint operator preserves orthogonal complements of its eigenspaces. -/
theorem invariant_orthogonalComplement_eigenspace (μ : 𝕜) (v : E) (hv : v ∈ (eigenspace T μ)ᗮ) :
    T v ∈ (eigenspace T μ)ᗮ := by
  

Proof state:
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
μ : 𝕜
v : E
hv : v ∈ (eigenspace T μ)ᗮ
⊢ T v ∈ (eigenspace T μ)ᗮ

Next tactic:
intro w hw
/-- A self-adjoint operator preserves orthogonal complements of its eigenspaces. -/
theorem invariant_orthogonalComplement_eigenspace (μ : 𝕜) (v : E) (hv : v ∈ (eigenspace T μ)ᗮ) :
    T v ∈ (eigenspace T μ)ᗮ := by
  intro w hw
  

Proof state:
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
μ : 𝕜
v : E
hv : v ∈ (eigenspace T μ)ᗮ
w : E
hw : w ∈ eigenspace T μ
⊢ inner w (T v) = 0

Next tactic:
have : T w = (μ : 𝕜) • w := by rwa [mem_eigenspace_iff] at hw
/-- A self-adjoint operator preserves orthogonal complements of its eigenspaces. -/
theorem invariant_orthogonalComplement_eigenspace (μ : 𝕜) (v : E) (hv : v ∈ (eigenspace T μ)ᗮ) :
    T v ∈ (eigenspace T μ)ᗮ := by
  intro w hw
  have : T w = (μ : 𝕜) • w := by 

Proof state:
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
μ : 𝕜
v : E
hv : v ∈ (eigenspace T μ)ᗮ
w : E
hw : w ∈ eigenspace T μ
⊢ T w = μ • w

Next tactic:
rwa [mem_eigenspace_iff] at hw
/-- A self-adjoint operator preserves orthogonal complements of its eigenspaces. -/
theorem invariant_orthogonalComplement_eigenspace (μ : 𝕜) (v : E) (hv : v ∈ (eigenspace T μ)ᗮ) :
    T v ∈ (eigenspace T μ)ᗮ := by
  intro w hw
  have : T w = (μ : 𝕜) • w := by rwa [mem_eigenspace_iff] at hw
  

Proof state:
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
μ : 𝕜
v : E
hv : v ∈ (eigenspace T μ)ᗮ
w : E
hw : w ∈ eigenspace T μ
this : T w = μ • w
⊢ inner w (T v) = 0

Next tactic:
simp [← hT w, this, inner_smul_left, hv w hw]
/-- The eigenvalues of a self-adjoint operator are real. -/
theorem conj_eigenvalue_eq_self {μ : 𝕜} (hμ : HasEigenvalue T μ) : conj μ = μ := by
  

Proof state:
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
μ : 𝕜
hμ : HasEigenvalue T μ
⊢ (starRingEnd 𝕜) μ = μ

Next tactic:
obtain ⟨v, hv₁, hv₂⟩ := hμ.exists_hasEigenvector
/-- The eigenvalues of a self-adjoint operator are real. -/
theorem conj_eigenvalue_eq_self {μ : 𝕜} (hμ : HasEigenvalue T μ) : conj μ = μ := by
  obtain ⟨v, hv₁, hv₂⟩ := hμ.exists_hasEigenvector
  

Proof state:
case intro.intro
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
μ : 𝕜
hμ : HasEigenvalue T μ
v : E
hv₁ : v ∈ eigenspace T μ
hv₂ : v ≠ 0
⊢ (starRingEnd 𝕜) μ = μ

Next tactic:
rw [mem_eigenspace_iff] at hv₁
/-- The eigenvalues of a self-adjoint operator are real. -/
theorem conj_eigenvalue_eq_self {μ : 𝕜} (hμ : HasEigenvalue T μ) : conj μ = μ := by
  obtain ⟨v, hv₁, hv₂⟩ := hμ.exists_hasEigenvector
  rw [mem_eigenspace_iff] at hv₁
  

Proof state:
case intro.intro
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
μ : 𝕜
hμ : HasEigenvalue T μ
v : E
hv₁ : T v = μ • v
hv₂ : v ≠ 0
⊢ (starRingEnd 𝕜) μ = μ

Next tactic:
simpa [hv₂, inner_smul_left, inner_smul_right, hv₁] using hT v v
/-- The eigenspaces of a self-adjoint operator are mutually orthogonal. -/
theorem orthogonalFamily_eigenspaces :
    OrthogonalFamily 𝕜 (fun μ => eigenspace T μ) fun μ => (eigenspace T μ).subtypeₗᵢ := by
  

Proof state:
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
⊢ OrthogonalFamily 𝕜 (fun μ => ↥(eigenspace T μ)) fun μ => Submodule.subtypeₗᵢ (eigenspace T μ)

Next tactic:
rintro μ ν hμν ⟨v, hv⟩ ⟨w, hw⟩
/-- The eigenspaces of a self-adjoint operator are mutually orthogonal. -/
theorem orthogonalFamily_eigenspaces :
    OrthogonalFamily 𝕜 (fun μ => eigenspace T μ) fun μ => (eigenspace T μ).subtypeₗᵢ := by
  rintro μ ν hμν ⟨v, hv⟩ ⟨w, hw⟩
  

Proof state:
case mk.mk
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
μ ν : 𝕜
hμν : μ ≠ ν
v : E
hv : v ∈ eigenspace T μ
w : E
hw : w ∈ eigenspace T ν
⊢ inner (((fun μ => Submodule.subtypeₗᵢ (eigenspace T μ)) μ) { val := v, property := hv })
      (((fun μ => Submodule.subtypeₗᵢ (eigenspace T μ)) ν) { val := w, property := hw }) =
    0

Next tactic:
by_cases hv' : v = 0
/-- The eigenspaces of a self-adjoint operator are mutually orthogonal. -/
theorem orthogonalFamily_eigenspaces :
    OrthogonalFamily 𝕜 (fun μ => eigenspace T μ) fun μ => (eigenspace T μ).subtypeₗᵢ := by
  rintro μ ν hμν ⟨v, hv⟩ ⟨w, hw⟩
  by_cases hv' : v = 0
  · 

Proof state:
case pos
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
μ ν : 𝕜
hμν : μ ≠ ν
v : E
hv : v ∈ eigenspace T μ
w : E
hw : w ∈ eigenspace T ν
hv' : v = 0
⊢ inner (((fun μ => Submodule.subtypeₗᵢ (eigenspace T μ)) μ) { val := v, property := hv })
      (((fun μ => Submodule.subtypeₗᵢ (eigenspace T μ)) ν) { val := w, property := hw }) =
    0

Next tactic:
simp [hv']
/-- The eigenspaces of a self-adjoint operator are mutually orthogonal. -/
theorem orthogonalFamily_eigenspaces :
    OrthogonalFamily 𝕜 (fun μ => eigenspace T μ) fun μ => (eigenspace T μ).subtypeₗᵢ := by
  rintro μ ν hμν ⟨v, hv⟩ ⟨w, hw⟩
  by_cases hv' : v = 0
  · simp [hv']
  

Proof state:
case neg
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
μ ν : 𝕜
hμν : μ ≠ ν
v : E
hv : v ∈ eigenspace T μ
w : E
hw : w ∈ eigenspace T ν
hv' : ¬v = 0
⊢ inner (((fun μ => Submodule.subtypeₗᵢ (eigenspace T μ)) μ) { val := v, property := hv })
      (((fun μ => Submodule.subtypeₗᵢ (eigenspace T μ)) ν) { val := w, property := hw }) =
    0

Next tactic:
have H := hT.conj_eigenvalue_eq_self (hasEigenvalue_of_hasEigenvector ⟨hv, hv'⟩)
/-- The eigenspaces of a self-adjoint operator are mutually orthogonal. -/
theorem orthogonalFamily_eigenspaces :
    OrthogonalFamily 𝕜 (fun μ => eigenspace T μ) fun μ => (eigenspace T μ).subtypeₗᵢ := by
  rintro μ ν hμν ⟨v, hv⟩ ⟨w, hw⟩
  by_cases hv' : v = 0
  · simp [hv']
  have H := hT.conj_eigenvalue_eq_self (hasEigenvalue_of_hasEigenvector ⟨hv, hv'⟩)
  

Proof state:
case neg
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
μ ν : 𝕜
hμν : μ ≠ ν
v : E
hv : v ∈ eigenspace T μ
w : E
hw : w ∈ eigenspace T ν
hv' : ¬v = 0
H : (starRingEnd 𝕜) μ = μ
⊢ inner (((fun μ => Submodule.subtypeₗᵢ (eigenspace T μ)) μ) { val := v, property := hv })
      (((fun μ => Submodule.subtypeₗᵢ (eigenspace T μ)) ν) { val := w, property := hw }) =
    0

Next tactic:
rw [mem_eigenspace_iff] at hv hw
/-- The eigenspaces of a self-adjoint operator are mutually orthogonal. -/
theorem orthogonalFamily_eigenspaces :
    OrthogonalFamily 𝕜 (fun μ => eigenspace T μ) fun μ => (eigenspace T μ).subtypeₗᵢ := by
  rintro μ ν hμν ⟨v, hv⟩ ⟨w, hw⟩
  by_cases hv' : v = 0
  · simp [hv']
  have H := hT.conj_eigenvalue_eq_self (hasEigenvalue_of_hasEigenvector ⟨hv, hv'⟩)
  rw [mem_eigenspace_iff] at hv hw
  

Proof state:
case neg
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
μ ν : 𝕜
hμν : μ ≠ ν
v : E
hv✝ : v ∈ eigenspace T μ
hv : T v = μ • v
w : E
hw✝ : w ∈ eigenspace T ν
hw : T w = ν • w
hv' : ¬v = 0
H : (starRingEnd 𝕜) μ = μ
⊢ inner (((fun μ => Submodule.subtypeₗᵢ (eigenspace T μ)) μ) { val := v, property := hv✝ })
      (((fun μ => Submodule.subtypeₗᵢ (eigenspace T μ)) ν) { val := w, property := hw✝ }) =
    0

Next tactic:
refine' Or.resolve_left _ hμν.symm
/-- The eigenspaces of a self-adjoint operator are mutually orthogonal. -/
theorem orthogonalFamily_eigenspaces :
    OrthogonalFamily 𝕜 (fun μ => eigenspace T μ) fun μ => (eigenspace T μ).subtypeₗᵢ := by
  rintro μ ν hμν ⟨v, hv⟩ ⟨w, hw⟩
  by_cases hv' : v = 0
  · simp [hv']
  have H := hT.conj_eigenvalue_eq_self (hasEigenvalue_of_hasEigenvector ⟨hv, hv'⟩)
  rw [mem_eigenspace_iff] at hv hw
  refine' Or.resolve_left _ hμν.symm
  

Proof state:
case neg
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
μ ν : 𝕜
hμν : μ ≠ ν
v : E
hv✝ : v ∈ eigenspace T μ
hv : T v = μ • v
w : E
hw✝ : w ∈ eigenspace T ν
hw : T w = ν • w
hv' : ¬v = 0
H : (starRingEnd 𝕜) μ = μ
⊢ ν = μ ∨
    inner (((fun μ => Submodule.subtypeₗᵢ (eigenspace T μ)) μ) { val := v, property := hv✝ })
        (((fun μ => Submodule.subtypeₗᵢ (eigenspace T μ)) ν) { val := w, property := hw✝ }) =
      0

Next tactic:
simpa [inner_smul_left, inner_smul_right, hv, hw, H] using (hT v w).symm
/-- The mutual orthogonal complement of the eigenspaces of a self-adjoint operator on an inner
product space is an invariant subspace of the operator. -/
theorem orthogonalComplement_iSup_eigenspaces_invariant ⦃v : E⦄ (hv : v ∈ (⨆ μ, eigenspace T μ)ᗮ) :
    T v ∈ (⨆ μ, eigenspace T μ)ᗮ := by
  

Proof state:
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
v : E
hv : v ∈ (⨆ μ, eigenspace T μ)ᗮ
⊢ T v ∈ (⨆ μ, eigenspace T μ)ᗮ

Next tactic:
rw [← Submodule.iInf_orthogonal] at hv ⊢
/-- The mutual orthogonal complement of the eigenspaces of a self-adjoint operator on an inner
product space is an invariant subspace of the operator. -/
theorem orthogonalComplement_iSup_eigenspaces_invariant ⦃v : E⦄ (hv : v ∈ (⨆ μ, eigenspace T μ)ᗮ) :
    T v ∈ (⨆ μ, eigenspace T μ)ᗮ := by
  rw [← Submodule.iInf_orthogonal] at hv ⊢
  

Proof state:
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
v : E
hv : v ∈ ⨅ i, (eigenspace T i)ᗮ
⊢ T v ∈ ⨅ i, (eigenspace T i)ᗮ

Next tactic:
exact T.iInf_invariant hT.invariant_orthogonalComplement_eigenspace v hv
/-- The mutual orthogonal complement of the eigenspaces of a self-adjoint operator on an inner
product space has no eigenvalues. -/
theorem orthogonalComplement_iSup_eigenspaces (μ : 𝕜) :
    eigenspace (T.restrict hT.orthogonalComplement_iSup_eigenspaces_invariant) μ = ⊥ := by
  

Proof state:
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
μ : 𝕜
⊢ eigenspace (restrict T (_ : ∀ ⦃v : E⦄, v ∈ (⨆ μ, eigenspace T μ)ᗮ → T v ∈ (⨆ μ, eigenspace T μ)ᗮ)) μ = ⊥

Next tactic:
set p : Submodule 𝕜 E := (⨆ μ, eigenspace T μ)ᗮ
/-- The mutual orthogonal complement of the eigenspaces of a self-adjoint operator on an inner
product space has no eigenvalues. -/
theorem orthogonalComplement_iSup_eigenspaces (μ : 𝕜) :
    eigenspace (T.restrict hT.orthogonalComplement_iSup_eigenspaces_invariant) μ = ⊥ := by
  set p : Submodule 𝕜 E := (⨆ μ, eigenspace T μ)ᗮ
  

Proof state:
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
μ : 𝕜
p : Submodule 𝕜 E := (⨆ μ, eigenspace T μ)ᗮ
⊢ eigenspace (restrict T (_ : ∀ ⦃v : E⦄, v ∈ (⨆ μ, eigenspace T μ)ᗮ → T v ∈ (⨆ μ, eigenspace T μ)ᗮ)) μ = ⊥

Next tactic:
refine' eigenspace_restrict_eq_bot hT.orthogonalComplement_iSup_eigenspaces_invariant _
/-- The mutual orthogonal complement of the eigenspaces of a self-adjoint operator on an inner
product space has no eigenvalues. -/
theorem orthogonalComplement_iSup_eigenspaces (μ : 𝕜) :
    eigenspace (T.restrict hT.orthogonalComplement_iSup_eigenspaces_invariant) μ = ⊥ := by
  set p : Submodule 𝕜 E := (⨆ μ, eigenspace T μ)ᗮ
  refine' eigenspace_restrict_eq_bot hT.orthogonalComplement_iSup_eigenspaces_invariant _
  

Proof state:
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
μ : 𝕜
p : Submodule 𝕜 E := (⨆ μ, eigenspace T μ)ᗮ
⊢ Disjoint (eigenspace T μ) (⨆ μ, eigenspace T μ)ᗮ

Next tactic:
have H₂ : eigenspace T μ ⟂ p := (Submodule.isOrtho_orthogonal_right _).mono_left (le_iSup _ _)
/-- The mutual orthogonal complement of the eigenspaces of a self-adjoint operator on an inner
product space has no eigenvalues. -/
theorem orthogonalComplement_iSup_eigenspaces (μ : 𝕜) :
    eigenspace (T.restrict hT.orthogonalComplement_iSup_eigenspaces_invariant) μ = ⊥ := by
  set p : Submodule 𝕜 E := (⨆ μ, eigenspace T μ)ᗮ
  refine' eigenspace_restrict_eq_bot hT.orthogonalComplement_iSup_eigenspaces_invariant _
  have H₂ : eigenspace T μ ⟂ p := (Submodule.isOrtho_orthogonal_right _).mono_left (le_iSup _ _)
  

Proof state:
𝕜 : Type u_1
inst✝² : IsROrC 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
μ : 𝕜
p : Submodule 𝕜 E := (⨆ μ, eigenspace T μ)ᗮ
H₂ : eigenspace T μ ⟂ p
⊢ Disjoint (eigenspace T μ) (⨆ μ, eigenspace T μ)ᗮ

Next tactic:
exact H₂.disjoint
/-- The mutual orthogonal complement of the eigenspaces of a self-adjoint operator on a
finite-dimensional inner product space is trivial. -/
theorem orthogonalComplement_iSup_eigenspaces_eq_bot : (⨆ μ, eigenspace T μ)ᗮ = ⊥ := by
  

Proof state:
𝕜 : Type u_1
inst✝³ : IsROrC 𝕜
E : Type u_2
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
inst✝ : FiniteDimensional 𝕜 E
⊢ (⨆ μ, eigenspace T μ)ᗮ = ⊥

Next tactic:
have hT' : IsSymmetric _ :=
    hT.restrict_invariant hT.orthogonalComplement_iSup_eigenspaces_invariant
/-- The mutual orthogonal complement of the eigenspaces of a self-adjoint operator on a
finite-dimensional inner product space is trivial. -/
theorem orthogonalComplement_iSup_eigenspaces_eq_bot : (⨆ μ, eigenspace T μ)ᗮ = ⊥ := by
  have hT' : IsSymmetric _ :=
    hT.restrict_invariant hT.orthogonalComplement_iSup_eigenspaces_invariant
  -- a self-adjoint operator on a nontrivial inner product space has an eigenvalue
  

Proof state:
𝕜 : Type u_1
inst✝³ : IsROrC 𝕜
E : Type u_2
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
inst✝ : FiniteDimensional 𝕜 E
hT' : IsSymmetric (restrict T (_ : ∀ ⦃v : E⦄, v ∈ (⨆ μ, eigenspace T μ)ᗮ → T v ∈ (⨆ μ, eigenspace T μ)ᗮ))
⊢ (⨆ μ, eigenspace T μ)ᗮ = ⊥

Next tactic:
haveI :=
    hT'.subsingleton_of_no_eigenvalue_finiteDimensional hT.orthogonalComplement_iSup_eigenspaces
/-- The mutual orthogonal complement of the eigenspaces of a self-adjoint operator on a
finite-dimensional inner product space is trivial. -/
theorem orthogonalComplement_iSup_eigenspaces_eq_bot : (⨆ μ, eigenspace T μ)ᗮ = ⊥ := by
  have hT' : IsSymmetric _ :=
    hT.restrict_invariant hT.orthogonalComplement_iSup_eigenspaces_invariant
  -- a self-adjoint operator on a nontrivial inner product space has an eigenvalue
  haveI :=
    hT'.subsingleton_of_no_eigenvalue_finiteDimensional hT.orthogonalComplement_iSup_eigenspaces
  

Proof state:
𝕜 : Type u_1
inst✝³ : IsROrC 𝕜
E : Type u_2
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
inst✝ : FiniteDimensional 𝕜 E
hT' : IsSymmetric (restrict T (_ : ∀ ⦃v : E⦄, v ∈ (⨆ μ, eigenspace T μ)ᗮ → T v ∈ (⨆ μ, eigenspace T μ)ᗮ))
this : Subsingleton ↥(⨆ μ, eigenspace T μ)ᗮ
⊢ (⨆ μ, eigenspace T μ)ᗮ = ⊥

Next tactic:
exact Submodule.eq_bot_of_subsingleton
theorem orthogonalComplement_iSup_eigenspaces_eq_bot' :
    (⨆ μ : Eigenvalues T, eigenspace T μ)ᗮ = ⊥ :=
  show (⨆ μ : { μ // eigenspace T μ ≠ ⊥ }, eigenspace T μ)ᗮ = ⊥ by
    

Proof state:
𝕜 : Type u_1
inst✝³ : IsROrC 𝕜
E : Type u_2
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
inst✝ : FiniteDimensional 𝕜 E
⊢ (⨆ μ, eigenspace T ↑μ)ᗮ = ⊥

Next tactic:
rw [iSup_ne_bot_subtype, hT.orthogonalComplement_iSup_eigenspaces_eq_bot]
/-- The eigenspaces of a self-adjoint operator on a finite-dimensional inner product space `E` gives
an internal direct sum decomposition of `E`.

Note this takes `hT` as a `Fact` to allow it to be an instance. -/
noncomputable instance directSumDecomposition [hT : Fact T.IsSymmetric] :
    DirectSum.Decomposition fun μ : Eigenvalues T => eigenspace T μ :=
  haveI h : ∀ μ : Eigenvalues T, CompleteSpace (eigenspace T μ) := fun μ => by 

Proof state:
𝕜 : Type u_1
inst✝³ : IsROrC 𝕜
E : Type u_2
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT✝ : IsSymmetric T
inst✝ : FiniteDimensional 𝕜 E
hT : Fact (IsSymmetric T)
μ : Eigenvalues T
⊢ CompleteSpace ↥(eigenspace T (↑T μ))

Next tactic:
infer_instance
/-- *Diagonalization theorem*, *spectral theorem*; version 1: A self-adjoint operator `T` on a
finite-dimensional inner product space `E` acts diagonally on the decomposition of `E` into the
direct sum of the eigenspaces of `T`. -/
theorem diagonalization_apply_self_apply (v : E) (μ : Eigenvalues T) :
    hT.diagonalization (T v) μ = (μ : 𝕜) • hT.diagonalization v μ := by
  

Proof state:
𝕜 : Type u_1
inst✝³ : IsROrC 𝕜
E : Type u_2
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
inst✝ : FiniteDimensional 𝕜 E
v : E
μ : Eigenvalues T
⊢ (diagonalization hT) (T v) μ = ↑T μ • (diagonalization hT) v μ

Next tactic:
suffices
    ∀ w : PiLp 2 fun μ : Eigenvalues T => eigenspace T μ,
      T (hT.diagonalization.symm w) = hT.diagonalization.symm fun μ => (μ : 𝕜) • w μ by
    simpa only [LinearIsometryEquiv.symm_apply_apply, LinearIsometryEquiv.apply_symm_apply] using
      congr_arg (fun w => hT.diagonalization w μ) (this (hT.diagonalization v))
/-- *Diagonalization theorem*, *spectral theorem*; version 1: A self-adjoint operator `T` on a
finite-dimensional inner product space `E` acts diagonally on the decomposition of `E` into the
direct sum of the eigenspaces of `T`. -/
theorem diagonalization_apply_self_apply (v : E) (μ : Eigenvalues T) :
    hT.diagonalization (T v) μ = (μ : 𝕜) • hT.diagonalization v μ := by
  suffices
    ∀ w : PiLp 2 fun μ : Eigenvalues T => eigenspace T μ,
      T (hT.diagonalization.symm w) = hT.diagonalization.symm fun μ => (μ : 𝕜) • w μ by
    

Proof state:
𝕜 : Type u_1
inst✝³ : IsROrC 𝕜
E : Type u_2
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace 𝕜 E
T : E →ₗ[𝕜] E
hT : IsSymmetric T
inst✝ : FiniteDimensional 𝕜 E
v : E
μ : Eigenvalues T
this :
  ∀ (w : PiLp 2 fun μ => ↥(eigenspace T (↑T μ))),
    T ((LinearIsometryEquiv.symm (diagonalization hT)) w) =
      (LinearIsometryEquiv.symm (diagonalization hT)) fun μ => ↑T μ • w μ
⊢ (diagonalization hT) (T v) μ = ↑T μ • (diagonalization hT) v μ

Next tactic:
simpa only [LinearIsometryEquiv.symm_apply_apply, LinearIsometryEquiv.apply_symm_apply] using
      congr_arg (fun w => hT.diagonalization w μ) (this (hT.diagonalization v))