[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
i j : n
⊢ transvection i j 0 = 1
[PROOFSTEP]
simp [transvection]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Finite n
c : R
⊢ updateRow 1 i (OfNat.ofNat 1 i + c • OfNat.ofNat 1 j) = transvection i j c
[PROOFSTEP]
cases nonempty_fintype n
[GOAL]
case intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Finite n
c : R
val✝ : Fintype n
⊢ updateRow 1 i (OfNat.ofNat 1 i + c • OfNat.ofNat 1 j) = transvection i j c
[PROOFSTEP]
ext a b
[GOAL]
case intro.a.h
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Finite n
c : R
val✝ : Fintype n
a b : n
⊢ updateRow 1 i (OfNat.ofNat 1 i + c • OfNat.ofNat 1 j) a b = transvection i j c a b
[PROOFSTEP]
by_cases ha : i = a
[GOAL]
case pos
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Finite n
c : R
val✝ : Fintype n
a b : n
ha : i = a
⊢ updateRow 1 i (OfNat.ofNat 1 i + c • OfNat.ofNat 1 j) a b = transvection i j c a b
case neg
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Finite n
c : R
val✝ : Fintype n
a b : n
ha : ¬i = a
⊢ updateRow 1 i (OfNat.ofNat 1 i + c • OfNat.ofNat 1 j) a b = transvection i j c a b
[PROOFSTEP]
by_cases hb : j = b
[GOAL]
case pos
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Finite n
c : R
val✝ : Fintype n
a b : n
ha : i = a
hb : j = b
⊢ updateRow 1 i (OfNat.ofNat 1 i + c • OfNat.ofNat 1 j) a b = transvection i j c a b
[PROOFSTEP]
simp only [updateRow_self, transvection, ha, hb, Pi.add_apply, StdBasisMatrix.apply_same, one_apply_eq, Pi.smul_apply,
  mul_one, Algebra.id.smul_eq_mul, add_apply]
[GOAL]
case neg
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Finite n
c : R
val✝ : Fintype n
a b : n
ha : i = a
hb : ¬j = b
⊢ updateRow 1 i (OfNat.ofNat 1 i + c • OfNat.ofNat 1 j) a b = transvection i j c a b
[PROOFSTEP]
simp only [updateRow_self, transvection, ha, hb, StdBasisMatrix.apply_of_ne, Pi.add_apply, Ne.def, not_false_iff,
  Pi.smul_apply, and_false_iff, one_apply_ne, Algebra.id.smul_eq_mul, mul_zero, add_apply]
[GOAL]
case neg
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Finite n
c : R
val✝ : Fintype n
a b : n
ha : ¬i = a
⊢ updateRow 1 i (OfNat.ofNat 1 i + c • OfNat.ofNat 1 j) a b = transvection i j c a b
[PROOFSTEP]
simp only [updateRow_ne, transvection, ha, Ne.symm ha, StdBasisMatrix.apply_of_ne, add_zero, Algebra.id.smul_eq_mul,
  Ne.def, not_false_iff, DMatrix.add_apply, Pi.smul_apply, mul_zero, false_and_iff, add_apply]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
h : i ≠ j
c d : R
⊢ transvection i j c * transvection i j d = transvection i j (c + d)
[PROOFSTEP]
simp [transvection, Matrix.add_mul, Matrix.mul_add, h, h.symm, add_smul, add_assoc, stdBasisMatrix_add]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
b : n
c : R
M : Matrix n n R
⊢ (transvection i j c * M) i b = M i b + c * M j b
[PROOFSTEP]
simp [transvection, Matrix.add_mul]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
a : n
c : R
M : Matrix n n R
⊢ (M * transvection i j c) a j = M a j + c * M a i
[PROOFSTEP]
simp [transvection, Matrix.mul_add, mul_comm]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
a b : n
ha : a ≠ i
c : R
M : Matrix n n R
⊢ (transvection i j c * M) a b = M a b
[PROOFSTEP]
simp [transvection, Matrix.add_mul, ha]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
a b : n
hb : b ≠ j
c : R
M : Matrix n n R
⊢ (M * transvection i j c) a b = M a b
[PROOFSTEP]
simp [transvection, Matrix.mul_add, hb]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
h : i ≠ j
c : R
⊢ det (transvection i j c) = 1
[PROOFSTEP]
rw [← updateRow_eq_transvection i j, det_updateRow_add_smul_self _ h, det_one]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Nontrivial n
⊢ Nonempty (TransvectionStruct n R)
[PROOFSTEP]
choose x y hxy using exists_pair_ne n
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Nontrivial n
x y : n
hxy : x ≠ y
⊢ Nonempty (TransvectionStruct n R)
[PROOFSTEP]
exact ⟨⟨x, y, hxy, 0⟩⟩
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
L : List (TransvectionStruct n 𝕜)
⊢ det (List.prod (List.map toMatrix L)) = 1
[PROOFSTEP]
induction' L with t L IH
[GOAL]
case nil
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
⊢ det (List.prod (List.map toMatrix [])) = 1
[PROOFSTEP]
simp
[GOAL]
case cons
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
t : TransvectionStruct n 𝕜
L : List (TransvectionStruct n 𝕜)
IH : det (List.prod (List.map toMatrix L)) = 1
⊢ det (List.prod (List.map toMatrix (t :: L))) = 1
[PROOFSTEP]
simp [IH]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
t : TransvectionStruct n R
⊢ toMatrix (TransvectionStruct.inv t) * toMatrix t = 1
[PROOFSTEP]
rcases t with ⟨_, _, t_hij⟩
[GOAL]
case mk
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
i✝ j✝ : n
t_hij : i✝ ≠ j✝
c✝ : R
⊢ toMatrix (TransvectionStruct.inv { i := i✝, j := j✝, hij := t_hij, c := c✝ }) *
      toMatrix { i := i✝, j := j✝, hij := t_hij, c := c✝ } =
    1
[PROOFSTEP]
simp [toMatrix, transvection_mul_transvection_same, t_hij]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
t : TransvectionStruct n R
⊢ toMatrix t * toMatrix (TransvectionStruct.inv t) = 1
[PROOFSTEP]
rcases t with ⟨_, _, t_hij⟩
[GOAL]
case mk
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
i✝ j✝ : n
t_hij : i✝ ≠ j✝
c✝ : R
⊢ toMatrix { i := i✝, j := j✝, hij := t_hij, c := c✝ } *
      toMatrix (TransvectionStruct.inv { i := i✝, j := j✝, hij := t_hij, c := c✝ }) =
    1
[PROOFSTEP]
simp [toMatrix, transvection_mul_transvection_same, t_hij]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
L : List (TransvectionStruct n R)
⊢ List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse L)) * List.prod (List.map toMatrix L) = 1
[PROOFSTEP]
induction' L with t L IH
[GOAL]
case nil
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
⊢ List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse [])) * List.prod (List.map toMatrix []) = 1
[PROOFSTEP]
simp
[GOAL]
case cons
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
t : TransvectionStruct n R
L : List (TransvectionStruct n R)
IH : List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse L)) * List.prod (List.map toMatrix L) = 1
⊢ List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse (t :: L))) *
      List.prod (List.map toMatrix (t :: L)) =
    1
[PROOFSTEP]
suffices
  (L.reverse.map (toMatrix ∘ TransvectionStruct.inv)).prod * (t.inv.toMatrix * t.toMatrix) * (L.map toMatrix).prod = 1
  by simpa [Matrix.mul_assoc]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
t : TransvectionStruct n R
L : List (TransvectionStruct n R)
IH : List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse L)) * List.prod (List.map toMatrix L) = 1
this :
  List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse L)) *
        (toMatrix (TransvectionStruct.inv t) * toMatrix t) *
      List.prod (List.map toMatrix L) =
    1
⊢ List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse (t :: L))) *
      List.prod (List.map toMatrix (t :: L)) =
    1
[PROOFSTEP]
simpa [Matrix.mul_assoc]
[GOAL]
case cons
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
t : TransvectionStruct n R
L : List (TransvectionStruct n R)
IH : List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse L)) * List.prod (List.map toMatrix L) = 1
⊢ List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse L)) *
        (toMatrix (TransvectionStruct.inv t) * toMatrix t) *
      List.prod (List.map toMatrix L) =
    1
[PROOFSTEP]
simpa [inv_mul] using IH
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
L : List (TransvectionStruct n R)
⊢ List.prod (List.map toMatrix L) * List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse L)) = 1
[PROOFSTEP]
induction' L with t L IH
[GOAL]
case nil
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
⊢ List.prod (List.map toMatrix []) * List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse [])) = 1
[PROOFSTEP]
simp
[GOAL]
case cons
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
t : TransvectionStruct n R
L : List (TransvectionStruct n R)
IH : List.prod (List.map toMatrix L) * List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse L)) = 1
⊢ List.prod (List.map toMatrix (t :: L)) *
      List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse (t :: L))) =
    1
[PROOFSTEP]
suffices
  t.toMatrix * ((L.map toMatrix).prod * (L.reverse.map (toMatrix ∘ TransvectionStruct.inv)).prod) * t.inv.toMatrix = 1
  by simpa [Matrix.mul_assoc]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
t : TransvectionStruct n R
L : List (TransvectionStruct n R)
IH : List.prod (List.map toMatrix L) * List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse L)) = 1
this :
  toMatrix t *
        (List.prod (List.map toMatrix L) * List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse L))) *
      toMatrix (TransvectionStruct.inv t) =
    1
⊢ List.prod (List.map toMatrix (t :: L)) *
      List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse (t :: L))) =
    1
[PROOFSTEP]
simpa [Matrix.mul_assoc]
[GOAL]
case cons
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
i j : n
inst✝ : Fintype n
t : TransvectionStruct n R
L : List (TransvectionStruct n R)
IH : List.prod (List.map toMatrix L) * List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse L)) = 1
⊢ toMatrix t *
        (List.prod (List.map toMatrix L) * List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse L))) *
      toMatrix (TransvectionStruct.inv t) =
    1
[PROOFSTEP]
simp_rw [IH, Matrix.mul_one, t.mul_inv]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
i j : n
t : TransvectionStruct n R
⊢ inl t.i ≠ inl t.j
[PROOFSTEP]
simp [t.hij]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
i j : n
t : TransvectionStruct n R
⊢ toMatrix (sumInl p t) = fromBlocks (toMatrix t) 0 0 1
[PROOFSTEP]
cases t
[GOAL]
case mk
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
i j i✝ j✝ : n
hij✝ : i✝ ≠ j✝
c✝ : R
⊢ toMatrix (sumInl p { i := i✝, j := j✝, hij := hij✝, c := c✝ }) =
    fromBlocks (toMatrix { i := i✝, j := j✝, hij := hij✝, c := c✝ }) 0 0 1
[PROOFSTEP]
ext a b
[GOAL]
case mk.a.h
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
i j i✝ j✝ : n
hij✝ : i✝ ≠ j✝
c✝ : R
a b : n ⊕ p
⊢ toMatrix (sumInl p { i := i✝, j := j✝, hij := hij✝, c := c✝ }) a b =
    fromBlocks (toMatrix { i := i✝, j := j✝, hij := hij✝, c := c✝ }) 0 0 1 a b
[PROOFSTEP]
cases' a with a a
[GOAL]
case mk.a.h.inl
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
i j i✝ j✝ : n
hij✝ : i✝ ≠ j✝
c✝ : R
b : n ⊕ p
a : n
⊢ toMatrix (sumInl p { i := i✝, j := j✝, hij := hij✝, c := c✝ }) (inl a) b =
    fromBlocks (toMatrix { i := i✝, j := j✝, hij := hij✝, c := c✝ }) 0 0 1 (inl a) b
[PROOFSTEP]
cases' b with b b
[GOAL]
case mk.a.h.inr
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
i j i✝ j✝ : n
hij✝ : i✝ ≠ j✝
c✝ : R
b : n ⊕ p
a : p
⊢ toMatrix (sumInl p { i := i✝, j := j✝, hij := hij✝, c := c✝ }) (inr a) b =
    fromBlocks (toMatrix { i := i✝, j := j✝, hij := hij✝, c := c✝ }) 0 0 1 (inr a) b
[PROOFSTEP]
cases' b with b b
[GOAL]
case mk.a.h.inl.inl
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
i j i✝ j✝ : n
hij✝ : i✝ ≠ j✝
c✝ : R
a b : n
⊢ toMatrix (sumInl p { i := i✝, j := j✝, hij := hij✝, c := c✝ }) (inl a) (inl b) =
    fromBlocks (toMatrix { i := i✝, j := j✝, hij := hij✝, c := c✝ }) 0 0 1 (inl a) (inl b)
[PROOFSTEP]
by_cases h : a = b
[GOAL]
case pos
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
i j i✝ j✝ : n
hij✝ : i✝ ≠ j✝
c✝ : R
a b : n
h : a = b
⊢ toMatrix (sumInl p { i := i✝, j := j✝, hij := hij✝, c := c✝ }) (inl a) (inl b) =
    fromBlocks (toMatrix { i := i✝, j := j✝, hij := hij✝, c := c✝ }) 0 0 1 (inl a) (inl b)
[PROOFSTEP]
simp [TransvectionStruct.sumInl, transvection, h, stdBasisMatrix]
[GOAL]
case neg
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
i j i✝ j✝ : n
hij✝ : i✝ ≠ j✝
c✝ : R
a b : n
h : ¬a = b
⊢ toMatrix (sumInl p { i := i✝, j := j✝, hij := hij✝, c := c✝ }) (inl a) (inl b) =
    fromBlocks (toMatrix { i := i✝, j := j✝, hij := hij✝, c := c✝ }) 0 0 1 (inl a) (inl b)
[PROOFSTEP]
simp [TransvectionStruct.sumInl, transvection, h, stdBasisMatrix]
[GOAL]
case mk.a.h.inl.inr
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
i j i✝ j✝ : n
hij✝ : i✝ ≠ j✝
c✝ : R
a : n
b : p
⊢ toMatrix (sumInl p { i := i✝, j := j✝, hij := hij✝, c := c✝ }) (inl a) (inr b) =
    fromBlocks (toMatrix { i := i✝, j := j✝, hij := hij✝, c := c✝ }) 0 0 1 (inl a) (inr b)
[PROOFSTEP]
simp [TransvectionStruct.sumInl, transvection]
[GOAL]
case mk.a.h.inr.inl
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
i j i✝ j✝ : n
hij✝ : i✝ ≠ j✝
c✝ : R
a : p
b : n
⊢ toMatrix (sumInl p { i := i✝, j := j✝, hij := hij✝, c := c✝ }) (inr a) (inl b) =
    fromBlocks (toMatrix { i := i✝, j := j✝, hij := hij✝, c := c✝ }) 0 0 1 (inr a) (inl b)
[PROOFSTEP]
simp [TransvectionStruct.sumInl, transvection]
[GOAL]
case mk.a.h.inr.inr
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
i j i✝ j✝ : n
hij✝ : i✝ ≠ j✝
c✝ : R
a b : p
⊢ toMatrix (sumInl p { i := i✝, j := j✝, hij := hij✝, c := c✝ }) (inr a) (inr b) =
    fromBlocks (toMatrix { i := i✝, j := j✝, hij := hij✝, c := c✝ }) 0 0 1 (inr a) (inr b)
[PROOFSTEP]
by_cases h : a = b
[GOAL]
case pos
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
i j i✝ j✝ : n
hij✝ : i✝ ≠ j✝
c✝ : R
a b : p
h : a = b
⊢ toMatrix (sumInl p { i := i✝, j := j✝, hij := hij✝, c := c✝ }) (inr a) (inr b) =
    fromBlocks (toMatrix { i := i✝, j := j✝, hij := hij✝, c := c✝ }) 0 0 1 (inr a) (inr b)
[PROOFSTEP]
simp [TransvectionStruct.sumInl, transvection, h]
[GOAL]
case neg
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
i j i✝ j✝ : n
hij✝ : i✝ ≠ j✝
c✝ : R
a b : p
h : ¬a = b
⊢ toMatrix (sumInl p { i := i✝, j := j✝, hij := hij✝, c := c✝ }) (inr a) (inr b) =
    fromBlocks (toMatrix { i := i✝, j := j✝, hij := hij✝, c := c✝ }) 0 0 1 (inr a) (inr b)
[PROOFSTEP]
simp [TransvectionStruct.sumInl, transvection, h]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
M : Matrix n n R
L : List (TransvectionStruct n R)
N : Matrix p p R
⊢ List.prod (List.map (toMatrix ∘ sumInl p) L) * fromBlocks M 0 0 N =
    fromBlocks (List.prod (List.map toMatrix L) * M) 0 0 N
[PROOFSTEP]
induction' L with t L IH
[GOAL]
case nil
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
M : Matrix n n R
N : Matrix p p R
⊢ List.prod (List.map (toMatrix ∘ sumInl p) []) * fromBlocks M 0 0 N =
    fromBlocks (List.prod (List.map toMatrix []) * M) 0 0 N
[PROOFSTEP]
simp
[GOAL]
case cons
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
M : Matrix n n R
N : Matrix p p R
t : TransvectionStruct n R
L : List (TransvectionStruct n R)
IH :
  List.prod (List.map (toMatrix ∘ sumInl p) L) * fromBlocks M 0 0 N =
    fromBlocks (List.prod (List.map toMatrix L) * M) 0 0 N
⊢ List.prod (List.map (toMatrix ∘ sumInl p) (t :: L)) * fromBlocks M 0 0 N =
    fromBlocks (List.prod (List.map toMatrix (t :: L)) * M) 0 0 N
[PROOFSTEP]
simp [Matrix.mul_assoc, IH, toMatrix_sumInl, fromBlocks_multiply]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
M : Matrix n n R
L : List (TransvectionStruct n R)
N : Matrix p p R
⊢ fromBlocks M 0 0 N * List.prod (List.map (toMatrix ∘ sumInl p) L) =
    fromBlocks (M * List.prod (List.map toMatrix L)) 0 0 N
[PROOFSTEP]
induction' L with t L IH generalizing M N
[GOAL]
case nil
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
M✝ : Matrix n n R
N✝ : Matrix p p R
M : Matrix n n R
N : Matrix p p R
⊢ fromBlocks M 0 0 N * List.prod (List.map (toMatrix ∘ sumInl p) []) =
    fromBlocks (M * List.prod (List.map toMatrix [])) 0 0 N
[PROOFSTEP]
simp
[GOAL]
case cons
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
M✝ : Matrix n n R
N✝ : Matrix p p R
t : TransvectionStruct n R
L : List (TransvectionStruct n R)
IH :
  ∀ (M : Matrix n n R) (N : Matrix p p R),
    fromBlocks M 0 0 N * List.prod (List.map (toMatrix ∘ sumInl p) L) =
      fromBlocks (M * List.prod (List.map toMatrix L)) 0 0 N
