l3lab/ntp-mathlib huggingface dataset:
theorem det_eq_of_forall_row_eq_smul_add_pred_aux {n : ℕ} (k : Fin (n + 1)) :
    ∀ (c : Fin n → R) (_hc : ∀ i : Fin n, k < i.succ → c i = 0)
      {M N : Matrix (Fin n.succ) (Fin n.succ) R} (_h0 : ∀ j, M 0 j = N 0 j)
      (_hsucc : ∀ (i : Fin n) (j), M i.succ j = N i.succ j + c i * M (Fin.castSucc i) j),
      det M = det N := by
  refine' Fin.induction _ (fun k ih => _) k <;> intro c hc M N h0 hsucc
  · congr
    ext i j
    refine' Fin.cases (h0 j) (fun i => _) i
    rw [hsucc, hc i (Fin.succ_pos _), zero_mul, add_zero]
  set M' := updateRow M k.succ (N k.succ) with hM'
  have hM : M = updateRow M' k.succ (M' k.succ + c k • M (Fin.castSucc k)) := by
    ext i j
    by_cases hi : i = k.succ
    · simp [hi, hM', hsucc, updateRow_self]
    rw [updateRow_ne hi, hM', updateRow_ne hi]
  have k_ne_succ : (Fin.castSucc k) ≠ k.succ := (Fin.castSucc_lt_succ k).ne
  have M_k : M (Fin.castSucc k) = M' (Fin.castSucc k) := (updateRow_ne k_ne_succ).symm
  rw [hM, M_k, det_updateRow_add_smul_self M' k_ne_succ.symm, ih (Function.update c k 0)]
  · intro i hi
    rw [Fin.lt_iff_val_lt_val, Fin.coe_castSucc, Fin.val_succ, Nat.lt_succ_iff] at hi
    rw [Function.update_apply]
    split_ifs with hik
    · rfl
    exact hc _ (Fin.succ_lt_succ_iff.mpr (lt_of_le_of_ne hi (Ne.symm hik)))
  · rwa [hM', updateRow_ne (Fin.succ_ne_zero _).symm]
  intro i j
  rw [Function.update_apply]
  split_ifs with hik
  · 

Proof state:
case pos
m : Type u_1
n✝ : Type u_2
inst✝⁴ : DecidableEq n✝
inst✝³ : Fintype n✝
inst✝² : DecidableEq m
inst✝¹ : Fintype m
R : Type v
inst✝ : CommRing R
n : ℕ
k✝ : Fin (n + 1)
k : Fin n
ih :
  ∀ (c : Fin n → R),
    (∀ (i : Fin n), Fin.castSucc k < Fin.succ i → c i = 0) →
      ∀ {M N : Matrix (Fin (Nat.succ n)) (Fin (Nat.succ n)) R},
        (∀ (j : Fin (Nat.succ n)), M 0 j = N 0 j) →
          (∀ (i : Fin n) (j : Fin (Nat.succ n)), M (Fin.succ i) j = N (Fin.succ i) j + c i * M (Fin.castSucc i) j) →
            det M = det N
c : Fin n → R
hc : ∀ (i : Fin n), Fin.succ k < Fin.succ i → c i = 0
M N : Matrix (Fin (Nat.succ n)) (Fin (Nat.succ n)) R
h0 : ∀ (j : Fin (Nat.succ n)), M 0 j = N 0 j
hsucc : ∀ (i : Fin n) (j : Fin (Nat.succ n)), M (Fin.succ i) j = N (Fin.succ i) j + c i * M (Fin.castSucc i) j
M' : Matrix (Fin (Nat.succ n)) (Fin (Nat.succ n)) R := updateRow M (Fin.succ k) (N (Fin.succ k))
hM' : M' = updateRow M (Fin.succ k) (N (Fin.succ k))
hM : M = updateRow M' (Fin.succ k) (M' (Fin.succ k) + c k • M (Fin.castSucc k))
k_ne_succ : Fin.castSucc k ≠ Fin.succ k
M_k : M (Fin.castSucc k) = M' (Fin.castSucc k)
i : Fin n
j : Fin (Nat.succ n)
hik : i = k
⊢ M' (Fin.succ i) j = N (Fin.succ i) j + 0 * M' (Fin.castSucc i) j

Next tactic:
rw [zero_mul, add_zero, hM', hik, updateRow_self]
theorem det_eq_of_forall_row_eq_smul_add_pred_aux {n : ℕ} (k : Fin (n + 1)) :
    ∀ (c : Fin n → R) (_hc : ∀ i : Fin n, k < i.succ → c i = 0)
      {M N : Matrix (Fin n.succ) (Fin n.succ) R} (_h0 : ∀ j, M 0 j = N 0 j)
      (_hsucc : ∀ (i : Fin n) (j), M i.succ j = N i.succ j + c i * M (Fin.castSucc i) j),
      det M = det N := by
  refine' Fin.induction _ (fun k ih => _) k <;> intro c hc M N h0 hsucc
  · congr
    ext i j
    refine' Fin.cases (h0 j) (fun i => _) i
    rw [hsucc, hc i (Fin.succ_pos _), zero_mul, add_zero]
  set M' := updateRow M k.succ (N k.succ) with hM'
  have hM : M = updateRow M' k.succ (M' k.succ + c k • M (Fin.castSucc k)) := by
    ext i j
    by_cases hi : i = k.succ
    · simp [hi, hM', hsucc, updateRow_self]
    rw [updateRow_ne hi, hM', updateRow_ne hi]
  have k_ne_succ : (Fin.castSucc k) ≠ k.succ := (Fin.castSucc_lt_succ k).ne
  have M_k : M (Fin.castSucc k) = M' (Fin.castSucc k) := (updateRow_ne k_ne_succ).symm
  rw [hM, M_k, det_updateRow_add_smul_self M' k_ne_succ.symm, ih (Function.update c k 0)]
  · intro i hi
    rw [Fin.lt_iff_val_lt_val, Fin.coe_castSucc, Fin.val_succ, Nat.lt_succ_iff] at hi
    rw [Function.update_apply]
    split_ifs with hik
    · rfl
    exact hc _ (Fin.succ_lt_succ_iff.mpr (lt_of_le_of_ne hi (Ne.symm hik)))
  · rwa [hM', updateRow_ne (Fin.succ_ne_zero _).symm]
  intro i j
  rw [Function.update_apply]
  split_ifs with hik
  · rw [zero_mul, add_zero, hM', hik, updateRow_self]
  

Proof state:
case neg
m : Type u_1
n✝ : Type u_2
inst✝⁴ : DecidableEq n✝
inst✝³ : Fintype n✝
inst✝² : DecidableEq m
inst✝¹ : Fintype m
R : Type v
inst✝ : CommRing R
n : ℕ
k✝ : Fin (n + 1)
k : Fin n
ih :
  ∀ (c : Fin n → R),
    (∀ (i : Fin n), Fin.castSucc k < Fin.succ i → c i = 0) →
      ∀ {M N : Matrix (Fin (Nat.succ n)) (Fin (Nat.succ n)) R},
        (∀ (j : Fin (Nat.succ n)), M 0 j = N 0 j) →
          (∀ (i : Fin n) (j : Fin (Nat.succ n)), M (Fin.succ i) j = N (Fin.succ i) j + c i * M (Fin.castSucc i) j) →
            det M = det N
c : Fin n → R
hc : ∀ (i : Fin n), Fin.succ k < Fin.succ i → c i = 0
M N : Matrix (Fin (Nat.succ n)) (Fin (Nat.succ n)) R
h0 : ∀ (j : Fin (Nat.succ n)), M 0 j = N 0 j
hsucc : ∀ (i : Fin n) (j : Fin (Nat.succ n)), M (Fin.succ i) j = N (Fin.succ i) j + c i * M (Fin.castSucc i) j
M' : Matrix (Fin (Nat.succ n)) (Fin (Nat.succ n)) R := updateRow M (Fin.succ k) (N (Fin.succ k))
hM' : M' = updateRow M (Fin.succ k) (N (Fin.succ k))
hM : M = updateRow M' (Fin.succ k) (M' (Fin.succ k) + c k • M (Fin.castSucc k))
k_ne_succ : Fin.castSucc k ≠ Fin.succ k
M_k : M (Fin.castSucc k) = M' (Fin.castSucc k)
i : Fin n
j : Fin (Nat.succ n)
hik : ¬i = k
⊢ M' (Fin.succ i) j = N (Fin.succ i) j + c i * M' (Fin.castSucc i) j

Next tactic:
rw [hM', updateRow_ne ((Fin.succ_injective _).ne hik), hsucc]
theorem det_eq_of_forall_row_eq_smul_add_pred_aux {n : ℕ} (k : Fin (n + 1)) :
    ∀ (c : Fin n → R) (_hc : ∀ i : Fin n, k < i.succ → c i = 0)
      {M N : Matrix (Fin n.succ) (Fin n.succ) R} (_h0 : ∀ j, M 0 j = N 0 j)
      (_hsucc : ∀ (i : Fin n) (j), M i.succ j = N i.succ j + c i * M (Fin.castSucc i) j),
      det M = det N := by
  refine' Fin.induction _ (fun k ih => _) k <;> intro c hc M N h0 hsucc
  · congr
    ext i j
    refine' Fin.cases (h0 j) (fun i => _) i
    rw [hsucc, hc i (Fin.succ_pos _), zero_mul, add_zero]
  set M' := updateRow M k.succ (N k.succ) with hM'
  have hM : M = updateRow M' k.succ (M' k.succ + c k • M (Fin.castSucc k)) := by
    ext i j
    by_cases hi : i = k.succ
    · simp [hi, hM', hsucc, updateRow_self]
    rw [updateRow_ne hi, hM', updateRow_ne hi]
  have k_ne_succ : (Fin.castSucc k) ≠ k.succ := (Fin.castSucc_lt_succ k).ne
  have M_k : M (Fin.castSucc k) = M' (Fin.castSucc k) := (updateRow_ne k_ne_succ).symm
  rw [hM, M_k, det_updateRow_add_smul_self M' k_ne_succ.symm, ih (Function.update c k 0)]
  · intro i hi
    rw [Fin.lt_iff_val_lt_val, Fin.coe_castSucc, Fin.val_succ, Nat.lt_succ_iff] at hi
    rw [Function.update_apply]
    split_ifs with hik
    · rfl
    exact hc _ (Fin.succ_lt_succ_iff.mpr (lt_of_le_of_ne hi (Ne.symm hik)))
  · rwa [hM', updateRow_ne (Fin.succ_ne_zero _).symm]
  intro i j
  rw [Function.update_apply]
  split_ifs with hik
  · rw [zero_mul, add_zero, hM', hik, updateRow_self]
  rw [hM', updateRow_ne ((Fin.succ_injective _).ne hik), hsucc]
  

Proof state:
case neg
m : Type u_1
n✝ : Type u_2
inst✝⁴ : DecidableEq n✝
inst✝³ : Fintype n✝
inst✝² : DecidableEq m
inst✝¹ : Fintype m
R : Type v
inst✝ : CommRing R
n : ℕ
k✝ : Fin (n + 1)
k : Fin n
ih :
  ∀ (c : Fin n → R),
    (∀ (i : Fin n), Fin.castSucc k < Fin.succ i → c i = 0) →
      ∀ {M N : Matrix (Fin (Nat.succ n)) (Fin (Nat.succ n)) R},
        (∀ (j : Fin (Nat.succ n)), M 0 j = N 0 j) →
          (∀ (i : Fin n) (j : Fin (Nat.succ n)), M (Fin.succ i) j = N (Fin.succ i) j + c i * M (Fin.castSucc i) j) →
            det M = det N
c : Fin n → R
hc : ∀ (i : Fin n), Fin.succ k < Fin.succ i → c i = 0
M N : Matrix (Fin (Nat.succ n)) (Fin (Nat.succ n)) R
h0 : ∀ (j : Fin (Nat.succ n)), M 0 j = N 0 j
hsucc : ∀ (i : Fin n) (j : Fin (Nat.succ n)), M (Fin.succ i) j = N (Fin.succ i) j + c i * M (Fin.castSucc i) j
M' : Matrix (Fin (Nat.succ n)) (Fin (Nat.succ n)) R := updateRow M (Fin.succ k) (N (Fin.succ k))
hM' : M' = updateRow M (Fin.succ k) (N (Fin.succ k))
hM : M = updateRow M' (Fin.succ k) (M' (Fin.succ k) + c k • M (Fin.castSucc k))
k_ne_succ : Fin.castSucc k ≠ Fin.succ k
M_k : M (Fin.castSucc k) = M' (Fin.castSucc k)
i : Fin n
j : Fin (Nat.succ n)
hik : ¬i = k
⊢ N (Fin.succ i) j + c i * M (Fin.castSucc i) j =
    N (Fin.succ i) j + c i * updateRow M (Fin.succ k) (N (Fin.succ k)) (Fin.castSucc i) j

Next tactic:
by_cases hik2 : k < i
theorem det_eq_of_forall_row_eq_smul_add_pred_aux {n : ℕ} (k : Fin (n + 1)) :
    ∀ (c : Fin n → R) (_hc : ∀ i : Fin n, k < i.succ → c i = 0)
      {M N : Matrix (Fin n.succ) (Fin n.succ) R} (_h0 : ∀ j, M 0 j = N 0 j)
      (_hsucc : ∀ (i : Fin n) (j), M i.succ j = N i.succ j + c i * M (Fin.castSucc i) j),
      det M = det N := by
  refine' Fin.induction _ (fun k ih => _) k <;> intro c hc M N h0 hsucc
  · congr
    ext i j
    refine' Fin.cases (h0 j) (fun i => _) i
    rw [hsucc, hc i (Fin.succ_pos _), zero_mul, add_zero]
  set M' := updateRow M k.succ (N k.succ) with hM'
  have hM : M = updateRow M' k.succ (M' k.succ + c k • M (Fin.castSucc k)) := by
    ext i j
    by_cases hi : i = k.succ
    · simp [hi, hM', hsucc, updateRow_self]
    rw [updateRow_ne hi, hM', updateRow_ne hi]
  have k_ne_succ : (Fin.castSucc k) ≠ k.succ := (Fin.castSucc_lt_succ k).ne
  have M_k : M (Fin.castSucc k) = M' (Fin.castSucc k) := (updateRow_ne k_ne_succ).symm
  rw [hM, M_k, det_updateRow_add_smul_self M' k_ne_succ.symm, ih (Function.update c k 0)]
  · intro i hi
    rw [Fin.lt_iff_val_lt_val, Fin.coe_castSucc, Fin.val_succ, Nat.lt_succ_iff] at hi
    rw [Function.update_apply]
    split_ifs with hik
    · rfl
    exact hc _ (Fin.succ_lt_succ_iff.mpr (lt_of_le_of_ne hi (Ne.symm hik)))
  · rwa [hM', updateRow_ne (Fin.succ_ne_zero _).symm]
  intro i j
  rw [Function.update_apply]
  split_ifs with hik
  · rw [zero_mul, add_zero, hM', hik, updateRow_self]
  rw [hM', updateRow_ne ((Fin.succ_injective _).ne hik), hsucc]
  by_cases hik2 : k < i
  · 

Proof state:
case pos
m : Type u_1
n✝ : Type u_2
inst✝⁴ : DecidableEq n✝
inst✝³ : Fintype n✝
inst✝² : DecidableEq m
inst✝¹ : Fintype m
R : Type v
inst✝ : CommRing R
n : ℕ
k✝ : Fin (n + 1)
k : Fin n
ih :
  ∀ (c : Fin n → R),
    (∀ (i : Fin n), Fin.castSucc k < Fin.succ i → c i = 0) →
      ∀ {M N : Matrix (Fin (Nat.succ n)) (Fin (Nat.succ n)) R},
        (∀ (j : Fin (Nat.succ n)), M 0 j = N 0 j) →
          (∀ (i : Fin n) (j : Fin (Nat.succ n)), M (Fin.succ i) j = N (Fin.succ i) j + c i * M (Fin.castSucc i) j) →
            det M = det N
c : Fin n → R
hc : ∀ (i : Fin n), Fin.succ k < Fin.succ i → c i = 0
M N : Matrix (Fin (Nat.succ n)) (Fin (Nat.succ n)) R
h0 : ∀ (j : Fin (Nat.succ n)), M 0 j = N 0 j
hsucc : ∀ (i : Fin n) (j : Fin (Nat.succ n)), M (Fin.succ i) j = N (Fin.succ i) j + c i * M (Fin.castSucc i) j
M' : Matrix (Fin (Nat.succ n)) (Fin (Nat.succ n)) R := updateRow M (Fin.succ k) (N (Fin.succ k))
hM' : M' = updateRow M (Fin.succ k) (N (Fin.succ k))
hM : M = updateRow M' (Fin.succ k) (M' (Fin.succ k) + c k • M (Fin.castSucc k))
k_ne_succ : Fin.castSucc k ≠ Fin.succ k
M_k : M (Fin.castSucc k) = M' (Fin.castSucc k)
i : Fin n
j : Fin (Nat.succ n)
hik : ¬i = k
hik2 : k < i
⊢ N (Fin.succ i) j + c i * M (Fin.castSucc i) j =
    N (Fin.succ i) j + c i * updateRow M (Fin.succ k) (N (Fin.succ k)) (Fin.castSucc i) j

Next tactic:
simp [hc i (Fin.succ_lt_succ_iff.mpr hik2)]
theorem det_eq_of_forall_row_eq_smul_add_pred_aux {n : ℕ} (k : Fin (n + 1)) :
    ∀ (c : Fin n → R) (_hc : ∀ i : Fin n, k < i.succ → c i = 0)
      {M N : Matrix (Fin n.succ) (Fin n.succ) R} (_h0 : ∀ j, M 0 j = N 0 j)
      (_hsucc : ∀ (i : Fin n) (j), M i.succ j = N i.succ j + c i * M (Fin.castSucc i) j),
      det M = det N := by
  refine' Fin.induction _ (fun k ih => _) k <;> intro c hc M N h0 hsucc
  · congr
    ext i j
    refine' Fin.cases (h0 j) (fun i => _) i
    rw [hsucc, hc i (Fin.succ_pos _), zero_mul, add_zero]
  set M' := updateRow M k.succ (N k.succ) with hM'
  have hM : M = updateRow M' k.succ (M' k.succ + c k • M (Fin.castSucc k)) := by
    ext i j
    by_cases hi : i = k.succ
    · simp [hi, hM', hsucc, updateRow_self]
    rw [updateRow_ne hi, hM', updateRow_ne hi]
  have k_ne_succ : (Fin.castSucc k) ≠ k.succ := (Fin.castSucc_lt_succ k).ne
  have M_k : M (Fin.castSucc k) = M' (Fin.castSucc k) := (updateRow_ne k_ne_succ).symm
  rw [hM, M_k, det_updateRow_add_smul_self M' k_ne_succ.symm, ih (Function.update c k 0)]
  · intro i hi
    rw [Fin.lt_iff_val_lt_val, Fin.coe_castSucc, Fin.val_succ, Nat.lt_succ_iff] at hi
    rw [Function.update_apply]
    split_ifs with hik
    · rfl
    exact hc _ (Fin.succ_lt_succ_iff.mpr (lt_of_le_of_ne hi (Ne.symm hik)))
  · rwa [hM', updateRow_ne (Fin.succ_ne_zero _).symm]
  intro i j
  rw [Function.update_apply]
  split_ifs with hik
  · rw [zero_mul, add_zero, hM', hik, updateRow_self]
  rw [hM', updateRow_ne ((Fin.succ_injective _).ne hik), hsucc]
  by_cases hik2 : k < i
  · simp [hc i (Fin.succ_lt_succ_iff.mpr hik2)]
  

Proof state:
case neg
m : Type u_1
n✝ : Type u_2
inst✝⁴ : DecidableEq n✝
inst✝³ : Fintype n✝
inst✝² : DecidableEq m
inst✝¹ : Fintype m
R : Type v
inst✝ : CommRing R
n : ℕ
k✝ : Fin (n + 1)
k : Fin n
ih :
  ∀ (c : Fin n → R),
    (∀ (i : Fin n), Fin.castSucc k < Fin.succ i → c i = 0) →
      ∀ {M N : Matrix (Fin (Nat.succ n)) (Fin (Nat.succ n)) R},
        (∀ (j : Fin (Nat.succ n)), M 0 j = N 0 j) →
          (∀ (i : Fin n) (j : Fin (Nat.succ n)), M (Fin.succ i) j = N (Fin.succ i) j + c i * M (Fin.castSucc i) j) →
            det M = det N
c : Fin n → R
hc : ∀ (i : Fin n), Fin.succ k < Fin.succ i → c i = 0
M N : Matrix (Fin (Nat.succ n)) (Fin (Nat.succ n)) R
h0 : ∀ (j : Fin (Nat.succ n)), M 0 j = N 0 j
hsucc : ∀ (i : Fin n) (j : Fin (Nat.succ n)), M (Fin.succ i) j = N (Fin.succ i) j + c i * M (Fin.castSucc i) j
M' : Matrix (Fin (Nat.succ n)) (Fin (Nat.succ n)) R := updateRow M (Fin.succ k) (N (Fin.succ k))
hM' : M' = updateRow M (Fin.succ k) (N (Fin.succ k))
hM : M = updateRow M' (Fin.succ k) (M' (Fin.succ k) + c k • M (Fin.castSucc k))
k_ne_succ : Fin.castSucc k ≠ Fin.succ k
M_k : M (Fin.castSucc k) = M' (Fin.castSucc k)
i : Fin n
j : Fin (Nat.succ n)
hik : ¬i = k
hik2 : ¬k < i
⊢ N (Fin.succ i) j + c i * M (Fin.castSucc i) j =
    N (Fin.succ i) j + c i * updateRow M (Fin.succ k) (N (Fin.succ k)) (Fin.castSucc i) j

Next tactic:
rw [updateRow_ne]
theorem det_eq_of_forall_row_eq_smul_add_pred_aux {n : ℕ} (k : Fin (n + 1)) :
    ∀ (c : Fin n → R) (_hc : ∀ i : Fin n, k < i.succ → c i = 0)
      {M N : Matrix (Fin n.succ) (Fin n.succ) R} (_h0 : ∀ j, M 0 j = N 0 j)
      (_hsucc : ∀ (i : Fin n) (j), M i.succ j = N i.succ j + c i * M (Fin.castSucc i) j),
      det M = det N := by
  refine' Fin.induction _ (fun k ih => _) k <;> intro c hc M N h0 hsucc
  · congr
    ext i j
    refine' Fin.cases (h0 j) (fun i => _) i
    rw [hsucc, hc i (Fin.succ_pos _), zero_mul, add_zero]
  set M' := updateRow M k.succ (N k.succ) with hM'
  have hM : M = updateRow M' k.succ (M' k.succ + c k • M (Fin.castSucc k)) := by
    ext i j
    by_cases hi : i = k.succ
    · simp [hi, hM', hsucc, updateRow_self]
    rw [updateRow_ne hi, hM', updateRow_ne hi]
  have k_ne_succ : (Fin.castSucc k) ≠ k.succ := (Fin.castSucc_lt_succ k).ne
  have M_k : M (Fin.castSucc k) = M' (Fin.castSucc k) := (updateRow_ne k_ne_succ).symm
  rw [hM, M_k, det_updateRow_add_smul_self M' k_ne_succ.symm, ih (Function.update c k 0)]
  · intro i hi
    rw [Fin.lt_iff_val_lt_val, Fin.coe_castSucc, Fin.val_succ, Nat.lt_succ_iff] at hi
    rw [Function.update_apply]
    split_ifs with hik
    · rfl
    exact hc _ (Fin.succ_lt_succ_iff.mpr (lt_of_le_of_ne hi (Ne.symm hik)))
  · rwa [hM', updateRow_ne (Fin.succ_ne_zero _).symm]
  intro i j
  rw [Function.update_apply]
  split_ifs with hik
  · rw [zero_mul, add_zero, hM', hik, updateRow_self]
  rw [hM', updateRow_ne ((Fin.succ_injective _).ne hik), hsucc]
  by_cases hik2 : k < i
  · simp [hc i (Fin.succ_lt_succ_iff.mpr hik2)]
  rw [updateRow_ne]
  

Proof state:
case neg
m : Type u_1
n✝ : Type u_2
inst✝⁴ : DecidableEq n✝
inst✝³ : Fintype n✝
inst✝² : DecidableEq m
inst✝¹ : Fintype m
R : Type v
inst✝ : CommRing R
n : ℕ
k✝ : Fin (n + 1)
k : Fin n
ih :
  ∀ (c : Fin n → R),
    (∀ (i : Fin n), Fin.castSucc k < Fin.succ i → c i = 0) →
      ∀ {M N : Matrix (Fin (Nat.succ n)) (Fin (Nat.succ n)) R},
        (∀ (j : Fin (Nat.succ n)), M 0 j = N 0 j) →
          (∀ (i : Fin n) (j : Fin (Nat.succ n)), M (Fin.succ i) j = N (Fin.succ i) j + c i * M (Fin.castSucc i) j) →
            det M = det N
c : Fin n → R
hc : ∀ (i : Fin n), Fin.succ k < Fin.succ i → c i = 0
M N : Matrix (Fin (Nat.succ n)) (Fin (Nat.succ n)) R
h0 : ∀ (j : Fin (Nat.succ n)), M 0 j = N 0 j
hsucc : ∀ (i : Fin n) (j : Fin (Nat.succ n)), M (Fin.succ i) j = N (Fin.succ i) j + c i * M (Fin.castSucc i) j
M' : Matrix (Fin (Nat.succ n)) (Fin (Nat.succ n)) R := updateRow M (Fin.succ k) (N (Fin.succ k))
hM' : M' = updateRow M (Fin.succ k) (N (Fin.succ k))
hM : M = updateRow M' (Fin.succ k) (M' (Fin.succ k) + c k • M (Fin.castSucc k))
k_ne_succ : Fin.castSucc k ≠ Fin.succ k
M_k : M (Fin.castSucc k) = M' (Fin.castSucc k)
i : Fin n
j : Fin (Nat.succ n)
hik : ¬i = k
hik2 : ¬k < i
⊢ Fin.castSucc i ≠ Fin.succ k

Next tactic:
apply ne_of_lt
theorem det_eq_of_forall_row_eq_smul_add_pred_aux {n : ℕ} (k : Fin (n + 1)) :
    ∀ (c : Fin n → R) (_hc : ∀ i : Fin n, k < i.succ → c i = 0)
      {M N : Matrix (Fin n.succ) (Fin n.succ) R} (_h0 : ∀ j, M 0 j = N 0 j)
      (_hsucc : ∀ (i : Fin n) (j), M i.succ j = N i.succ j + c i * M (Fin.castSucc i) j),
      det M = det N := by
  refine' Fin.induction _ (fun k ih => _) k <;> intro c hc M N h0 hsucc
  · congr
    ext i j
    refine' Fin.cases (h0 j) (fun i => _) i
    rw [hsucc, hc i (Fin.succ_pos _), zero_mul, add_zero]
  set M' := updateRow M k.succ (N k.succ) with hM'
  have hM : M = updateRow M' k.succ (M' k.succ + c k • M (Fin.castSucc k)) := by
    ext i j
    by_cases hi : i = k.succ
    · simp [hi, hM', hsucc, updateRow_self]
    rw [updateRow_ne hi, hM', updateRow_ne hi]
  have k_ne_succ : (Fin.castSucc k) ≠ k.succ := (Fin.castSucc_lt_succ k).ne
  have M_k : M (Fin.castSucc k) = M' (Fin.castSucc k) := (updateRow_ne k_ne_succ).symm
  rw [hM, M_k, det_updateRow_add_smul_self M' k_ne_succ.symm, ih (Function.update c k 0)]
  · intro i hi
    rw [Fin.lt_iff_val_lt_val, Fin.coe_castSucc, Fin.val_succ, Nat.lt_succ_iff] at hi
    rw [Function.update_apply]
    split_ifs with hik
    · rfl
    exact hc _ (Fin.succ_lt_succ_iff.mpr (lt_of_le_of_ne hi (Ne.symm hik)))
  · rwa [hM', updateRow_ne (Fin.succ_ne_zero _).symm]
  intro i j
  rw [Function.update_apply]
  split_ifs with hik
  · rw [zero_mul, add_zero, hM', hik, updateRow_self]
  rw [hM', updateRow_ne ((Fin.succ_injective _).ne hik), hsucc]
  by_cases hik2 : k < i
  · simp [hc i (Fin.succ_lt_succ_iff.mpr hik2)]
  rw [updateRow_ne]
  apply ne_of_lt
  

Proof state:
case neg.h
m : Type u_1
n✝ : Type u_2
inst✝⁴ : DecidableEq n✝
inst✝³ : Fintype n✝
inst✝² : DecidableEq m
inst✝¹ : Fintype m
R : Type v
inst✝ : CommRing R
n : ℕ
k✝ : Fin (n + 1)
k : Fin n
ih :
  ∀ (c : Fin n → R),
    (∀ (i : Fin n), Fin.castSucc k < Fin.succ i → c i = 0) →
      ∀ {M N : Matrix (Fin (Nat.succ n)) (Fin (Nat.succ n)) R},
        (∀ (j : Fin (Nat.succ n)), M 0 j = N 0 j) →
          (∀ (i : Fin n) (j : Fin (Nat.succ n)), M (Fin.succ i) j = N (Fin.succ i) j + c i * M (Fin.castSucc i) j) →
            det M = det N
c : Fin n → R
hc : ∀ (i : Fin n), Fin.succ k < Fin.succ i → c i = 0
M N : Matrix (Fin (Nat.succ n)) (Fin (Nat.succ n)) R
h0 : ∀ (j : Fin (Nat.succ n)), M 0 j = N 0 j
hsucc : ∀ (i : Fin n) (j : Fin (Nat.succ n)), M (Fin.succ i) j = N (Fin.succ i) j + c i * M (Fin.castSucc i) j
M' : Matrix (Fin (Nat.succ n)) (Fin (Nat.succ n)) R := updateRow M (Fin.succ k) (N (Fin.succ k))
hM' : M' = updateRow M (Fin.succ k) (N (Fin.succ k))
hM : M = updateRow M' (Fin.succ k) (M' (Fin.succ k) + c k • M (Fin.castSucc k))
k_ne_succ : Fin.castSucc k ≠ Fin.succ k
M_k : M (Fin.castSucc k) = M' (Fin.castSucc k)
i : Fin n
j : Fin (Nat.succ n)
hik : ¬i = k
hik2 : ¬k < i
⊢ Fin.castSucc i < Fin.succ k

Next tactic:
rwa [Fin.lt_iff_val_lt_val, Fin.coe_castSucc, Fin.val_succ, Nat.lt_succ_iff, ← not_lt]
/-- If you add multiples of previous columns to the next columns, the determinant doesn't change. -/
theorem det_eq_of_forall_col_eq_smul_add_pred {n : ℕ} {A B : Matrix (Fin (n + 1)) (Fin (n + 1)) R}
    (c : Fin n → R) (A_zero : ∀ i, A i 0 = B i 0)
    (A_succ : ∀ (i) (j : Fin n), A i j.succ = B i j.succ + c j * A i (Fin.castSucc j)) :
    det A = det B := by
  

Proof state:
m : Type u_1
n✝ : Type u_2
inst✝⁴ : DecidableEq n✝
inst✝³ : Fintype n✝
inst✝² : DecidableEq m
inst✝¹ : Fintype m
R : Type v
inst✝ : CommRing R
n : ℕ
A B : Matrix (Fin (n + 1)) (Fin (n + 1)) R
c : Fin n → R
A_zero : ∀ (i : Fin (n + 1)), A i 0 = B i 0
A_succ : ∀ (i : Fin (n + 1)) (j : Fin n), A i (Fin.succ j) = B i (Fin.succ j) + c j * A i (Fin.castSucc j)
⊢ det A = det B

Next tactic:
rw [← det_transpose A, ← det_transpose B]
/-- If you add multiples of previous columns to the next columns, the determinant doesn't change. -/
theorem det_eq_of_forall_col_eq_smul_add_pred {n : ℕ} {A B : Matrix (Fin (n + 1)) (Fin (n + 1)) R}
    (c : Fin n → R) (A_zero : ∀ i, A i 0 = B i 0)
    (A_succ : ∀ (i) (j : Fin n), A i j.succ = B i j.succ + c j * A i (Fin.castSucc j)) :
    det A = det B := by
  rw [← det_transpose A, ← det_transpose B]
  

Proof state:
m : Type u_1
n✝ : Type u_2
inst✝⁴ : DecidableEq n✝
inst✝³ : Fintype n✝
inst✝² : DecidableEq m
inst✝¹ : Fintype m
R : Type v
inst✝ : CommRing R
n : ℕ
A B : Matrix (Fin (n + 1)) (Fin (n + 1)) R
c : Fin n → R
A_zero : ∀ (i : Fin (n + 1)), A i 0 = B i 0
A_succ : ∀ (i : Fin (n + 1)) (j : Fin n), A i (Fin.succ j) = B i (Fin.succ j) + c j * A i (Fin.castSucc j)
⊢ det Aᵀ = det Bᵀ

Next tactic:
exact det_eq_of_forall_row_eq_smul_add_pred c A_zero fun i j => A_succ j i
@[simp]
theorem det_blockDiagonal {o : Type*} [Fintype o] [DecidableEq o] (M : o → Matrix n n R) :
    (blockDiagonal M).det = ∏ k, (M k).det := by
  -- Rewrite the determinants as a sum over permutations.
  

Proof state:
m : Type u_1
n : Type u_2
inst✝⁶ : DecidableEq n
inst✝⁵ : Fintype n
inst✝⁴ : DecidableEq m
inst✝³ : Fintype m
R : Type v
inst✝² : CommRing R
o : Type u_3
inst✝¹ : Fintype o
inst✝ : DecidableEq o
M : o → Matrix n n R
⊢ det (blockDiagonal M) = ∏ k : o, det (M k)

Next tactic:
simp_rw [det_apply']
@[simp]
theorem det_blockDiagonal {o : Type*} [Fintype o] [DecidableEq o] (M : o → Matrix n n R) :
    (blockDiagonal M).det = ∏ k, (M k).det := by
  -- Rewrite the determinants as a sum over permutations.
  simp_rw [det_apply']
  -- The right hand side is a product of sums, rewrite it as a sum of products.
  

Proof state:
m : Type u_1
n : Type u_2
inst✝⁶ : DecidableEq n
inst✝⁵ : Fintype n
inst✝⁴ : DecidableEq m
inst✝³ : Fintype m
R : Type v
inst✝² : CommRing R
o : Type u_3
inst✝¹ : Fintype o
inst✝ : DecidableEq o
M : o → Matrix n n R
⊢ ∑ σ : Perm (n × o), ↑↑(sign σ) * ∏ i : n × o, blockDiagonal M (σ i) i =
    ∏ x : o, ∑ σ : Perm n, ↑↑(sign σ) * ∏ i : n, M x (σ i) i

Next tactic:
rw [Finset.prod_sum]
@[simp]
theorem det_blockDiagonal {o : Type*} [Fintype o] [DecidableEq o] (M : o → Matrix n n R) :
    (blockDiagonal M).det = ∏ k, (M k).det := by
  -- Rewrite the determinants as a sum over permutations.
  simp_rw [det_apply']
  -- The right hand side is a product of sums, rewrite it as a sum of products.
  rw [Finset.prod_sum]
  

Proof state:
m : Type u_1
n : Type u_2
inst✝⁶ : DecidableEq n
inst✝⁵ : Fintype n
inst✝⁴ : DecidableEq m
inst✝³ : Fintype m
R : Type v
inst✝² : CommRing R
o : Type u_3
inst✝¹ : Fintype o
inst✝ : DecidableEq o
M : o → Matrix n n R
⊢ ∑ σ : Perm (n × o), ↑↑(sign σ) * ∏ i : n × o, blockDiagonal M (σ i) i =
    ∑ p in pi univ fun x => univ,
      ∏ x in attach univ, ↑↑(sign (p ↑x (_ : ↑x ∈ univ))) * ∏ i : n, M (↑x) ((p ↑x (_ : ↑x ∈ univ)) i) i

Next tactic:
simp_rw [Finset.prod_attach_univ, Finset.univ_pi_univ]