-- Mathlib/LinearAlgebra/Matrix/ToLinearEquiv.lean
theorem exists_mulVec_eq_zero_iff_aux {K : Type*} [DecidableEq n] [Field K] {M : Matrix n n K} :
    (∃ v ≠ 0, M *ᵥ v = 0) ↔ M.det = 0

Proof state:
case mp
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
⊢ (∃ v, v ≠ 0 ∧ M *ᵥ v = 0) → M.det = 0

Tactic:
rintro ⟨v, hv, mul_eq⟩

Result:
case mp.intro.intro
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
v : n → K
hv : v ≠ 0
mul_eq : M *ᵥ v = 0
⊢ M.det = 0

Proof state:
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
h : ∀ (v : n → K), v ≠ 0 → M *ᵥ v ≠ 0
⊢ Function.Injective ⇑(toLin' M)

Tactic:
simpa only [← LinearMap.ker_eq_bot, ker_toLin'_eq_bot_iff, not_imp_not] using h

Result:
no goals

Proof state:
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
h : ∀ (v : n → K), v ≠ 0 → M *ᵥ v ≠ 0
this : Function.Injective ⇑(toLin' M)
⊢ M * toMatrix' ↑(LinearEquiv.ofInjectiveEndo (toLin' M) this).symm = 1

Tactic:
refine Matrix.toLin'.injective (LinearMap.ext fun v => ?_)

Result:
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
h : ∀ (v : n → K), v ≠ 0 → M *ᵥ v ≠ 0
this : Function.Injective ⇑(toLin' M)
v : n → K
⊢ (toLin' (M * toMatrix' ↑(LinearEquiv.ofInjectiveEndo (toLin' M) this).symm)) v = (toLin' 1) v

Proof state:
case mp.intro.intro
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
v : n → K
mul_eq : M *ᵥ v = 0
hv : M.det ≠ 0
⊢ v = 0

Tactic:
exact eq_zero_of_mulVec_eq_zero hv mul_eq

Result:
no goals

Proof state:
case mp.intro.intro
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
v : n → K
hv : v ≠ 0
mul_eq : M *ᵥ v = 0
⊢ M.det = 0

Tactic:
contrapose! hv

Result:
case mp.intro.intro
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
v : n → K
mul_eq : M *ᵥ v = 0
hv : M.det ≠ 0
⊢ v = 0

Proof state:
case mpr
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
h : ∀ (v : n → K), v ≠ 0 → M *ᵥ v ≠ 0
⊢ M.det ≠ 0

Tactic:
have : Function.Injective (Matrix.toLin' M) := by
  simpa only [← LinearMap.ker_eq_bot, ker_toLin'_eq_bot_iff, not_imp_not] using h

Result:
case mpr
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
h : ∀ (v : n → K), v ≠ 0 → M *ᵥ v ≠ 0
this : Function.Injective ⇑(toLin' M)
⊢ M.det ≠ 0

Proof state:
case mpr
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
h : ∀ (v : n → K), v ≠ 0 → M *ᵥ v ≠ 0
this✝ : Function.Injective ⇑(toLin' M)
this : M * toMatrix' ↑(LinearEquiv.ofInjectiveEndo (toLin' M) this✝).symm = 1
⊢ M.det ≠ 0

Tactic:
exact Matrix.det_ne_zero_of_right_inverse this

Result:
no goals

Proof state:
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
h : ∀ (v : n → K), v ≠ 0 → M *ᵥ v ≠ 0
this : Function.Injective ⇑(toLin' M)
v : n → K
⊢ (toLin' (M * toMatrix' ↑(LinearEquiv.ofInjectiveEndo (toLin' M) this).symm)) v = (toLin' 1) v

Tactic:
rw [Matrix.toLin'_mul, Matrix.toLin'_one, Matrix.toLin'_toMatrix', LinearMap.comp_apply]

Result:
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
h : ∀ (v : n → K), v ≠ 0 → M *ᵥ v ≠ 0
this : Function.Injective ⇑(toLin' M)
v : n → K
⊢ (toLin' M) (↑(LinearEquiv.ofInjectiveEndo (toLin' M) this).symm v) = LinearMap.id v

Proof state:
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
h : ∀ (v : n → K), v ≠ 0 → M *ᵥ v ≠ 0
this : Function.Injective ⇑(toLin' M)
v : n → K
⊢ (toLin' M) (↑(LinearEquiv.ofInjectiveEndo (toLin' M) this).symm v) = LinearMap.id v

Tactic:
exact (LinearEquiv.ofInjectiveEndo (Matrix.toLin' M) this).apply_symm_apply v

Result:
no goals

Proof state:
case mpr
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
⊢ (∀ (v : n → K), v ≠ 0 → M *ᵥ v ≠ 0) → M.det ≠ 0

Tactic:
intro h

Result:
case mpr
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
h : ∀ (v : n → K), v ≠ 0 → M *ᵥ v ≠ 0
⊢ M.det ≠ 0

Proof state:
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
⊢ (∃ v, v ≠ 0 ∧ M *ᵥ v = 0) ↔ M.det = 0

Tactic:
constructor

Result:
case mp
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
⊢ (∃ v, v ≠ 0 ∧ M *ᵥ v = 0) → M.det = 0

case mpr
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
⊢ M.det = 0 → ∃ v, v ≠ 0 ∧ M *ᵥ v = 0

Proof state:
case mpr
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
h : ∀ (v : n → K), v ≠ 0 → M *ᵥ v ≠ 0
this : Function.Injective ⇑(toLin' M)
⊢ M.det ≠ 0

Tactic:
have :
  M *
      LinearMap.toMatrix'
        ((LinearEquiv.ofInjectiveEndo (Matrix.toLin' M) this).symm : (n → K) →ₗ[K] n → K) =
    1 := by
  refine Matrix.toLin'.injective (LinearMap.ext fun v => ?_)
  rw [Matrix.toLin'_mul, Matrix.toLin'_one, Matrix.toLin'_toMatrix', LinearMap.comp_apply]
  exact (LinearEquiv.ofInjectiveEndo (Matrix.toLin' M) this).apply_symm_apply v

Result:
case mpr
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
h : ∀ (v : n → K), v ≠ 0 → M *ᵥ v ≠ 0
this✝ : Function.Injective ⇑(toLin' M)
this : M * toMatrix' ↑(LinearEquiv.ofInjectiveEndo (toLin' M) this✝).symm = 1
⊢ M.det ≠ 0

Proof state:
case mpr
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
⊢ M.det = 0 → ∃ v, v ≠ 0 ∧ M *ᵥ v = 0

Tactic:
contrapose!

Result:
case mpr
n : Type u_1
inst✝² : Fintype n
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
⊢ (∀ (v : n → K), v ≠ 0 → M *ᵥ v ≠ 0) → M.det ≠ 0