-- Mathlib/LinearAlgebra/Eigenspace/Zero.lean
lemma hasEigenvalue_zero_tfae (φ : Module.End K M) :
    List.TFAE [
      Module.End.HasEigenvalue φ 0,
      IsRoot (minpoly K φ) 0,
      constantCoeff φ.charpoly = 0,
      LinearMap.det φ = 0,
      ⊥ < ker φ,
      ∃ (m : M), m ≠ 0 ∧ φ m = 0 ]

Proof state:
case intro
K : Type u_2
M : Type u_3
inst✝³ : Field K
inst✝² : AddCommGroup M
inst✝¹ : Module K M
inst✝ : Module.Finite K M
φ : End K M
tfae_1_iff_2 : φ.HasEigenvalue 0 ↔ (minpoly K φ).IsRoot 0
F : K[X]
hF : charpoly φ = minpoly K φ * F
h : eval 0 (minpoly K φ) = 0
⊢ eval 0 (minpoly K φ) * eval 0 F = 0

Tactic:
rw [h, zero_mul]

Result:
no goals

Proof state:
K : Type u_2
M : Type u_3
inst✝³ : Field K
inst✝² : AddCommGroup M
inst✝¹ : Module K M
inst✝ : Module.Finite K M
φ : End K M
tfae_1_iff_2 : φ.HasEigenvalue 0 ↔ (minpoly K φ).IsRoot 0
tfae_2_to_3 : (minpoly K φ).IsRoot 0 → constantCoeff (charpoly φ) = 0
h : ((toMatrix (chooseBasis K M) (chooseBasis K M)) φ).charpoly.coeff 0 = 0
⊢ (-1) ^ Fintype.card (ChooseBasisIndex K M) * ((toMatrix (chooseBasis K M) (chooseBasis K M)) φ).charpoly.coeff 0 = 0

Tactic:
rw [h, mul_zero]

Result:
no goals

Proof state:
K : Type u_2
M : Type u_3
inst✝³ : Field K
inst✝² : AddCommGroup M
inst✝¹ : Module K M
inst✝ : Module.Finite K M
φ : End K M
tfae_1_iff_2 : φ.HasEigenvalue 0 ↔ (minpoly K φ).IsRoot 0
tfae_2_to_3 : (minpoly K φ).IsRoot 0 → constantCoeff (charpoly φ) = 0
⊢ [φ.HasEigenvalue 0, (minpoly K φ).IsRoot 0, constantCoeff (charpoly φ) = 0, LinearMap.det φ = 0, ⊥ < ker φ,
      ∃ m, m ≠ 0 ∧ φ m = 0].TFAE

Tactic:
tfae_have 3 → 4 := by
  rw [← LinearMap.det_toMatrix (chooseBasis K M), Matrix.det_eq_sign_charpoly_coeff,
    constantCoeff_apply, charpoly]
  intro h; rw [h, mul_zero]

Result:
K : Type u_2
M : Type u_3
inst✝³ : Field K
inst✝² : AddCommGroup M
inst✝¹ : Module K M
inst✝ : Module.Finite K M
φ : End K M
tfae_1_iff_2 : φ.HasEigenvalue 0 ↔ (minpoly K φ).IsRoot 0
tfae_2_to_3 : (minpoly K φ).IsRoot 0 → constantCoeff (charpoly φ) = 0
tfae_3_to_4 : constantCoeff (charpoly φ) = 0 → LinearMap.det φ = 0
⊢ [φ.HasEigenvalue 0, (minpoly K φ).IsRoot 0, constantCoeff (charpoly φ) = 0, LinearMap.det φ = 0, ⊥ < ker φ,
      ∃ m, m ≠ 0 ∧ φ m = 0].TFAE

Proof state:
K : Type u_2
M : Type u_3
inst✝³ : Field K
inst✝² : AddCommGroup M
inst✝¹ : Module K M
inst✝ : Module.Finite K M
φ : End K M
tfae_1_iff_2 : φ.HasEigenvalue 0 ↔ (minpoly K φ).IsRoot 0
tfae_2_to_3 : (minpoly K φ).IsRoot 0 → constantCoeff (charpoly φ) = 0
tfae_3_to_4 : constantCoeff (charpoly φ) = 0 → LinearMap.det φ = 0
tfae_4_to_5 : LinearMap.det φ = 0 → ⊥ < ker φ
tfae_5_to_6 : ⊥ < ker φ → ∃ m, m ≠ 0 ∧ φ m = 0
x : M
h1 : x ≠ 0
h2 : φ x = 0
⊢ φ.HasEigenvalue 0