M : Matrix n n R
N : Matrix p p R
⊢ fromBlocks M 0 0 N * List.prod (List.map (toMatrix ∘ sumInl p) (t :: L)) =
    fromBlocks (M * List.prod (List.map toMatrix (t :: L))) 0 0 N
[PROOFSTEP]
simp [IH, toMatrix_sumInl, fromBlocks_multiply]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
i j : n
e : n ≃ p
t : TransvectionStruct n R
⊢ ↑e t.i ≠ ↑e t.j
[PROOFSTEP]
simp [t.hij]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
t : TransvectionStruct n R
⊢ toMatrix (reindexEquiv e t) = ↑(reindexAlgEquiv R e) (toMatrix t)
[PROOFSTEP]
rcases t with ⟨t_i, t_j, _⟩
[GOAL]
case mk
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
t_i t_j : n
hij✝ : t_i ≠ t_j
c✝ : R
⊢ toMatrix (reindexEquiv e { i := t_i, j := t_j, hij := hij✝, c := c✝ }) =
    ↑(reindexAlgEquiv R e) (toMatrix { i := t_i, j := t_j, hij := hij✝, c := c✝ })
[PROOFSTEP]
ext a b
[GOAL]
case mk.a.h
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
t_i t_j : n
hij✝ : t_i ≠ t_j
c✝ : R
a b : p
⊢ toMatrix (reindexEquiv e { i := t_i, j := t_j, hij := hij✝, c := c✝ }) a b =
    ↑(reindexAlgEquiv R e) (toMatrix { i := t_i, j := t_j, hij := hij✝, c := c✝ }) a b
[PROOFSTEP]
simp only [reindexEquiv, transvection, mul_boole, Algebra.id.smul_eq_mul, toMatrix_mk, submatrix_apply, reindex_apply,
  DMatrix.add_apply, Pi.smul_apply, reindexAlgEquiv_apply]
[GOAL]
case mk.a.h
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
t_i t_j : n
hij✝ : t_i ≠ t_j
c✝ : R
a b : p
⊢ (1 + stdBasisMatrix (↑e t_i) (↑e t_j) c✝) a b = (1 + stdBasisMatrix t_i t_j c✝) (↑e.symm a) (↑e.symm b)
[PROOFSTEP]
by_cases ha : e t_i = a
[GOAL]
case pos
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
t_i t_j : n
hij✝ : t_i ≠ t_j
c✝ : R
a b : p
ha : ↑e t_i = a
⊢ (1 + stdBasisMatrix (↑e t_i) (↑e t_j) c✝) a b = (1 + stdBasisMatrix t_i t_j c✝) (↑e.symm a) (↑e.symm b)
[PROOFSTEP]
by_cases hb : e t_j = b
[GOAL]
case neg
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
t_i t_j : n
hij✝ : t_i ≠ t_j
c✝ : R
a b : p
ha : ¬↑e t_i = a
⊢ (1 + stdBasisMatrix (↑e t_i) (↑e t_j) c✝) a b = (1 + stdBasisMatrix t_i t_j c✝) (↑e.symm a) (↑e.symm b)
[PROOFSTEP]
by_cases hb : e t_j = b
[GOAL]
case pos
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
t_i t_j : n
hij✝ : t_i ≠ t_j
c✝ : R
a b : p
ha : ↑e t_i = a
hb : ↑e t_j = b
⊢ (1 + stdBasisMatrix (↑e t_i) (↑e t_j) c✝) a b = (1 + stdBasisMatrix t_i t_j c✝) (↑e.symm a) (↑e.symm b)
[PROOFSTEP]
by_cases hab : a = b
[GOAL]
case neg
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
t_i t_j : n
hij✝ : t_i ≠ t_j
c✝ : R
a b : p
ha : ↑e t_i = a
hb : ¬↑e t_j = b
⊢ (1 + stdBasisMatrix (↑e t_i) (↑e t_j) c✝) a b = (1 + stdBasisMatrix t_i t_j c✝) (↑e.symm a) (↑e.symm b)
[PROOFSTEP]
by_cases hab : a = b
[GOAL]
case pos
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
t_i t_j : n
hij✝ : t_i ≠ t_j
c✝ : R
a b : p
ha : ¬↑e t_i = a
hb : ↑e t_j = b
⊢ (1 + stdBasisMatrix (↑e t_i) (↑e t_j) c✝) a b = (1 + stdBasisMatrix t_i t_j c✝) (↑e.symm a) (↑e.symm b)
[PROOFSTEP]
by_cases hab : a = b
[GOAL]
case neg
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
t_i t_j : n
hij✝ : t_i ≠ t_j
c✝ : R
a b : p
ha : ¬↑e t_i = a
hb : ¬↑e t_j = b
⊢ (1 + stdBasisMatrix (↑e t_i) (↑e t_j) c✝) a b = (1 + stdBasisMatrix t_i t_j c✝) (↑e.symm a) (↑e.symm b)
[PROOFSTEP]
by_cases hab : a = b
[GOAL]
case pos
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
t_i t_j : n
hij✝ : t_i ≠ t_j
c✝ : R
a b : p
ha : ↑e t_i = a
hb : ↑e t_j = b
hab : a = b
⊢ (1 + stdBasisMatrix (↑e t_i) (↑e t_j) c✝) a b = (1 + stdBasisMatrix t_i t_j c✝) (↑e.symm a) (↑e.symm b)
[PROOFSTEP]
simp [ha, hb, hab, ← e.apply_eq_iff_eq_symm_apply, stdBasisMatrix]
[GOAL]
case neg
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
t_i t_j : n
hij✝ : t_i ≠ t_j
c✝ : R
a b : p
ha : ↑e t_i = a
hb : ↑e t_j = b
hab : ¬a = b
⊢ (1 + stdBasisMatrix (↑e t_i) (↑e t_j) c✝) a b = (1 + stdBasisMatrix t_i t_j c✝) (↑e.symm a) (↑e.symm b)
[PROOFSTEP]
simp [ha, hb, hab, ← e.apply_eq_iff_eq_symm_apply, stdBasisMatrix]
[GOAL]
case pos
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
t_i t_j : n
hij✝ : t_i ≠ t_j
c✝ : R
a b : p
ha : ↑e t_i = a
hb : ¬↑e t_j = b
hab : a = b
⊢ (1 + stdBasisMatrix (↑e t_i) (↑e t_j) c✝) a b = (1 + stdBasisMatrix t_i t_j c✝) (↑e.symm a) (↑e.symm b)
[PROOFSTEP]
simp [ha, hb, hab, ← e.apply_eq_iff_eq_symm_apply, stdBasisMatrix]
[GOAL]
case neg
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
t_i t_j : n
hij✝ : t_i ≠ t_j
c✝ : R
a b : p
ha : ↑e t_i = a
hb : ¬↑e t_j = b
hab : ¬a = b
⊢ (1 + stdBasisMatrix (↑e t_i) (↑e t_j) c✝) a b = (1 + stdBasisMatrix t_i t_j c✝) (↑e.symm a) (↑e.symm b)
[PROOFSTEP]
simp [ha, hb, hab, ← e.apply_eq_iff_eq_symm_apply, stdBasisMatrix]
[GOAL]
case pos
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
t_i t_j : n
hij✝ : t_i ≠ t_j
c✝ : R
a b : p
ha : ¬↑e t_i = a
hb : ↑e t_j = b
hab : a = b
⊢ (1 + stdBasisMatrix (↑e t_i) (↑e t_j) c✝) a b = (1 + stdBasisMatrix t_i t_j c✝) (↑e.symm a) (↑e.symm b)
[PROOFSTEP]
simp [ha, hb, hab, ← e.apply_eq_iff_eq_symm_apply, stdBasisMatrix]
[GOAL]
case neg
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
t_i t_j : n
hij✝ : t_i ≠ t_j
c✝ : R
a b : p
ha : ¬↑e t_i = a
hb : ↑e t_j = b
hab : ¬a = b
⊢ (1 + stdBasisMatrix (↑e t_i) (↑e t_j) c✝) a b = (1 + stdBasisMatrix t_i t_j c✝) (↑e.symm a) (↑e.symm b)
[PROOFSTEP]
simp [ha, hb, hab, ← e.apply_eq_iff_eq_symm_apply, stdBasisMatrix]
[GOAL]
case pos
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
t_i t_j : n
hij✝ : t_i ≠ t_j
c✝ : R
a b : p
ha : ¬↑e t_i = a
hb : ¬↑e t_j = b
hab : a = b
⊢ (1 + stdBasisMatrix (↑e t_i) (↑e t_j) c✝) a b = (1 + stdBasisMatrix t_i t_j c✝) (↑e.symm a) (↑e.symm b)
[PROOFSTEP]
simp [ha, hb, hab, ← e.apply_eq_iff_eq_symm_apply, stdBasisMatrix]
[GOAL]
case neg
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
t_i t_j : n
hij✝ : t_i ≠ t_j
c✝ : R
a b : p
ha : ¬↑e t_i = a
hb : ¬↑e t_j = b
hab : ¬a = b
⊢ (1 + stdBasisMatrix (↑e t_i) (↑e t_j) c✝) a b = (1 + stdBasisMatrix t_i t_j c✝) (↑e.symm a) (↑e.symm b)
[PROOFSTEP]
simp [ha, hb, hab, ← e.apply_eq_iff_eq_symm_apply, stdBasisMatrix]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
L : List (TransvectionStruct n R)
⊢ List.prod (List.map (toMatrix ∘ reindexEquiv e) L) = ↑(reindexAlgEquiv R e) (List.prod (List.map toMatrix L))
[PROOFSTEP]
induction' L with t L IH
[GOAL]
case nil
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
⊢ List.prod (List.map (toMatrix ∘ reindexEquiv e) []) = ↑(reindexAlgEquiv R e) (List.prod (List.map toMatrix []))
[PROOFSTEP]
simp
[GOAL]
case cons
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
t : TransvectionStruct n R
L : List (TransvectionStruct n R)
IH : List.prod (List.map (toMatrix ∘ reindexEquiv e) L) = ↑(reindexAlgEquiv R e) (List.prod (List.map toMatrix L))
⊢ List.prod (List.map (toMatrix ∘ reindexEquiv e) (t :: L)) =
    ↑(reindexAlgEquiv R e) (List.prod (List.map toMatrix (t :: L)))
[PROOFSTEP]
simp only [toMatrix_reindexEquiv, IH, Function.comp_apply, List.prod_cons, reindexAlgEquiv_apply, List.map]
[GOAL]
case cons
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
i j : n
inst✝¹ : Fintype n
inst✝ : Fintype p
e : n ≃ p
t : TransvectionStruct n R
L : List (TransvectionStruct n R)
IH : List.prod (List.map (toMatrix ∘ reindexEquiv e) L) = ↑(reindexAlgEquiv R e) (List.prod (List.map toMatrix L))
⊢ ↑(reindex e e) (toMatrix t) * ↑(reindex e e) (List.prod (List.map toMatrix L)) =
    ↑(reindex e e) (toMatrix t * List.prod (List.map toMatrix L))
[PROOFSTEP]
exact (reindexAlgEquiv_mul _ _ _ _).symm
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
i : Fin r ⊕ Unit
k : ℕ
hk : k ≤ r
⊢ (List.prod (List.drop k (listTransvecCol M)) * M) (inr ()) i = M (inr ()) i
[PROOFSTEP]
refine' Nat.decreasingInduction' _ hk _
[GOAL]
case refine'_1
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
i : Fin r ⊕ Unit
k : ℕ
hk : k ≤ r
⊢ ∀ (k_1 : ℕ),
    k_1 < r →
      k ≤ k_1 →
        (List.prod (List.drop (k_1 + 1) (listTransvecCol M)) * M) (inr ()) i = M (inr ()) i →
          (List.prod (List.drop k_1 (listTransvecCol M)) * M) (inr ()) i = M (inr ()) i
