l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem adjugate_submatrix_equiv_self (e : n ≃ m) (A : Matrix m m α) :
    adjugate (A.submatrix e e) = (adjugate A).submatrix e e := by
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
e : n ≃ m
A : Matrix m m α
⊢ adjugate (submatrix A ⇑e ⇑e) = submatrix (adjugate A) ⇑e ⇑e

Next tactic:
ext i j
@[simp]
theorem adjugate_submatrix_equiv_self (e : n ≃ m) (A : Matrix m m α) :
    adjugate (A.submatrix e e) = (adjugate A).submatrix e e := by
  ext i j
  

Proof state:
case a.h
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
e : n ≃ m
A : Matrix m m α
i j : n
⊢ adjugate (submatrix A ⇑e ⇑e) i j = submatrix (adjugate A) (⇑e) (⇑e) i j

Next tactic:
rw [adjugate_apply, submatrix_apply, adjugate_apply, ← det_submatrix_equiv_self e,
    updateRow_submatrix_equiv]
@[simp]
theorem adjugate_submatrix_equiv_self (e : n ≃ m) (A : Matrix m m α) :
    adjugate (A.submatrix e e) = (adjugate A).submatrix e e := by
  ext i j
  rw [adjugate_apply, submatrix_apply, adjugate_apply, ← det_submatrix_equiv_self e,
    updateRow_submatrix_equiv]
  -- Porting note: added
  

Proof state:
case a.h
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
e : n ≃ m
A : Matrix m m α
i j : n
⊢ det (submatrix (updateRow A (e j) fun j => Pi.single i 1 (e.symm j)) ⇑e ⇑e) =
    det (submatrix (updateRow A (e j) (Pi.single (e i) 1)) ⇑e ⇑e)

Next tactic:
suffices (fun j => Pi.single i 1 (e.symm j)) = Pi.single (e i) 1 by
    erw [this]
@[simp]
theorem adjugate_submatrix_equiv_self (e : n ≃ m) (A : Matrix m m α) :
    adjugate (A.submatrix e e) = (adjugate A).submatrix e e := by
  ext i j
  rw [adjugate_apply, submatrix_apply, adjugate_apply, ← det_submatrix_equiv_self e,
    updateRow_submatrix_equiv]
  -- Porting note: added
  suffices (fun j => Pi.single i 1 (e.symm j)) = Pi.single (e i) 1 by
    

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
e : n ≃ m
A : Matrix m m α
i j : n
this : (fun j => Pi.single i 1 (e.symm j)) = Pi.single (e i) 1
⊢ det (submatrix (updateRow A (e j) fun j => Pi.single i 1 (e.symm j)) ⇑e ⇑e) =
    det (submatrix (updateRow A (e j) (Pi.single (e i) 1)) ⇑e ⇑e)

Next tactic:
erw [this]
@[simp]
theorem adjugate_submatrix_equiv_self (e : n ≃ m) (A : Matrix m m α) :
    adjugate (A.submatrix e e) = (adjugate A).submatrix e e := by
  ext i j
  rw [adjugate_apply, submatrix_apply, adjugate_apply, ← det_submatrix_equiv_self e,
    updateRow_submatrix_equiv]
  -- Porting note: added
  suffices (fun j => Pi.single i 1 (e.symm j)) = Pi.single (e i) 1 by
    erw [this]
  

Proof state:
case a.h
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
e : n ≃ m
A : Matrix m m α
i j : n
⊢ (fun j => Pi.single i 1 (e.symm j)) = Pi.single (e i) 1

Next tactic:
exact Function.update_comp_equiv _ e.symm _ _
/-- Since the map `b ↦ cramer A b` is linear in `b`, it must be multiplication by some matrix. This
matrix is `A.adjugate`. -/
theorem cramer_eq_adjugate_mulVec (A : Matrix n n α) (b : n → α) :
    cramer A b = A.adjugate.mulVec b := by
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
⊢ (cramer A) b = mulVec (adjugate A) b

Next tactic:
nth_rw 2 [← A.transpose_transpose]
/-- Since the map `b ↦ cramer A b` is linear in `b`, it must be multiplication by some matrix. This
matrix is `A.adjugate`. -/
theorem cramer_eq_adjugate_mulVec (A : Matrix n n α) (b : n → α) :
    cramer A b = A.adjugate.mulVec b := by
  nth_rw 2 [← A.transpose_transpose]
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
⊢ (cramer A) b = mulVec (adjugate Aᵀᵀ) b

