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

Proof steps:
state_before: l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
⊢ (Aᵀ * A).rank = A.rank
state_after: l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
⊢ finrank R ↥(LinearMap.range (Aᵀ * A).mulVecLin) = finrank R ↥(LinearMap.range A.mulVecLin)
tactic: dsimp only [rank]
state_before: l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
⊢ finrank R ↥(LinearMap.range (Aᵀ * A).mulVecLin) = finrank R ↥(LinearMap.range A.mulVecLin)
state_after: l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
⊢ (fun x => x + finrank R ↥(LinearMap.ker A.mulVecLin)) (finrank R ↥(LinearMap.range (Aᵀ * A).mulVecLin)) =
    (fun x => x + finrank R ↥(LinearMap.ker A.mulVecLin)) (finrank R ↥(LinearMap.range A.mulVecLin))
tactic: refine add_left_injective (finrank R <| LinearMap.ker A.mulVecLin) ?_
state_before: l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
⊢ (fun x => x + finrank R ↥(LinearMap.ker A.mulVecLin)) (finrank R ↥(LinearMap.range (Aᵀ * A).mulVecLin)) =
    (fun x => x + finrank R ↥(LinearMap.ker A.mulVecLin)) (finrank R ↥(LinearMap.range A.mulVecLin))
state_after: l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
⊢ finrank R ↥(LinearMap.range (Aᵀ * A).mulVecLin) + finrank R ↥(LinearMap.ker A.mulVecLin) =
    finrank R ↥(LinearMap.range A.mulVecLin) + finrank R ↥(LinearMap.ker A.mulVecLin)
tactic: dsimp only
state_before: l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
⊢ finrank R ↥(LinearMap.range (Aᵀ * A).mulVecLin) + finrank R ↥(LinearMap.ker A.mulVecLin) =
    finrank R ↥(LinearMap.range A.mulVecLin) + finrank R ↥(LinearMap.ker A.mulVecLin)
state_after: l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
⊢ finrank R ↥(LinearMap.range (Aᵀ * A).mulVecLin) + finrank R ↥(LinearMap.ker A.mulVecLin) =
    finrank R ↥(LinearMap.range (Aᵀ * A).mulVecLin) + finrank R ↥(LinearMap.ker (Aᵀ * A).mulVecLin)

l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
⊢ finrank R ↥(LinearMap.range (Aᵀ * A).mulVecLin) + finrank R ↥(LinearMap.ker (Aᵀ * A).mulVecLin) =
    finrank R ↥(LinearMap.range A.mulVecLin) + finrank R ↥(LinearMap.ker A.mulVecLin)
tactic: trans finrank R { x // x ∈ LinearMap.range (mulVecLin (Aᵀ * A)) } +
    finrank R { x // x ∈ LinearMap.ker (mulVecLin (Aᵀ * A)) }