Tactic:
apply Module.End.hasEigenvalue_of_hasEigenvector ⟨_, h1⟩

Result:
K : Type u_2
M : Type u_3
inst✝³ : Field K
inst✝² : AddCommGroup M
inst✝¹ : Module K M
inst✝ : Module.Finite K M
φ : End K M
tfae_1_iff_2 : φ.HasEigenvalue 0 ↔ (minpoly K φ).IsRoot 0
tfae_2_to_3 : (minpoly K φ).IsRoot 0 → constantCoeff (charpoly φ) = 0
tfae_3_to_4 : constantCoeff (charpoly φ) = 0 → LinearMap.det φ = 0
tfae_4_to_5 : LinearMap.det φ = 0 → ⊥ < ker φ
tfae_5_to_6 : ⊥ < ker φ → ∃ m, m ≠ 0 ∧ φ m = 0
x : M
h1 : x ≠ 0
h2 : φ x = 0
⊢ x ∈ (φ.genEigenspace 0) 1

Proof state:
K : Type u_2
M : Type u_3
inst✝³ : Field K
inst✝² : AddCommGroup M
inst✝¹ : Module K M
inst✝ : Module.Finite K M
φ : End K M
tfae_1_iff_2 : φ.HasEigenvalue 0 ↔ (minpoly K φ).IsRoot 0
⊢ [φ.HasEigenvalue 0, (minpoly K φ).IsRoot 0, constantCoeff (charpoly φ) = 0, LinearMap.det φ = 0, ⊥ < ker φ,
      ∃ m, m ≠ 0 ∧ φ m = 0].TFAE

Tactic:
tfae_have 2 → 3 := by
  obtain ⟨F, hF⟩ := minpoly_dvd_charpoly φ
  simp only [IsRoot.def, constantCoeff_apply, coeff_zero_eq_eval_zero, hF, eval_mul]
  intro h; rw [h, zero_mul]

Result:
K : Type u_2
M : Type u_3
inst✝³ : Field K
inst✝² : AddCommGroup M
inst✝¹ : Module K M
inst✝ : Module.Finite K M
φ : End K M
tfae_1_iff_2 : φ.HasEigenvalue 0 ↔ (minpoly K φ).IsRoot 0
tfae_2_to_3 : (minpoly K φ).IsRoot 0 → constantCoeff (charpoly φ) = 0
⊢ [φ.HasEigenvalue 0, (minpoly K φ).IsRoot 0, constantCoeff (charpoly φ) = 0, LinearMap.det φ = 0, ⊥ < ker φ,
      ∃ m, m ≠ 0 ∧ φ m = 0].TFAE

Proof state:
K : Type u_2
M : Type u_3
inst✝³ : Field K
inst✝² : AddCommGroup M
inst✝¹ : Module K M
inst✝ : Module.Finite K M
φ : End K M
tfae_1_iff_2 : φ.HasEigenvalue 0 ↔ (minpoly K φ).IsRoot 0
tfae_2_to_3 : (minpoly K φ).IsRoot 0 → constantCoeff (charpoly φ) = 0
tfae_3_to_4 : constantCoeff (charpoly φ) = 0 → LinearMap.det φ = 0
⊢ [φ.HasEigenvalue 0, (minpoly K φ).IsRoot 0, constantCoeff (charpoly φ) = 0, LinearMap.det φ = 0, ⊥ < ker φ,
      ∃ m, m ≠ 0 ∧ φ m = 0].TFAE

Tactic:
tfae_have 4 → 5 := bot_lt_ker_of_det_eq_zero

Result:
K : Type u_2
M : Type u_3
inst✝³ : Field K
inst✝² : AddCommGroup M
inst✝¹ : Module K M
inst✝ : Module.Finite K M
φ : End K M
tfae_1_iff_2 : φ.HasEigenvalue 0 ↔ (minpoly K φ).IsRoot 0
tfae_2_to_3 : (minpoly K φ).IsRoot 0 → constantCoeff (charpoly φ) = 0
tfae_3_to_4 : constantCoeff (charpoly φ) = 0 → LinearMap.det φ = 0
tfae_4_to_5 : LinearMap.det φ = 0 → ⊥ < ker φ
⊢ [φ.HasEigenvalue 0, (minpoly K φ).IsRoot 0, constantCoeff (charpoly φ) = 0, LinearMap.det φ = 0, ⊥ < ker φ,
      ∃ m, m ≠ 0 ∧ φ m = 0].TFAE