Next tactic:
rw [← adjugate_transpose, adjugate_def]
/-- Since the map `b ↦ cramer A b` is linear in `b`, it must be multiplication by some matrix. This
matrix is `A.adjugate`. -/
theorem cramer_eq_adjugate_mulVec (A : Matrix n n α) (b : n → α) :
    cramer A b = A.adjugate.mulVec b := by
  nth_rw 2 [← A.transpose_transpose]
  rw [← adjugate_transpose, adjugate_def]
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
⊢ (cramer A) b = mulVec (of fun i => (cramer Aᵀᵀ) (Pi.single i 1))ᵀ b

Next tactic:
have : b = ∑ i, b i • Pi.single i 1 := by
    refine' (pi_eq_sum_univ b).trans _
    congr with j
    -- Porting note: needed to help `Pi.smul_apply`
    simp [Pi.single_apply, eq_comm, Pi.smul_apply (b j)]
/-- Since the map `b ↦ cramer A b` is linear in `b`, it must be multiplication by some matrix. This
matrix is `A.adjugate`. -/
theorem cramer_eq_adjugate_mulVec (A : Matrix n n α) (b : n → α) :
    cramer A b = A.adjugate.mulVec b := by
  nth_rw 2 [← A.transpose_transpose]
  rw [← adjugate_transpose, adjugate_def]
  have : b = ∑ i, b i • Pi.single i 1 := by
    

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
⊢ b = ∑ i : n, b i • Pi.single i 1

Next tactic:
refine' (pi_eq_sum_univ b).trans _
/-- Since the map `b ↦ cramer A b` is linear in `b`, it must be multiplication by some matrix. This
matrix is `A.adjugate`. -/
theorem cramer_eq_adjugate_mulVec (A : Matrix n n α) (b : n → α) :
    cramer A b = A.adjugate.mulVec b := by
  nth_rw 2 [← A.transpose_transpose]
  rw [← adjugate_transpose, adjugate_def]
  have : b = ∑ i, b i • Pi.single i 1 := by
    refine' (pi_eq_sum_univ b).trans _
    

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
⊢ (∑ i : n, b i • fun j => if i = j then 1 else 0) = ∑ i : n, b i • Pi.single i 1

Next tactic:
congr with j
/-- Since the map `b ↦ cramer A b` is linear in `b`, it must be multiplication by some matrix. This
matrix is `A.adjugate`. -/
theorem cramer_eq_adjugate_mulVec (A : Matrix n n α) (b : n → α) :
    cramer A b = A.adjugate.mulVec b := by
  nth_rw 2 [← A.transpose_transpose]
  rw [← adjugate_transpose, adjugate_def]
  have : b = ∑ i, b i • Pi.single i 1 := by
    refine' (pi_eq_sum_univ b).trans _
    congr with j
    -- Porting note: needed to help `Pi.smul_apply`
    

Proof state:
case e_f.h.h
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
j x✝ : n
⊢ (b j • fun j_1 => if j = j_1 then 1 else 0) x✝ = (b j • Pi.single j 1) x✝

Next tactic:
simp [Pi.single_apply, eq_comm, Pi.smul_apply (b j)]
/-- Since the map `b ↦ cramer A b` is linear in `b`, it must be multiplication by some matrix. This
matrix is `A.adjugate`. -/
theorem cramer_eq_adjugate_mulVec (A : Matrix n n α) (b : n → α) :
    cramer A b = A.adjugate.mulVec b := by
  nth_rw 2 [← A.transpose_transpose]
  rw [← adjugate_transpose, adjugate_def]
  have : b = ∑ i, b i • Pi.single i 1 := by
    refine' (pi_eq_sum_univ b).trans _
    congr with j
    -- Porting note: needed to help `Pi.smul_apply`
    simp [Pi.single_apply, eq_comm, Pi.smul_apply (b j)]
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
this : b = ∑ i : n, b i • Pi.single i 1
⊢ (cramer A) b = mulVec (of fun i => (cramer Aᵀᵀ) (Pi.single i 1))ᵀ b

Next tactic:
conv_lhs =>
    rw [this]
