Theorem: Matrix.Pivot.exists_list_transvec_mul_mul_list_transvec_eq_diagonal_induction
File: Mathlib/LinearAlgebra/Matrix/Transvection.lean

tactic: rcases exists_isTwoBlockDiagonal_list_transvec_mul_mul_list_transvec M with ⟨L₁, L₁', hM⟩
state_before: n : Type ?u.245499
p : Type ?u.245502
R : Type u₂
𝕜 : Type u_1
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
IH :
  ∀ (M : Matrix (Fin r) (Fin r) 𝕜),
    ∃ L₀ L₀' D₀, List.prod (List.map toMatrix L₀) ⬝ M ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
⊢ ∃ L L' D, List.prod (List.map toMatrix L) ⬝ M ⬝ List.prod (List.map toMatrix L') = diagonal D

tactic: let M' := (L₁.map toMatrix).prod ⬝ M ⬝ (L₁'.map toMatrix).prod
state_before: case intro.intro
n : Type ?u.245499
p : Type ?u.245502
R : Type u₂
𝕜 : Type u_1
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
IH :
  ∀ (M : Matrix (Fin r) (Fin r) 𝕜),
    ∃ L₀ L₀' D₀, List.prod (List.map toMatrix L₀) ⬝ M ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
L₁ L₁' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hM : IsTwoBlockDiagonal (List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁'))
⊢ ∃ L L' D, List.prod (List.map toMatrix L) ⬝ M ⬝ List.prod (List.map toMatrix L') = diagonal D

tactic: let M'' := toBlocks₁₁ M'
state_before: case intro.intro
n : Type ?u.245499
p : Type ?u.245502
R : Type u₂
𝕜 : Type u_1
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
IH :
  ∀ (M : Matrix (Fin r) (Fin r) 𝕜),
    ∃ L₀ L₀' D₀, List.prod (List.map toMatrix L₀) ⬝ M ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
L₁ L₁' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hM : IsTwoBlockDiagonal (List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁'))
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁')
⊢ ∃ L L' D, List.prod (List.map toMatrix L) ⬝ M ⬝ List.prod (List.map toMatrix L') = diagonal D

tactic: rcases IH M'' with ⟨L₀, L₀', D₀, h₀⟩
state_before: case intro.intro
n : Type ?u.245499
p : Type ?u.245502
R : Type u₂
𝕜 : Type u_1
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
IH :
  ∀ (M : Matrix (Fin r) (Fin r) 𝕜),
    ∃ L₀ L₀' D₀, List.prod (List.map toMatrix L₀) ⬝ M ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
L₁ L₁' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hM : IsTwoBlockDiagonal (List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁'))
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁')
M'' : Matrix (Fin r) (Fin r) 𝕜 := toBlocks₁₁ M'
⊢ ∃ L L' D, List.prod (List.map toMatrix L) ⬝ M ⬝ List.prod (List.map toMatrix L') = diagonal D

tactic: set c := M' (inr unit) (inr unit)
state_before: case intro.intro.intro.intro.intro
n : Type ?u.245499
p : Type ?u.245502
R : Type u₂
𝕜 : Type u_1
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
IH :
  ∀ (M : Matrix (Fin r) (Fin r) 𝕜),
    ∃ L₀ L₀' D₀, List.prod (List.map toMatrix L₀) ⬝ M ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
L₁ L₁' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hM : IsTwoBlockDiagonal (List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁'))
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁')
M'' : Matrix (Fin r) (Fin r) 𝕜 := toBlocks₁₁ M'
L₀ L₀' : List (TransvectionStruct (Fin r) 𝕜)
D₀ : Fin r → 𝕜
h₀ : List.prod (List.map toMatrix L₀) ⬝ M'' ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
⊢ ∃ L L' D, List.prod (List.map toMatrix L) ⬝ M ⬝ List.prod (List.map toMatrix L') = diagonal D

tactic: refine'
  ⟨L₀.map (sumInl Unit) ++ L₁, L₁' ++ L₀'.map (sumInl Unit),
    Sum.elim D₀ fun _ => M' (inr unit) (inr unit), _⟩
state_before: case intro.intro.intro.intro.intro
n : Type ?u.245499
p : Type ?u.245502
R : Type u₂
𝕜 : Type u_1
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
IH :
  ∀ (M : Matrix (Fin r) (Fin r) 𝕜),
    ∃ L₀ L₀' D₀, List.prod (List.map toMatrix L₀) ⬝ M ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