[PROOFSTEP]
intro n hn _ IH
[GOAL]
case refine'_1
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
i : Fin r ⊕ Unit
k : ℕ
hk : k ≤ r
n : ℕ
hn : n < r
a✝ : k ≤ n
IH : (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inr ()) i = M (inr ()) i
⊢ (List.prod (List.drop n (listTransvecCol M)) * M) (inr ()) i = M (inr ()) i
[PROOFSTEP]
have hn' : n < (listTransvecCol M).length := by simpa [listTransvecCol] using hn
[GOAL]
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
i : Fin r ⊕ Unit
k : ℕ
hk : k ≤ r
n : ℕ
hn : n < r
a✝ : k ≤ n
IH : (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inr ()) i = M (inr ()) i
⊢ n < List.length (listTransvecCol M)
[PROOFSTEP]
simpa [listTransvecCol] using hn
[GOAL]
case refine'_1
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
i : Fin r ⊕ Unit
k : ℕ
hk : k ≤ r
n : ℕ
hn : n < r
a✝ : k ≤ n
IH : (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inr ()) i = M (inr ()) i
hn' : n < List.length (listTransvecCol M)
⊢ (List.prod (List.drop n (listTransvecCol M)) * M) (inr ()) i = M (inr ()) i
[PROOFSTEP]
rw [← @List.cons_get_drop_succ _ _ ⟨n, hn'⟩]
[GOAL]
case refine'_1
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
i : Fin r ⊕ Unit
k : ℕ
hk : k ≤ r
n : ℕ
hn : n < r
a✝ : k ≤ n
IH : (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inr ()) i = M (inr ()) i
hn' : n < List.length (listTransvecCol M)
⊢ (List.prod
          (List.get (listTransvecCol M) { val := n, isLt := hn' } ::
            List.drop (↑{ val := n, isLt := hn' } + 1) (listTransvecCol M)) *
        M)
      (inr ()) i =
    M (inr ()) i
[PROOFSTEP]
simpa [listTransvecCol, Matrix.mul_assoc]
[GOAL]
case refine'_2
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
i : Fin r ⊕ Unit
k : ℕ
hk : k ≤ r
⊢ (List.prod (List.drop r (listTransvecCol M)) * M) (inr ()) i = M (inr ()) i
[PROOFSTEP]
simp only [listTransvecCol, List.length_ofFn, le_refl, List.drop_eq_nil_of_le, List.prod_nil, Matrix.one_mul]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
i : Fin r ⊕ Unit
⊢ (List.prod (listTransvecCol M) * M) (inr ()) i = M (inr ()) i
[PROOFSTEP]
simpa using listTransvecCol_mul_last_row_drop M i (zero_le _)
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
⊢ (List.prod (listTransvecCol M) * M) (inl i) (inr ()) = 0
[PROOFSTEP]
suffices H :
  ∀ k : ℕ,
    k ≤ r → (((listTransvecCol M).drop k).prod * M) (inl i) (inr unit) = if k ≤ i then 0 else M (inl i) (inr unit)
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
H :
  ∀ (k : ℕ),
    k ≤ r →
      (List.prod (List.drop k (listTransvecCol M)) * M) (inl i) (inr ()) = if k ≤ ↑i then 0 else M (inl i) (inr ())
⊢ (List.prod (listTransvecCol M) * M) (inl i) (inr ()) = 0
[PROOFSTEP]
simpa only [List.drop, _root_.zero_le, ite_true] using H 0 (zero_le _)
[GOAL]
case H
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
⊢ ∀ (k : ℕ),
    k ≤ r →
      (List.prod (List.drop k (listTransvecCol M)) * M) (inl i) (inr ()) = if k ≤ ↑i then 0 else M (inl i) (inr ())
[PROOFSTEP]
intro k hk
[GOAL]
case H
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk : k ≤ r
⊢ (List.prod (List.drop k (listTransvecCol M)) * M) (inl i) (inr ()) = if k ≤ ↑i then 0 else M (inl i) (inr ())
[PROOFSTEP]
refine' Nat.decreasingInduction' _ hk _
[GOAL]
case H.refine'_1
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk : k ≤ r
⊢ ∀ (k_1 : ℕ),
    k_1 < r →
      k ≤ k_1 →
        ((List.prod (List.drop (k_1 + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
            if k_1 + 1 ≤ ↑i then 0 else M (inl i) (inr ())) →
          (List.prod (List.drop k_1 (listTransvecCol M)) * M) (inl i) (inr ()) =
            if k_1 ≤ ↑i then 0 else M (inl i) (inr ())
[PROOFSTEP]
intro n hn hk IH
[GOAL]
case H.refine'_1
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())
⊢ (List.prod (List.drop n (listTransvecCol M)) * M) (inl i) (inr ()) = if n ≤ ↑i then 0 else M (inl i) (inr ())
[PROOFSTEP]
have hn' : n < (listTransvecCol M).length := by simpa [listTransvecCol] using hn
[GOAL]
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())
⊢ n < List.length (listTransvecCol M)
[PROOFSTEP]
simpa [listTransvecCol] using hn
[GOAL]
case H.refine'_1
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())
hn' : n < List.length (listTransvecCol M)
⊢ (List.prod (List.drop n (listTransvecCol M)) * M) (inl i) (inr ()) = if n ≤ ↑i then 0 else M (inl i) (inr ())
[PROOFSTEP]
let n' : Fin r :=
  ⟨n, hn⟩
    -- porting note: after changing from `nthLe` to `get`, we need to provide all arguments
[GOAL]
case H.refine'_1
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())
hn' : n < List.length (listTransvecCol M)
n' : Fin r := { val := n, isLt := hn }
⊢ (List.prod (List.drop n (listTransvecCol M)) * M) (inl i) (inr ()) = if n ≤ ↑i then 0 else M (inl i) (inr ())
[PROOFSTEP]
rw [← @List.cons_get_drop_succ _ _ ⟨n, hn'⟩]
[GOAL]
case H.refine'_1
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())
hn' : n < List.length (listTransvecCol M)
n' : Fin r := { val := n, isLt := hn }
⊢ (List.prod
          (List.get (listTransvecCol M) { val := n, isLt := hn' } ::
            List.drop (↑{ val := n, isLt := hn' } + 1) (listTransvecCol M)) *
        M)
      (inl i) (inr ()) =
    if n ≤ ↑i then 0 else M (inl i) (inr ())
[PROOFSTEP]
have A :
  (listTransvecCol M).get ⟨n, hn'⟩ =
    transvection (inl n') (inr unit) (-M (inl n') (inr unit) / M (inr unit) (inr unit)) :=
  by simp [listTransvecCol]
[GOAL]
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())
hn' : n < List.length (listTransvecCol M)
n' : Fin r := { val := n, isLt := hn }
⊢ List.get (listTransvecCol M) { val := n, isLt := hn' } =
    transvection (inl n') (inr ()) (-M (inl n') (inr ()) / M (inr ()) (inr ()))
[PROOFSTEP]
simp [listTransvecCol]
[GOAL]
case H.refine'_1
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())
hn' : n < List.length (listTransvecCol M)
n' : Fin r := { val := n, isLt := hn }
A :
  List.get (listTransvecCol M) { val := n, isLt := hn' } =
    transvection (inl n') (inr ()) (-M (inl n') (inr ()) / M (inr ()) (inr ()))
⊢ (List.prod
          (List.get (listTransvecCol M) { val := n, isLt := hn' } ::
            List.drop (↑{ val := n, isLt := hn' } + 1) (listTransvecCol M)) *
        M)
      (inl i) (inr ()) =
    if n ≤ ↑i then 0 else M (inl i) (inr ())
[PROOFSTEP]
simp only [Matrix.mul_assoc, A, List.prod_cons]
[GOAL]
case H.refine'_1
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())
hn' : n < List.length (listTransvecCol M)
n' : Fin r := { val := n, isLt := hn }
A :
  List.get (listTransvecCol M) { val := n, isLt := hn' } =
    transvection (inl n') (inr ()) (-M (inl n') (inr ()) / M (inr ()) (inr ()))
⊢ (transvection (inl { val := n, isLt := hn }) (inr ())
          (-M (inl { val := n, isLt := hn }) (inr ()) / M (inr ()) (inr ())) *
        (List.prod (List.drop (n + 1) (listTransvecCol M)) * M))
      (inl i) (inr ()) =
    if n ≤ ↑i then 0 else M (inl i) (inr ())
[PROOFSTEP]
by_cases h : n' = i
[GOAL]
case pos
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())
hn' : n < List.length (listTransvecCol M)
n' : Fin r := { val := n, isLt := hn }
A :
  List.get (listTransvecCol M) { val := n, isLt := hn' } =
    transvection (inl n') (inr ()) (-M (inl n') (inr ()) / M (inr ()) (inr ()))
h : n' = i
⊢ (transvection (inl { val := n, isLt := hn }) (inr ())
          (-M (inl { val := n, isLt := hn }) (inr ()) / M (inr ()) (inr ())) *
        (List.prod (List.drop (n + 1) (listTransvecCol M)) * M))
      (inl i) (inr ()) =
    if n ≤ ↑i then 0 else M (inl i) (inr ())
[PROOFSTEP]
have hni : n = i := by
  cases i
  simp only [Fin.mk_eq_mk] at h 
  simp [h]
[GOAL]
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())
hn' : n < List.length (listTransvecCol M)
n' : Fin r := { val := n, isLt := hn }
A :
  List.get (listTransvecCol M) { val := n, isLt := hn' } =
    transvection (inl n') (inr ()) (-M (inl n') (inr ()) / M (inr ()) (inr ()))
h : n' = i
⊢ n = ↑i
[PROOFSTEP]
cases i
[GOAL]
case mk
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
hn' : n < List.length (listTransvecCol M)
n' : Fin r := { val := n, isLt := hn }
A :
  List.get (listTransvecCol M) { val := n, isLt := hn' } =
    transvection (inl n') (inr ()) (-M (inl n') (inr ()) / M (inr ()) (inr ()))
val✝ : ℕ
isLt✝ : val✝ < r
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl { val := val✝, isLt := isLt✝ }) (inr ()) =
    if n + 1 ≤ ↑{ val := val✝, isLt := isLt✝ } then 0 else M (inl { val := val✝, isLt := isLt✝ }) (inr ())
h : n' = { val := val✝, isLt := isLt✝ }
⊢ n = ↑{ val := val✝, isLt := isLt✝ }
[PROOFSTEP]
simp only [Fin.mk_eq_mk] at h 
[GOAL]
case mk
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
hn' : n < List.length (listTransvecCol M)
n' : Fin r := { val := n, isLt := hn }
A :
  List.get (listTransvecCol M) { val := n, isLt := hn' } =
    transvection (inl n') (inr ()) (-M (inl n') (inr ()) / M (inr ()) (inr ()))
val✝ : ℕ
isLt✝ : val✝ < r
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl { val := val✝, isLt := isLt✝ }) (inr ()) =
    if n + 1 ≤ ↑{ val := val✝, isLt := isLt✝ } then 0 else M (inl { val := val✝, isLt := isLt✝ }) (inr ())
h : n = val✝
⊢ n = ↑{ val := val✝, isLt := isLt✝ }
[PROOFSTEP]
simp [h]
[GOAL]
case pos
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())
hn' : n < List.length (listTransvecCol M)
n' : Fin r := { val := n, isLt := hn }
A :
  List.get (listTransvecCol M) { val := n, isLt := hn' } =
    transvection (inl n') (inr ()) (-M (inl n') (inr ()) / M (inr ()) (inr ()))
h : n' = i
hni : n = ↑i
⊢ (transvection (inl { val := n, isLt := hn }) (inr ())
          (-M (inl { val := n, isLt := hn }) (inr ()) / M (inr ()) (inr ())) *
        (List.prod (List.drop (n + 1) (listTransvecCol M)) * M))
      (inl i) (inr ()) =
    if n ≤ ↑i then 0 else M (inl i) (inr ())
[PROOFSTEP]
simp only [h, transvection_mul_apply_same, IH, ← hni, add_le_iff_nonpos_right, listTransvecCol_mul_last_row_drop _ _ hn]
[GOAL]
case pos
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())
hn' : n < List.length (listTransvecCol M)
n' : Fin r := { val := n, isLt := hn }
A :
  List.get (listTransvecCol M) { val := n, isLt := hn' } =
    transvection (inl n') (inr ()) (-M (inl n') (inr ()) / M (inr ()) (inr ()))
h : n' = i
hni : n = ↑i
⊢ (if False then 0 else M (inl i) (inr ())) + -M (inl i) (inr ()) / M (inr ()) (inr ()) * M (inr ()) (inr ()) =
    if n ≤ n then 0 else M (inl i) (inr ())
[PROOFSTEP]
field_simp [hM]
[GOAL]
case neg
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())
hn' : n < List.length (listTransvecCol M)
n' : Fin r := { val := n, isLt := hn }
A :
  List.get (listTransvecCol M) { val := n, isLt := hn' } =
    transvection (inl n') (inr ()) (-M (inl n') (inr ()) / M (inr ()) (inr ()))
h : ¬n' = i
⊢ (transvection (inl { val := n, isLt := hn }) (inr ())
          (-M (inl { val := n, isLt := hn }) (inr ()) / M (inr ()) (inr ())) *
        (List.prod (List.drop (n + 1) (listTransvecCol M)) * M))
      (inl i) (inr ()) =
    if n ≤ ↑i then 0 else M (inl i) (inr ())
[PROOFSTEP]
have hni : n ≠ i := by
  rintro rfl
  cases i
  simp at h 
[GOAL]
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())
hn' : n < List.length (listTransvecCol M)
n' : Fin r := { val := n, isLt := hn }
A :
  List.get (listTransvecCol M) { val := n, isLt := hn' } =
    transvection (inl n') (inr ()) (-M (inl n') (inr ()) / M (inr ()) (inr ()))
h : ¬n' = i
⊢ n ≠ ↑i
[PROOFSTEP]
rintro rfl
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
hn : ↑i < r
hk : k ≤ ↑i
IH :
  (List.prod (List.drop (↑i + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if ↑i + 1 ≤ ↑i then 0 else M (inl i) (inr ())
hn' : ↑i < List.length (listTransvecCol M)
n' : Fin r := { val := ↑i, isLt := hn }
A :
  List.get (listTransvecCol M) { val := ↑i, isLt := hn' } =
    transvection (inl n') (inr ()) (-M (inl n') (inr ()) / M (inr ()) (inr ()))
h : ¬n' = i
⊢ False
[PROOFSTEP]
cases i
[GOAL]
case mk
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
k : ℕ
hk✝ : k ≤ r
val✝ : ℕ
isLt✝ : val✝ < r
hn : ↑{ val := val✝, isLt := isLt✝ } < r
hk : k ≤ ↑{ val := val✝, isLt := isLt✝ }
IH :
  (List.prod (List.drop (↑{ val := val✝, isLt := isLt✝ } + 1) (listTransvecCol M)) * M)
      (inl { val := val✝, isLt := isLt✝ }) (inr ()) =
    if ↑{ val := val✝, isLt := isLt✝ } + 1 ≤ ↑{ val := val✝, isLt := isLt✝ } then 0
    else M (inl { val := val✝, isLt := isLt✝ }) (inr ())
hn' : ↑{ val := val✝, isLt := isLt✝ } < List.length (listTransvecCol M)
n' : Fin r := { val := ↑{ val := val✝, isLt := isLt✝ }, isLt := hn }
A :
  List.get (listTransvecCol M) { val := ↑{ val := val✝, isLt := isLt✝ }, isLt := hn' } =
    transvection (inl n') (inr ()) (-M (inl n') (inr ()) / M (inr ()) (inr ()))
h : ¬n' = { val := val✝, isLt := isLt✝ }
⊢ False
[PROOFSTEP]
simp at h 
[GOAL]
case neg
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())
hn' : n < List.length (listTransvecCol M)
n' : Fin r := { val := n, isLt := hn }
A :
  List.get (listTransvecCol M) { val := n, isLt := hn' } =
    transvection (inl n') (inr ()) (-M (inl n') (inr ()) / M (inr ()) (inr ()))
h : ¬n' = i
hni : n ≠ ↑i
⊢ (transvection (inl { val := n, isLt := hn }) (inr ())
          (-M (inl { val := n, isLt := hn }) (inr ()) / M (inr ()) (inr ())) *
        (List.prod (List.drop (n + 1) (listTransvecCol M)) * M))
      (inl i) (inr ()) =
    if n ≤ ↑i then 0 else M (inl i) (inr ())
[PROOFSTEP]
simp only [ne_eq, inl.injEq, Ne.symm h, not_false_eq_true, transvection_mul_apply_of_ne]
[GOAL]
case neg
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())
hn' : n < List.length (listTransvecCol M)
n' : Fin r := { val := n, isLt := hn }
A :
  List.get (listTransvecCol M) { val := n, isLt := hn' } =
    transvection (inl n') (inr ()) (-M (inl n') (inr ()) / M (inr ()) (inr ()))
h : ¬n' = i
hni : n ≠ ↑i
⊢ (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) = if n ≤ ↑i then 0 else M (inl i) (inr ())
[PROOFSTEP]
rw [IH]
[GOAL]
case neg
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())
hn' : n < List.length (listTransvecCol M)
n' : Fin r := { val := n, isLt := hn }
A :
  List.get (listTransvecCol M) { val := n, isLt := hn' } =
    transvection (inl n') (inr ()) (-M (inl n') (inr ()) / M (inr ()) (inr ()))
h : ¬n' = i
hni : n ≠ ↑i
⊢ (if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())) = if n ≤ ↑i then 0 else M (inl i) (inr ())
[PROOFSTEP]
rcases le_or_lt (n + 1) i with (hi | hi)
[GOAL]
case neg.inl
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())
hn' : n < List.length (listTransvecCol M)
n' : Fin r := { val := n, isLt := hn }
A :
  List.get (listTransvecCol M) { val := n, isLt := hn' } =
    transvection (inl n') (inr ()) (-M (inl n') (inr ()) / M (inr ()) (inr ()))
h : ¬n' = i
hni : n ≠ ↑i
hi : n + 1 ≤ ↑i
⊢ (if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())) = if n ≤ ↑i then 0 else M (inl i) (inr ())
[PROOFSTEP]
simp only [hi, n.le_succ.trans hi, if_true]
[GOAL]
case neg.inr
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())
hn' : n < List.length (listTransvecCol M)
n' : Fin r := { val := n, isLt := hn }
A :
  List.get (listTransvecCol M) { val := n, isLt := hn' } =
    transvection (inl n') (inr ()) (-M (inl n') (inr ()) / M (inr ()) (inr ()))
h : ¬n' = i
hni : n ≠ ↑i
hi : ↑i < n + 1
⊢ (if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())) = if n ≤ ↑i then 0 else M (inl i) (inr ())
[PROOFSTEP]
rw [if_neg, if_neg]
[GOAL]
case neg.inr.hnc
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())
hn' : n < List.length (listTransvecCol M)
n' : Fin r := { val := n, isLt := hn }
A :
  List.get (listTransvecCol M) { val := n, isLt := hn' } =
    transvection (inl n') (inr ()) (-M (inl n') (inr ()) / M (inr ()) (inr ()))
h : ¬n' = i
hni : n ≠ ↑i
hi : ↑i < n + 1
⊢ ¬n ≤ ↑i
[PROOFSTEP]
simpa only [hni.symm, not_le, or_false_iff] using Nat.lt_succ_iff_lt_or_eq.1 hi
[GOAL]
case neg.inr.hnc
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
hn : n < r
hk : k ≤ n
IH :
  (List.prod (List.drop (n + 1) (listTransvecCol M)) * M) (inl i) (inr ()) =
    if n + 1 ≤ ↑i then 0 else M (inl i) (inr ())
hn' : n < List.length (listTransvecCol M)
n' : Fin r := { val := n, isLt := hn }
A :
  List.get (listTransvecCol M) { val := n, isLt := hn' } =
    transvection (inl n') (inr ()) (-M (inl n') (inr ()) / M (inr ()) (inr ()))
h : ¬n' = i
hni : n ≠ ↑i
hi : ↑i < n + 1
⊢ ¬n + 1 ≤ ↑i
[PROOFSTEP]
simpa only [not_le] using hi
[GOAL]
case H.refine'_2
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk : k ≤ r
⊢ (List.prod (List.drop r (listTransvecCol M)) * M) (inl i) (inr ()) = if r ≤ ↑i then 0 else M (inl i) (inr ())
[PROOFSTEP]
simp only [listTransvecCol, List.length_ofFn, le_refl, List.drop_eq_nil_of_le, List.prod_nil, Matrix.one_mul]
[GOAL]
case H.refine'_2
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk : k ≤ r
⊢ M (inl i) (inr ()) = if r ≤ ↑i then 0 else M (inl i) (inr ())
[PROOFSTEP]
rw [if_neg]
[GOAL]
case H.refine'_2.hnc
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk : k ≤ r
⊢ ¬r ≤ ↑i
[PROOFSTEP]
simpa only [not_le] using i.2
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
i : Fin r ⊕ Unit
k : ℕ
hk : k ≤ r
⊢ (M * List.prod (List.take k (listTransvecRow M))) i (inr ()) = M i (inr ())
[PROOFSTEP]
induction' k with k IH
[GOAL]
case zero
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
i : Fin r ⊕ Unit
k : ℕ
hk✝ : k ≤ r
hk : Nat.zero ≤ r
⊢ (M * List.prod (List.take Nat.zero (listTransvecRow M))) i (inr ()) = M i (inr ())
[PROOFSTEP]
simp only [Matrix.mul_one, List.take_zero, List.prod_nil, List.take, Matrix.mul_one]
[GOAL]
case succ
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
i : Fin r ⊕ Unit
k✝ : ℕ
hk✝ : k✝ ≤ r
k : ℕ
IH : k ≤ r → (M * List.prod (List.take k (listTransvecRow M))) i (inr ()) = M i (inr ())
hk : Nat.succ k ≤ r
⊢ (M * List.prod (List.take (Nat.succ k) (listTransvecRow M))) i (inr ()) = M i (inr ())
[PROOFSTEP]
have hkr : k < r := hk
[GOAL]
case succ
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
i : Fin r ⊕ Unit
k✝ : ℕ
hk✝ : k✝ ≤ r
k : ℕ
IH : k ≤ r → (M * List.prod (List.take k (listTransvecRow M))) i (inr ()) = M i (inr ())
hk : Nat.succ k ≤ r
hkr : k < r
⊢ (M * List.prod (List.take (Nat.succ k) (listTransvecRow M))) i (inr ()) = M i (inr ())
[PROOFSTEP]
let k' : Fin r := ⟨k, hkr⟩
[GOAL]
case succ
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
i : Fin r ⊕ Unit
k✝ : ℕ
hk✝ : k✝ ≤ r
k : ℕ
IH : k ≤ r → (M * List.prod (List.take k (listTransvecRow M))) i (inr ()) = M i (inr ())
hk : Nat.succ k ≤ r
hkr : k < r
k' : Fin r := { val := k, isLt := hkr }
⊢ (M * List.prod (List.take (Nat.succ k) (listTransvecRow M))) i (inr ()) = M i (inr ())
[PROOFSTEP]
have :
  (listTransvecRow M).get? k =
    ↑(transvection (inr Unit.unit) (inl k') (-M (inr Unit.unit) (inl k') / M (inr Unit.unit) (inr Unit.unit))) :=
  by simp only [listTransvecRow, List.ofFnNthVal, hkr, dif_pos, List.get?_ofFn]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
i : Fin r ⊕ Unit
k✝ : ℕ
hk✝ : k✝ ≤ r
k : ℕ
IH : k ≤ r → (M * List.prod (List.take k (listTransvecRow M))) i (inr ()) = M i (inr ())
hk : Nat.succ k ≤ r
hkr : k < r
k' : Fin r := { val := k, isLt := hkr }
⊢ List.get? (listTransvecRow M) k = some (transvection (inr ()) (inl k') (-M (inr ()) (inl k') / M (inr ()) (inr ())))
[PROOFSTEP]
simp only [listTransvecRow, List.ofFnNthVal, hkr, dif_pos, List.get?_ofFn]
[GOAL]
case succ
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
i : Fin r ⊕ Unit
k✝ : ℕ
hk✝ : k✝ ≤ r
k : ℕ
IH : k ≤ r → (M * List.prod (List.take k (listTransvecRow M))) i (inr ()) = M i (inr ())
hk : Nat.succ k ≤ r
hkr : k < r
k' : Fin r := { val := k, isLt := hkr }
this :
  List.get? (listTransvecRow M) k = some (transvection (inr ()) (inl k') (-M (inr ()) (inl k') / M (inr ()) (inr ())))
⊢ (M * List.prod (List.take (Nat.succ k) (listTransvecRow M))) i (inr ()) = M i (inr ())
[PROOFSTEP]
simp only [List.take_succ, ← Matrix.mul_assoc, this, List.prod_append, Matrix.mul_one, List.prod_cons, List.prod_nil,
  Option.to_list_some]