/-- Since the map `b ↦ cramer A b` is linear in `b`, it must be multiplication by some matrix. This
matrix is `A.adjugate`. -/
theorem cramer_eq_adjugate_mulVec (A : Matrix n n α) (b : n → α) :
    cramer A b = A.adjugate.mulVec b := by
  nth_rw 2 [← A.transpose_transpose]
  rw [← adjugate_transpose, adjugate_def]
  have : b = ∑ i, b i • Pi.single i 1 := by
    refine' (pi_eq_sum_univ b).trans _
    congr with j
    -- Porting note: needed to help `Pi.smul_apply`
    simp [Pi.single_apply, eq_comm, Pi.smul_apply (b j)]
  conv_lhs =>
    

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
this : b = ∑ i : n, b i • Pi.single i 1
| (cramer A) b

Next tactic:
rw [this]
/-- Since the map `b ↦ cramer A b` is linear in `b`, it must be multiplication by some matrix. This
matrix is `A.adjugate`. -/
theorem cramer_eq_adjugate_mulVec (A : Matrix n n α) (b : n → α) :
    cramer A b = A.adjugate.mulVec b := by
  nth_rw 2 [← A.transpose_transpose]
  rw [← adjugate_transpose, adjugate_def]
  have : b = ∑ i, b i • Pi.single i 1 := by
    refine' (pi_eq_sum_univ b).trans _
    congr with j
    -- Porting note: needed to help `Pi.smul_apply`
    simp [Pi.single_apply, eq_comm, Pi.smul_apply (b j)]
  conv_lhs =>
    rw [this]
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
this : b = ∑ i : n, b i • Pi.single i 1
⊢ (cramer A) (∑ i : n, b i • Pi.single i 1) = mulVec (of fun i => (cramer Aᵀᵀ) (Pi.single i 1))ᵀ b

Next tactic:
ext k
/-- Since the map `b ↦ cramer A b` is linear in `b`, it must be multiplication by some matrix. This
matrix is `A.adjugate`. -/
theorem cramer_eq_adjugate_mulVec (A : Matrix n n α) (b : n → α) :
    cramer A b = A.adjugate.mulVec b := by
  nth_rw 2 [← A.transpose_transpose]
  rw [← adjugate_transpose, adjugate_def]
  have : b = ∑ i, b i • Pi.single i 1 := by
    refine' (pi_eq_sum_univ b).trans _
    congr with j
    -- Porting note: needed to help `Pi.smul_apply`
    simp [Pi.single_apply, eq_comm, Pi.smul_apply (b j)]
  conv_lhs =>
    rw [this]
  ext k
  

Proof state:
case h
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
this : b = ∑ i : n, b i • Pi.single i 1
k : n
⊢ (cramer A) (∑ i : n, b i • Pi.single i 1) k = mulVec (of fun i => (cramer Aᵀᵀ) (Pi.single i 1))ᵀ b k

Next tactic:
simp [mulVec, dotProduct, mul_comm]
theorem mul_adjugate_apply (A : Matrix n n α) (i j k) :
    A i k * adjugate A k j = cramer Aᵀ (Pi.single k (A i k)) j := by
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
i j k : n
⊢ A i k * adjugate A k j = (cramer Aᵀ) (Pi.single k (A i k)) j

Next tactic:
erw [← smul_eq_mul, adjugate, of_apply, ← Pi.smul_apply, ← LinearMap.map_smul, ← Pi.single_smul',
    smul_eq_mul, mul_one]
theorem mul_adjugate (A : Matrix n n α) : A * adjugate A = A.det • (1 : Matrix n n α) := by
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
⊢ A * adjugate A = det A • 1

Next tactic:
ext i j
theorem mul_adjugate (A : Matrix n n α) : A * adjugate A = A.det • (1 : Matrix n n α) := by
  ext i j
  

Proof state:
case a.h
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
i j : n
⊢ (A * adjugate A) i j = (det A • 1) i j

Next tactic:
rw [mul_apply, Pi.smul_apply, Pi.smul_apply, one_apply, smul_eq_mul, mul_boole]
theorem mul_adjugate (A : Matrix n n α) : A * adjugate A = A.det • (1 : Matrix n n α) := by
  ext i j
  rw [mul_apply, Pi.smul_apply, Pi.smul_apply, one_apply, smul_eq_mul, mul_boole]
  

Proof state:
case a.h
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
i j : n
⊢ ∑ j_1 : n, A i j_1 * adjugate A j_1 j = if i = j then det A else 0

Next tactic:
simp [mul_adjugate_apply, sum_cramer_apply, cramer_transpose_row_self, Pi.single_apply, eq_comm]
theorem adjugate_mul (A : Matrix n n α) : adjugate A * A = A.det • (1 : Matrix n n α) :=
  calc
    adjugate A * A = (Aᵀ * adjugate Aᵀ)ᵀ := by
      

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
⊢ adjugate A * A = (Aᵀ * adjugate Aᵀ)ᵀ

