l3lab/ntp-mathlib huggingface dataset:
/-- Multiplying by all the matrices in `listTransvecCol M` kills all the coefficients in the
last column but the last one. -/
theorem listTransvecCol_mul_last_col (hM : M (inr unit) (inr unit) ≠ 0) (i : Fin r) :
    ((listTransvecCol M).prod * M) (inl i) (inr unit) = 0 := by
  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)
  · simpa only [List.drop, _root_.zero_le, ite_true] using H 0 (zero_le _)
  intro k hk
  -- porting note: `apply` didn't work anymore, because of the implicit arguments
  refine' Nat.decreasingInduction' _ hk _
  · intro n hn hk IH
    have hn' : n < (listTransvecCol M).length := by simpa [listTransvecCol] using hn
    let n' : Fin r := ⟨n, hn⟩
    -- porting note: after changing from `nthLe` to `get`, we need to provide all arguments
    rw [← @List.cons_get_drop_succ _ _ ⟨n, hn'⟩]
    have A :
      (listTransvecCol M).get ⟨n, hn'⟩ =
        transvection (inl n') (inr unit) (-M (inl n') (inr unit) / M (inr unit) (inr unit)) :=
      by 

Proof state:
n✝ : 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 ()))

Next tactic:
simp [listTransvecCol]
/-- Multiplying by all the matrices in `listTransvecCol M` kills all the coefficients in the
last column but the last one. -/
theorem listTransvecCol_mul_last_col (hM : M (inr unit) (inr unit) ≠ 0) (i : Fin r) :
    ((listTransvecCol M).prod * M) (inl i) (inr unit) = 0 := by
  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)
  · simpa only [List.drop, _root_.zero_le, ite_true] using H 0 (zero_le _)
  intro k hk
  -- porting note: `apply` didn't work anymore, because of the implicit arguments
  refine' Nat.decreasingInduction' _ hk _
  · intro n hn hk IH
    have hn' : n < (listTransvecCol M).length := by simpa [listTransvecCol] using hn
    let n' : Fin r := ⟨n, hn⟩
    -- porting note: after changing from `nthLe` to `get`, we need to provide all arguments
    rw [← @List.cons_get_drop_succ _ _ ⟨n, hn'⟩]
    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]
    

Proof state:
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 ())

Next tactic:
simp only [Matrix.mul_assoc, A, List.prod_cons]
/-- Multiplying by all the matrices in `listTransvecCol M` kills all the coefficients in the
last column but the last one. -/
theorem listTransvecCol_mul_last_col (hM : M (inr unit) (inr unit) ≠ 0) (i : Fin r) :
    ((listTransvecCol M).prod * M) (inl i) (inr unit) = 0 := by
  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)
  · simpa only [List.drop, _root_.zero_le, ite_true] using H 0 (zero_le _)
  intro k hk
  -- porting note: `apply` didn't work anymore, because of the implicit arguments
  refine' Nat.decreasingInduction' _ hk _
  · intro n hn hk IH
    have hn' : n < (listTransvecCol M).length := by simpa [listTransvecCol] using hn
    let n' : Fin r := ⟨n, hn⟩
    -- porting note: after changing from `nthLe` to `get`, we need to provide all arguments
    rw [← @List.cons_get_drop_succ _ _ ⟨n, hn'⟩]
    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]
    simp only [Matrix.mul_assoc, A, List.prod_cons]
    

Proof state:
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 ())

Next tactic:
by_cases h : n' = i
/-- Multiplying by all the matrices in `listTransvecCol M` kills all the coefficients in the
last column but the last one. -/
theorem listTransvecCol_mul_last_col (hM : M (inr unit) (inr unit) ≠ 0) (i : Fin r) :
    ((listTransvecCol M).prod * M) (inl i) (inr unit) = 0 := by
  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)
  · simpa only [List.drop, _root_.zero_le, ite_true] using H 0 (zero_le _)
  intro k hk
  -- porting note: `apply` didn't work anymore, because of the implicit arguments
  refine' Nat.decreasingInduction' _ hk _
  · intro n hn hk IH
    have hn' : n < (listTransvecCol M).length := by simpa [listTransvecCol] using hn
    let n' : Fin r := ⟨n, hn⟩
    -- porting note: after changing from `nthLe` to `get`, we need to provide all arguments
    rw [← @List.cons_get_drop_succ _ _ ⟨n, hn'⟩]
    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]
    simp only [Matrix.mul_assoc, A, List.prod_cons]
    by_cases h : n' = i
    · 

Proof state:
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 ())

Next tactic:
have hni : n = i := by
        cases i
        simp only [Fin.mk_eq_mk] at h
        simp [h]