[GOAL]
case succ
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
i : Fin r ⊕ Unit
k✝ : ℕ
hk✝ : k✝ ≤ r
k : ℕ
IH : k ≤ r → (M * List.prod (List.take k (listTransvecRow M))) i (inr ()) = M i (inr ())
hk : Nat.succ k ≤ r
hkr : k < r
k' : Fin r := { val := k, isLt := hkr }
this :
  List.get? (listTransvecRow M) k = some (transvection (inr ()) (inl k') (-M (inr ()) (inl k') / M (inr ()) (inr ())))
⊢ (M * List.prod (List.take k (listTransvecRow M)) *
        transvection (inr ()) (inl { val := k, isLt := hkr })
          (-M (inr ()) (inl { val := k, isLt := hkr }) / M (inr ()) (inr ())))
      i (inr ()) =
    M i (inr ())
[PROOFSTEP]
rw [mul_transvection_apply_of_ne, IH hkr.le]
[GOAL]
case succ.hb
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
i : Fin r ⊕ Unit
k✝ : ℕ
hk✝ : k✝ ≤ r
k : ℕ
IH : k ≤ r → (M * List.prod (List.take k (listTransvecRow M))) i (inr ()) = M i (inr ())
hk : Nat.succ k ≤ r
hkr : k < r
k' : Fin r := { val := k, isLt := hkr }
this :
  List.get? (listTransvecRow M) k = some (transvection (inr ()) (inl k') (-M (inr ()) (inl k') / M (inr ()) (inr ())))
⊢ inr () ≠ inl { val := k, isLt := hkr }
[PROOFSTEP]
simp only [Ne.def, not_false_iff]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
i : Fin r ⊕ Unit
⊢ (M * List.prod (listTransvecRow M)) i (inr ()) = M i (inr ())
[PROOFSTEP]
have A : (listTransvecRow M).length = r := by simp [listTransvecRow]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
i : Fin r ⊕ Unit
⊢ List.length (listTransvecRow M) = r
[PROOFSTEP]
simp [listTransvecRow]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
i : Fin r ⊕ Unit
A : List.length (listTransvecRow M) = r
⊢ (M * List.prod (listTransvecRow M)) i (inr ()) = M i (inr ())
[PROOFSTEP]
rw [← List.take_length (listTransvecRow M), A]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
i : Fin r ⊕ Unit
A : List.length (listTransvecRow M) = r
⊢ (M * List.prod (List.take r (listTransvecRow M))) i (inr ()) = M i (inr ())
[PROOFSTEP]
simpa using mul_listTransvecRow_last_col_take M i le_rfl
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
⊢ (M * List.prod (listTransvecRow M)) (inr ()) (inl i) = 0
[PROOFSTEP]
suffices H :
  ∀ k : ℕ,
    k ≤ r → (M * ((listTransvecRow M).take k).prod) (inr unit) (inl i) = if k ≤ i then M (inr unit) (inl i) else 0
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
H :
  ∀ (k : ℕ),
    k ≤ r →
      (M * List.prod (List.take k (listTransvecRow M))) (inr ()) (inl i) = if k ≤ ↑i then M (inr ()) (inl i) else 0
⊢ (M * List.prod (listTransvecRow M)) (inr ()) (inl i) = 0
[PROOFSTEP]
have A : (listTransvecRow M).length = r := by simp [listTransvecRow]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
H :
  ∀ (k : ℕ),
    k ≤ r →
      (M * List.prod (List.take k (listTransvecRow M))) (inr ()) (inl i) = if k ≤ ↑i then M (inr ()) (inl i) else 0
⊢ List.length (listTransvecRow M) = r
[PROOFSTEP]
simp [listTransvecRow]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
H :
  ∀ (k : ℕ),
    k ≤ r →
      (M * List.prod (List.take k (listTransvecRow M))) (inr ()) (inl i) = if k ≤ ↑i then M (inr ()) (inl i) else 0
A : List.length (listTransvecRow M) = r
⊢ (M * List.prod (listTransvecRow M)) (inr ()) (inl i) = 0
[PROOFSTEP]
rw [← List.take_length (listTransvecRow M), A]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
H :
  ∀ (k : ℕ),
    k ≤ r →
      (M * List.prod (List.take k (listTransvecRow M))) (inr ()) (inl i) = if k ≤ ↑i then M (inr ()) (inl i) else 0
A : List.length (listTransvecRow M) = r
⊢ (M * List.prod (List.take r (listTransvecRow M))) (inr ()) (inl i) = 0
[PROOFSTEP]
have : ¬r ≤ i := by simp
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
H :
  ∀ (k : ℕ),
    k ≤ r →
      (M * List.prod (List.take k (listTransvecRow M))) (inr ()) (inl i) = if k ≤ ↑i then M (inr ()) (inl i) else 0
A : List.length (listTransvecRow M) = r
⊢ ¬r ≤ ↑i
[PROOFSTEP]
simp
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
H :
  ∀ (k : ℕ),
    k ≤ r →
      (M * List.prod (List.take k (listTransvecRow M))) (inr ()) (inl i) = if k ≤ ↑i then M (inr ()) (inl i) else 0
A : List.length (listTransvecRow M) = r
this : ¬r ≤ ↑i
⊢ (M * List.prod (List.take r (listTransvecRow M))) (inr ()) (inl i) = 0
[PROOFSTEP]
simpa only [this, ite_eq_right_iff] using H r le_rfl
[GOAL]
case H
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
⊢ ∀ (k : ℕ),
    k ≤ r →
      (M * List.prod (List.take k (listTransvecRow M))) (inr ()) (inl i) = if k ≤ ↑i then M (inr ()) (inl i) else 0
[PROOFSTEP]
intro k hk
[GOAL]
case H
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk : k ≤ r
⊢ (M * List.prod (List.take k (listTransvecRow M))) (inr ()) (inl i) = if k ≤ ↑i then M (inr ()) (inl i) else 0
[PROOFSTEP]
induction' k with n IH
[GOAL]
case H.zero
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
hk : Nat.zero ≤ r
⊢ (M * List.prod (List.take Nat.zero (listTransvecRow M))) (inr ()) (inl i) =
    if Nat.zero ≤ ↑i then M (inr ()) (inl i) else 0
[PROOFSTEP]
simp only [if_true, Matrix.mul_one, List.take_zero, zero_le', List.prod_nil, Nat.zero_eq]
[GOAL]
case H.succ
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
IH :
  n ≤ r → (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl i) = if n ≤ ↑i then M (inr ()) (inl i) else 0
hk : Nat.succ n ≤ r
⊢ (M * List.prod (List.take (Nat.succ n) (listTransvecRow M))) (inr ()) (inl i) =
    if Nat.succ n ≤ ↑i then M (inr ()) (inl i) else 0
[PROOFSTEP]
have hnr : n < r := hk
[GOAL]
case H.succ
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
IH :
  n ≤ r → (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl i) = if n ≤ ↑i then M (inr ()) (inl i) else 0
hk : Nat.succ n ≤ r
hnr : n < r
⊢ (M * List.prod (List.take (Nat.succ n) (listTransvecRow M))) (inr ()) (inl i) =
    if Nat.succ n ≤ ↑i then M (inr ()) (inl i) else 0
[PROOFSTEP]
let n' : Fin r := ⟨n, hnr⟩
[GOAL]
case H.succ
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
IH :
  n ≤ r → (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl i) = if n ≤ ↑i then M (inr ()) (inl i) else 0
hk : Nat.succ n ≤ r
hnr : n < r
n' : Fin r := { val := n, isLt := hnr }
⊢ (M * List.prod (List.take (Nat.succ n) (listTransvecRow M))) (inr ()) (inl i) =
    if Nat.succ n ≤ ↑i then M (inr ()) (inl i) else 0
[PROOFSTEP]
have A :
  (listTransvecRow M).get? n = ↑(transvection (inr unit) (inl n') (-M (inr unit) (inl n') / M (inr unit) (inr unit))) :=
  by simp only [listTransvecRow, List.ofFnNthVal, hnr, dif_pos, List.get?_ofFn]
[GOAL]
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
IH :
  n ≤ r → (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl i) = if n ≤ ↑i then M (inr ()) (inl i) else 0
hk : Nat.succ n ≤ r
hnr : n < r
n' : Fin r := { val := n, isLt := hnr }
⊢ List.get? (listTransvecRow M) n = some (transvection (inr ()) (inl n') (-M (inr ()) (inl n') / M (inr ()) (inr ())))
[PROOFSTEP]
simp only [listTransvecRow, List.ofFnNthVal, hnr, dif_pos, List.get?_ofFn]
[GOAL]
case H.succ
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
IH :
  n ≤ r → (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl i) = if n ≤ ↑i then M (inr ()) (inl i) else 0
hk : Nat.succ n ≤ r
hnr : n < r
n' : Fin r := { val := n, isLt := hnr }
A : List.get? (listTransvecRow M) n = some (transvection (inr ()) (inl n') (-M (inr ()) (inl n') / M (inr ()) (inr ())))
⊢ (M * List.prod (List.take (Nat.succ n) (listTransvecRow M))) (inr ()) (inl i) =
    if Nat.succ n ≤ ↑i then M (inr ()) (inl i) else 0
[PROOFSTEP]
simp only [List.take_succ, A, ← Matrix.mul_assoc, List.prod_append, Matrix.mul_one, List.prod_cons, List.prod_nil,
  Option.to_list_some]
[GOAL]
case H.succ
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
IH :
  n ≤ r → (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl i) = if n ≤ ↑i then M (inr ()) (inl i) else 0
hk : Nat.succ n ≤ r
hnr : n < r
n' : Fin r := { val := n, isLt := hnr }
A : List.get? (listTransvecRow M) n = some (transvection (inr ()) (inl n') (-M (inr ()) (inl n') / M (inr ()) (inr ())))
⊢ (M * List.prod (List.take n (listTransvecRow M)) *
        transvection (inr ()) (inl { val := n, isLt := hnr })
          (-M (inr ()) (inl { val := n, isLt := hnr }) / M (inr ()) (inr ())))
      (inr ()) (inl i) =
    if Nat.succ n ≤ ↑i then M (inr ()) (inl i) else 0
[PROOFSTEP]
by_cases h : n' = i
[GOAL]
case pos
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
IH :
  n ≤ r → (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl i) = if n ≤ ↑i then M (inr ()) (inl i) else 0
hk : Nat.succ n ≤ r
hnr : n < r
n' : Fin r := { val := n, isLt := hnr }
A : List.get? (listTransvecRow M) n = some (transvection (inr ()) (inl n') (-M (inr ()) (inl n') / M (inr ()) (inr ())))
h : n' = i
⊢ (M * List.prod (List.take n (listTransvecRow M)) *
        transvection (inr ()) (inl { val := n, isLt := hnr })
          (-M (inr ()) (inl { val := n, isLt := hnr }) / M (inr ()) (inr ())))
      (inr ()) (inl i) =
    if Nat.succ n ≤ ↑i then M (inr ()) (inl i) else 0
[PROOFSTEP]
have hni : n = i := by
  cases i
  simp only [Fin.mk_eq_mk] at h 
  simp only [h]
[GOAL]
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
IH :
  n ≤ r → (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl i) = if n ≤ ↑i then M (inr ()) (inl i) else 0
hk : Nat.succ n ≤ r
hnr : n < r
n' : Fin r := { val := n, isLt := hnr }
A : List.get? (listTransvecRow M) n = some (transvection (inr ()) (inl n') (-M (inr ()) (inl n') / M (inr ()) (inr ())))
h : n' = i
⊢ n = ↑i
[PROOFSTEP]
cases i
[GOAL]
case mk
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
k : ℕ
hk✝ : k ≤ r
n : ℕ
hk : Nat.succ n ≤ r
hnr : n < r
n' : Fin r := { val := n, isLt := hnr }
A : List.get? (listTransvecRow M) n = some (transvection (inr ()) (inl n') (-M (inr ()) (inl n') / M (inr ()) (inr ())))
val✝ : ℕ
isLt✝ : val✝ < r
IH :
  n ≤ r →
    (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl { val := val✝, isLt := isLt✝ }) =
      if n ≤ ↑{ val := val✝, isLt := isLt✝ } then M (inr ()) (inl { val := val✝, isLt := isLt✝ }) else 0
h : n' = { val := val✝, isLt := isLt✝ }
⊢ n = ↑{ val := val✝, isLt := isLt✝ }
[PROOFSTEP]
simp only [Fin.mk_eq_mk] at h 
[GOAL]
case mk
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
k : ℕ
hk✝ : k ≤ r
n : ℕ
hk : Nat.succ n ≤ r
hnr : n < r
n' : Fin r := { val := n, isLt := hnr }
A : List.get? (listTransvecRow M) n = some (transvection (inr ()) (inl n') (-M (inr ()) (inl n') / M (inr ()) (inr ())))
val✝ : ℕ
isLt✝ : val✝ < r
IH :
  n ≤ r →
    (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl { val := val✝, isLt := isLt✝ }) =
      if n ≤ ↑{ val := val✝, isLt := isLt✝ } then M (inr ()) (inl { val := val✝, isLt := isLt✝ }) else 0
h : n = val✝
⊢ n = ↑{ val := val✝, isLt := isLt✝ }
[PROOFSTEP]
simp only [h]
[GOAL]
case pos
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
IH :
  n ≤ r → (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl i) = if n ≤ ↑i then M (inr ()) (inl i) else 0
hk : Nat.succ n ≤ r
hnr : n < r
n' : Fin r := { val := n, isLt := hnr }
A : List.get? (listTransvecRow M) n = some (transvection (inr ()) (inl n') (-M (inr ()) (inl n') / M (inr ()) (inr ())))
h : n' = i
hni : n = ↑i
⊢ (M * List.prod (List.take n (listTransvecRow M)) *
        transvection (inr ()) (inl { val := n, isLt := hnr })
          (-M (inr ()) (inl { val := n, isLt := hnr }) / M (inr ()) (inr ())))
      (inr ()) (inl i) =
    if Nat.succ n ≤ ↑i then M (inr ()) (inl i) else 0
[PROOFSTEP]
have : ¬n.succ ≤ i := by simp only [← hni, n.lt_succ_self, not_le]
[GOAL]
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
IH :
  n ≤ r → (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl i) = if n ≤ ↑i then M (inr ()) (inl i) else 0
hk : Nat.succ n ≤ r
hnr : n < r
n' : Fin r := { val := n, isLt := hnr }
A : List.get? (listTransvecRow M) n = some (transvection (inr ()) (inl n') (-M (inr ()) (inl n') / M (inr ()) (inr ())))
h : n' = i
hni : n = ↑i
⊢ ¬Nat.succ n ≤ ↑i
[PROOFSTEP]
simp only [← hni, n.lt_succ_self, not_le]
[GOAL]
case pos
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
IH :
  n ≤ r → (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl i) = if n ≤ ↑i then M (inr ()) (inl i) else 0
hk : Nat.succ n ≤ r
hnr : n < r
n' : Fin r := { val := n, isLt := hnr }
A : List.get? (listTransvecRow M) n = some (transvection (inr ()) (inl n') (-M (inr ()) (inl n') / M (inr ()) (inr ())))
h : n' = i
hni : n = ↑i
this : ¬Nat.succ n ≤ ↑i
⊢ (M * List.prod (List.take n (listTransvecRow M)) *
        transvection (inr ()) (inl { val := n, isLt := hnr })
          (-M (inr ()) (inl { val := n, isLt := hnr }) / M (inr ()) (inr ())))
      (inr ()) (inl i) =
    if Nat.succ n ≤ ↑i then M (inr ()) (inl i) else 0
[PROOFSTEP]
simp only [h, mul_transvection_apply_same, List.take, if_false, mul_listTransvecRow_last_col_take _ _ hnr.le, hni.le,
  this, if_true, IH hnr.le]
[GOAL]
case pos
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
IH :
  n ≤ r → (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl i) = if n ≤ ↑i then M (inr ()) (inl i) else 0
hk : Nat.succ n ≤ r
hnr : n < r
n' : Fin r := { val := n, isLt := hnr }
A : List.get? (listTransvecRow M) n = some (transvection (inr ()) (inl n') (-M (inr ()) (inl n') / M (inr ()) (inr ())))
h : n' = i
hni : n = ↑i
this : ¬Nat.succ n ≤ ↑i
⊢ M (inr ()) (inl i) + -M (inr ()) (inl i) / M (inr ()) (inr ()) * M (inr ()) (inr ()) = 0
[PROOFSTEP]
field_simp [hM]
[GOAL]
case neg
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
IH :
  n ≤ r → (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl i) = if n ≤ ↑i then M (inr ()) (inl i) else 0
hk : Nat.succ n ≤ r
hnr : n < r
n' : Fin r := { val := n, isLt := hnr }
A : List.get? (listTransvecRow M) n = some (transvection (inr ()) (inl n') (-M (inr ()) (inl n') / M (inr ()) (inr ())))
h : ¬n' = i
⊢ (M * List.prod (List.take n (listTransvecRow M)) *
        transvection (inr ()) (inl { val := n, isLt := hnr })
          (-M (inr ()) (inl { val := n, isLt := hnr }) / M (inr ()) (inr ())))
      (inr ()) (inl i) =
    if Nat.succ n ≤ ↑i then M (inr ()) (inl i) else 0
[PROOFSTEP]
have hni : n ≠ i := by
  rintro rfl
  cases i
  tauto
[GOAL]
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
IH :
  n ≤ r → (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl i) = if n ≤ ↑i then M (inr ()) (inl i) else 0
hk : Nat.succ n ≤ r
hnr : n < r
n' : Fin r := { val := n, isLt := hnr }
A : List.get? (listTransvecRow M) n = some (transvection (inr ()) (inl n') (-M (inr ()) (inl n') / M (inr ()) (inr ())))
h : ¬n' = i
⊢ n ≠ ↑i
[PROOFSTEP]
rintro rfl
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
IH :
  ↑i ≤ r →
    (M * List.prod (List.take (↑i) (listTransvecRow M))) (inr ()) (inl i) = if ↑i ≤ ↑i then M (inr ()) (inl i) else 0
hk : Nat.succ ↑i ≤ r
hnr : ↑i < r
n' : Fin r := { val := ↑i, isLt := hnr }
A :
  List.get? (listTransvecRow M) ↑i = some (transvection (inr ()) (inl n') (-M (inr ()) (inl n') / M (inr ()) (inr ())))