Next tactic:
rw [← adjugate_transpose, ← transpose_mul, transpose_transpose]
theorem adjugate_mul (A : Matrix n n α) : adjugate A * A = A.det • (1 : Matrix n n α) :=
  calc
    adjugate A * A = (Aᵀ * adjugate Aᵀ)ᵀ := by
      rw [← adjugate_transpose, ← transpose_mul, transpose_transpose]
    _ = _ := by 

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
⊢ (Aᵀ * adjugate Aᵀ)ᵀ = det A • 1

Next tactic:
rw [mul_adjugate Aᵀ, det_transpose, transpose_smul, transpose_one]
theorem adjugate_smul (r : α) (A : Matrix n n α) :
    adjugate (r • A) = r ^ (Fintype.card n - 1) • adjugate A := by
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
r : α
A : Matrix n n α
⊢ adjugate (r • A) = r ^ (Fintype.card n - 1) • adjugate A

Next tactic:
rw [adjugate, adjugate, transpose_smul, cramer_smul]
theorem adjugate_smul (r : α) (A : Matrix n n α) :
    adjugate (r • A) = r ^ (Fintype.card n - 1) • adjugate A := by
  rw [adjugate, adjugate, transpose_smul, cramer_smul]
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
r : α
A : Matrix n n α
⊢ (of fun i => (r ^ (Fintype.card n - 1) • cramer Aᵀ) (Pi.single i 1)) =
    r ^ (Fintype.card n - 1) • of fun i => (cramer Aᵀ) (Pi.single i 1)

Next tactic:
rfl
/-- A stronger form of **Cramer's rule** that allows us to solve some instances of `A * x = b` even
if the determinant is not a unit. A sufficient (but still not necessary) condition is that `A.det`
divides `b`. -/
@[simp]
theorem mulVec_cramer (A : Matrix n n α) (b : n → α) : A.mulVec (cramer A b) = A.det • b := by
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
A : Matrix n n α
b : n → α
⊢ mulVec A ((cramer A) b) = det A • b

Next tactic:
rw [cramer_eq_adjugate_mulVec, mulVec_mulVec, mul_adjugate, smul_mulVec_assoc, one_mulVec]
theorem adjugate_subsingleton [Subsingleton n] (A : Matrix n n α) : adjugate A = 1 := by
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁵ : DecidableEq n
inst✝⁴ : Fintype n
inst✝³ : DecidableEq m
inst✝² : Fintype m
inst✝¹ : CommRing α
inst✝ : Subsingleton n
A : Matrix n n α
⊢ adjugate A = 1

Next tactic:
ext i j
theorem adjugate_subsingleton [Subsingleton n] (A : Matrix n n α) : adjugate A = 1 := by
  ext i j
  

Proof state:
case a.h
m : Type u
n : Type v
α : Type w
inst✝⁵ : DecidableEq n
inst✝⁴ : Fintype n
inst✝³ : DecidableEq m
inst✝² : Fintype m
inst✝¹ : CommRing α
inst✝ : Subsingleton n
A : Matrix n n α
i j : n
⊢ adjugate A i j = OfNat.ofNat 1 i j

Next tactic:
simp [Subsingleton.elim i j, adjugate_apply, det_eq_elem_of_subsingleton _ i]
@[simp]
theorem adjugate_zero [Nontrivial n] : adjugate (0 : Matrix n n α) = 0 := by
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁵ : DecidableEq n
inst✝⁴ : Fintype n
inst✝³ : DecidableEq m
inst✝² : Fintype m
inst✝¹ : CommRing α
inst✝ : Nontrivial n
⊢ adjugate 0 = 0

Next tactic:
ext i j
@[simp]
theorem adjugate_zero [Nontrivial n] : adjugate (0 : Matrix n n α) = 0 := by
  ext i j
  

Proof state:
case a.h
m : Type u
n : Type v
α : Type w
inst✝⁵ : DecidableEq n
inst✝⁴ : Fintype n
inst✝³ : DecidableEq m
inst✝² : Fintype m
inst✝¹ : CommRing α
inst✝ : Nontrivial n
i j : n
⊢ adjugate 0 i j = OfNat.ofNat 0 i j