/-- Multiplying by all the matrices in `listTransvecCol M` kills all the coefficients in the
last column but the last one. -/
theorem listTransvecCol_mul_last_col (hM : M (inr unit) (inr unit) ≠ 0) (i : Fin r) :
    ((listTransvecCol M).prod * M) (inl i) (inr unit) = 0 := by
  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)
  · simpa only [List.drop, _root_.zero_le, ite_true] using H 0 (zero_le _)
  intro k hk
  -- porting note: `apply` didn't work anymore, because of the implicit arguments
  refine' Nat.decreasingInduction' _ hk _
  · intro n hn hk IH
    have hn' : n < (listTransvecCol M).length := by simpa [listTransvecCol] using hn
    let n' : Fin r := ⟨n, hn⟩
    -- porting note: after changing from `nthLe` to `get`, we need to provide all arguments
    rw [← @List.cons_get_drop_succ _ _ ⟨n, hn'⟩]
    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]
    simp only [Matrix.mul_assoc, A, List.prod_cons]
    by_cases h : n' = i
    · have hni : n = i := by
        

Proof state:
n✝ : 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

Next tactic:
cases i
/-- Multiplying by all the matrices in `listTransvecCol M` kills all the coefficients in the
last column but the last one. -/
theorem listTransvecCol_mul_last_col (hM : M (inr unit) (inr unit) ≠ 0) (i : Fin r) :
    ((listTransvecCol M).prod * M) (inl i) (inr unit) = 0 := by
  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)
  · simpa only [List.drop, _root_.zero_le, ite_true] using H 0 (zero_le _)
  intro k hk
  -- porting note: `apply` didn't work anymore, because of the implicit arguments
  refine' Nat.decreasingInduction' _ hk _
  · intro n hn hk IH
    have hn' : n < (listTransvecCol M).length := by simpa [listTransvecCol] using hn
    let n' : Fin r := ⟨n, hn⟩
    -- porting note: after changing from `nthLe` to `get`, we need to provide all arguments
    rw [← @List.cons_get_drop_succ _ _ ⟨n, hn'⟩]
    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]
    simp only [Matrix.mul_assoc, A, List.prod_cons]
    by_cases h : n' = i
    · have hni : n = i := by
        cases i
        

Proof state:
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✝ }

Next tactic:
simp only [Fin.mk_eq_mk] at h
/-- Multiplying by all the matrices in `listTransvecCol M` kills all the coefficients in the
last column but the last one. -/
theorem listTransvecCol_mul_last_col (hM : M (inr unit) (inr unit) ≠ 0) (i : Fin r) :
    ((listTransvecCol M).prod * M) (inl i) (inr unit) = 0 := by
  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)
  · simpa only [List.drop, _root_.zero_le, ite_true] using H 0 (zero_le _)
  intro k hk
  -- porting note: `apply` didn't work anymore, because of the implicit arguments
  refine' Nat.decreasingInduction' _ hk _
  · intro n hn hk IH
    have hn' : n < (listTransvecCol M).length := by simpa [listTransvecCol] using hn
    let n' : Fin r := ⟨n, hn⟩
    -- porting note: after changing from `nthLe` to `get`, we need to provide all arguments
    rw [← @List.cons_get_drop_succ _ _ ⟨n, hn'⟩]
    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]
    simp only [Matrix.mul_assoc, A, List.prod_cons]
    by_cases h : n' = i
    · have hni : n = i := by
        cases i
        simp only [Fin.mk_eq_mk] at h
        

Proof state:
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✝ }

Next tactic:
simp [h]
/-- Multiplying by all the matrices in `listTransvecCol M` kills all the coefficients in the
last column but the last one. -/
theorem listTransvecCol_mul_last_col (hM : M (inr unit) (inr unit) ≠ 0) (i : Fin r) :
    ((listTransvecCol M).prod * M) (inl i) (inr unit) = 0 := by
  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)
  · simpa only [List.drop, _root_.zero_le, ite_true] using H 0 (zero_le _)
  intro k hk
  -- porting note: `apply` didn't work anymore, because of the implicit arguments
  refine' Nat.decreasingInduction' _ hk _
  · intro n hn hk IH
    have hn' : n < (listTransvecCol M).length := by simpa [listTransvecCol] using hn
    let n' : Fin r := ⟨n, hn⟩
    -- porting note: after changing from `nthLe` to `get`, we need to provide all arguments
    rw [← @List.cons_get_drop_succ _ _ ⟨n, hn'⟩]
    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]
    simp only [Matrix.mul_assoc, A, List.prod_cons]
    by_cases h : n' = i
    · have hni : n = i := by
        cases i
        simp only [Fin.mk_eq_mk] at h
        simp [h]
      