h : ¬n' = i
⊢ False
[PROOFSTEP]
cases i
[GOAL]
case mk
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
k : ℕ
hk✝ : k ≤ r
val✝ : ℕ
isLt✝ : val✝ < r
IH :
  ↑{ val := val✝, isLt := isLt✝ } ≤ r →
    (M * List.prod (List.take (↑{ val := val✝, isLt := isLt✝ }) (listTransvecRow M))) (inr ())
        (inl { val := val✝, isLt := isLt✝ }) =
      if ↑{ val := val✝, isLt := isLt✝ } ≤ ↑{ val := val✝, isLt := isLt✝ } then
        M (inr ()) (inl { val := val✝, isLt := isLt✝ })
      else 0
hk : Nat.succ ↑{ val := val✝, isLt := isLt✝ } ≤ r
hnr : ↑{ val := val✝, isLt := isLt✝ } < r
n' : Fin r := { val := ↑{ val := val✝, isLt := isLt✝ }, isLt := hnr }
A :
  List.get? (listTransvecRow M) ↑{ val := val✝, isLt := isLt✝ } =
    some (transvection (inr ()) (inl n') (-M (inr ()) (inl n') / M (inr ()) (inr ())))
h : ¬n' = { val := val✝, isLt := isLt✝ }
⊢ False
[PROOFSTEP]
tauto
[GOAL]
case neg
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
IH :
  n ≤ r → (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl i) = if n ≤ ↑i then M (inr ()) (inl i) else 0
hk : Nat.succ n ≤ r
hnr : n < r
n' : Fin r := { val := n, isLt := hnr }
A : List.get? (listTransvecRow M) n = some (transvection (inr ()) (inl n') (-M (inr ()) (inl n') / M (inr ()) (inr ())))
h : ¬n' = i
hni : n ≠ ↑i
⊢ (M * List.prod (List.take n (listTransvecRow M)) *
        transvection (inr ()) (inl { val := n, isLt := hnr })
          (-M (inr ()) (inl { val := n, isLt := hnr }) / M (inr ()) (inr ())))
      (inr ()) (inl i) =
    if Nat.succ n ≤ ↑i then M (inr ()) (inl i) else 0
[PROOFSTEP]
simp only [IH hnr.le, Ne.def, mul_transvection_apply_of_ne, Ne.symm h, inl.injEq]
[GOAL]
case neg
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
IH :
  n ≤ r → (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl i) = if n ≤ ↑i then M (inr ()) (inl i) else 0
hk : Nat.succ n ≤ r
hnr : n < r
n' : Fin r := { val := n, isLt := hnr }
A : List.get? (listTransvecRow M) n = some (transvection (inr ()) (inl n') (-M (inr ()) (inl n') / M (inr ()) (inr ())))
h : ¬n' = i
hni : n ≠ ↑i
⊢ (if n ≤ ↑i then M (inr ()) (inl i) else 0) = if Nat.succ n ≤ ↑i then M (inr ()) (inl i) else 0
[PROOFSTEP]
rcases le_or_lt (n + 1) i with (hi | hi)
[GOAL]
case neg.inl
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
IH :
  n ≤ r → (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl i) = if n ≤ ↑i then M (inr ()) (inl i) else 0
hk : Nat.succ n ≤ r
hnr : n < r
n' : Fin r := { val := n, isLt := hnr }
A : List.get? (listTransvecRow M) n = some (transvection (inr ()) (inl n') (-M (inr ()) (inl n') / M (inr ()) (inr ())))
h : ¬n' = i
hni : n ≠ ↑i
hi : n + 1 ≤ ↑i
⊢ (if n ≤ ↑i then M (inr ()) (inl i) else 0) = if Nat.succ n ≤ ↑i then M (inr ()) (inl i) else 0
[PROOFSTEP]
simp [hi, n.le_succ.trans hi, if_true]
[GOAL]
case neg.inr
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
IH :
  n ≤ r → (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl i) = if n ≤ ↑i then M (inr ()) (inl i) else 0
hk : Nat.succ n ≤ r
hnr : n < r
n' : Fin r := { val := n, isLt := hnr }
A : List.get? (listTransvecRow M) n = some (transvection (inr ()) (inl n') (-M (inr ()) (inl n') / M (inr ()) (inr ())))
h : ¬n' = i
hni : n ≠ ↑i
hi : ↑i < n + 1
⊢ (if n ≤ ↑i then M (inr ()) (inl i) else 0) = if Nat.succ n ≤ ↑i then M (inr ()) (inl i) else 0
[PROOFSTEP]
rw [if_neg, if_neg]
[GOAL]
case neg.inr.hnc
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
IH :
  n ≤ r → (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl i) = if n ≤ ↑i then M (inr ()) (inl i) else 0
hk : Nat.succ n ≤ r
hnr : n < r
n' : Fin r := { val := n, isLt := hnr }
A : List.get? (listTransvecRow M) n = some (transvection (inr ()) (inl n') (-M (inr ()) (inl n') / M (inr ()) (inr ())))
h : ¬n' = i
hni : n ≠ ↑i
hi : ↑i < n + 1
⊢ ¬Nat.succ n ≤ ↑i
[PROOFSTEP]
simpa only [not_le] using hi
[GOAL]
case neg.inr.hnc
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n✝
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
k : ℕ
hk✝ : k ≤ r
n : ℕ
IH :
  n ≤ r → (M * List.prod (List.take n (listTransvecRow M))) (inr ()) (inl i) = if n ≤ ↑i then M (inr ()) (inl i) else 0
hk : Nat.succ n ≤ r
hnr : n < r
n' : Fin r := { val := n, isLt := hnr }
A : List.get? (listTransvecRow M) n = some (transvection (inr ()) (inl n') (-M (inr ()) (inl n') / M (inr ()) (inr ())))
h : ¬n' = i
hni : n ≠ ↑i
hi : ↑i < n + 1
⊢ ¬n ≤ ↑i
[PROOFSTEP]
simpa only [hni.symm, not_le, or_false_iff] using Nat.lt_succ_iff_lt_or_eq.1 hi
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
⊢ (List.prod (listTransvecCol M) * M * List.prod (listTransvecRow M)) (inr ()) (inl i) = 0
[PROOFSTEP]
have : listTransvecRow M = listTransvecRow ((listTransvecCol M).prod * M) := by
  simp [listTransvecRow, listTransvecCol_mul_last_row]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
⊢ listTransvecRow M = listTransvecRow (List.prod (listTransvecCol M) * M)
[PROOFSTEP]
simp [listTransvecRow, listTransvecCol_mul_last_row]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
this : listTransvecRow M = listTransvecRow (List.prod (listTransvecCol M) * M)
⊢ (List.prod (listTransvecCol M) * M * List.prod (listTransvecRow M)) (inr ()) (inl i) = 0
[PROOFSTEP]
rw [this]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
this : listTransvecRow M = listTransvecRow (List.prod (listTransvecCol M) * M)
⊢ (List.prod (listTransvecCol M) * M * List.prod (listTransvecRow (List.prod (listTransvecCol M) * M))) (inr ())
      (inl i) =
    0
[PROOFSTEP]
apply mul_listTransvecRow_last_row
[GOAL]
case hM
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
this : listTransvecRow M = listTransvecRow (List.prod (listTransvecCol M) * M)
⊢ (List.prod (listTransvecCol M) * M) (inr ()) (inr ()) ≠ 0
[PROOFSTEP]
simpa [listTransvecCol_mul_last_row] using hM
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
⊢ (List.prod (listTransvecCol M) * M * List.prod (listTransvecRow M)) (inl i) (inr ()) = 0
[PROOFSTEP]
have : listTransvecCol M = listTransvecCol (M * (listTransvecRow M).prod) := by
  simp [listTransvecCol, mul_listTransvecRow_last_col]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
⊢ listTransvecCol M = listTransvecCol (M * List.prod (listTransvecRow M))
[PROOFSTEP]
simp [listTransvecCol, mul_listTransvecRow_last_col]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
this : listTransvecCol M = listTransvecCol (M * List.prod (listTransvecRow M))
⊢ (List.prod (listTransvecCol M) * M * List.prod (listTransvecRow M)) (inl i) (inr ()) = 0
[PROOFSTEP]
rw [this, Matrix.mul_assoc]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
this : listTransvecCol M = listTransvecCol (M * List.prod (listTransvecRow M))
⊢ (List.prod (listTransvecCol (M * List.prod (listTransvecRow M))) * (M * List.prod (listTransvecRow M))) (inl i)
      (inr ()) =
    0
[PROOFSTEP]
apply listTransvecCol_mul_last_col
[GOAL]
case hM
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
this : listTransvecCol M = listTransvecCol (M * List.prod (listTransvecRow M))
⊢ (M * List.prod (listTransvecRow M)) (inr ()) (inr ()) ≠ 0
[PROOFSTEP]
simpa [mul_listTransvecRow_last_col] using hM
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
⊢ IsTwoBlockDiagonal (List.prod (listTransvecCol M) * M * List.prod (listTransvecRow M))
[PROOFSTEP]
constructor
[GOAL]
case left
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
⊢ toBlocks₁₂ (List.prod (listTransvecCol M) * M * List.prod (listTransvecRow M)) = 0
[PROOFSTEP]
ext i j
[GOAL]
case left.a.h
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
j : Unit
⊢ toBlocks₁₂ (List.prod (listTransvecCol M) * M * List.prod (listTransvecRow M)) i j = OfNat.ofNat 0 i j
[PROOFSTEP]
have : j = unit := by simp only [eq_iff_true_of_subsingleton]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
j : Unit
⊢ j = ()
[PROOFSTEP]
simp only [eq_iff_true_of_subsingleton]
[GOAL]
case left.a.h
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
j : Unit
this : j = ()
⊢ toBlocks₁₂ (List.prod (listTransvecCol M) * M * List.prod (listTransvecRow M)) i j = OfNat.ofNat 0 i j
[PROOFSTEP]
simp [toBlocks₁₂, this, listTransvecCol_mul_mul_listTransvecRow_last_row M hM]
[GOAL]
case right
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
⊢ toBlocks₂₁ (List.prod (listTransvecCol M) * M * List.prod (listTransvecRow M)) = 0
[PROOFSTEP]
ext i j
[GOAL]
case right.a.h
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Unit
j : Fin r
⊢ toBlocks₂₁ (List.prod (listTransvecCol M) * M * List.prod (listTransvecRow M)) i j = OfNat.ofNat 0 i j
[PROOFSTEP]
have : i = unit := by simp only [eq_iff_true_of_subsingleton]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Unit
j : Fin r
⊢ i = ()
[PROOFSTEP]
simp only [eq_iff_true_of_subsingleton]
[GOAL]
case right.a.h
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Unit
j : Fin r
this : i = ()
⊢ toBlocks₂₁ (List.prod (listTransvecCol M) * M * List.prod (listTransvecRow M)) i j = OfNat.ofNat 0 i j
[PROOFSTEP]
simp [toBlocks₂₁, this, listTransvecCol_mul_mul_listTransvecRow_last_col M hM]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
⊢ ∃ L L', IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
let L : List (TransvectionStruct (Sum (Fin r) Unit) 𝕜) :=
  List.ofFn fun i : Fin r => ⟨inl i, inr unit, by simp, -M (inl i) (inr unit) / M (inr unit) (inr unit)⟩
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
i : Fin r
⊢ inl i ≠ inr ()
[PROOFSTEP]
simp
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
L : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜) :=
  List.ofFn fun i =>
    { i := inl i, j := inr (), hij := (_ : ¬inl i = inr ()), c := -M (inl i) (inr ()) / M (inr ()) (inr ()) }
⊢ ∃ L L', IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
let L' : List (TransvectionStruct (Sum (Fin r) Unit) 𝕜) :=
  List.ofFn fun i : Fin r => ⟨inr unit, inl i, by simp, -M (inr unit) (inl i) / M (inr unit) (inr unit)⟩
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
L : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜) :=
  List.ofFn fun i =>
    { i := inl i, j := inr (), hij := (_ : ¬inl i = inr ()), c := -M (inl i) (inr ()) / M (inr ()) (inr ()) }
i : Fin r
⊢ inr () ≠ inl i
[PROOFSTEP]
simp
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
L : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜) :=
  List.ofFn fun i =>
    { i := inl i, j := inr (), hij := (_ : ¬inl i = inr ()), c := -M (inl i) (inr ()) / M (inr ()) (inr ()) }
L' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜) :=
  List.ofFn fun i =>
    { i := inr (), j := inl i, hij := (_ : ¬inr () = inl i), c := -M (inr ()) (inl i) / M (inr ()) (inr ()) }
⊢ ∃ L L', IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
refine' ⟨L, L', _⟩
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
L : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜) :=
  List.ofFn fun i =>
    { i := inl i, j := inr (), hij := (_ : ¬inl i = inr ()), c := -M (inl i) (inr ()) / M (inr ()) (inr ()) }
L' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜) :=
  List.ofFn fun i =>
    { i := inr (), j := inl i, hij := (_ : ¬inr () = inl i), c := -M (inr ()) (inl i) / M (inr ()) (inr ()) }
⊢ IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
have A : L.map toMatrix = listTransvecCol M := by simp [listTransvecCol, (· ∘ ·)]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
L : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜) :=
  List.ofFn fun i =>
    { i := inl i, j := inr (), hij := (_ : ¬inl i = inr ()), c := -M (inl i) (inr ()) / M (inr ()) (inr ()) }
L' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜) :=
  List.ofFn fun i =>
    { i := inr (), j := inl i, hij := (_ : ¬inr () = inl i), c := -M (inr ()) (inl i) / M (inr ()) (inr ()) }
⊢ List.map toMatrix L = listTransvecCol M
[PROOFSTEP]
simp [listTransvecCol, (· ∘ ·)]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
L : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜) :=
  List.ofFn fun i =>
    { i := inl i, j := inr (), hij := (_ : ¬inl i = inr ()), c := -M (inl i) (inr ()) / M (inr ()) (inr ()) }
L' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜) :=
  List.ofFn fun i =>
    { i := inr (), j := inl i, hij := (_ : ¬inr () = inl i), c := -M (inr ()) (inl i) / M (inr ()) (inr ()) }
A : List.map toMatrix L = listTransvecCol M
⊢ IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
have B : L'.map toMatrix = listTransvecRow M := by simp [listTransvecRow, (· ∘ ·)]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
L : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜) :=
  List.ofFn fun i =>
    { i := inl i, j := inr (), hij := (_ : ¬inl i = inr ()), c := -M (inl i) (inr ()) / M (inr ()) (inr ()) }
L' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜) :=
  List.ofFn fun i =>
    { i := inr (), j := inl i, hij := (_ : ¬inr () = inl i), c := -M (inr ()) (inl i) / M (inr ()) (inr ()) }
A : List.map toMatrix L = listTransvecCol M
⊢ List.map toMatrix L' = listTransvecRow M
[PROOFSTEP]
simp [listTransvecRow, (· ∘ ·)]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
L : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜) :=
  List.ofFn fun i =>
    { i := inl i, j := inr (), hij := (_ : ¬inl i = inr ()), c := -M (inl i) (inr ()) / M (inr ()) (inr ()) }
L' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜) :=
  List.ofFn fun i =>
    { i := inr (), j := inl i, hij := (_ : ¬inr () = inl i), c := -M (inr ()) (inl i) / M (inr ()) (inr ()) }
A : List.map toMatrix L = listTransvecCol M
B : List.map toMatrix L' = listTransvecRow M
⊢ IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
rw [A, B]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) ≠ 0
L : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜) :=
  List.ofFn fun i =>
    { i := inl i, j := inr (), hij := (_ : ¬inl i = inr ()), c := -M (inl i) (inr ()) / M (inr ()) (inr ()) }
L' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜) :=
  List.ofFn fun i =>
    { i := inr (), j := inl i, hij := (_ : ¬inr () = inl i), c := -M (inr ()) (inl i) / M (inr ()) (inr ()) }
A : List.map toMatrix L = listTransvecCol M
B : List.map toMatrix L' = listTransvecRow M
⊢ IsTwoBlockDiagonal (List.prod (listTransvecCol M) * M * List.prod (listTransvecRow M))
[PROOFSTEP]
exact isTwoBlockDiagonal_listTransvecCol_mul_mul_listTransvecRow M hM
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
⊢ ∃ L L', IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
by_cases H : IsTwoBlockDiagonal M
[GOAL]
case pos
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
H : IsTwoBlockDiagonal M
⊢ ∃ L L', IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
refine'
  ⟨List.nil, List.nil, by simpa using H⟩
    -- we have already proved this when the last coefficient is nonzero
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
H : IsTwoBlockDiagonal M
⊢ IsTwoBlockDiagonal (List.prod (List.map toMatrix []) * M * List.prod (List.map toMatrix []))
[PROOFSTEP]
simpa using H
[GOAL]
case neg
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
H : ¬IsTwoBlockDiagonal M
⊢ ∃ L L', IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
by_cases hM : M (inr unit) (inr unit) ≠ 0
[GOAL]
case pos
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
H : ¬IsTwoBlockDiagonal M
hM : M (inr ()) (inr ()) ≠ 0
⊢ ∃ L L', IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
exact exists_isTwoBlockDiagonal_of_ne_zero M hM
[GOAL]
case neg
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
H : ¬IsTwoBlockDiagonal M
hM : ¬M (inr ()) (inr ()) ≠ 0
⊢ ∃ L L', IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
push_neg at hM 
[GOAL]
case neg
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
H : ¬IsTwoBlockDiagonal M
hM : M (inr ()) (inr ()) = 0
⊢ ∃ L L', IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
simp only [not_and_or, IsTwoBlockDiagonal, toBlocks₁₂, toBlocks₂₁, ← Matrix.ext_iff] at H 
[GOAL]
case neg
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H :
  (¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j) ∨
    ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
⊢ ∃ L L', IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
have : ∃ i : Fin r, M (inl i) (inr unit) ≠ 0 ∨ M (inr unit) (inl i) ≠ 0 :=
  by
  cases' H with H H
  · contrapose! H
    rintro i ⟨⟩
    exact (H i).1
  · contrapose! H
    rintro ⟨⟩ j
    exact (H j).2
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H :
  (¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j) ∨
    ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