Next tactic:
obtain ⟨j', hj'⟩ : ∃ j', j' ≠ j := exists_ne j
@[simp]
theorem adjugate_zero [Nontrivial n] : adjugate (0 : Matrix n n α) = 0 := by
  ext i j
  obtain ⟨j', hj'⟩ : ∃ j', j' ≠ j := exists_ne j
  

Proof state:
case a.h.intro
m : Type u
n : Type v
α : Type w
inst✝⁵ : DecidableEq n
inst✝⁴ : Fintype n
inst✝³ : DecidableEq m
inst✝² : Fintype m
inst✝¹ : CommRing α
inst✝ : Nontrivial n
i j j' : n
hj' : j' ≠ j
⊢ adjugate 0 i j = OfNat.ofNat 0 i j

Next tactic:
apply det_eq_zero_of_column_eq_zero j'
@[simp]
theorem adjugate_zero [Nontrivial n] : adjugate (0 : Matrix n n α) = 0 := by
  ext i j
  obtain ⟨j', hj'⟩ : ∃ j', j' ≠ j := exists_ne j
  apply det_eq_zero_of_column_eq_zero j'
  

Proof state:
case a.h.intro
m : Type u
n : Type v
α : Type w
inst✝⁵ : DecidableEq n
inst✝⁴ : Fintype n
inst✝³ : DecidableEq m
inst✝² : Fintype m
inst✝¹ : CommRing α
inst✝ : Nontrivial n
i j j' : n
hj' : j' ≠ j
⊢ ∀ (i_1 : n), updateColumn 0ᵀ j (Pi.single i 1) i_1 j' = 0

Next tactic:
intro j''
@[simp]
theorem adjugate_zero [Nontrivial n] : adjugate (0 : Matrix n n α) = 0 := by
  ext i j
  obtain ⟨j', hj'⟩ : ∃ j', j' ≠ j := exists_ne j
  apply det_eq_zero_of_column_eq_zero j'
  intro j''
  

Proof state:
case a.h.intro
m : Type u
n : Type v
α : Type w
inst✝⁵ : DecidableEq n
inst✝⁴ : Fintype n
inst✝³ : DecidableEq m
inst✝² : Fintype m
inst✝¹ : CommRing α
inst✝ : Nontrivial n
i j j' : n
hj' : j' ≠ j
j'' : n
⊢ updateColumn 0ᵀ j (Pi.single i 1) j'' j' = 0