Proof state:
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 ())

Next tactic:
simp only [h, transvection_mul_apply_same, IH, ← hni, add_le_iff_nonpos_right,
          listTransvecCol_mul_last_row_drop _ _ hn]
/-- Multiplying by all the matrices in `listTransvecCol M` kills all the coefficients in the
last column but the last one. -/
theorem listTransvecCol_mul_last_col (hM : M (inr unit) (inr unit) ≠ 0) (i : Fin r) :
    ((listTransvecCol M).prod * M) (inl i) (inr unit) = 0 := by
  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)
  · simpa only [List.drop, _root_.zero_le, ite_true] using H 0 (zero_le _)
  intro k hk
  -- porting note: `apply` didn't work anymore, because of the implicit arguments
  refine' Nat.decreasingInduction' _ hk _
  · intro n hn hk IH
    have hn' : n < (listTransvecCol M).length := by simpa [listTransvecCol] using hn
    let n' : Fin r := ⟨n, hn⟩
    -- porting note: after changing from `nthLe` to `get`, we need to provide all arguments
    rw [← @List.cons_get_drop_succ _ _ ⟨n, hn'⟩]
    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]
    simp only [Matrix.mul_assoc, A, List.prod_cons]
    by_cases h : n' = i
    · have hni : n = i := by
        cases i
        simp only [Fin.mk_eq_mk] at h
        simp [h]
      simp only [h, transvection_mul_apply_same, IH, ← hni, add_le_iff_nonpos_right,
          listTransvecCol_mul_last_row_drop _ _ hn]
      

Proof state:
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 1 ≤ 0 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 ())

Next tactic:
field_simp [hM]
/-- Multiplying by all the matrices in `listTransvecCol M` kills all the coefficients in the
last column but the last one. -/
theorem listTransvecCol_mul_last_col (hM : M (inr unit) (inr unit) ≠ 0) (i : Fin r) :
    ((listTransvecCol M).prod * M) (inl i) (inr unit) = 0 := by
  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)
  · simpa only [List.drop, _root_.zero_le, ite_true] using H 0 (zero_le _)
  intro k hk
  -- porting note: `apply` didn't work anymore, because of the implicit arguments
  refine' Nat.decreasingInduction' _ hk _
  · intro n hn hk IH
    have hn' : n < (listTransvecCol M).length := by simpa [listTransvecCol] using hn
    let n' : Fin r := ⟨n, hn⟩
    -- porting note: after changing from `nthLe` to `get`, we need to provide all arguments
    rw [← @List.cons_get_drop_succ _ _ ⟨n, hn'⟩]
    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]
    simp only [Matrix.mul_assoc, A, List.prod_cons]
    by_cases h : n' = i
    · have hni : n = i := by
        cases i
        simp only [Fin.mk_eq_mk] at h
        simp [h]
      simp only [h, transvection_mul_apply_same, IH, ← hni, add_le_iff_nonpos_right,
          listTransvecCol_mul_last_row_drop _ _ hn]
      field_simp [hM]
    · 

Proof state:
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 ())

Next tactic:
have hni : n ≠ i := by
        rintro rfl
        cases i
        simp at h
/-- Multiplying by all the matrices in `listTransvecCol M` kills all the coefficients in the
last column but the last one. -/
theorem listTransvecCol_mul_last_col (hM : M (inr unit) (inr unit) ≠ 0) (i : Fin r) :
    ((listTransvecCol M).prod * M) (inl i) (inr unit) = 0 := by
  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)
  · simpa only [List.drop, _root_.zero_le, ite_true] using H 0 (zero_le _)
  intro k hk
  -- porting note: `apply` didn't work anymore, because of the implicit arguments
  refine' Nat.decreasingInduction' _ hk _
  · intro n hn hk IH
    have hn' : n < (listTransvecCol M).length := by simpa [listTransvecCol] using hn
    let n' : Fin r := ⟨n, hn⟩
    -- porting note: after changing from `nthLe` to `get`, we need to provide all arguments
    rw [← @List.cons_get_drop_succ _ _ ⟨n, hn'⟩]
    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]
    simp only [Matrix.mul_assoc, A, List.prod_cons]
    by_cases h : n' = i
    · have hni : n = i := by
        cases i
        simp only [Fin.mk_eq_mk] at h
        simp [h]
      simp only [h, transvection_mul_apply_same, IH, ← hni, add_le_iff_nonpos_right,
          listTransvecCol_mul_last_row_drop _ _ hn]
      field_simp [hM]
    · have hni : n ≠ i := by
        

Proof state:
n✝ : 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

Next tactic:
rintro rfl