l3lab/ntp-mathlib huggingface dataset:
theorem charpoly_degree_eq_dim [Nontrivial R] (M : Matrix n n R) :
    M.charpoly.degree = Fintype.card n := by
  by_cases h : Fintype.card n = 0
  · rw [h]
    unfold charpoly
    rw [det_of_card_zero]
    · simp
    · assumption
  rw [← sub_add_cancel M.charpoly (∏ i : n, (X - C (M i i)))]
  -- porting note: added `↑` in front of `Fintype.card n`
  have h1 : (∏ i : n, (X - C (M i i))).degree = ↑(Fintype.card n) := by
    rw [degree_eq_iff_natDegree_eq_of_pos (Nat.pos_of_ne_zero h), natDegree_prod']
    simp_rw [natDegree_X_sub_C]
    rw [← Finset.card_univ, sum_const, smul_eq_mul, mul_one]
    simp_rw [(monic_X_sub_C _).leadingCoeff]
    simp
  rw [degree_add_eq_right_of_degree_lt]
  exact h1
  rw [h1]
  apply lt_trans (charpoly_sub_diagonal_degree_lt M)
  rw [Nat.cast_lt]
  rw [← Nat.pred_eq_sub_one]
  

Proof state:
case neg
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M✝ : Matrix n n R
inst✝ : Nontrivial R
M : Matrix n n R
h : ¬Fintype.card n = 0
h1 : degree (∏ i : n, (X - C (M i i))) = ↑(Fintype.card n)
⊢ Nat.pred (Fintype.card n) < Fintype.card n

Next tactic:
apply Nat.pred_lt
theorem charpoly_degree_eq_dim [Nontrivial R] (M : Matrix n n R) :
    M.charpoly.degree = Fintype.card n := by
  by_cases h : Fintype.card n = 0
  · rw [h]
    unfold charpoly
    rw [det_of_card_zero]
    · simp
    · assumption
  rw [← sub_add_cancel M.charpoly (∏ i : n, (X - C (M i i)))]
  -- porting note: added `↑` in front of `Fintype.card n`
  have h1 : (∏ i : n, (X - C (M i i))).degree = ↑(Fintype.card n) := by
    rw [degree_eq_iff_natDegree_eq_of_pos (Nat.pos_of_ne_zero h), natDegree_prod']
    simp_rw [natDegree_X_sub_C]
    rw [← Finset.card_univ, sum_const, smul_eq_mul, mul_one]
    simp_rw [(monic_X_sub_C _).leadingCoeff]
    simp
  rw [degree_add_eq_right_of_degree_lt]
  exact h1
  rw [h1]
  apply lt_trans (charpoly_sub_diagonal_degree_lt M)
  rw [Nat.cast_lt]
  rw [← Nat.pred_eq_sub_one]
  apply Nat.pred_lt
  

Proof state:
case neg.a
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M✝ : Matrix n n R
inst✝ : Nontrivial R
M : Matrix n n R
h : ¬Fintype.card n = 0
h1 : degree (∏ i : n, (X - C (M i i))) = ↑(Fintype.card n)
⊢ Fintype.card n ≠ 0

Next tactic:
apply h
theorem charpoly_monic (M : Matrix n n R) : M.charpoly.Monic := by
  

Proof state:
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ M : Matrix n n R
⊢ Monic (charpoly M)

Next tactic:
nontriviality R
theorem charpoly_monic (M : Matrix n n R) : M.charpoly.Monic := by
  nontriviality R -- porting note: was simply `nontriviality`
  

Proof state:
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ M : Matrix n n R
✝ : Nontrivial R
⊢ Monic (charpoly M)

Next tactic:
by_cases h : Fintype.card n = 0
theorem charpoly_monic (M : Matrix n n R) : M.charpoly.Monic := by
  nontriviality R -- porting note: was simply `nontriviality`
  by_cases h : Fintype.card n = 0
  · 

Proof state:
case pos
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ M : Matrix n n R
✝ : Nontrivial R
h : Fintype.card n = 0
⊢ Monic (charpoly M)

Next tactic:
rw [charpoly, det_of_card_zero h]
theorem charpoly_monic (M : Matrix n n R) : M.charpoly.Monic := by
  nontriviality R -- porting note: was simply `nontriviality`
  by_cases h : Fintype.card n = 0
  · rw [charpoly, det_of_card_zero h]
    

Proof state:
case pos
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ M : Matrix n n R
✝ : Nontrivial R
h : Fintype.card n = 0
⊢ Monic 1

Next tactic:
apply monic_one
theorem charpoly_monic (M : Matrix n n R) : M.charpoly.Monic := by
  nontriviality R -- porting note: was simply `nontriviality`
  by_cases h : Fintype.card n = 0
  · rw [charpoly, det_of_card_zero h]
    apply monic_one
  

Proof state:
case neg
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ M : Matrix n n R
✝ : Nontrivial R
h : ¬Fintype.card n = 0
⊢ Monic (charpoly M)

Next tactic:
have mon : (∏ i : n, (X - C (M i i))).Monic := by
    apply monic_prod_of_monic univ fun i : n => X - C (M i i)
    simp [monic_X_sub_C]
theorem charpoly_monic (M : Matrix n n R) : M.charpoly.Monic := by
  nontriviality R -- porting note: was simply `nontriviality`
  by_cases h : Fintype.card n = 0
  · rw [charpoly, det_of_card_zero h]
    apply monic_one
  have mon : (∏ i : n, (X - C (M i i))).Monic := by
    

Proof state:
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ M : Matrix n n R
✝ : Nontrivial R
h : ¬Fintype.card n = 0
⊢ Monic (∏ i : n, (X - C (M i i)))

Next tactic:
apply monic_prod_of_monic univ fun i : n => X - C (M i i)
theorem charpoly_monic (M : Matrix n n R) : M.charpoly.Monic := by
  nontriviality R -- porting note: was simply `nontriviality`
  by_cases h : Fintype.card n = 0
  · rw [charpoly, det_of_card_zero h]
    apply monic_one
  have mon : (∏ i : n, (X - C (M i i))).Monic := by
    apply monic_prod_of_monic univ fun i : n => X - C (M i i)
    

Proof state:
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ M : Matrix n n R
✝ : Nontrivial R
h : ¬Fintype.card n = 0
⊢ ∀ i ∈ univ, Monic (X - C (M i i))

Next tactic:
simp [monic_X_sub_C]
theorem charpoly_monic (M : Matrix n n R) : M.charpoly.Monic := by
  nontriviality R -- porting note: was simply `nontriviality`
  by_cases h : Fintype.card n = 0
  · rw [charpoly, det_of_card_zero h]
    apply monic_one
  have mon : (∏ i : n, (X - C (M i i))).Monic := by
    apply monic_prod_of_monic univ fun i : n => X - C (M i i)
    simp [monic_X_sub_C]
  

Proof state:
case neg
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ M : Matrix n n R
✝ : Nontrivial R
h : ¬Fintype.card n = 0
mon : Monic (∏ i : n, (X - C (M i i)))
⊢ Monic (charpoly M)

Next tactic:
rw [← sub_add_cancel (∏ i : n, (X - C (M i i))) M.charpoly] at mon
theorem charpoly_monic (M : Matrix n n R) : M.charpoly.Monic := by
  nontriviality R -- porting note: was simply `nontriviality`
  by_cases h : Fintype.card n = 0
  · rw [charpoly, det_of_card_zero h]
    apply monic_one
  have mon : (∏ i : n, (X - C (M i i))).Monic := by
    apply monic_prod_of_monic univ fun i : n => X - C (M i i)
    simp [monic_X_sub_C]
  rw [← sub_add_cancel (∏ i : n, (X - C (M i i))) M.charpoly] at mon
  

Proof state:
case neg
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ M : Matrix n n R
✝ : Nontrivial R
h : ¬Fintype.card n = 0
mon : Monic (∏ i : n, (X - C (M i i)) - charpoly M + charpoly M)
⊢ Monic (charpoly M)

Next tactic:
rw [Monic] at *
theorem charpoly_monic (M : Matrix n n R) : M.charpoly.Monic := by
  nontriviality R -- porting note: was simply `nontriviality`
  by_cases h : Fintype.card n = 0
  · rw [charpoly, det_of_card_zero h]
    apply monic_one
  have mon : (∏ i : n, (X - C (M i i))).Monic := by
    apply monic_prod_of_monic univ fun i : n => X - C (M i i)
    simp [monic_X_sub_C]
  rw [← sub_add_cancel (∏ i : n, (X - C (M i i))) M.charpoly] at mon
  rw [Monic] at *
  

Proof state:
case neg
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ M : Matrix n n R
✝ : Nontrivial R
h : ¬Fintype.card n = 0
mon : leadingCoeff (∏ i : n, (X - C (M i i)) - charpoly M + charpoly M) = 1
⊢ leadingCoeff (charpoly M) = 1

Next tactic:
rwa [leadingCoeff_add_of_degree_lt] at mon
theorem charpoly_monic (M : Matrix n n R) : M.charpoly.Monic := by
  nontriviality R -- porting note: was simply `nontriviality`
  by_cases h : Fintype.card n = 0
  · rw [charpoly, det_of_card_zero h]
    apply monic_one
  have mon : (∏ i : n, (X - C (M i i))).Monic := by
    apply monic_prod_of_monic univ fun i : n => X - C (M i i)
    simp [monic_X_sub_C]
  rw [← sub_add_cancel (∏ i : n, (X - C (M i i))) M.charpoly] at mon
  rw [Monic] at *
  rwa [leadingCoeff_add_of_degree_lt] at mon
  

Proof state:
case neg
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ M : Matrix n n R
✝ : Nontrivial R
h : ¬Fintype.card n = 0
mon : leadingCoeff (∏ i : n, (X - C (M i i)) - charpoly M + charpoly M) = 1
⊢ degree (∏ i : n, (X - C (M i i)) - charpoly M) < degree (charpoly M)

Next tactic:
rw [charpoly_degree_eq_dim]
theorem charpoly_monic (M : Matrix n n R) : M.charpoly.Monic := by
  nontriviality R -- porting note: was simply `nontriviality`
  by_cases h : Fintype.card n = 0
  · rw [charpoly, det_of_card_zero h]
    apply monic_one
  have mon : (∏ i : n, (X - C (M i i))).Monic := by
    apply monic_prod_of_monic univ fun i : n => X - C (M i i)
    simp [monic_X_sub_C]
  rw [← sub_add_cancel (∏ i : n, (X - C (M i i))) M.charpoly] at mon
  rw [Monic] at *
  rwa [leadingCoeff_add_of_degree_lt] at mon
  rw [charpoly_degree_eq_dim]
  

Proof state:
case neg
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ M : Matrix n n R
✝ : Nontrivial R
h : ¬Fintype.card n = 0
mon : leadingCoeff (∏ i : n, (X - C (M i i)) - charpoly M + charpoly M) = 1
⊢ degree (∏ i : n, (X - C (M i i)) - charpoly M) < ↑(Fintype.card n)

Next tactic:
rw [← neg_sub]
theorem charpoly_monic (M : Matrix n n R) : M.charpoly.Monic := by
  nontriviality R -- porting note: was simply `nontriviality`
  by_cases h : Fintype.card n = 0
  · rw [charpoly, det_of_card_zero h]
    apply monic_one
  have mon : (∏ i : n, (X - C (M i i))).Monic := by
    apply monic_prod_of_monic univ fun i : n => X - C (M i i)
    simp [monic_X_sub_C]
  rw [← sub_add_cancel (∏ i : n, (X - C (M i i))) M.charpoly] at mon
  rw [Monic] at *
  rwa [leadingCoeff_add_of_degree_lt] at mon
  rw [charpoly_degree_eq_dim]
  rw [← neg_sub]
  

Proof state:
case neg
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ M : Matrix n n R
✝ : Nontrivial R
h : ¬Fintype.card n = 0
mon : leadingCoeff (∏ i : n, (X - C (M i i)) - charpoly M + charpoly M) = 1
⊢ degree (-(charpoly M - ∏ i : n, (X - C (M i i)))) < ↑(Fintype.card n)

Next tactic:
rw [degree_neg]
theorem charpoly_monic (M : Matrix n n R) : M.charpoly.Monic := by
  nontriviality R -- porting note: was simply `nontriviality`
  by_cases h : Fintype.card n = 0
  · rw [charpoly, det_of_card_zero h]
    apply monic_one
  have mon : (∏ i : n, (X - C (M i i))).Monic := by
    apply monic_prod_of_monic univ fun i : n => X - C (M i i)
    simp [monic_X_sub_C]
  rw [← sub_add_cancel (∏ i : n, (X - C (M i i))) M.charpoly] at mon
  rw [Monic] at *
  rwa [leadingCoeff_add_of_degree_lt] at mon
  rw [charpoly_degree_eq_dim]
  rw [← neg_sub]
  rw [degree_neg]
  

Proof state:
case neg
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ M : Matrix n n R
✝ : Nontrivial R
h : ¬Fintype.card n = 0
mon : leadingCoeff (∏ i : n, (X - C (M i i)) - charpoly M + charpoly M) = 1
⊢ degree (charpoly M - ∏ i : n, (X - C (M i i))) < ↑(Fintype.card n)

Next tactic:
apply lt_trans (charpoly_sub_diagonal_degree_lt M)
theorem charpoly_monic (M : Matrix n n R) : M.charpoly.Monic := by
  nontriviality R -- porting note: was simply `nontriviality`
  by_cases h : Fintype.card n = 0
  · rw [charpoly, det_of_card_zero h]
    apply monic_one
  have mon : (∏ i : n, (X - C (M i i))).Monic := by
    apply monic_prod_of_monic univ fun i : n => X - C (M i i)
    simp [monic_X_sub_C]
  rw [← sub_add_cancel (∏ i : n, (X - C (M i i))) M.charpoly] at mon
  rw [Monic] at *
  rwa [leadingCoeff_add_of_degree_lt] at mon
  rw [charpoly_degree_eq_dim]
  rw [← neg_sub]
  rw [degree_neg]
  apply lt_trans (charpoly_sub_diagonal_degree_lt M)
  

Proof state:
case neg
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ M : Matrix n n R
✝ : Nontrivial R
h : ¬Fintype.card n = 0
mon : leadingCoeff (∏ i : n, (X - C (M i i)) - charpoly M + charpoly M) = 1
⊢ ↑(Fintype.card n - 1) < ↑(Fintype.card n)

Next tactic:
rw [Nat.cast_lt]
theorem charpoly_monic (M : Matrix n n R) : M.charpoly.Monic := by
  nontriviality R -- porting note: was simply `nontriviality`
  by_cases h : Fintype.card n = 0
  · rw [charpoly, det_of_card_zero h]
    apply monic_one
  have mon : (∏ i : n, (X - C (M i i))).Monic := by
    apply monic_prod_of_monic univ fun i : n => X - C (M i i)
    simp [monic_X_sub_C]
  rw [← sub_add_cancel (∏ i : n, (X - C (M i i))) M.charpoly] at mon
  rw [Monic] at *
  rwa [leadingCoeff_add_of_degree_lt] at mon
  rw [charpoly_degree_eq_dim]
  rw [← neg_sub]
  rw [degree_neg]
  apply lt_trans (charpoly_sub_diagonal_degree_lt M)
  rw [Nat.cast_lt]
  

Proof state:
case neg
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ M : Matrix n n R
✝ : Nontrivial R
h : ¬Fintype.card n = 0
mon : leadingCoeff (∏ i : n, (X - C (M i i)) - charpoly M + charpoly M) = 1
⊢ Fintype.card n - 1 < Fintype.card n

Next tactic:
rw [← Nat.pred_eq_sub_one]
theorem charpoly_monic (M : Matrix n n R) : M.charpoly.Monic := by
  nontriviality R -- porting note: was simply `nontriviality`
  by_cases h : Fintype.card n = 0
  · rw [charpoly, det_of_card_zero h]
    apply monic_one
  have mon : (∏ i : n, (X - C (M i i))).Monic := by
    apply monic_prod_of_monic univ fun i : n => X - C (M i i)
    simp [monic_X_sub_C]
  rw [← sub_add_cancel (∏ i : n, (X - C (M i i))) M.charpoly] at mon
  rw [Monic] at *
  rwa [leadingCoeff_add_of_degree_lt] at mon
  rw [charpoly_degree_eq_dim]
  rw [← neg_sub]
  rw [degree_neg]
  apply lt_trans (charpoly_sub_diagonal_degree_lt M)
  rw [Nat.cast_lt]
  rw [← Nat.pred_eq_sub_one]
  

Proof state:
case neg
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ M : Matrix n n R
✝ : Nontrivial R
h : ¬Fintype.card n = 0
mon : leadingCoeff (∏ i : n, (X - C (M i i)) - charpoly M + charpoly M) = 1
⊢ Nat.pred (Fintype.card n) < Fintype.card n

Next tactic:
apply Nat.pred_lt
theorem charpoly_monic (M : Matrix n n R) : M.charpoly.Monic := by
  nontriviality R -- porting note: was simply `nontriviality`
  by_cases h : Fintype.card n = 0
  · rw [charpoly, det_of_card_zero h]
    apply monic_one
  have mon : (∏ i : n, (X - C (M i i))).Monic := by
    apply monic_prod_of_monic univ fun i : n => X - C (M i i)
    simp [monic_X_sub_C]
  rw [← sub_add_cancel (∏ i : n, (X - C (M i i))) M.charpoly] at mon
  rw [Monic] at *
  rwa [leadingCoeff_add_of_degree_lt] at mon
  rw [charpoly_degree_eq_dim]
  rw [← neg_sub]
  rw [degree_neg]
  apply lt_trans (charpoly_sub_diagonal_degree_lt M)
  rw [Nat.cast_lt]
  rw [← Nat.pred_eq_sub_one]
  apply Nat.pred_lt
  

Proof state:
case neg.a
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ M : Matrix n n R
✝ : Nontrivial R
h : ¬Fintype.card n = 0
mon : leadingCoeff (∏ i : n, (X - C (M i i)) - charpoly M + charpoly M) = 1
⊢ Fintype.card n ≠ 0

Next tactic:
apply h
/-- See also `Matrix.coeff_charpolyRev_eq_neg_trace`. -/
theorem trace_eq_neg_charpoly_coeff [Nonempty n] (M : Matrix n n R) :
    trace M = -M.charpoly.coeff (Fintype.card n - 1) := by
  

Proof state:
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M✝ : Matrix n n R
inst✝ : Nonempty n
M : Matrix n n R
⊢ trace M = -coeff (charpoly M) (Fintype.card n - 1)

Next tactic:
rw [charpoly_coeff_eq_prod_coeff_of_le _ le_rfl, Fintype.card,
    prod_X_sub_C_coeff_card_pred univ (fun i : n => M i i) Fintype.card_pos, neg_neg, trace]
/-- See also `Matrix.coeff_charpolyRev_eq_neg_trace`. -/
theorem trace_eq_neg_charpoly_coeff [Nonempty n] (M : Matrix n n R) :
    trace M = -M.charpoly.coeff (Fintype.card n - 1) := by
  rw [charpoly_coeff_eq_prod_coeff_of_le _ le_rfl, Fintype.card,
    prod_X_sub_C_coeff_card_pred univ (fun i : n => M i i) Fintype.card_pos, neg_neg, trace]
  

Proof state:
R : Type u
inst✝⁴ : CommRing R
n G : Type v
inst✝³ : DecidableEq n
inst✝² : Fintype n
α β : Type v
inst✝¹ : DecidableEq α
M✝ : Matrix n n R
inst✝ : Nonempty n
M : Matrix n n R
⊢ ∑ i : n, diag M i = ∑ i : n, M i i

Next tactic:
simp_rw [diag_apply]
theorem matPolyEquiv_symm_map_eval (M : (Matrix n n R)[X]) (r : R) :
    (matPolyEquiv.symm M).map (eval r) = M.eval (scalar n r) := by
  

Proof state:
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ : Matrix n n R
M : (Matrix n n R)[X]
r : R
⊢ map ((AlgEquiv.symm matPolyEquiv) M) (eval r) = eval ((scalar n) r) M

Next tactic:
suffices ((aeval r).mapMatrix.comp matPolyEquiv.symm.toAlgHom : (Matrix n n R)[X] →ₐ[R] _) =
      (eval₂AlgHom' (AlgHom.id R _) (scalar n r)
        fun x => (scalar_commute _ (Commute.all _) _).symm) from
    FunLike.congr_fun this M
theorem matPolyEquiv_symm_map_eval (M : (Matrix n n R)[X]) (r : R) :
    (matPolyEquiv.symm M).map (eval r) = M.eval (scalar n r) := by
  suffices ((aeval r).mapMatrix.comp matPolyEquiv.symm.toAlgHom : (Matrix n n R)[X] →ₐ[R] _) =
      (eval₂AlgHom' (AlgHom.id R _) (scalar n r)
        fun x => (scalar_commute _ (Commute.all _) _).symm) from
    FunLike.congr_fun this M
  

Proof state:
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ : Matrix n n R
M : (Matrix n n R)[X]
r : R
⊢ AlgHom.comp (AlgHom.mapMatrix (aeval r)) ↑(AlgEquiv.symm matPolyEquiv) =
    eval₂AlgHom' (AlgHom.id R (Matrix n n R)) ((scalar n) r)
      (_ : ∀ (x : Matrix n n R), Commute ((AlgHom.id R (Matrix n n R)) x) ((scalar n) r))

Next tactic:
ext : 1
theorem matPolyEquiv_symm_map_eval (M : (Matrix n n R)[X]) (r : R) :
    (matPolyEquiv.symm M).map (eval r) = M.eval (scalar n r) := by
  suffices ((aeval r).mapMatrix.comp matPolyEquiv.symm.toAlgHom : (Matrix n n R)[X] →ₐ[R] _) =
      (eval₂AlgHom' (AlgHom.id R _) (scalar n r)
        fun x => (scalar_commute _ (Commute.all _) _).symm) from
    FunLike.congr_fun this M
  ext : 1
  · 

Proof state:
case hC
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ : Matrix n n R
M : (Matrix n n R)[X]
r : R
⊢ AlgHom.comp (AlgHom.comp (AlgHom.mapMatrix (aeval r)) ↑(AlgEquiv.symm matPolyEquiv)) CAlgHom =
    AlgHom.comp
      (eval₂AlgHom' (AlgHom.id R (Matrix n n R)) ((scalar n) r)
        (_ : ∀ (x : Matrix n n R), Commute ((AlgHom.id R (Matrix n n R)) x) ((scalar n) r)))
      CAlgHom

Next tactic:
ext M : 1
theorem matPolyEquiv_symm_map_eval (M : (Matrix n n R)[X]) (r : R) :
    (matPolyEquiv.symm M).map (eval r) = M.eval (scalar n r) := by
  suffices ((aeval r).mapMatrix.comp matPolyEquiv.symm.toAlgHom : (Matrix n n R)[X] →ₐ[R] _) =
      (eval₂AlgHom' (AlgHom.id R _) (scalar n r)
        fun x => (scalar_commute _ (Commute.all _) _).symm) from
    FunLike.congr_fun this M
  ext : 1
  · ext M : 1
    

Proof state:
case hC.H
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝¹ : Matrix n n R
M✝ : (Matrix n n R)[X]
r : R
M : Matrix n n R
⊢ (AlgHom.comp (AlgHom.comp (AlgHom.mapMatrix (aeval r)) ↑(AlgEquiv.symm matPolyEquiv)) CAlgHom) M =
    (AlgHom.comp
        (eval₂AlgHom' (AlgHom.id R (Matrix n n R)) ((scalar n) r)
          (_ : ∀ (x : Matrix n n R), Commute ((AlgHom.id R (Matrix n n R)) x) ((scalar n) r)))
        CAlgHom)
      M

Next tactic:
simp [Function.comp]
theorem matPolyEquiv_symm_map_eval (M : (Matrix n n R)[X]) (r : R) :
    (matPolyEquiv.symm M).map (eval r) = M.eval (scalar n r) := by
  suffices ((aeval r).mapMatrix.comp matPolyEquiv.symm.toAlgHom : (Matrix n n R)[X] →ₐ[R] _) =
      (eval₂AlgHom' (AlgHom.id R _) (scalar n r)
        fun x => (scalar_commute _ (Commute.all _) _).symm) from
    FunLike.congr_fun this M
  ext : 1
  · ext M : 1
    simp [Function.comp]
  · 

Proof state:
case hX
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ : Matrix n n R
M : (Matrix n n R)[X]
r : R
⊢ (AlgHom.comp (AlgHom.mapMatrix (aeval r)) ↑(AlgEquiv.symm matPolyEquiv)) X =
    (eval₂AlgHom' (AlgHom.id R (Matrix n n R)) ((scalar n) r)
        (_ : ∀ (x : Matrix n n R), Commute ((AlgHom.id R (Matrix n n R)) x) ((scalar n) r)))
      X

Next tactic:
simp [smul_eq_diagonal_mul]
theorem matPolyEquiv_eval_eq_map (M : Matrix n n R[X]) (r : R) :
    (matPolyEquiv M).eval (scalar n r) = M.map (eval r) := by
  

Proof state:
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ : Matrix n n R
M : Matrix n n R[X]
r : R
⊢ eval ((scalar n) r) (matPolyEquiv M) = map M (eval r)

Next tactic:
simpa only [AlgEquiv.symm_apply_apply] using (matPolyEquiv_symm_map_eval (matPolyEquiv M) r).symm
theorem matPolyEquiv_eval (M : Matrix n n R[X]) (r : R) (i j : n) :
    (matPolyEquiv M).eval (scalar n r) i j = (M i j).eval r := by
  

Proof state:
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ : Matrix n n R
M : Matrix n n R[X]
r : R
i j : n
⊢ eval ((scalar n) r) (matPolyEquiv M) i j = eval r (M i j)

Next tactic:
rw [matPolyEquiv_eval_eq_map, map_apply]
theorem eval_det (M : Matrix n n R[X]) (r : R) :
    Polynomial.eval r M.det = (Polynomial.eval (scalar n r) (matPolyEquiv M)).det := by
  

Proof state:
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ : Matrix n n R
M : Matrix n n R[X]
r : R
⊢ eval r (det M) = det (eval ((scalar n) r) (matPolyEquiv M))

Next tactic:
rw [Polynomial.eval, ← coe_eval₂RingHom, RingHom.map_det]
theorem eval_det (M : Matrix n n R[X]) (r : R) :
    Polynomial.eval r M.det = (Polynomial.eval (scalar n r) (matPolyEquiv M)).det := by
  rw [Polynomial.eval, ← coe_eval₂RingHom, RingHom.map_det]
  

Proof state:
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ : Matrix n n R
M : Matrix n n R[X]
r : R
⊢ det ((RingHom.mapMatrix (eval₂RingHom (RingHom.id R) r)) M) = det (eval ((scalar n) r) (matPolyEquiv M))

Next tactic:
apply congr_arg det
theorem eval_det (M : Matrix n n R[X]) (r : R) :
    Polynomial.eval r M.det = (Polynomial.eval (scalar n r) (matPolyEquiv M)).det := by
  rw [Polynomial.eval, ← coe_eval₂RingHom, RingHom.map_det]
  apply congr_arg det
  

Proof state:
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ : Matrix n n R
M : Matrix n n R[X]
r : R
⊢ (RingHom.mapMatrix (eval₂RingHom (RingHom.id R) r)) M = eval ((scalar n) r) (matPolyEquiv M)

Next tactic:
ext
theorem eval_det (M : Matrix n n R[X]) (r : R) :
    Polynomial.eval r M.det = (Polynomial.eval (scalar n r) (matPolyEquiv M)).det := by
  rw [Polynomial.eval, ← coe_eval₂RingHom, RingHom.map_det]
  apply congr_arg det
  ext
  

Proof state:
case a.h
R : Type u
inst✝³ : CommRing R
n G : Type v
inst✝² : DecidableEq n
inst✝¹ : Fintype n
α β : Type v
inst✝ : DecidableEq α
M✝ : Matrix n n R
M : Matrix n n R[X]
r : R
i✝ x✝ : n
⊢ (RingHom.mapMatrix (eval₂RingHom (RingHom.id R) r)) M i✝ x✝ = eval ((scalar n) r) (matPolyEquiv M) i✝ x✝

Next tactic:
symm