⊢ ∃ i, M (inl i) (inr ()) ≠ 0 ∨ M (inr ()) (inl i) ≠ 0
[PROOFSTEP]
cases' H with H H
[GOAL]
case inl
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H : ¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j
⊢ ∃ i, M (inl i) (inr ()) ≠ 0 ∨ M (inr ()) (inl i) ≠ 0
[PROOFSTEP]
contrapose! H
[GOAL]
case inl
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H : ∀ (i : Fin r), M (inl i) (inr ()) = 0 ∧ M (inr ()) (inl i) = 0
⊢ ∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j
[PROOFSTEP]
rintro i ⟨⟩
[GOAL]
case inl.unit
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H : ∀ (i : Fin r), M (inl i) (inr ()) = 0 ∧ M (inr ()) (inl i) = 0
i : Fin r
⊢ ↑of (fun i j => M (inl i) (inr j)) i PUnit.unit = OfNat.ofNat 0 i PUnit.unit
[PROOFSTEP]
exact (H i).1
[GOAL]
case inr
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H : ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
⊢ ∃ i, M (inl i) (inr ()) ≠ 0 ∨ M (inr ()) (inl i) ≠ 0
[PROOFSTEP]
contrapose! H
[GOAL]
case inr
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H : ∀ (i : Fin r), M (inl i) (inr ()) = 0 ∧ M (inr ()) (inl i) = 0
⊢ ∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
[PROOFSTEP]
rintro ⟨⟩ j
[GOAL]
case inr.unit
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H : ∀ (i : Fin r), M (inl i) (inr ()) = 0 ∧ M (inr ()) (inl i) = 0
j : Fin r
⊢ ↑of (fun i j => M (inr i) (inl j)) PUnit.unit j = OfNat.ofNat 0 PUnit.unit j
[PROOFSTEP]
exact (H j).2
[GOAL]
case neg
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H :
  (¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j) ∨
    ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
this : ∃ i, M (inl i) (inr ()) ≠ 0 ∨ M (inr ()) (inl i) ≠ 0
⊢ ∃ L L', IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
rcases this with ⟨i, h | h⟩
[GOAL]
case neg.intro.inl
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H :
  (¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j) ∨
    ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
i : Fin r
h : M (inl i) (inr ()) ≠ 0
⊢ ∃ L L', IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
let M' := transvection (inr Unit.unit) (inl i) 1 * M
[GOAL]
case neg.intro.inl
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H :
  (¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j) ∨
    ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
i : Fin r
h : M (inl i) (inr ()) ≠ 0
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := transvection (inr ()) (inl i) 1 * M
⊢ ∃ L L', IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
have hM' : M' (inr unit) (inr unit) ≠ 0 := by simpa [hM]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H :
  (¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j) ∨
    ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
i : Fin r
h : M (inl i) (inr ()) ≠ 0
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := transvection (inr ()) (inl i) 1 * M
⊢ M' (inr ()) (inr ()) ≠ 0
[PROOFSTEP]
simpa [hM]
[GOAL]
case neg.intro.inl
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H :
  (¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j) ∨
    ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
i : Fin r
h : M (inl i) (inr ()) ≠ 0
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := transvection (inr ()) (inl i) 1 * M
hM' : M' (inr ()) (inr ()) ≠ 0
⊢ ∃ L L', IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
rcases exists_isTwoBlockDiagonal_of_ne_zero M' hM' with ⟨L, L', hLL'⟩
[GOAL]
case neg.intro.inl.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H :
  (¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j) ∨
    ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
i : Fin r
h : M (inl i) (inr ()) ≠ 0
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := transvection (inr ()) (inl i) 1 * M
hM' : M' (inr ()) (inr ()) ≠ 0
L L' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hLL' : IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M' * List.prod (List.map toMatrix L'))
⊢ ∃ L L', IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
rw [Matrix.mul_assoc] at hLL' 
[GOAL]
case neg.intro.inl.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H :
  (¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j) ∨
    ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
i : Fin r
h : M (inl i) (inr ()) ≠ 0
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := transvection (inr ()) (inl i) 1 * M
hM' : M' (inr ()) (inr ()) ≠ 0
L L' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hLL' : IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * (M' * List.prod (List.map toMatrix L')))
⊢ ∃ L L', IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
refine' ⟨L ++ [⟨inr unit, inl i, by simp, 1⟩], L', _⟩
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H :
  (¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j) ∨
    ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
i : Fin r
h : M (inl i) (inr ()) ≠ 0
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := transvection (inr ()) (inl i) 1 * M
hM' : M' (inr ()) (inr ()) ≠ 0
L L' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hLL' : IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * (M' * List.prod (List.map toMatrix L')))
⊢ inr () ≠ inl i
[PROOFSTEP]
simp
[GOAL]
case neg.intro.inl.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H :
  (¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j) ∨
    ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
i : Fin r
h : M (inl i) (inr ()) ≠ 0
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := transvection (inr ()) (inl i) 1 * M
hM' : M' (inr ()) (inr ()) ≠ 0
L L' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hLL' : IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * (M' * List.prod (List.map toMatrix L')))
⊢ IsTwoBlockDiagonal
    (List.prod (List.map toMatrix (L ++ [{ i := inr (), j := inl i, hij := (_ : ¬inr () = inl i), c := 1 }])) * M *
      List.prod (List.map toMatrix L'))
[PROOFSTEP]
simp only [List.map_append, List.prod_append, Matrix.mul_one, toMatrix_mk, List.prod_cons, List.prod_nil, List.map,
  Matrix.mul_assoc (L.map toMatrix).prod]
[GOAL]
case neg.intro.inl.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H :
  (¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j) ∨
    ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
i : Fin r
h : M (inl i) (inr ()) ≠ 0
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := transvection (inr ()) (inl i) 1 * M
hM' : M' (inr ()) (inr ()) ≠ 0
L L' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hLL' : IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * (M' * List.prod (List.map toMatrix L')))
⊢ IsTwoBlockDiagonal
    (List.prod (List.map toMatrix L) * (transvection (inr ()) (inl i) 1 * M * List.prod (List.map toMatrix L')))
[PROOFSTEP]
exact hLL'
[GOAL]
case neg.intro.inr
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H :
  (¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j) ∨
    ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
i : Fin r
h : M (inr ()) (inl i) ≠ 0
⊢ ∃ L L', IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
let M' := M * transvection (inl i) (inr unit) 1
[GOAL]
case neg.intro.inr
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H :
  (¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j) ∨
    ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
i : Fin r
h : M (inr ()) (inl i) ≠ 0
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := M * transvection (inl i) (inr ()) 1
⊢ ∃ L L', IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
have hM' : M' (inr unit) (inr unit) ≠ 0 := by simpa [hM]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H :
  (¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j) ∨
    ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
i : Fin r
h : M (inr ()) (inl i) ≠ 0
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := M * transvection (inl i) (inr ()) 1
⊢ M' (inr ()) (inr ()) ≠ 0
[PROOFSTEP]
simpa [hM]
[GOAL]
case neg.intro.inr
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H :
  (¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j) ∨
    ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
i : Fin r
h : M (inr ()) (inl i) ≠ 0
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := M * transvection (inl i) (inr ()) 1
hM' : M' (inr ()) (inr ()) ≠ 0
⊢ ∃ L L', IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
rcases exists_isTwoBlockDiagonal_of_ne_zero M' hM' with ⟨L, L', hLL'⟩
[GOAL]
case neg.intro.inr.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H :
  (¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j) ∨
    ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
i : Fin r
h : M (inr ()) (inl i) ≠ 0
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := M * transvection (inl i) (inr ()) 1
hM' : M' (inr ()) (inr ()) ≠ 0
L L' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hLL' : IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M' * List.prod (List.map toMatrix L'))
⊢ ∃ L L', IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L'))
[PROOFSTEP]
refine' ⟨L, ⟨inl i, inr unit, by simp, 1⟩ :: L', _⟩
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H :
  (¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j) ∨
    ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
i : Fin r
h : M (inr ()) (inl i) ≠ 0
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := M * transvection (inl i) (inr ()) 1
hM' : M' (inr ()) (inr ()) ≠ 0
L L' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hLL' : IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M' * List.prod (List.map toMatrix L'))
⊢ inl i ≠ inr ()
[PROOFSTEP]
simp
[GOAL]
case neg.intro.inr.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H :
  (¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j) ∨
    ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
