Theorem: Matrix.rank_eq_finrank_range_toLin
File: Mathlib/Data/Matrix/Rank.lean

tactic: let e₁ := (Pi.basisFun R m).equiv v₁ (Equiv.refl _)
state_before: l : Type ?u.189630
m : Type u_5
n : Type u_1
o : Type ?u.189639
R : Type u_4
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_2
M₂ : Type u_3
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
⊢ rank A = finrank R { x // x ∈ LinearMap.range (↑(toLin v₂ v₁) A) }

tactic: let e₂ := (Pi.basisFun R n).equiv v₂ (Equiv.refl _)
state_before: l : Type ?u.189630
m : Type u_5
n : Type u_1
o : Type ?u.189639
R : Type u_4
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_2
M₂ : Type u_3
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
⊢ rank A = finrank R { x // x ∈ LinearMap.range (↑(toLin v₂ v₁) A) }

tactic: have range_e₂ : LinearMap.range e₂ = ⊤ := by
  rw [LinearMap.range_eq_top]
  exact e₂.surjective
state_before: l : Type ?u.189630
m : Type u_5
n : Type u_1
o : Type ?u.189639
R : Type u_4
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_2
M₂ : Type u_3
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
⊢ rank A = finrank R { x // x ∈ LinearMap.range (↑(toLin v₂ v₁) A) }

tactic: refine' LinearEquiv.finrank_eq (e₁.ofSubmodules _ _ _)
state_before: l : Type ?u.189630
m : Type u_5
n : Type u_1
o : Type ?u.189639
R : Type u_4
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_2
M₂ : Type u_3
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
⊢ rank A = finrank R { x // x ∈ LinearMap.range (↑(toLin v₂ v₁) A) }

tactic: rw [← LinearMap.range_comp, ← LinearMap.range_comp_of_range_eq_top (toLin v₂ v₁ A) range_e₂]
state_before: l : Type ?u.189630
m : Type u_5
n : Type u_1
o : Type ?u.189639
R : Type u_4
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_2
M₂ : Type u_3
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
⊢ Submodule.map (↑e₁) (LinearMap.range (mulVecLin A)) = LinearMap.range (↑(toLin v₂ v₁) A)

tactic: congr 1
state_before: l : Type ?u.189630
m : Type u_5
n : Type u_1
o : Type ?u.189639
R : Type u_4
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_2
M₂ : Type u_3
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
⊢ LinearMap.range (LinearMap.comp (↑e₁) (mulVecLin A)) = LinearMap.range (LinearMap.comp (↑(toLin v₂ v₁) A) ↑e₂)

tactic: apply LinearMap.pi_ext'
state_before: case e_f
l : Type ?u.189630
m : Type u_5
n : Type u_1
o : Type ?u.189639
R : Type u_4
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_2
M₂ : Type u_3
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
⊢ LinearMap.comp (↑e₁) (mulVecLin A) = LinearMap.comp (↑(toLin v₂ v₁) A) ↑e₂

tactic: rintro i
state_before: case e_f.h
l : Type ?u.189630
m : Type u_5
n : Type u_1
o : Type ?u.189639
R : Type u_4
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_2
M₂ : Type u_3
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
⊢ ∀ (i : n),
    LinearMap.comp (LinearMap.comp (↑e₁) (mulVecLin A)) (LinearMap.single i) =
      LinearMap.comp (LinearMap.comp (↑(toLin v₂ v₁) A) ↑e₂) (LinearMap.single i)

tactic: apply LinearMap.ext_ring
state_before: case e_f.h
l : Type ?u.189630
m : Type u_5
n : Type u_1
o : Type ?u.189639
R : Type u_4
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_2
M₂ : Type u_3
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
i : n
⊢ LinearMap.comp (LinearMap.comp (↑e₁) (mulVecLin A)) (LinearMap.single i) =
    LinearMap.comp (LinearMap.comp (↑(toLin v₂ v₁) A) ↑e₂) (LinearMap.single i)

tactic: have aux₁ := toLin_self (Pi.basisFun R n) (Pi.basisFun R m) A i
state_before: case e_f.h.h
l : Type ?u.189630
m : Type u_5
n : Type u_1
o : Type ?u.189639
R : Type u_4
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_2
M₂ : Type u_3
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
i : n
⊢ ↑(LinearMap.comp (LinearMap.comp (↑e₁) (mulVecLin A)) (LinearMap.single i)) 1 =
    ↑(LinearMap.comp (LinearMap.comp (↑(toLin v₂ v₁) A) ↑e₂) (LinearMap.single i)) 1

tactic: have aux₂ := Basis.equiv_apply (Pi.basisFun R n) i v₂
state_before: case e_f.h.h
l : Type ?u.189630
m : Type u_5
n : Type u_1
o : Type ?u.189639
R : Type u_4
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_2
M₂ : Type u_3
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
i : n
aux₁ :
  ↑(↑(toLin (Pi.basisFun R n) (Pi.basisFun R m)) A) (↑(Pi.basisFun R n) i) =
    Finset.sum Finset.univ fun j => A j i • ↑(Pi.basisFun R m) j
⊢ ↑(LinearMap.comp (LinearMap.comp (↑e₁) (mulVecLin A)) (LinearMap.single i)) 1 =
    ↑(LinearMap.comp (LinearMap.comp (↑(toLin v₂ v₁) A) ↑e₂) (LinearMap.single i)) 1

tactic: rw [toLin_eq_toLin', toLin'_apply'] at aux₁
state_before: case e_f.h.h
l : Type ?u.189630
m : Type u_5
n : Type u_1
o : Type ?u.189639
R : Type u_4
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_2
M₂ : Type u_3
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
i : n
aux₁ :
  ↑(↑(toLin (Pi.basisFun R n) (Pi.basisFun R m)) A) (↑(Pi.basisFun R n) i) =
    Finset.sum Finset.univ fun j => A j i • ↑(Pi.basisFun R m) j
aux₂ : ∀ (e : n ≃ n), ↑(Basis.equiv (Pi.basisFun R n) v₂ e) (↑(Pi.basisFun R n) i) = ↑v₂ (↑e i)
⊢ ↑(LinearMap.comp (LinearMap.comp (↑e₁) (mulVecLin A)) (LinearMap.single i)) 1 =
    ↑(LinearMap.comp (LinearMap.comp (↑(toLin v₂ v₁) A) ↑e₂) (LinearMap.single i)) 1

tactic: rw [Pi.basisFun_apply, LinearMap.coe_stdBasis] at aux₁ aux₂
state_before: case e_f.h.h
l : Type ?u.189630
m : Type u_5
n : Type u_1
o : Type ?u.189639
R : Type u_4
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_2
M₂ : Type u_3
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
i : n
aux₁ : ↑(mulVecLin A) (↑(Pi.basisFun R n) i) = Finset.sum Finset.univ fun j => A j i • ↑(Pi.basisFun R m) j
aux₂ : ∀ (e : n ≃ n), ↑(Basis.equiv (Pi.basisFun R n) v₂ e) (↑(Pi.basisFun R n) i) = ↑v₂ (↑e i)
⊢ ↑(LinearMap.comp (LinearMap.comp (↑e₁) (mulVecLin A)) (LinearMap.single i)) 1 =
    ↑(LinearMap.comp (LinearMap.comp (↑(toLin v₂ v₁) A) ↑e₂) (LinearMap.single i)) 1

tactic: simp only [LinearMap.comp_apply, LinearEquiv.coe_coe, Equiv.refl_apply, aux₁, aux₂,
  LinearMap.coe_single, toLin_self, LinearEquiv.map_sum, LinearEquiv.map_smul, Basis.equiv_apply]
state_before: case e_f.h.h
l : Type ?u.189630
m : Type u_5
n : Type u_1
o : Type ?u.189639
R : Type u_4
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_2
M₂ : Type u_3
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
i : n
aux₁ : ↑(mulVecLin A) (Pi.single i 1) = Finset.sum Finset.univ fun j => A j i • ↑(Pi.basisFun R m) j
aux₂ : ∀ (e : n ≃ n), ↑(Basis.equiv (Pi.basisFun R n) v₂ e) (Pi.single i 1) = ↑v₂ (↑e i)
⊢ ↑(LinearMap.comp (LinearMap.comp (↑e₁) (mulVecLin A)) (LinearMap.single i)) 1 =
    ↑(LinearMap.comp (LinearMap.comp (↑(toLin v₂ v₁) A) ↑e₂) (LinearMap.single i)) 1

tactic: rw [LinearMap.range_eq_top]
state_before: l : Type ?u.189630
m : Type u_5
n : Type u_1
o : Type ?u.189639
R : Type u_4
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_2
M₂ : Type u_3
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
⊢ LinearMap.range e₂ = ⊤

tactic: exact e₂.surjective
state_before: l : Type ?u.189630
m : Type u_5
n : Type u_1
o : Type ?u.189639
R : Type u_4
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_2
M₂ : Type u_3
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
⊢ Function.Surjective ↑e₂