L₁ L₁' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hM : IsTwoBlockDiagonal (List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁'))
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁')
M'' : Matrix (Fin r) (Fin r) 𝕜 := toBlocks₁₁ M'
L₀ L₀' : List (TransvectionStruct (Fin r) 𝕜)
D₀ : Fin r → 𝕜
h₀ : List.prod (List.map toMatrix L₀) ⬝ M'' ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
c : 𝕜 := M' (inr ()) (inr ())
⊢ ∃ L L' D, List.prod (List.map toMatrix L) ⬝ M ⬝ List.prod (List.map toMatrix L') = diagonal D

tactic: suffices (L₀.map (toMatrix ∘ sumInl Unit)).prod ⬝ M' ⬝ (L₀'.map (toMatrix ∘ sumInl Unit)).prod =
    diagonal (Sum.elim D₀ fun _ => c) by
  simpa [Matrix.mul_assoc]
state_before: case intro.intro.intro.intro.intro
n : Type ?u.245499
p : Type ?u.245502
R : Type u₂
𝕜 : Type u_1
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
IH :
  ∀ (M : Matrix (Fin r) (Fin r) 𝕜),
    ∃ L₀ L₀' D₀, List.prod (List.map toMatrix L₀) ⬝ M ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
L₁ L₁' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hM : IsTwoBlockDiagonal (List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁'))
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁')
M'' : Matrix (Fin r) (Fin r) 𝕜 := toBlocks₁₁ M'
L₀ L₀' : List (TransvectionStruct (Fin r) 𝕜)
D₀ : Fin r → 𝕜
h₀ : List.prod (List.map toMatrix L₀) ⬝ M'' ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
c : 𝕜 := M' (inr ()) (inr ())
⊢ List.prod (List.map toMatrix (List.map (sumInl Unit) L₀ ++ L₁)) ⬝ M ⬝
      List.prod (List.map toMatrix (L₁' ++ List.map (sumInl Unit) L₀')) =
    diagonal (Sum.elim D₀ fun x => M' (inr ()) (inr ()))

tactic: have : M' = fromBlocks M'' 0 0 (diagonal fun _ => c) := by
  rw [← fromBlocks_toBlocks M', hM.1, hM.2]
  rfl
state_before: case intro.intro.intro.intro.intro
n : Type ?u.245499
p : Type ?u.245502
R : Type u₂
𝕜 : Type u_1
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
IH :
  ∀ (M : Matrix (Fin r) (Fin r) 𝕜),
    ∃ L₀ L₀' D₀, List.prod (List.map toMatrix L₀) ⬝ M ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
L₁ L₁' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hM : IsTwoBlockDiagonal (List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁'))
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁')
M'' : Matrix (Fin r) (Fin r) 𝕜 := toBlocks₁₁ M'
L₀ L₀' : List (TransvectionStruct (Fin r) 𝕜)
D₀ : Fin r → 𝕜
h₀ : List.prod (List.map toMatrix L₀) ⬝ M'' ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
c : 𝕜 := M' (inr ()) (inr ())
⊢ List.prod (List.map (toMatrix ∘ sumInl Unit) L₀) ⬝ M' ⬝ List.prod (List.map (toMatrix ∘ sumInl Unit) L₀') =
    diagonal (Sum.elim D₀ fun x => c)

tactic: rw [this]
state_before: case intro.intro.intro.intro.intro
n : Type ?u.245499
p : Type ?u.245502
R : Type u₂
𝕜 : Type u_1
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
IH :
  ∀ (M : Matrix (Fin r) (Fin r) 𝕜),
    ∃ L₀ L₀' D₀, List.prod (List.map toMatrix L₀) ⬝ M ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
L₁ L₁' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hM : IsTwoBlockDiagonal (List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁'))
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁')
M'' : Matrix (Fin r) (Fin r) 𝕜 := toBlocks₁₁ M'
L₀ L₀' : List (TransvectionStruct (Fin r) 𝕜)
D₀ : Fin r → 𝕜
h₀ : List.prod (List.map toMatrix L₀) ⬝ M'' ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
c : 𝕜 := M' (inr ()) (inr ())
this : M' = fromBlocks M'' 0 0 (diagonal fun x => c)
⊢ List.prod (List.map (toMatrix ∘ sumInl Unit) L₀) ⬝ M' ⬝ List.prod (List.map (toMatrix ∘ sumInl Unit) L₀') =
    diagonal (Sum.elim D₀ fun x => c)