Next tactic:
simp [updateColumn_ne hj']
@[simp]
theorem adjugate_one : adjugate (1 : Matrix n n α) = 1 := by
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
⊢ adjugate 1 = 1

Next tactic:
ext
@[simp]
theorem adjugate_one : adjugate (1 : Matrix n n α) = 1 := by
  ext
  

Proof state:
case a.h
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
i✝ x✝ : n
⊢ adjugate 1 i✝ x✝ = OfNat.ofNat 1 i✝ x✝

Next tactic:
simp [adjugate_def, Matrix.one_apply, Pi.single_apply, eq_comm]
@[simp]
theorem adjugate_diagonal (v : n → α) :
    adjugate (diagonal v) = diagonal fun i => ∏ j in Finset.univ.erase i, v j := by
  

Proof state:
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
v : n → α
⊢ adjugate (diagonal v) = diagonal fun i => ∏ j in Finset.erase univ i, v j

Next tactic:
ext i j
@[simp]
theorem adjugate_diagonal (v : n → α) :
    adjugate (diagonal v) = diagonal fun i => ∏ j in Finset.univ.erase i, v j := by
  ext i j
  

Proof state:
case a.h
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
v : n → α
i j : n
⊢ adjugate (diagonal v) i j = diagonal (fun i => ∏ j in Finset.erase univ i, v j) i j

Next tactic:
simp only [adjugate_def, cramer_apply, diagonal_transpose, of_apply]
@[simp]
theorem adjugate_diagonal (v : n → α) :
    adjugate (diagonal v) = diagonal fun i => ∏ j in Finset.univ.erase i, v j := by
  ext i j
  simp only [adjugate_def, cramer_apply, diagonal_transpose, of_apply]
  

Proof state:
case a.h
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
v : n → α
i j : n
⊢ det (updateColumn (diagonal v) j (Pi.single i 1)) = diagonal (fun i => ∏ j in Finset.erase univ i, v j) i j

Next tactic:
obtain rfl | hij := eq_or_ne i j
@[simp]
theorem adjugate_diagonal (v : n → α) :
    adjugate (diagonal v) = diagonal fun i => ∏ j in Finset.univ.erase i, v j := by
  ext i j
  simp only [adjugate_def, cramer_apply, diagonal_transpose, of_apply]
  obtain rfl | hij := eq_or_ne i j
  · 

Proof state:
case a.h.inl
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
v : n → α
i : n
⊢ det (updateColumn (diagonal v) i (Pi.single i 1)) = diagonal (fun i => ∏ j in Finset.erase univ i, v j) i i

Next tactic:
rw [diagonal_apply_eq, diagonal_updateColumn_single, det_diagonal,
      prod_update_of_mem (Finset.mem_univ _), sdiff_singleton_eq_erase, one_mul]
@[simp]
theorem adjugate_diagonal (v : n → α) :
    adjugate (diagonal v) = diagonal fun i => ∏ j in Finset.univ.erase i, v j := by
  ext i j
  simp only [adjugate_def, cramer_apply, diagonal_transpose, of_apply]
  obtain rfl | hij := eq_or_ne i j
  · rw [diagonal_apply_eq, diagonal_updateColumn_single, det_diagonal,
      prod_update_of_mem (Finset.mem_univ _), sdiff_singleton_eq_erase, one_mul]
  · 

Proof state:
case a.h.inr
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
v : n → α
i j : n
hij : i ≠ j
⊢ det (updateColumn (diagonal v) j (Pi.single i 1)) = diagonal (fun i => ∏ j in Finset.erase univ i, v j) i j

Next tactic:
rw [diagonal_apply_ne _ hij]
@[simp]
theorem adjugate_diagonal (v : n → α) :
    adjugate (diagonal v) = diagonal fun i => ∏ j in Finset.univ.erase i, v j := by
  ext i j
  simp only [adjugate_def, cramer_apply, diagonal_transpose, of_apply]
  obtain rfl | hij := eq_or_ne i j
  · rw [diagonal_apply_eq, diagonal_updateColumn_single, det_diagonal,
      prod_update_of_mem (Finset.mem_univ _), sdiff_singleton_eq_erase, one_mul]
  · rw [diagonal_apply_ne _ hij]
    

Proof state:
case a.h.inr
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
v : n → α
i j : n
hij : i ≠ j
⊢ det (updateColumn (diagonal v) j (Pi.single i 1)) = 0

Next tactic:
refine' det_eq_zero_of_row_eq_zero j fun k => _
@[simp]
theorem adjugate_diagonal (v : n → α) :
    adjugate (diagonal v) = diagonal fun i => ∏ j in Finset.univ.erase i, v j := by
  ext i j
  simp only [adjugate_def, cramer_apply, diagonal_transpose, of_apply]
  obtain rfl | hij := eq_or_ne i j
  · rw [diagonal_apply_eq, diagonal_updateColumn_single, det_diagonal,
      prod_update_of_mem (Finset.mem_univ _), sdiff_singleton_eq_erase, one_mul]
  · rw [diagonal_apply_ne _ hij]
    refine' det_eq_zero_of_row_eq_zero j fun k => _
    

Proof state:
case a.h.inr
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
v : n → α
i j : n
hij : i ≠ j
k : n
⊢ updateColumn (diagonal v) j (Pi.single i 1) j k = 0

Next tactic:
obtain rfl | hjk := eq_or_ne k j
@[simp]
theorem adjugate_diagonal (v : n → α) :
    adjugate (diagonal v) = diagonal fun i => ∏ j in Finset.univ.erase i, v j := by
  ext i j
  simp only [adjugate_def, cramer_apply, diagonal_transpose, of_apply]
  obtain rfl | hij := eq_or_ne i j
  · rw [diagonal_apply_eq, diagonal_updateColumn_single, det_diagonal,
      prod_update_of_mem (Finset.mem_univ _), sdiff_singleton_eq_erase, one_mul]
  · rw [diagonal_apply_ne _ hij]
    refine' det_eq_zero_of_row_eq_zero j fun k => _
    obtain rfl | hjk := eq_or_ne k j
    · 

Proof state:
case a.h.inr.inl
m : Type u
n : Type v
α : Type w
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : DecidableEq m
inst✝¹ : Fintype m
inst✝ : CommRing α
v : n → α
i k : n
hij : i ≠ k
⊢ updateColumn (diagonal v) k (Pi.single i 1) k k = 0

Next tactic:
rw [updateColumn_self, Pi.single_eq_of_ne' hij]