Proof state:
case intro
K : Type u_2
M : Type u_3
inst✝³ : Field K
inst✝² : AddCommGroup M
inst✝¹ : Module K M
inst✝ : Module.Finite K M
φ : End K M
tfae_1_iff_2 : φ.HasEigenvalue 0 ↔ (minpoly K φ).IsRoot 0
F : K[X]
hF : charpoly φ = minpoly K φ * F
⊢ (minpoly K φ).IsRoot 0 → constantCoeff (charpoly φ) = 0

Tactic:
simp only [IsRoot.def, constantCoeff_apply, coeff_zero_eq_eval_zero, hF, eval_mul]

Result:
case intro
K : Type u_2
M : Type u_3
inst✝³ : Field K
inst✝² : AddCommGroup M
inst✝¹ : Module K M
inst✝ : Module.Finite K M
φ : End K M
tfae_1_iff_2 : φ.HasEigenvalue 0 ↔ (minpoly K φ).IsRoot 0
F : K[X]
hF : charpoly φ = minpoly K φ * F
⊢ eval 0 (minpoly K φ) = 0 → eval 0 (minpoly K φ) * eval 0 F = 0

Proof state:
K : Type u_2
M : Type u_3
inst✝³ : Field K
inst✝² : AddCommGroup M
inst✝¹ : Module K M
inst✝ : Module.Finite K M
φ : End K M
tfae_1_iff_2 : φ.HasEigenvalue 0 ↔ (minpoly K φ).IsRoot 0
tfae_2_to_3 : (minpoly K φ).IsRoot 0 → constantCoeff (charpoly φ) = 0
tfae_3_to_4 : constantCoeff (charpoly φ) = 0 → LinearMap.det φ = 0
tfae_4_to_5 : LinearMap.det φ = 0 → ⊥ < ker φ
tfae_5_to_6 : ⊥ < ker φ → ∃ m, m ≠ 0 ∧ φ m = 0
⊢ [φ.HasEigenvalue 0, (minpoly K φ).IsRoot 0, constantCoeff (charpoly φ) = 0, LinearMap.det φ = 0, ⊥ < ker φ,
      ∃ m, m ≠ 0 ∧ φ m = 0].TFAE

Tactic:
tfae_have 6 → 1
| ⟨x, h1, h2⟩ => by
  apply Module.End.hasEigenvalue_of_hasEigenvector ⟨_, h1⟩
  simpa only [Module.End.eigenspace_zero, mem_ker] using h2

Result:
K : Type u_2
M : Type u_3
inst✝³ : Field K
inst✝² : AddCommGroup M
inst✝¹ : Module K M
inst✝ : Module.Finite K M
φ : End K M
tfae_1_iff_2 : φ.HasEigenvalue 0 ↔ (minpoly K φ).IsRoot 0
tfae_2_to_3 : (minpoly K φ).IsRoot 0 → constantCoeff (charpoly φ) = 0
tfae_3_to_4 : constantCoeff (charpoly φ) = 0 → LinearMap.det φ = 0
tfae_4_to_5 : LinearMap.det φ = 0 → ⊥ < ker φ
tfae_5_to_6 : ⊥ < ker φ → ∃ m, m ≠ 0 ∧ φ m = 0
tfae_6_to_1 : (∃ m, m ≠ 0 ∧ φ m = 0) → φ.HasEigenvalue 0
⊢ [φ.HasEigenvalue 0, (minpoly K φ).IsRoot 0, constantCoeff (charpoly φ) = 0, LinearMap.det φ = 0, ⊥ < ker φ,
      ∃ m, m ≠ 0 ∧ φ m = 0].TFAE

Proof state:
K : Type u_2
M : Type u_3
inst✝³ : Field K
inst✝² : AddCommGroup M
inst✝¹ : Module K M
inst✝ : Module.Finite K M
φ : End K M
tfae_1_iff_2 : φ.HasEigenvalue 0 ↔ (minpoly K φ).IsRoot 0
tfae_2_to_3 : (minpoly K φ).IsRoot 0 → constantCoeff (charpoly φ) = 0
tfae_3_to_4 : constantCoeff (charpoly φ) = 0 → LinearMap.det φ = 0
tfae_4_to_5 : LinearMap.det φ = 0 → ⊥ < ker φ
tfae_5_to_6 : ⊥ < ker φ → ∃ m, m ≠ 0 ∧ φ m = 0
x : M
h1 : x ≠ 0
h2 : φ x = 0
⊢ x ∈ (φ.genEigenspace 0) 1

Tactic:
simpa only [Module.End.eigenspace_zero, mem_ker] using h2

Result:
no goals