i : Fin r
h : M (inr ()) (inl i) ≠ 0
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := M * transvection (inl i) (inr ()) 1
hM' : M' (inr ()) (inr ()) ≠ 0
L L' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hLL' : IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M' * List.prod (List.map toMatrix L'))
⊢ IsTwoBlockDiagonal
    (List.prod (List.map toMatrix L) * M *
      List.prod (List.map toMatrix ({ i := inl i, j := inr (), hij := (_ : ¬inl i = inr ()), c := 1 } :: L')))
[PROOFSTEP]
simp only [← Matrix.mul_assoc, toMatrix_mk, List.prod_cons, List.map]
[GOAL]
case neg.intro.inr.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H :
  (¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j) ∨
    ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
i : Fin r
h : M (inr ()) (inl i) ≠ 0
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := M * transvection (inl i) (inr ()) 1
hM' : M' (inr ()) (inr ()) ≠ 0
L L' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hLL' : IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M' * List.prod (List.map toMatrix L'))
⊢ IsTwoBlockDiagonal
    (List.prod (List.map toMatrix L) * M * transvection (inl i) (inr ()) 1 * List.prod (List.map toMatrix L'))
[PROOFSTEP]
rw [Matrix.mul_assoc (L.map toMatrix).prod]
[GOAL]
case neg.intro.inr.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝³ : Field 𝕜
inst✝² : DecidableEq n
inst✝¹ : DecidableEq p
inst✝ : CommRing R
r : ℕ
M✝ M : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
hM : M (inr ()) (inr ()) = 0
H :
  (¬∀ (i : Fin r) (j : Unit), ↑of (fun i j => M (inl i) (inr j)) i j = OfNat.ofNat 0 i j) ∨
    ¬∀ (i : Unit) (j : Fin r), ↑of (fun i j => M (inr i) (inl j)) i j = OfNat.ofNat 0 i j
i : Fin r
h : M (inr ()) (inl i) ≠ 0
M' : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜 := M * transvection (inl i) (inr ()) 1
hM' : M' (inr ()) (inr ()) ≠ 0
L L' : List (TransvectionStruct (Fin r ⊕ Unit) 𝕜)
hLL' : IsTwoBlockDiagonal (List.prod (List.map toMatrix L) * M' * List.prod (List.map toMatrix L'))
⊢ IsTwoBlockDiagonal
    (List.prod (List.map toMatrix L) * (M * transvection (inl i) (inr ()) 1) * List.prod (List.map toMatrix L'))
[PROOFSTEP]
exact hLL'
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
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
[PROOFSTEP]
rcases exists_isTwoBlockDiagonal_list_transvec_mul_mul_list_transvec M with ⟨L₁, L₁', hM⟩
[GOAL]
case intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
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
[PROOFSTEP]
let M' := (L₁.map toMatrix).prod * M * (L₁'.map toMatrix).prod
[GOAL]
case intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
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
[PROOFSTEP]
let M'' := toBlocks₁₁ M'
[GOAL]
case intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
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
[PROOFSTEP]
rcases IH M'' with ⟨L₀, L₀', D₀, h₀⟩
[GOAL]
case intro.intro.intro.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
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
[PROOFSTEP]
set c := M' (inr unit) (inr unit)
[GOAL]
case intro.intro.intro.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
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
[PROOFSTEP]
refine' ⟨L₀.map (sumInl Unit) ++ L₁, L₁' ++ L₀'.map (sumInl Unit), Sum.elim D₀ fun _ => M' (inr unit) (inr unit), _⟩
[GOAL]
case intro.intro.intro.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
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 ()))
[PROOFSTEP]
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]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
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 ()))
[PROOFSTEP]
simpa [Matrix.mul_assoc]
[GOAL]
case intro.intro.intro.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
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)
[PROOFSTEP]
have : M' = fromBlocks M'' 0 0 (diagonal fun _ => c) := by
  -- porting note: simplified proof, because `congr` didn't work anymore
  rw [← fromBlocks_toBlocks M', hM.1, hM.2]
  rfl
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
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)
[PROOFSTEP]
rw [← fromBlocks_toBlocks M', hM.1, hM.2]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
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)
[PROOFSTEP]
rfl
[GOAL]
case intro.intro.intro.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
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)
[PROOFSTEP]
rw [this]
[GOAL]
case intro.intro.intro.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
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)
[PROOFSTEP]
simp [h₀]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝¹ : Fintype n
inst✝ : Fintype p
M : Matrix p p 𝕜
e : p ≃ n
H : ∃ L L' D, List.prod (List.map toMatrix L) * ↑(reindexAlgEquiv 𝕜 e) 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
[PROOFSTEP]
rcases H with ⟨L₀, L₀', D₀, h₀⟩
[GOAL]
case intro.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝¹ : Fintype n
inst✝ : Fintype p
M : Matrix p p 𝕜
e : p ≃ n
L₀ L₀' : List (TransvectionStruct n 𝕜)
D₀ : n → 𝕜
h₀ : List.prod (List.map toMatrix L₀) * ↑(reindexAlgEquiv 𝕜 e) 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
[PROOFSTEP]
refine' ⟨L₀.map (reindexEquiv e.symm), L₀'.map (reindexEquiv e.symm), D₀ ∘ e, _⟩
[GOAL]
case intro.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝¹ : Fintype n
inst✝ : Fintype p
M : Matrix p p 𝕜
e : p ≃ n
L₀ L₀' : List (TransvectionStruct n 𝕜)
D₀ : n → 𝕜
h₀ : List.prod (List.map toMatrix L₀) * ↑(reindexAlgEquiv 𝕜 e) M * List.prod (List.map toMatrix L₀') = diagonal D₀
⊢ List.prod (List.map toMatrix (List.map (reindexEquiv e.symm) L₀)) * M *
      List.prod (List.map toMatrix (List.map (reindexEquiv e.symm) L₀')) =
    diagonal (D₀ ∘ ↑e)
[PROOFSTEP]
have : M = reindexAlgEquiv 𝕜 e.symm (reindexAlgEquiv 𝕜 e M) := by
  simp only [Equiv.symm_symm, submatrix_submatrix, reindex_apply, submatrix_id_id, Equiv.symm_comp_self,
    reindexAlgEquiv_apply]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝¹ : Fintype n
inst✝ : Fintype p
M : Matrix p p 𝕜
e : p ≃ n
L₀ L₀' : List (TransvectionStruct n 𝕜)
D₀ : n → 𝕜
h₀ : List.prod (List.map toMatrix L₀) * ↑(reindexAlgEquiv 𝕜 e) M * List.prod (List.map toMatrix L₀') = diagonal D₀
⊢ M = ↑(reindexAlgEquiv 𝕜 e.symm) (↑(reindexAlgEquiv 𝕜 e) M)
[PROOFSTEP]
simp only [Equiv.symm_symm, submatrix_submatrix, reindex_apply, submatrix_id_id, Equiv.symm_comp_self,
  reindexAlgEquiv_apply]
[GOAL]
case intro.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝¹ : Fintype n
inst✝ : Fintype p
M : Matrix p p 𝕜
e : p ≃ n
L₀ L₀' : List (TransvectionStruct n 𝕜)
D₀ : n → 𝕜
h₀ : List.prod (List.map toMatrix L₀) * ↑(reindexAlgEquiv 𝕜 e) M * List.prod (List.map toMatrix L₀') = diagonal D₀
this : M = ↑(reindexAlgEquiv 𝕜 e.symm) (↑(reindexAlgEquiv 𝕜 e) M)
⊢ List.prod (List.map toMatrix (List.map (reindexEquiv e.symm) L₀)) * M *
      List.prod (List.map toMatrix (List.map (reindexEquiv e.symm) L₀')) =
    diagonal (D₀ ∘ ↑e)
[PROOFSTEP]
rw [this]
[GOAL]
case intro.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝¹ : Fintype n
inst✝ : Fintype p
M : Matrix p p 𝕜
e : p ≃ n
L₀ L₀' : List (TransvectionStruct n 𝕜)
D₀ : n → 𝕜
h₀ : List.prod (List.map toMatrix L₀) * ↑(reindexAlgEquiv 𝕜 e) M * List.prod (List.map toMatrix L₀') = diagonal D₀
this : M = ↑(reindexAlgEquiv 𝕜 e.symm) (↑(reindexAlgEquiv 𝕜 e) M)
⊢ List.prod (List.map toMatrix (List.map (reindexEquiv e.symm) L₀)) *
        ↑(reindexAlgEquiv 𝕜 e.symm) (↑(reindexAlgEquiv 𝕜 e) M) *
      List.prod (List.map toMatrix (List.map (reindexEquiv e.symm) L₀')) =
    diagonal (D₀ ∘ ↑e)
[PROOFSTEP]
simp only [toMatrix_reindexEquiv_prod, List.map_map, reindexAlgEquiv_apply]
[GOAL]
case intro.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝¹ : Fintype n
inst✝ : Fintype p
M : Matrix p p 𝕜
e : p ≃ n
L₀ L₀' : List (TransvectionStruct n 𝕜)
D₀ : n → 𝕜
h₀ : List.prod (List.map toMatrix L₀) * ↑(reindexAlgEquiv 𝕜 e) M * List.prod (List.map toMatrix L₀') = diagonal D₀
this : M = ↑(reindexAlgEquiv 𝕜 e.symm) (↑(reindexAlgEquiv 𝕜 e) M)
⊢ ↑(reindex e.symm e.symm) (List.prod (List.map toMatrix L₀)) * ↑(reindex e.symm e.symm) (↑(reindex e e) M) *
      ↑(reindex e.symm e.symm) (List.prod (List.map toMatrix L₀')) =
    diagonal (D₀ ∘ ↑e)
[PROOFSTEP]
simp only [← reindexAlgEquiv_apply, ← reindexAlgEquiv_mul, h₀]
[GOAL]
case intro.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝¹ : Fintype n
inst✝ : Fintype p
M : Matrix p p 𝕜
e : p ≃ n
L₀ L₀' : List (TransvectionStruct n 𝕜)
D₀ : n → 𝕜
h₀ : List.prod (List.map toMatrix L₀) * ↑(reindexAlgEquiv 𝕜 e) M * List.prod (List.map toMatrix L₀') = diagonal D₀
this : M = ↑(reindexAlgEquiv 𝕜 e.symm) (↑(reindexAlgEquiv 𝕜 e) M)
⊢ ↑(reindexAlgEquiv 𝕜 e.symm) (diagonal D₀) = diagonal (D₀ ∘ ↑e)
[PROOFSTEP]
simp only [Equiv.symm_symm, reindex_apply, submatrix_diagonal_equiv, reindexAlgEquiv_apply]
[GOAL]
n✝ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁷ : Field 𝕜
inst✝⁶ : DecidableEq n✝
inst✝⁵ : DecidableEq p
inst✝⁴ : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝³ : Fintype n✝
inst✝² : Fintype p
n : Type
inst✝¹ : Fintype n
inst✝ : DecidableEq n
M : Matrix n n 𝕜
⊢ ∃ L L' D, List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L') = diagonal D
[PROOFSTEP]
induction' hn : Fintype.card n with r IH generalizing n M
[GOAL]
case zero
n✝¹ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁹ : Field 𝕜
inst✝⁸ : DecidableEq n✝¹
inst✝⁷ : DecidableEq p
inst✝⁶ : CommRing R
r : ℕ
M✝¹ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝⁵ : Fintype n✝¹
inst✝⁴ : Fintype p
n✝ : Type
inst✝³ : Fintype n✝
inst✝² : DecidableEq n✝
M✝ : Matrix n✝ n✝ 𝕜
x✝ : ℕ
hn✝ : Fintype.card n✝ = x✝
n : Type
inst✝¹ : Fintype n
inst✝ : DecidableEq n
M : Matrix n n 𝕜
hn : Fintype.card n = Nat.zero
⊢ ∃ L L' D, List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L') = diagonal D
[PROOFSTEP]
refine' ⟨List.nil, List.nil, fun _ => 1, _⟩
[GOAL]
case zero
n✝¹ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁹ : Field 𝕜
inst✝⁸ : DecidableEq n✝¹
inst✝⁷ : DecidableEq p
inst✝⁶ : CommRing R
r : ℕ
M✝¹ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝⁵ : Fintype n✝¹
inst✝⁴ : Fintype p
n✝ : Type
inst✝³ : Fintype n✝
inst✝² : DecidableEq n✝
M✝ : Matrix n✝ n✝ 𝕜
x✝ : ℕ
hn✝ : Fintype.card n✝ = x✝
n : Type
inst✝¹ : Fintype n
inst✝ : DecidableEq n
M : Matrix n n 𝕜
hn : Fintype.card n = Nat.zero
⊢ List.prod (List.map toMatrix []) * M * List.prod (List.map toMatrix []) = diagonal fun x => 1
[PROOFSTEP]
ext i j
[GOAL]
case zero.a.h
n✝¹ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁹ : Field 𝕜
inst✝⁸ : DecidableEq n✝¹
inst✝⁷ : DecidableEq p
inst✝⁶ : CommRing R
r : ℕ
M✝¹ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝⁵ : Fintype n✝¹
inst✝⁴ : Fintype p
n✝ : Type
inst✝³ : Fintype n✝
inst✝² : DecidableEq n✝
M✝ : Matrix n✝ n✝ 𝕜
x✝ : ℕ
hn✝ : Fintype.card n✝ = x✝
n : Type
inst✝¹ : Fintype n
inst✝ : DecidableEq n
M : Matrix n n 𝕜
hn : Fintype.card n = Nat.zero
i j : n
⊢ (List.prod (List.map toMatrix []) * M * List.prod (List.map toMatrix [])) i j = diagonal (fun x => 1) i j
[PROOFSTEP]
rw [Fintype.card_eq_zero_iff] at hn 
[GOAL]
case zero.a.h
n✝¹ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁹ : Field 𝕜
inst✝⁸ : DecidableEq n✝¹
inst✝⁷ : DecidableEq p
inst✝⁶ : CommRing R
r : ℕ
M✝¹ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝⁵ : Fintype n✝¹
inst✝⁴ : Fintype p
n✝ : Type
inst✝³ : Fintype n✝
inst✝² : DecidableEq n✝
M✝ : Matrix n✝ n✝ 𝕜
x✝ : ℕ
hn✝ : Fintype.card n✝ = x✝
n : Type
inst✝¹ : Fintype n
inst✝ : DecidableEq n
M : Matrix n n 𝕜
hn : IsEmpty n
i j : n
⊢ (List.prod (List.map toMatrix []) * M * List.prod (List.map toMatrix [])) i j = diagonal (fun x => 1) i j
[PROOFSTEP]
exact hn.elim' i
[GOAL]
case succ
n✝¹ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁹ : Field 𝕜
inst✝⁸ : DecidableEq n✝¹
inst✝⁷ : DecidableEq p
inst✝⁶ : CommRing R
r✝ : ℕ
M✝¹ : Matrix (Fin r✝ ⊕ Unit) (Fin r✝ ⊕ Unit) 𝕜
inst✝⁵ : Fintype n✝¹
inst✝⁴ : Fintype p
n✝ : Type
inst✝³ : Fintype n✝
inst✝² : DecidableEq n✝
M✝ : Matrix n✝ n✝ 𝕜
x✝ : ℕ
hn✝ : Fintype.card n✝ = x✝
r : ℕ
IH :
  ∀ (n : Type) [inst : Fintype n] [inst_1 : DecidableEq n] (M : Matrix n n 𝕜),
    Fintype.card n = r → ∃ L L' D, List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L') = diagonal D
n : Type
inst✝¹ : Fintype n
inst✝ : DecidableEq n
M : Matrix n n 𝕜
hn : Fintype.card n = Nat.succ r
⊢ ∃ L L' D, List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L') = diagonal D
[PROOFSTEP]
have e : n ≃ Sum (Fin r) Unit := by
  refine' Fintype.equivOfCardEq _
  rw [hn]
  rw [@Fintype.card_sum (Fin r) Unit _ _]
  simp
[GOAL]
n✝¹ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁹ : Field 𝕜
inst✝⁸ : DecidableEq n✝¹
inst✝⁷ : DecidableEq p
inst✝⁶ : CommRing R
r✝ : ℕ
M✝¹ : Matrix (Fin r✝ ⊕ Unit) (Fin r✝ ⊕ Unit) 𝕜
inst✝⁵ : Fintype n✝¹
inst✝⁴ : Fintype p
n✝ : Type
inst✝³ : Fintype n✝
inst✝² : DecidableEq n✝
M✝ : Matrix n✝ n✝ 𝕜
x✝ : ℕ
hn✝ : Fintype.card n✝ = x✝
r : ℕ
IH :
  ∀ (n : Type) [inst : Fintype n] [inst_1 : DecidableEq n] (M : Matrix n n 𝕜),
    Fintype.card n = r → ∃ L L' D, List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L') = diagonal D
n : Type
inst✝¹ : Fintype n
inst✝ : DecidableEq n
M : Matrix n n 𝕜
hn : Fintype.card n = Nat.succ r
⊢ n ≃ Fin r ⊕ Unit
[PROOFSTEP]
refine' Fintype.equivOfCardEq _
[GOAL]
n✝¹ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁹ : Field 𝕜
inst✝⁸ : DecidableEq n✝¹
inst✝⁷ : DecidableEq p
inst✝⁶ : CommRing R
r✝ : ℕ
M✝¹ : Matrix (Fin r✝ ⊕ Unit) (Fin r✝ ⊕ Unit) 𝕜
inst✝⁵ : Fintype n✝¹
inst✝⁴ : Fintype p
n✝ : Type
inst✝³ : Fintype n✝
inst✝² : DecidableEq n✝
M✝ : Matrix n✝ n✝ 𝕜
x✝ : ℕ
hn✝ : Fintype.card n✝ = x✝
r : ℕ
IH :
  ∀ (n : Type) [inst : Fintype n] [inst_1 : DecidableEq n] (M : Matrix n n 𝕜),
    Fintype.card n = r → ∃ L L' D, List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L') = diagonal D
n : Type
inst✝¹ : Fintype n
inst✝ : DecidableEq n
M : Matrix n n 𝕜
hn : Fintype.card n = Nat.succ r
⊢ Fintype.card n = Fintype.card (Fin r ⊕ Unit)
[PROOFSTEP]
rw [hn]
[GOAL]
n✝¹ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁹ : Field 𝕜
inst✝⁸ : DecidableEq n✝¹
inst✝⁷ : DecidableEq p
inst✝⁶ : CommRing R
r✝ : ℕ
M✝¹ : Matrix (Fin r✝ ⊕ Unit) (Fin r✝ ⊕ Unit) 𝕜
inst✝⁵ : Fintype n✝¹
inst✝⁴ : Fintype p
n✝ : Type
inst✝³ : Fintype n✝
inst✝² : DecidableEq n✝
M✝ : Matrix n✝ n✝ 𝕜
x✝ : ℕ
hn✝ : Fintype.card n✝ = x✝
r : ℕ
IH :
  ∀ (n : Type) [inst : Fintype n] [inst_1 : DecidableEq n] (M : Matrix n n 𝕜),
    Fintype.card n = r → ∃ L L' D, List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L') = diagonal D
n : Type
inst✝¹ : Fintype n
inst✝ : DecidableEq n
M : Matrix n n 𝕜
hn : Fintype.card n = Nat.succ r
⊢ Nat.succ r = Fintype.card (Fin r ⊕ Unit)
[PROOFSTEP]
rw [@Fintype.card_sum (Fin r) Unit _ _]
[GOAL]
n✝¹ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁹ : Field 𝕜
inst✝⁸ : DecidableEq n✝¹
inst✝⁷ : DecidableEq p
inst✝⁶ : CommRing R
r✝ : ℕ
M✝¹ : Matrix (Fin r✝ ⊕ Unit) (Fin r✝ ⊕ Unit) 𝕜
inst✝⁵ : Fintype n✝¹
inst✝⁴ : Fintype p
n✝ : Type
inst✝³ : Fintype n✝
inst✝² : DecidableEq n✝
M✝ : Matrix n✝ n✝ 𝕜
x✝ : ℕ
hn✝ : Fintype.card n✝ = x✝
r : ℕ
IH :
  ∀ (n : Type) [inst : Fintype n] [inst_1 : DecidableEq n] (M : Matrix n n 𝕜),
    Fintype.card n = r → ∃ L L' D, List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L') = diagonal D
n : Type
inst✝¹ : Fintype n
inst✝ : DecidableEq n
M : Matrix n n 𝕜
hn : Fintype.card n = Nat.succ r
⊢ Nat.succ r = Fintype.card (Fin r) + Fintype.card Unit
[PROOFSTEP]
simp
[GOAL]
case succ
n✝¹ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁹ : Field 𝕜
inst✝⁸ : DecidableEq n✝¹
inst✝⁷ : DecidableEq p
inst✝⁶ : CommRing R
r✝ : ℕ
M✝¹ : Matrix (Fin r✝ ⊕ Unit) (Fin r✝ ⊕ Unit) 𝕜
inst✝⁵ : Fintype n✝¹
inst✝⁴ : Fintype p
n✝ : Type
inst✝³ : Fintype n✝
inst✝² : DecidableEq n✝
M✝ : Matrix n✝ n✝ 𝕜
x✝ : ℕ
hn✝ : Fintype.card n✝ = x✝
r : ℕ
IH :
  ∀ (n : Type) [inst : Fintype n] [inst_1 : DecidableEq n] (M : Matrix n n 𝕜),
    Fintype.card n = r → ∃ L L' D, List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L') = diagonal D
n : Type
inst✝¹ : Fintype n
inst✝ : DecidableEq n
M : Matrix n n 𝕜
hn : Fintype.card n = Nat.succ r
e : n ≃ Fin r ⊕ Unit
⊢ ∃ L L' D, List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L') = diagonal D
[PROOFSTEP]
apply reindex_exists_list_transvec_mul_mul_list_transvec_eq_diagonal M e
[GOAL]
case succ
n✝¹ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁹ : Field 𝕜
inst✝⁸ : DecidableEq n✝¹
inst✝⁷ : DecidableEq p
inst✝⁶ : CommRing R
r✝ : ℕ
M✝¹ : Matrix (Fin r✝ ⊕ Unit) (Fin r✝ ⊕ Unit) 𝕜
inst✝⁵ : Fintype n✝¹
inst✝⁴ : Fintype p
n✝ : Type
inst✝³ : Fintype n✝
inst✝² : DecidableEq n✝
M✝ : Matrix n✝ n✝ 𝕜
x✝ : ℕ
hn✝ : Fintype.card n✝ = x✝
r : ℕ
IH :
  ∀ (n : Type) [inst : Fintype n] [inst_1 : DecidableEq n] (M : Matrix n n 𝕜),
    Fintype.card n = r → ∃ L L' D, List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L') = diagonal D
n : Type
inst✝¹ : Fintype n
inst✝ : DecidableEq n
M : Matrix n n 𝕜
hn : Fintype.card n = Nat.succ r
e : n ≃ Fin r ⊕ Unit
⊢ ∃ L L' D, List.prod (List.map toMatrix L) * ↑(reindexAlgEquiv 𝕜 e) M * List.prod (List.map toMatrix L') = diagonal D
[PROOFSTEP]
apply exists_list_transvec_mul_mul_list_transvec_eq_diagonal_induction fun N => IH (Fin r) N (by simp)
[GOAL]
n✝¹ : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁹ : Field 𝕜
inst✝⁸ : DecidableEq n✝¹
inst✝⁷ : DecidableEq p
inst✝⁶ : CommRing R
r✝ : ℕ
M✝¹ : Matrix (Fin r✝ ⊕ Unit) (Fin r✝ ⊕ Unit) 𝕜
inst✝⁵ : Fintype n✝¹
inst✝⁴ : Fintype p
n✝ : Type
inst✝³ : Fintype n✝
inst✝² : DecidableEq n✝
M✝ : Matrix n✝ n✝ 𝕜
x✝ : ℕ
hn✝ : Fintype.card n✝ = x✝
r : ℕ
IH :
  ∀ (n : Type) [inst : Fintype n] [inst_1 : DecidableEq n] (M : Matrix n n 𝕜),
    Fintype.card n = r → ∃ L L' D, List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L') = diagonal D
n : Type
inst✝¹ : Fintype n
inst✝ : DecidableEq n
M : Matrix n n 𝕜
hn : Fintype.card n = Nat.succ r
e : n ≃ Fin r ⊕ Unit
N : Matrix (Fin r) (Fin r) 𝕜
⊢ Fintype.card (Fin r) = r
[PROOFSTEP]
simp
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝¹ : Fintype n
inst✝ : Fintype p
M : Matrix n n 𝕜
⊢ ∃ L L' D, List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L') = diagonal D
[PROOFSTEP]
have e : n ≃ Fin (Fintype.card n) := Fintype.equivOfCardEq (by simp)
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝¹ : Fintype n
inst✝ : Fintype p
M : Matrix n n 𝕜
⊢ Fintype.card n = Fintype.card (Fin (Fintype.card n))
[PROOFSTEP]
simp
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝¹ : Fintype n
inst✝ : Fintype p
M : Matrix n n 𝕜
e : n ≃ Fin (Fintype.card n)
⊢ ∃ L L' D, List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L') = diagonal D
[PROOFSTEP]
apply reindex_exists_list_transvec_mul_mul_list_transvec_eq_diagonal M e
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝¹ : Fintype n
inst✝ : Fintype p
M : Matrix n n 𝕜
e : n ≃ Fin (Fintype.card n)
⊢ ∃ L L' D, List.prod (List.map toMatrix L) * ↑(reindexAlgEquiv 𝕜 e) M * List.prod (List.map toMatrix L') = diagonal D
[PROOFSTEP]
apply exists_list_transvec_mul_mul_list_transvec_eq_diagonal_aux
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝¹ : Fintype n
inst✝ : Fintype p
M : Matrix n n 𝕜
⊢ ∃ L L' D, M = List.prod (List.map toMatrix L) * diagonal D * List.prod (List.map toMatrix L')
[PROOFSTEP]
rcases exists_list_transvec_mul_mul_list_transvec_eq_diagonal M with ⟨L, L', D, h⟩
[GOAL]
case intro.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝¹ : Fintype n
inst✝ : Fintype p
M : Matrix n n 𝕜
L L' : List (TransvectionStruct n 𝕜)
D : n → 𝕜
h : List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L') = diagonal D
⊢ ∃ L L' D, M = List.prod (List.map toMatrix L) * diagonal D * List.prod (List.map toMatrix L')
[PROOFSTEP]
refine' ⟨L.reverse.map TransvectionStruct.inv, L'.reverse.map TransvectionStruct.inv, D, _⟩
[GOAL]
case intro.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝¹ : Fintype n
inst✝ : Fintype p
M : Matrix n n 𝕜
L L' : List (TransvectionStruct n 𝕜)
D : n → 𝕜
h : List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L') = diagonal D
⊢ M =
    List.prod (List.map toMatrix (List.map TransvectionStruct.inv (List.reverse L))) * diagonal D *
      List.prod (List.map toMatrix (List.map TransvectionStruct.inv (List.reverse L')))
[PROOFSTEP]
suffices
  M =
    (L.reverse.map (toMatrix ∘ TransvectionStruct.inv)).prod * (L.map toMatrix).prod * M *
      ((L'.map toMatrix).prod * (L'.reverse.map (toMatrix ∘ TransvectionStruct.inv)).prod)
  by simpa [← h, Matrix.mul_assoc]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝¹ : Fintype n
inst✝ : Fintype p
M : Matrix n n 𝕜
L L' : List (TransvectionStruct n 𝕜)
D : n → 𝕜
h : List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L') = diagonal D
this :
  M =
    List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse L)) * List.prod (List.map toMatrix L) * M *
      (List.prod (List.map toMatrix L') * List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse L')))
