l3lab/ntp-mathlib huggingface dataset:
/-- This holds for all integral domains (see `Matrix.exists_mulVec_eq_zero_iff`),
not just fields, but it's easier to prove it for the field of fractions first. -/
theorem exists_mulVec_eq_zero_iff_aux {K : Type*} [DecidableEq n] [Field K] {M : Matrix n n K} :
    (∃ v ≠ 0, M.mulVec v = 0) ↔ M.det = 0 := by
  constructor
  · rintro ⟨v, hv, mul_eq⟩
    contrapose! hv
    exact eq_zero_of_mulVec_eq_zero hv mul_eq
  · contrapose!
    intro h
    have : Function.Injective (Matrix.toLin' M) := by
      simpa only [← LinearMap.ker_eq_bot, ker_toLin'_eq_bot_iff, not_imp_not] using h
    have :
      M *
          LinearMap.toMatrix'
            ((LinearEquiv.ofInjectiveEndo (Matrix.toLin' M) this).symm : (n → K) →ₗ[K] n → K) =
        1 := by
      

Proof state:
n : Type u_1
inst✝⁵ : Fintype n
R : Type u_2
M✝ : Type u_3
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M✝
inst✝² : Module R M✝
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
h : ∀ (v : n → K), v ≠ 0 → mulVec M v ≠ 0
this : Function.Injective ⇑(toLin' M)
⊢ M * toMatrix' ↑(LinearEquiv.symm (LinearEquiv.ofInjectiveEndo (toLin' M) this)) = 1

Next tactic:
refine' Matrix.toLin'.injective (LinearMap.ext fun v => _)
/-- This holds for all integral domains (see `Matrix.exists_mulVec_eq_zero_iff`),
not just fields, but it's easier to prove it for the field of fractions first. -/
theorem exists_mulVec_eq_zero_iff_aux {K : Type*} [DecidableEq n] [Field K] {M : Matrix n n K} :
    (∃ v ≠ 0, M.mulVec v = 0) ↔ M.det = 0 := by
  constructor
  · rintro ⟨v, hv, mul_eq⟩
    contrapose! hv
    exact eq_zero_of_mulVec_eq_zero hv mul_eq
  · contrapose!
    intro h
    have : Function.Injective (Matrix.toLin' M) := by
      simpa only [← LinearMap.ker_eq_bot, ker_toLin'_eq_bot_iff, not_imp_not] using h
    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 => _)
      

Proof state:
n : Type u_1
inst✝⁵ : Fintype n
R : Type u_2
M✝ : Type u_3
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M✝
inst✝² : Module R M✝
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
h : ∀ (v : n → K), v ≠ 0 → mulVec M v ≠ 0
this : Function.Injective ⇑(toLin' M)
v : n → K
⊢ (toLin' (M * toMatrix' ↑(LinearEquiv.symm (LinearEquiv.ofInjectiveEndo (toLin' M) this)))) v = (toLin' 1) v

Next tactic:
rw [Matrix.toLin'_mul, Matrix.toLin'_one, Matrix.toLin'_toMatrix', LinearMap.comp_apply]
/-- This holds for all integral domains (see `Matrix.exists_mulVec_eq_zero_iff`),
not just fields, but it's easier to prove it for the field of fractions first. -/
theorem exists_mulVec_eq_zero_iff_aux {K : Type*} [DecidableEq n] [Field K] {M : Matrix n n K} :
    (∃ v ≠ 0, M.mulVec v = 0) ↔ M.det = 0 := by
  constructor
  · rintro ⟨v, hv, mul_eq⟩
    contrapose! hv
    exact eq_zero_of_mulVec_eq_zero hv mul_eq
  · contrapose!
    intro h
    have : Function.Injective (Matrix.toLin' M) := by
      simpa only [← LinearMap.ker_eq_bot, ker_toLin'_eq_bot_iff, not_imp_not] using h
    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]
      

Proof state:
n : Type u_1
inst✝⁵ : Fintype n
R : Type u_2
M✝ : Type u_3
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M✝
inst✝² : Module R M✝
K : Type u_4
inst✝¹ : DecidableEq n
inst✝ : Field K
M : Matrix n n K
h : ∀ (v : n → K), v ≠ 0 → mulVec M v ≠ 0
this : Function.Injective ⇑(toLin' M)
v : n → K
⊢ (toLin' M) (↑(LinearEquiv.symm (LinearEquiv.ofInjectiveEndo (toLin' M) this)) v) = LinearMap.id v

Next tactic:
exact (LinearEquiv.ofInjectiveEndo (Matrix.toLin' M) this).apply_symm_apply v
/-- This holds for all integral domains (see `Matrix.exists_mulVec_eq_zero_iff`),
not just fields, but it's easier to prove it for the field of fractions first. -/
theorem exists_mulVec_eq_zero_iff_aux {K : Type*} [DecidableEq n] [Field K] {M : Matrix n n K} :
    (∃ v ≠ 0, M.mulVec v = 0) ↔ M.det = 0 := by
  constructor
  · rintro ⟨v, hv, mul_eq⟩
    contrapose! hv
    exact eq_zero_of_mulVec_eq_zero hv mul_eq
  · contrapose!
    intro h
    have : Function.Injective (Matrix.toLin' M) := by
      simpa only [← LinearMap.ker_eq_bot, ker_toLin'_eq_bot_iff, not_imp_not] using h
    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
    

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

Next tactic:
exact Matrix.det_ne_zero_of_right_inverse this
theorem exists_mulVec_eq_zero_iff' {A : Type*} (K : Type*) [DecidableEq n] [CommRing A]
    [Nontrivial A] [Field K] [Algebra A K] [IsFractionRing A K] {M : Matrix n n A} :
    (∃ v ≠ 0, M.mulVec v = 0) ↔ M.det = 0 := by
  

Proof state:
n : Type u_1
inst✝⁹ : Fintype n
R : Type u_2
M✝ : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : AddCommGroup M✝
inst✝⁶ : Module R M✝
A : Type u_4
K : Type u_5
inst✝⁵ : DecidableEq n
inst✝⁴ : CommRing A
inst✝³ : Nontrivial A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
M : Matrix n n A
⊢ (∃ v, v ≠ 0 ∧ mulVec M v = 0) ↔ det M = 0

Next tactic:
have : (∃ v ≠ 0, mulVec ((algebraMap A K).mapMatrix M) v = 0) ↔ _ :=
    exists_mulVec_eq_zero_iff_aux
theorem exists_mulVec_eq_zero_iff' {A : Type*} (K : Type*) [DecidableEq n] [CommRing A]
    [Nontrivial A] [Field K] [Algebra A K] [IsFractionRing A K] {M : Matrix n n A} :
    (∃ v ≠ 0, M.mulVec v = 0) ↔ M.det = 0 := by
  have : (∃ v ≠ 0, mulVec ((algebraMap A K).mapMatrix M) v = 0) ↔ _ :=
    exists_mulVec_eq_zero_iff_aux
  

Proof state:
n : Type u_1
inst✝⁹ : Fintype n
R : Type u_2
M✝ : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : AddCommGroup M✝
inst✝⁶ : Module R M✝
A : Type u_4
K : Type u_5
inst✝⁵ : DecidableEq n
inst✝⁴ : CommRing A
inst✝³ : Nontrivial A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
M : Matrix n n A
this :
  (∃ v, v ≠ 0 ∧ mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0) ↔
    det ((RingHom.mapMatrix (algebraMap A K)) M) = 0
⊢ (∃ v, v ≠ 0 ∧ mulVec M v = 0) ↔ det M = 0

Next tactic:
rw [← RingHom.map_det, IsFractionRing.to_map_eq_zero_iff] at this
theorem exists_mulVec_eq_zero_iff' {A : Type*} (K : Type*) [DecidableEq n] [CommRing A]
    [Nontrivial A] [Field K] [Algebra A K] [IsFractionRing A K] {M : Matrix n n A} :
    (∃ v ≠ 0, M.mulVec v = 0) ↔ M.det = 0 := by
  have : (∃ v ≠ 0, mulVec ((algebraMap A K).mapMatrix M) v = 0) ↔ _ :=
    exists_mulVec_eq_zero_iff_aux
  rw [← RingHom.map_det, IsFractionRing.to_map_eq_zero_iff] at this
  

Proof state:
n : Type u_1
inst✝⁹ : Fintype n
R : Type u_2
M✝ : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : AddCommGroup M✝
inst✝⁶ : Module R M✝
A : Type u_4
K : Type u_5
inst✝⁵ : DecidableEq n
inst✝⁴ : CommRing A
inst✝³ : Nontrivial A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
M : Matrix n n A
this : (∃ v, v ≠ 0 ∧ mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0) ↔ det M = 0
⊢ (∃ v, v ≠ 0 ∧ mulVec M v = 0) ↔ det M = 0

Next tactic:
refine' Iff.trans _ this
theorem exists_mulVec_eq_zero_iff' {A : Type*} (K : Type*) [DecidableEq n] [CommRing A]
    [Nontrivial A] [Field K] [Algebra A K] [IsFractionRing A K] {M : Matrix n n A} :
    (∃ v ≠ 0, M.mulVec v = 0) ↔ M.det = 0 := by
  have : (∃ v ≠ 0, mulVec ((algebraMap A K).mapMatrix M) v = 0) ↔ _ :=
    exists_mulVec_eq_zero_iff_aux
  rw [← RingHom.map_det, IsFractionRing.to_map_eq_zero_iff] at this
  refine' Iff.trans _ this; 

Proof state:
n : Type u_1
inst✝⁹ : Fintype n
R : Type u_2
M✝ : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : AddCommGroup M✝
inst✝⁶ : Module R M✝
A : Type u_4
K : Type u_5
inst✝⁵ : DecidableEq n
inst✝⁴ : CommRing A
inst✝³ : Nontrivial A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
M : Matrix n n A
this : (∃ v, v ≠ 0 ∧ mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0) ↔ det M = 0
⊢ (∃ v, v ≠ 0 ∧ mulVec M v = 0) ↔ ∃ v, v ≠ 0 ∧ mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0

Next tactic:
constructor
theorem exists_mulVec_eq_zero_iff' {A : Type*} (K : Type*) [DecidableEq n] [CommRing A]
    [Nontrivial A] [Field K] [Algebra A K] [IsFractionRing A K] {M : Matrix n n A} :
    (∃ v ≠ 0, M.mulVec v = 0) ↔ M.det = 0 := by
  have : (∃ v ≠ 0, mulVec ((algebraMap A K).mapMatrix M) v = 0) ↔ _ :=
    exists_mulVec_eq_zero_iff_aux
  rw [← RingHom.map_det, IsFractionRing.to_map_eq_zero_iff] at this
  refine' Iff.trans _ this; constructor <;> 

Proof state:
case mp
n : Type u_1
inst✝⁹ : Fintype n
R : Type u_2
M✝ : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : AddCommGroup M✝
inst✝⁶ : Module R M✝
A : Type u_4
K : Type u_5
inst✝⁵ : DecidableEq n
inst✝⁴ : CommRing A
inst✝³ : Nontrivial A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
M : Matrix n n A
this : (∃ v, v ≠ 0 ∧ mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0) ↔ det M = 0
⊢ (∃ v, v ≠ 0 ∧ mulVec M v = 0) → ∃ v, v ≠ 0 ∧ mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0

Next tactic:
rintro ⟨v, hv, mul_eq⟩
theorem exists_mulVec_eq_zero_iff' {A : Type*} (K : Type*) [DecidableEq n] [CommRing A]
    [Nontrivial A] [Field K] [Algebra A K] [IsFractionRing A K] {M : Matrix n n A} :
    (∃ v ≠ 0, M.mulVec v = 0) ↔ M.det = 0 := by
  have : (∃ v ≠ 0, mulVec ((algebraMap A K).mapMatrix M) v = 0) ↔ _ :=
    exists_mulVec_eq_zero_iff_aux
  rw [← RingHom.map_det, IsFractionRing.to_map_eq_zero_iff] at this
  refine' Iff.trans _ this; constructor <;> 

Proof state:
case mpr
n : Type u_1
inst✝⁹ : Fintype n
R : Type u_2
M✝ : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : AddCommGroup M✝
inst✝⁶ : Module R M✝
A : Type u_4
K : Type u_5
inst✝⁵ : DecidableEq n
inst✝⁴ : CommRing A
inst✝³ : Nontrivial A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
M : Matrix n n A
this : (∃ v, v ≠ 0 ∧ mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0) ↔ det M = 0
⊢ (∃ v, v ≠ 0 ∧ mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0) → ∃ v, v ≠ 0 ∧ mulVec M v = 0

Next tactic:
rintro ⟨v, hv, mul_eq⟩
theorem exists_mulVec_eq_zero_iff' {A : Type*} (K : Type*) [DecidableEq n] [CommRing A]
    [Nontrivial A] [Field K] [Algebra A K] [IsFractionRing A K] {M : Matrix n n A} :
    (∃ v ≠ 0, M.mulVec v = 0) ↔ M.det = 0 := by
  have : (∃ v ≠ 0, mulVec ((algebraMap A K).mapMatrix M) v = 0) ↔ _ :=
    exists_mulVec_eq_zero_iff_aux
  rw [← RingHom.map_det, IsFractionRing.to_map_eq_zero_iff] at this
  refine' Iff.trans _ this; constructor <;> rintro ⟨v, hv, mul_eq⟩
  · 

Proof state:
case mp.intro.intro
n : Type u_1
inst✝⁹ : Fintype n
R : Type u_2
M✝ : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : AddCommGroup M✝
inst✝⁶ : Module R M✝
A : Type u_4
K : Type u_5
inst✝⁵ : DecidableEq n
inst✝⁴ : CommRing A
inst✝³ : Nontrivial A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
M : Matrix n n A
this : (∃ v, v ≠ 0 ∧ mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0) ↔ det M = 0
v : n → A
hv : v ≠ 0
mul_eq : mulVec M v = 0
⊢ ∃ v, v ≠ 0 ∧ mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0

Next tactic:
refine' ⟨fun i => algebraMap _ _ (v i), mt (fun h => funext fun i => _) hv, _⟩
theorem exists_mulVec_eq_zero_iff' {A : Type*} (K : Type*) [DecidableEq n] [CommRing A]
    [Nontrivial A] [Field K] [Algebra A K] [IsFractionRing A K] {M : Matrix n n A} :
    (∃ v ≠ 0, M.mulVec v = 0) ↔ M.det = 0 := by
  have : (∃ v ≠ 0, mulVec ((algebraMap A K).mapMatrix M) v = 0) ↔ _ :=
    exists_mulVec_eq_zero_iff_aux
  rw [← RingHom.map_det, IsFractionRing.to_map_eq_zero_iff] at this
  refine' Iff.trans _ this; constructor <;> rintro ⟨v, hv, mul_eq⟩
  · refine' ⟨fun i => algebraMap _ _ (v i), mt (fun h => funext fun i => _) hv, _⟩
    · 

Proof state:
case mp.intro.intro.refine'_1
n : Type u_1
inst✝⁹ : Fintype n
R : Type u_2
M✝ : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : AddCommGroup M✝
inst✝⁶ : Module R M✝
A : Type u_4
K : Type u_5
inst✝⁵ : DecidableEq n
inst✝⁴ : CommRing A
inst✝³ : Nontrivial A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
M : Matrix n n A
this : (∃ v, v ≠ 0 ∧ mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0) ↔ det M = 0
v : n → A
hv : v ≠ 0
mul_eq : mulVec M v = 0
h : (fun i => (algebraMap A K) (v i)) = 0
i : n
⊢ v i = OfNat.ofNat 0 i

Next tactic:
exact IsFractionRing.to_map_eq_zero_iff.mp (congr_fun h i)
theorem exists_mulVec_eq_zero_iff' {A : Type*} (K : Type*) [DecidableEq n] [CommRing A]
    [Nontrivial A] [Field K] [Algebra A K] [IsFractionRing A K] {M : Matrix n n A} :
    (∃ v ≠ 0, M.mulVec v = 0) ↔ M.det = 0 := by
  have : (∃ v ≠ 0, mulVec ((algebraMap A K).mapMatrix M) v = 0) ↔ _ :=
    exists_mulVec_eq_zero_iff_aux
  rw [← RingHom.map_det, IsFractionRing.to_map_eq_zero_iff] at this
  refine' Iff.trans _ this; constructor <;> rintro ⟨v, hv, mul_eq⟩
  · refine' ⟨fun i => algebraMap _ _ (v i), mt (fun h => funext fun i => _) hv, _⟩
    · exact IsFractionRing.to_map_eq_zero_iff.mp (congr_fun h i)
    · 

Proof state:
case mp.intro.intro.refine'_2
n : Type u_1
inst✝⁹ : Fintype n
R : Type u_2
M✝ : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : AddCommGroup M✝
inst✝⁶ : Module R M✝
A : Type u_4
K : Type u_5
inst✝⁵ : DecidableEq n
inst✝⁴ : CommRing A
inst✝³ : Nontrivial A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
M : Matrix n n A
this : (∃ v, v ≠ 0 ∧ mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0) ↔ det M = 0
v : n → A
hv : v ≠ 0
mul_eq : mulVec M v = 0
⊢ (mulVec ((RingHom.mapMatrix (algebraMap A K)) M) fun i => (algebraMap A K) (v i)) = 0

Next tactic:
ext i
theorem exists_mulVec_eq_zero_iff' {A : Type*} (K : Type*) [DecidableEq n] [CommRing A]
    [Nontrivial A] [Field K] [Algebra A K] [IsFractionRing A K] {M : Matrix n n A} :
    (∃ v ≠ 0, M.mulVec v = 0) ↔ M.det = 0 := by
  have : (∃ v ≠ 0, mulVec ((algebraMap A K).mapMatrix M) v = 0) ↔ _ :=
    exists_mulVec_eq_zero_iff_aux
  rw [← RingHom.map_det, IsFractionRing.to_map_eq_zero_iff] at this
  refine' Iff.trans _ this; constructor <;> rintro ⟨v, hv, mul_eq⟩
  · refine' ⟨fun i => algebraMap _ _ (v i), mt (fun h => funext fun i => _) hv, _⟩
    · exact IsFractionRing.to_map_eq_zero_iff.mp (congr_fun h i)
    · ext i
      

Proof state:
case mp.intro.intro.refine'_2.h
n : Type u_1
inst✝⁹ : Fintype n
R : Type u_2
M✝ : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : AddCommGroup M✝
inst✝⁶ : Module R M✝
A : Type u_4
K : Type u_5
inst✝⁵ : DecidableEq n
inst✝⁴ : CommRing A
inst✝³ : Nontrivial A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
M : Matrix n n A
this : (∃ v, v ≠ 0 ∧ mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0) ↔ det M = 0
v : n → A
hv : v ≠ 0
mul_eq : mulVec M v = 0
i : n
⊢ mulVec ((RingHom.mapMatrix (algebraMap A K)) M) (fun i => (algebraMap A K) (v i)) i = OfNat.ofNat 0 i

Next tactic:
refine' (RingHom.map_mulVec _ _ _ i).symm.trans _
theorem exists_mulVec_eq_zero_iff' {A : Type*} (K : Type*) [DecidableEq n] [CommRing A]
    [Nontrivial A] [Field K] [Algebra A K] [IsFractionRing A K] {M : Matrix n n A} :
    (∃ v ≠ 0, M.mulVec v = 0) ↔ M.det = 0 := by
  have : (∃ v ≠ 0, mulVec ((algebraMap A K).mapMatrix M) v = 0) ↔ _ :=
    exists_mulVec_eq_zero_iff_aux
  rw [← RingHom.map_det, IsFractionRing.to_map_eq_zero_iff] at this
  refine' Iff.trans _ this; constructor <;> rintro ⟨v, hv, mul_eq⟩
  · refine' ⟨fun i => algebraMap _ _ (v i), mt (fun h => funext fun i => _) hv, _⟩
    · exact IsFractionRing.to_map_eq_zero_iff.mp (congr_fun h i)
    · ext i
      refine' (RingHom.map_mulVec _ _ _ i).symm.trans _
      

Proof state:
case mp.intro.intro.refine'_2.h
n : Type u_1
inst✝⁹ : Fintype n
R : Type u_2
M✝ : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : AddCommGroup M✝
inst✝⁶ : Module R M✝
A : Type u_4
K : Type u_5
inst✝⁵ : DecidableEq n
inst✝⁴ : CommRing A
inst✝³ : Nontrivial A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
M : Matrix n n A
this : (∃ v, v ≠ 0 ∧ mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0) ↔ det M = 0
v : n → A
hv : v ≠ 0
mul_eq : mulVec M v = 0
i : n
⊢ (algebraMap A K) (mulVec (fun i j => M i j) (fun i => v i) i) = OfNat.ofNat 0 i

Next tactic:
rw [mul_eq, Pi.zero_apply, RingHom.map_zero, Pi.zero_apply]
theorem exists_mulVec_eq_zero_iff' {A : Type*} (K : Type*) [DecidableEq n] [CommRing A]
    [Nontrivial A] [Field K] [Algebra A K] [IsFractionRing A K] {M : Matrix n n A} :
    (∃ v ≠ 0, M.mulVec v = 0) ↔ M.det = 0 := by
  have : (∃ v ≠ 0, mulVec ((algebraMap A K).mapMatrix M) v = 0) ↔ _ :=
    exists_mulVec_eq_zero_iff_aux
  rw [← RingHom.map_det, IsFractionRing.to_map_eq_zero_iff] at this
  refine' Iff.trans _ this; constructor <;> rintro ⟨v, hv, mul_eq⟩
  · refine' ⟨fun i => algebraMap _ _ (v i), mt (fun h => funext fun i => _) hv, _⟩
    · exact IsFractionRing.to_map_eq_zero_iff.mp (congr_fun h i)
    · ext i
      refine' (RingHom.map_mulVec _ _ _ i).symm.trans _
      rw [mul_eq, Pi.zero_apply, RingHom.map_zero, Pi.zero_apply]
  · 

Proof state:
case mpr.intro.intro
n : Type u_1
inst✝⁹ : Fintype n
R : Type u_2
M✝ : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : AddCommGroup M✝
inst✝⁶ : Module R M✝
A : Type u_4
K : Type u_5
inst✝⁵ : DecidableEq n
inst✝⁴ : CommRing A
inst✝³ : Nontrivial A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
M : Matrix n n A
this : (∃ v, v ≠ 0 ∧ mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0) ↔ det M = 0
v : n → K
hv : v ≠ 0
mul_eq : mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0
⊢ ∃ v, v ≠ 0 ∧ mulVec M v = 0

Next tactic:
letI := Classical.decEq K
theorem exists_mulVec_eq_zero_iff' {A : Type*} (K : Type*) [DecidableEq n] [CommRing A]
    [Nontrivial A] [Field K] [Algebra A K] [IsFractionRing A K] {M : Matrix n n A} :
    (∃ v ≠ 0, M.mulVec v = 0) ↔ M.det = 0 := by
  have : (∃ v ≠ 0, mulVec ((algebraMap A K).mapMatrix M) v = 0) ↔ _ :=
    exists_mulVec_eq_zero_iff_aux
  rw [← RingHom.map_det, IsFractionRing.to_map_eq_zero_iff] at this
  refine' Iff.trans _ this; constructor <;> rintro ⟨v, hv, mul_eq⟩
  · refine' ⟨fun i => algebraMap _ _ (v i), mt (fun h => funext fun i => _) hv, _⟩
    · exact IsFractionRing.to_map_eq_zero_iff.mp (congr_fun h i)
    · ext i
      refine' (RingHom.map_mulVec _ _ _ i).symm.trans _
      rw [mul_eq, Pi.zero_apply, RingHom.map_zero, Pi.zero_apply]
  · letI := Classical.decEq K
    

Proof state:
case mpr.intro.intro
n : Type u_1
inst✝⁹ : Fintype n
R : Type u_2
M✝ : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : AddCommGroup M✝
inst✝⁶ : Module R M✝
A : Type u_4
K : Type u_5
inst✝⁵ : DecidableEq n
inst✝⁴ : CommRing A
inst✝³ : Nontrivial A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
M : Matrix n n A
this✝ : (∃ v, v ≠ 0 ∧ mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0) ↔ det M = 0
v : n → K
hv : v ≠ 0
mul_eq : mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0
this : DecidableEq K := Classical.decEq K
⊢ ∃ v, v ≠ 0 ∧ mulVec M v = 0

Next tactic:
obtain ⟨⟨b, hb⟩, ba_eq⟩ :=
      IsLocalization.exist_integer_multiples_of_finset (nonZeroDivisors A) (Finset.univ.image v)
theorem exists_mulVec_eq_zero_iff' {A : Type*} (K : Type*) [DecidableEq n] [CommRing A]
    [Nontrivial A] [Field K] [Algebra A K] [IsFractionRing A K] {M : Matrix n n A} :
    (∃ v ≠ 0, M.mulVec v = 0) ↔ M.det = 0 := by
  have : (∃ v ≠ 0, mulVec ((algebraMap A K).mapMatrix M) v = 0) ↔ _ :=
    exists_mulVec_eq_zero_iff_aux
  rw [← RingHom.map_det, IsFractionRing.to_map_eq_zero_iff] at this
  refine' Iff.trans _ this; constructor <;> rintro ⟨v, hv, mul_eq⟩
  · refine' ⟨fun i => algebraMap _ _ (v i), mt (fun h => funext fun i => _) hv, _⟩
    · exact IsFractionRing.to_map_eq_zero_iff.mp (congr_fun h i)
    · ext i
      refine' (RingHom.map_mulVec _ _ _ i).symm.trans _
      rw [mul_eq, Pi.zero_apply, RingHom.map_zero, Pi.zero_apply]
  · letI := Classical.decEq K
    obtain ⟨⟨b, hb⟩, ba_eq⟩ :=
      IsLocalization.exist_integer_multiples_of_finset (nonZeroDivisors A) (Finset.univ.image v)
    

Proof state:
case mpr.intro.intro.intro.mk
n : Type u_1
inst✝⁹ : Fintype n
R : Type u_2
M✝ : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : AddCommGroup M✝
inst✝⁶ : Module R M✝
A : Type u_4
K : Type u_5
inst✝⁵ : DecidableEq n
inst✝⁴ : CommRing A
inst✝³ : Nontrivial A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
M : Matrix n n A
this✝ : (∃ v, v ≠ 0 ∧ mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0) ↔ det M = 0
v : n → K
hv : v ≠ 0
mul_eq : mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0
this : DecidableEq K := Classical.decEq K
b : A
hb : b ∈ nonZeroDivisors A
ba_eq : ∀ a ∈ Finset.image v Finset.univ, IsLocalization.IsInteger A (↑{ val := b, property := hb } • a)
⊢ ∃ v, v ≠ 0 ∧ mulVec M v = 0

Next tactic:
choose f hf using ba_eq
theorem exists_mulVec_eq_zero_iff' {A : Type*} (K : Type*) [DecidableEq n] [CommRing A]
    [Nontrivial A] [Field K] [Algebra A K] [IsFractionRing A K] {M : Matrix n n A} :
    (∃ v ≠ 0, M.mulVec v = 0) ↔ M.det = 0 := by
  have : (∃ v ≠ 0, mulVec ((algebraMap A K).mapMatrix M) v = 0) ↔ _ :=
    exists_mulVec_eq_zero_iff_aux
  rw [← RingHom.map_det, IsFractionRing.to_map_eq_zero_iff] at this
  refine' Iff.trans _ this; constructor <;> rintro ⟨v, hv, mul_eq⟩
  · refine' ⟨fun i => algebraMap _ _ (v i), mt (fun h => funext fun i => _) hv, _⟩
    · exact IsFractionRing.to_map_eq_zero_iff.mp (congr_fun h i)
    · ext i
      refine' (RingHom.map_mulVec _ _ _ i).symm.trans _
      rw [mul_eq, Pi.zero_apply, RingHom.map_zero, Pi.zero_apply]
  · letI := Classical.decEq K
    obtain ⟨⟨b, hb⟩, ba_eq⟩ :=
      IsLocalization.exist_integer_multiples_of_finset (nonZeroDivisors A) (Finset.univ.image v)
    choose f hf using ba_eq
    

Proof state:
case mpr.intro.intro.intro.mk
n : Type u_1
inst✝⁹ : Fintype n
R : Type u_2
M✝ : Type u_3
inst✝⁸ : CommRing R
inst✝⁷ : AddCommGroup M✝
inst✝⁶ : Module R M✝
A : Type u_4
K : Type u_5
inst✝⁵ : DecidableEq n
inst✝⁴ : CommRing A
inst✝³ : Nontrivial A
inst✝² : Field K
inst✝¹ : Algebra A K
inst✝ : IsFractionRing A K
M : Matrix n n A
this✝ : (∃ v, v ≠ 0 ∧ mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0) ↔ det M = 0
v : n → K
hv : v ≠ 0
mul_eq : mulVec ((RingHom.mapMatrix (algebraMap A K)) M) v = 0
this : DecidableEq K := Classical.decEq K
b : A
hb : b ∈ nonZeroDivisors A
f : (a : K) → a ∈ Finset.image v Finset.univ → A
hf : ∀ (a : K) (a_1 : a ∈ Finset.image v Finset.univ), (algebraMap A K) (f a a_1) = ↑{ val := b, property := hb } • a
⊢ ∃ v, v ≠ 0 ∧ mulVec M v = 0

Next tactic:
refine'
      ⟨fun i => f _ (Finset.mem_image.mpr ⟨i, Finset.mem_univ i, rfl⟩),
        mt (fun h => funext fun i => _) hv, _⟩