tactic: simp [h₀]
state_before: case intro.intro.intro.intro.intro
n : Type ?u.245499
p : Type ?u.245502
R : Type u₂
𝕜 : Type u_1
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
IH :
  ∀ (M : Matrix (Fin r) (Fin r) 𝕜),
    ∃ L₀ L₀' D₀, List.prod (List.map toMatrix L₀) ⬝ M ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
L₁ L₁' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hM : IsTwoBlockDiagonal (List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁'))
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁')
M'' : Matrix (Fin r) (Fin r) 𝕜 := toBlocks₁₁ M'
L₀ L₀' : List (TransvectionStruct (Fin r) 𝕜)
D₀ : Fin r → 𝕜
h₀ : List.prod (List.map toMatrix L₀) ⬝ M'' ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
c : 𝕜 := M' (inr ()) (inr ())
this : M' = fromBlocks M'' 0 0 (diagonal fun x => c)
⊢ List.prod (List.map (toMatrix ∘ sumInl Unit) L₀) ⬝ fromBlocks M'' 0 0 (diagonal fun x => c) ⬝
      List.prod (List.map (toMatrix ∘ sumInl Unit) L₀') =
    diagonal (Sum.elim D₀ fun x => c)

tactic: simpa [Matrix.mul_assoc]
state_before: n : Type ?u.245499
p : Type ?u.245502
R : Type u₂
𝕜 : Type u_1
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
IH :
  ∀ (M : Matrix (Fin r) (Fin r) 𝕜),
    ∃ L₀ L₀' D₀, List.prod (List.map toMatrix L₀) ⬝ M ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
L₁ L₁' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hM : IsTwoBlockDiagonal (List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁'))
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁')
M'' : Matrix (Fin r) (Fin r) 𝕜 := toBlocks₁₁ M'
L₀ L₀' : List (TransvectionStruct (Fin r) 𝕜)
D₀ : Fin r → 𝕜
h₀ : List.prod (List.map toMatrix L₀) ⬝ M'' ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
c : 𝕜 := M' (inr ()) (inr ())
this :
  List.prod (List.map (toMatrix ∘ sumInl Unit) L₀) ⬝ M' ⬝ List.prod (List.map (toMatrix ∘ sumInl Unit) L₀') =
    diagonal (Sum.elim D₀ fun x => c)
⊢ List.prod (List.map toMatrix (List.map (sumInl Unit) L₀ ++ L₁)) ⬝ M ⬝
      List.prod (List.map toMatrix (L₁' ++ List.map (sumInl Unit) L₀')) =
    diagonal (Sum.elim D₀ fun x => M' (inr ()) (inr ()))

tactic: rw [← fromBlocks_toBlocks M', hM.1, hM.2]
state_before: n : Type ?u.245499
p : Type ?u.245502
R : Type u₂
𝕜 : Type u_1
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
IH :
  ∀ (M : Matrix (Fin r) (Fin r) 𝕜),
    ∃ L₀ L₀' D₀, List.prod (List.map toMatrix L₀) ⬝ M ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
L₁ L₁' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hM : IsTwoBlockDiagonal (List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁'))
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁')
M'' : Matrix (Fin r) (Fin r) 𝕜 := toBlocks₁₁ M'
L₀ L₀' : List (TransvectionStruct (Fin r) 𝕜)
D₀ : Fin r → 𝕜
h₀ : List.prod (List.map toMatrix L₀) ⬝ M'' ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
c : 𝕜 := M' (inr ()) (inr ())
⊢ M' = fromBlocks M'' 0 0 (diagonal fun x => c)

tactic: rfl
state_before: n : Type ?u.245499
p : Type ?u.245502
R : Type u₂
𝕜 : Type u_1
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
IH :
  ∀ (M : Matrix (Fin r) (Fin r) 𝕜),
    ∃ L₀ L₀' D₀, List.prod (List.map toMatrix L₀) ⬝ M ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
L₁ L₁' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hM : IsTwoBlockDiagonal (List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁'))
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := List.prod (List.map toMatrix L₁) ⬝ M ⬝ List.prod (List.map toMatrix L₁')
M'' : Matrix (Fin r) (Fin r) 𝕜 := toBlocks₁₁ M'
L₀ L₀' : List (TransvectionStruct (Fin r) 𝕜)
D₀ : Fin r → 𝕜
h₀ : List.prod (List.map toMatrix L₀) ⬝ M'' ⬝ List.prod (List.map toMatrix L₀') = diagonal D₀
c : 𝕜 := M' (inr ()) (inr ())
⊢ fromBlocks (toBlocks₁₁ M') 0 0 (toBlocks₂₂ M') = fromBlocks M'' 0 0 (diagonal fun x => c)