⊢ M =
    List.prod (List.map toMatrix (List.map TransvectionStruct.inv (List.reverse L))) * diagonal D *
      List.prod (List.map toMatrix (List.map TransvectionStruct.inv (List.reverse L')))
[PROOFSTEP]
simpa [← h, Matrix.mul_assoc]
[GOAL]
case intro.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁵ : Field 𝕜
inst✝⁴ : DecidableEq n
inst✝³ : DecidableEq p
inst✝² : CommRing R
r : ℕ
M✝ : Matrix (Fin r ⊕ Unit) (Fin r ⊕ Unit) 𝕜
inst✝¹ : Fintype n
inst✝ : Fintype p
M : Matrix n n 𝕜
L L' : List (TransvectionStruct n 𝕜)
D : n → 𝕜
h : List.prod (List.map toMatrix L) * M * List.prod (List.map toMatrix L') = diagonal D
⊢ M =
    List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse L)) * List.prod (List.map toMatrix L) * M *
      (List.prod (List.map toMatrix L') * List.prod (List.map (toMatrix ∘ TransvectionStruct.inv) (List.reverse L')))
[PROOFSTEP]
rw [reverse_inv_prod_mul_prod, prod_mul_reverse_inv_prod, Matrix.one_mul, Matrix.mul_one]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hdiag : ∀ (D : n → 𝕜), det (diagonal D) = det M → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), P A → P B → P (A * B)
⊢ P M
[PROOFSTEP]
rcases exists_list_transvec_mul_diagonal_mul_list_transvec M with ⟨L, L', D, h⟩
[GOAL]
case intro.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hdiag : ∀ (D : n → 𝕜), det (diagonal D) = det M → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), P A → P B → P (A * B)
L L' : List (TransvectionStruct n 𝕜)
D : n → 𝕜
h : M = List.prod (List.map toMatrix L) * diagonal D * List.prod (List.map toMatrix L')
⊢ P M
[PROOFSTEP]
have PD : P (diagonal D) := hdiag D (by simp [h])
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hdiag : ∀ (D : n → 𝕜), det (diagonal D) = det M → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), P A → P B → P (A * B)
L L' : List (TransvectionStruct n 𝕜)
D : n → 𝕜
h : M = List.prod (List.map toMatrix L) * diagonal D * List.prod (List.map toMatrix L')
⊢ det (diagonal D) = det M
[PROOFSTEP]
simp [h]
[GOAL]
case intro.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hdiag : ∀ (D : n → 𝕜), det (diagonal D) = det M → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), P A → P B → P (A * B)
L L' : List (TransvectionStruct n 𝕜)
D : n → 𝕜
h : M = List.prod (List.map toMatrix L) * diagonal D * List.prod (List.map toMatrix L')
PD : P (diagonal D)
⊢ P M
[PROOFSTEP]
suffices H :
  ∀ (L₁ L₂ : List (TransvectionStruct n 𝕜)) (E : Matrix n n 𝕜),
    P E → P ((L₁.map toMatrix).prod * E * (L₂.map toMatrix).prod)
[GOAL]
case intro.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hdiag : ∀ (D : n → 𝕜), det (diagonal D) = det M → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), P A → P B → P (A * B)
L L' : List (TransvectionStruct n 𝕜)
D : n → 𝕜
h : M = List.prod (List.map toMatrix L) * diagonal D * List.prod (List.map toMatrix L')
PD : P (diagonal D)
H :
  ∀ (L₁ L₂ : List (TransvectionStruct n 𝕜)) (E : Matrix n n 𝕜),
    P E → P (List.prod (List.map toMatrix L₁) * E * List.prod (List.map toMatrix L₂))
⊢ P M
[PROOFSTEP]
rw [h]
[GOAL]
case intro.intro.intro
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hdiag : ∀ (D : n → 𝕜), det (diagonal D) = det M → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), P A → P B → P (A * B)
L L' : List (TransvectionStruct n 𝕜)
D : n → 𝕜
h : M = List.prod (List.map toMatrix L) * diagonal D * List.prod (List.map toMatrix L')
PD : P (diagonal D)
H :
  ∀ (L₁ L₂ : List (TransvectionStruct n 𝕜)) (E : Matrix n n 𝕜),
    P E → P (List.prod (List.map toMatrix L₁) * E * List.prod (List.map toMatrix L₂))
⊢ P (List.prod (List.map toMatrix L) * diagonal D * List.prod (List.map toMatrix L'))
[PROOFSTEP]
apply H L L'
[GOAL]
case intro.intro.intro.a
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hdiag : ∀ (D : n → 𝕜), det (diagonal D) = det M → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), P A → P B → P (A * B)
L L' : List (TransvectionStruct n 𝕜)
D : n → 𝕜
h : M = List.prod (List.map toMatrix L) * diagonal D * List.prod (List.map toMatrix L')
PD : P (diagonal D)
H :
  ∀ (L₁ L₂ : List (TransvectionStruct n 𝕜)) (E : Matrix n n 𝕜),
    P E → P (List.prod (List.map toMatrix L₁) * E * List.prod (List.map toMatrix L₂))
⊢ P (diagonal D)
[PROOFSTEP]
exact PD
[GOAL]
case H
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hdiag : ∀ (D : n → 𝕜), det (diagonal D) = det M → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), P A → P B → P (A * B)
L L' : List (TransvectionStruct n 𝕜)
D : n → 𝕜
h : M = List.prod (List.map toMatrix L) * diagonal D * List.prod (List.map toMatrix L')
PD : P (diagonal D)
⊢ ∀ (L₁ L₂ : List (TransvectionStruct n 𝕜)) (E : Matrix n n 𝕜),
    P E → P (List.prod (List.map toMatrix L₁) * E * List.prod (List.map toMatrix L₂))
[PROOFSTEP]
intro L₁ L₂ E PE
[GOAL]
case H
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hdiag : ∀ (D : n → 𝕜), det (diagonal D) = det M → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), P A → P B → P (A * B)
L L' : List (TransvectionStruct n 𝕜)
D : n → 𝕜
h : M = List.prod (List.map toMatrix L) * diagonal D * List.prod (List.map toMatrix L')
PD : P (diagonal D)
L₁ L₂ : List (TransvectionStruct n 𝕜)
E : Matrix n n 𝕜
PE : P E
⊢ P (List.prod (List.map toMatrix L₁) * E * List.prod (List.map toMatrix L₂))
[PROOFSTEP]
induction' L₁ with t L₁ IH
[GOAL]
case H.nil
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hdiag : ∀ (D : n → 𝕜), det (diagonal D) = det M → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), P A → P B → P (A * B)
L L' : List (TransvectionStruct n 𝕜)
D : n → 𝕜
h : M = List.prod (List.map toMatrix L) * diagonal D * List.prod (List.map toMatrix L')
PD : P (diagonal D)
L₂ : List (TransvectionStruct n 𝕜)
E : Matrix n n 𝕜
PE : P E
⊢ P (List.prod (List.map toMatrix []) * E * List.prod (List.map toMatrix L₂))
[PROOFSTEP]
simp only [Matrix.one_mul, List.prod_nil, List.map]
[GOAL]
case H.nil
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hdiag : ∀ (D : n → 𝕜), det (diagonal D) = det M → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), P A → P B → P (A * B)
L L' : List (TransvectionStruct n 𝕜)
D : n → 𝕜
h : M = List.prod (List.map toMatrix L) * diagonal D * List.prod (List.map toMatrix L')
PD : P (diagonal D)
L₂ : List (TransvectionStruct n 𝕜)
E : Matrix n n 𝕜
PE : P E
⊢ P (E * List.prod (List.map toMatrix L₂))
[PROOFSTEP]
induction' L₂ with t L₂ IH generalizing E
[GOAL]
case H.nil.nil
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hdiag : ∀ (D : n → 𝕜), det (diagonal D) = det M → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), P A → P B → P (A * B)
L L' : List (TransvectionStruct n 𝕜)
D : n → 𝕜
h : M = List.prod (List.map toMatrix L) * diagonal D * List.prod (List.map toMatrix L')
PD : P (diagonal D)
E✝ : Matrix n n 𝕜
PE✝ : P E✝
E : Matrix n n 𝕜
PE : P E
⊢ P (E * List.prod (List.map toMatrix []))
[PROOFSTEP]
simpa
[GOAL]
case H.nil.cons
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hdiag : ∀ (D : n → 𝕜), det (diagonal D) = det M → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), P A → P B → P (A * B)
L L' : List (TransvectionStruct n 𝕜)
D : n → 𝕜
h : M = List.prod (List.map toMatrix L) * diagonal D * List.prod (List.map toMatrix L')
PD : P (diagonal D)
E✝ : Matrix n n 𝕜
PE✝ : P E✝
t : TransvectionStruct n 𝕜
L₂ : List (TransvectionStruct n 𝕜)
IH : ∀ (E : Matrix n n 𝕜), P E → P (E * List.prod (List.map toMatrix L₂))
E : Matrix n n 𝕜
PE : P E
⊢ P (E * List.prod (List.map toMatrix (t :: L₂)))
[PROOFSTEP]
simp only [← Matrix.mul_assoc, List.prod_cons, List.map]
[GOAL]
case H.nil.cons
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hdiag : ∀ (D : n → 𝕜), det (diagonal D) = det M → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), P A → P B → P (A * B)
L L' : List (TransvectionStruct n 𝕜)
D : n → 𝕜
h : M = List.prod (List.map toMatrix L) * diagonal D * List.prod (List.map toMatrix L')
PD : P (diagonal D)
E✝ : Matrix n n 𝕜
PE✝ : P E✝
t : TransvectionStruct n 𝕜
L₂ : List (TransvectionStruct n 𝕜)
IH : ∀ (E : Matrix n n 𝕜), P E → P (E * List.prod (List.map toMatrix L₂))
E : Matrix n n 𝕜
PE : P E
⊢ P (E * toMatrix t * List.prod (List.map toMatrix L₂))
[PROOFSTEP]
apply IH
[GOAL]
case H.nil.cons.PE
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hdiag : ∀ (D : n → 𝕜), det (diagonal D) = det M → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), P A → P B → P (A * B)
L L' : List (TransvectionStruct n 𝕜)
D : n → 𝕜
h : M = List.prod (List.map toMatrix L) * diagonal D * List.prod (List.map toMatrix L')
PD : P (diagonal D)
E✝ : Matrix n n 𝕜
PE✝ : P E✝
t : TransvectionStruct n 𝕜
L₂ : List (TransvectionStruct n 𝕜)
IH : ∀ (E : Matrix n n 𝕜), P E → P (E * List.prod (List.map toMatrix L₂))
E : Matrix n n 𝕜
PE : P E
⊢ P (E * toMatrix t)
[PROOFSTEP]
exact hmul _ _ PE (htransvec _)
[GOAL]
case H.cons
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hdiag : ∀ (D : n → 𝕜), det (diagonal D) = det M → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), P A → P B → P (A * B)
L L' : List (TransvectionStruct n 𝕜)
D : n → 𝕜
h : M = List.prod (List.map toMatrix L) * diagonal D * List.prod (List.map toMatrix L')
PD : P (diagonal D)
L₂ : List (TransvectionStruct n 𝕜)
E : Matrix n n 𝕜
PE : P E
t : TransvectionStruct n 𝕜
L₁ : List (TransvectionStruct n 𝕜)
IH : P (List.prod (List.map toMatrix L₁) * E * List.prod (List.map toMatrix L₂))
⊢ P (List.prod (List.map toMatrix (t :: L₁)) * E * List.prod (List.map toMatrix L₂))
[PROOFSTEP]
simp only [Matrix.mul_assoc, List.prod_cons, List.map] at IH ⊢
[GOAL]
case H.cons
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hdiag : ∀ (D : n → 𝕜), det (diagonal D) = det M → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), P A → P B → P (A * B)
L L' : List (TransvectionStruct n 𝕜)
D : n → 𝕜
h : M = List.prod (List.map toMatrix L) * diagonal D * List.prod (List.map toMatrix L')
PD : P (diagonal D)
L₂ : List (TransvectionStruct n 𝕜)
E : Matrix n n 𝕜
PE : P E
t : TransvectionStruct n 𝕜
L₁ : List (TransvectionStruct n 𝕜)
IH : P (List.prod (List.map toMatrix L₁) * (E * List.prod (List.map toMatrix L₂)))
⊢ P (toMatrix t * (List.prod (List.map toMatrix L₁) * (E * List.prod (List.map toMatrix L₂))))
[PROOFSTEP]
exact hmul _ _ (htransvec _) IH
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hMdet : det M ≠ 0
hdiag : ∀ (D : n → 𝕜), det (diagonal D) ≠ 0 → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), det A ≠ 0 → det B ≠ 0 → P A → P B → P (A * B)
⊢ P M
[PROOFSTEP]
let Q : Matrix n n 𝕜 → Prop := fun N => det N ≠ 0 ∧ P N
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hMdet : det M ≠ 0
hdiag : ∀ (D : n → 𝕜), det (diagonal D) ≠ 0 → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), det A ≠ 0 → det B ≠ 0 → P A → P B → P (A * B)
Q : Matrix n n 𝕜 → Prop := fun N => det N ≠ 0 ∧ P N
⊢ P M
[PROOFSTEP]
have : Q M := by
  apply diagonal_transvection_induction Q M
  · intro D hD
    have detD : det (diagonal D) ≠ 0 := by
      rw [hD]
      exact hMdet
    exact ⟨detD, hdiag _ detD⟩
  · intro t
    exact ⟨by simp, htransvec t⟩
  · intro A B QA QB
    exact ⟨by simp [QA.1, QB.1], hmul A B QA.1 QB.1 QA.2 QB.2⟩
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hMdet : det M ≠ 0
hdiag : ∀ (D : n → 𝕜), det (diagonal D) ≠ 0 → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), det A ≠ 0 → det B ≠ 0 → P A → P B → P (A * B)
Q : Matrix n n 𝕜 → Prop := fun N => det N ≠ 0 ∧ P N
⊢ Q M
[PROOFSTEP]
apply diagonal_transvection_induction Q M
[GOAL]
case hdiag
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hMdet : det M ≠ 0
hdiag : ∀ (D : n → 𝕜), det (diagonal D) ≠ 0 → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), det A ≠ 0 → det B ≠ 0 → P A → P B → P (A * B)
Q : Matrix n n 𝕜 → Prop := fun N => det N ≠ 0 ∧ P N
⊢ ∀ (D : n → 𝕜), det (diagonal D) = det M → Q (diagonal D)
[PROOFSTEP]
intro D hD
[GOAL]
case hdiag
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hMdet : det M ≠ 0
hdiag : ∀ (D : n → 𝕜), det (diagonal D) ≠ 0 → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), det A ≠ 0 → det B ≠ 0 → P A → P B → P (A * B)
Q : Matrix n n 𝕜 → Prop := fun N => det N ≠ 0 ∧ P N
D : n → 𝕜
hD : det (diagonal D) = det M
⊢ Q (diagonal D)
[PROOFSTEP]
have detD : det (diagonal D) ≠ 0 := by
  rw [hD]
  exact hMdet
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hMdet : det M ≠ 0
hdiag : ∀ (D : n → 𝕜), det (diagonal D) ≠ 0 → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), det A ≠ 0 → det B ≠ 0 → P A → P B → P (A * B)
Q : Matrix n n 𝕜 → Prop := fun N => det N ≠ 0 ∧ P N
D : n → 𝕜
hD : det (diagonal D) = det M
⊢ det (diagonal D) ≠ 0
[PROOFSTEP]
rw [hD]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hMdet : det M ≠ 0
hdiag : ∀ (D : n → 𝕜), det (diagonal D) ≠ 0 → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), det A ≠ 0 → det B ≠ 0 → P A → P B → P (A * B)
Q : Matrix n n 𝕜 → Prop := fun N => det N ≠ 0 ∧ P N
D : n → 𝕜
hD : det (diagonal D) = det M
⊢ det M ≠ 0
[PROOFSTEP]
exact hMdet
[GOAL]
case hdiag
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hMdet : det M ≠ 0
hdiag : ∀ (D : n → 𝕜), det (diagonal D) ≠ 0 → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), det A ≠ 0 → det B ≠ 0 → P A → P B → P (A * B)
Q : Matrix n n 𝕜 → Prop := fun N => det N ≠ 0 ∧ P N
D : n → 𝕜
hD : det (diagonal D) = det M
detD : det (diagonal D) ≠ 0
⊢ Q (diagonal D)
[PROOFSTEP]
exact ⟨detD, hdiag _ detD⟩
[GOAL]
case htransvec
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hMdet : det M ≠ 0
hdiag : ∀ (D : n → 𝕜), det (diagonal D) ≠ 0 → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), det A ≠ 0 → det B ≠ 0 → P A → P B → P (A * B)
Q : Matrix n n 𝕜 → Prop := fun N => det N ≠ 0 ∧ P N
⊢ ∀ (t : TransvectionStruct n 𝕜), Q (toMatrix t)
[PROOFSTEP]
intro t
[GOAL]
case htransvec
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hMdet : det M ≠ 0
hdiag : ∀ (D : n → 𝕜), det (diagonal D) ≠ 0 → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), det A ≠ 0 → det B ≠ 0 → P A → P B → P (A * B)
Q : Matrix n n 𝕜 → Prop := fun N => det N ≠ 0 ∧ P N
t : TransvectionStruct n 𝕜
⊢ Q (toMatrix t)
[PROOFSTEP]
exact ⟨by simp, htransvec t⟩
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hMdet : det M ≠ 0
hdiag : ∀ (D : n → 𝕜), det (diagonal D) ≠ 0 → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), det A ≠ 0 → det B ≠ 0 → P A → P B → P (A * B)
Q : Matrix n n 𝕜 → Prop := fun N => det N ≠ 0 ∧ P N
t : TransvectionStruct n 𝕜
⊢ det (toMatrix t) ≠ 0
[PROOFSTEP]
simp
[GOAL]
case hmul
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hMdet : det M ≠ 0
hdiag : ∀ (D : n → 𝕜), det (diagonal D) ≠ 0 → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), det A ≠ 0 → det B ≠ 0 → P A → P B → P (A * B)
Q : Matrix n n 𝕜 → Prop := fun N => det N ≠ 0 ∧ P N
⊢ ∀ (A B : Matrix n n 𝕜), Q A → Q B → Q (A * B)
[PROOFSTEP]
intro A B QA QB
[GOAL]
case hmul
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hMdet : det M ≠ 0
hdiag : ∀ (D : n → 𝕜), det (diagonal D) ≠ 0 → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), det A ≠ 0 → det B ≠ 0 → P A → P B → P (A * B)
Q : Matrix n n 𝕜 → Prop := fun N => det N ≠ 0 ∧ P N
A B : Matrix n n 𝕜
QA : Q A
QB : Q B
⊢ Q (A * B)
[PROOFSTEP]
exact ⟨by simp [QA.1, QB.1], hmul A B QA.1 QB.1 QA.2 QB.2⟩
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hMdet : det M ≠ 0
hdiag : ∀ (D : n → 𝕜), det (diagonal D) ≠ 0 → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), det A ≠ 0 → det B ≠ 0 → P A → P B → P (A * B)
Q : Matrix n n 𝕜 → Prop := fun N => det N ≠ 0 ∧ P N
A B : Matrix n n 𝕜
QA : Q A
QB : Q B
⊢ det (A * B) ≠ 0
[PROOFSTEP]
simp [QA.1, QB.1]
[GOAL]
n : Type u_1
p : Type u_2
R : Type u₂
𝕜 : Type u_3
inst✝⁴ : Field 𝕜
inst✝³ : DecidableEq n
inst✝² : DecidableEq p
inst✝¹ : CommRing R
inst✝ : Fintype n
P : Matrix n n 𝕜 → Prop
M : Matrix n n 𝕜
hMdet : det M ≠ 0
hdiag : ∀ (D : n → 𝕜), det (diagonal D) ≠ 0 → P (diagonal D)
htransvec : ∀ (t : TransvectionStruct n 𝕜), P (toMatrix t)
hmul : ∀ (A B : Matrix n n 𝕜), det A ≠ 0 → det B ≠ 0 → P A → P B → P (A * B)
Q : Matrix n n 𝕜 → Prop := fun N => det N ≠ 0 ∧ P N
this : Q M
⊢ P M
[PROOFSTEP]
exact this.2
