l3lab/ntp-mathlib huggingface dataset:
theorem matPolyEquiv_eq_x_pow_sub_c {K : Type*} (k : ℕ) [Field K] (M : Matrix n n K) :
    matPolyEquiv ((expand K k : K[X] →+* K[X]).mapMatrix (charmatrix (M ^ k))) =
      X ^ k - C (M ^ k) := by
  -- porting note: `i` and `j` are used later on, but were not mentioned in mathlib3
  ext m i j
  rw [coeff_sub, coeff_C, matPolyEquiv_coeff_apply, RingHom.mapMatrix_apply, Matrix.map_apply,
    AlgHom.coe_toRingHom, DMatrix.sub_apply, coeff_X_pow]
  

Proof state:
case a.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
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
K : Type u_1
k : ℕ
inst✝ : Field K
M : Matrix n n K
m : ℕ
i j : n
⊢ coeff ((expand K k) (charmatrix (M ^ k) i j)) m = ite (m = k) 1 0 i j - ite (m = 0) (M ^ k) 0 i j

Next tactic:
by_cases hij : i = j
theorem matPolyEquiv_eq_x_pow_sub_c {K : Type*} (k : ℕ) [Field K] (M : Matrix n n K) :
    matPolyEquiv ((expand K k : K[X] →+* K[X]).mapMatrix (charmatrix (M ^ k))) =
      X ^ k - C (M ^ k) := by
  -- porting note: `i` and `j` are used later on, but were not mentioned in mathlib3
  ext m i j
  rw [coeff_sub, coeff_C, matPolyEquiv_coeff_apply, RingHom.mapMatrix_apply, Matrix.map_apply,
    AlgHom.coe_toRingHom, DMatrix.sub_apply, coeff_X_pow]
  by_cases hij : i = j
  · 

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✝ : Matrix n n R
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
K : Type u_1
k : ℕ
inst✝ : Field K
M : Matrix n n K
m : ℕ
i j : n
hij : i = j
⊢ coeff ((expand K k) (charmatrix (M ^ k) i j)) m = ite (m = k) 1 0 i j - ite (m = 0) (M ^ k) 0 i j

Next tactic:
rw [hij, charmatrix_apply_eq, AlgHom.map_sub, expand_C, expand_X, coeff_sub, coeff_X_pow,
      coeff_C]
theorem matPolyEquiv_eq_x_pow_sub_c {K : Type*} (k : ℕ) [Field K] (M : Matrix n n K) :
    matPolyEquiv ((expand K k : K[X] →+* K[X]).mapMatrix (charmatrix (M ^ k))) =
      X ^ k - C (M ^ k) := by
  -- porting note: `i` and `j` are used later on, but were not mentioned in mathlib3
  ext m i j
  rw [coeff_sub, coeff_C, matPolyEquiv_coeff_apply, RingHom.mapMatrix_apply, Matrix.map_apply,
    AlgHom.coe_toRingHom, DMatrix.sub_apply, coeff_X_pow]
  by_cases hij : i = j
  · rw [hij, charmatrix_apply_eq, AlgHom.map_sub, expand_C, expand_X, coeff_sub, coeff_X_pow,
      coeff_C]
                             -- porting note: the second `Matrix.` was `DMatrix.`
    

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✝ : Matrix n n R
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
K : Type u_1
k : ℕ
inst✝ : Field K
M : Matrix n n K
m : ℕ
i j : n
hij : i = j
⊢ ((if m = k then 1 else 0) - if m = 0 then (M ^ k) j j else 0) = ite (m = k) 1 0 j j - ite (m = 0) (M ^ k) 0 j j

Next tactic:
split_ifs with mp m0
theorem matPolyEquiv_eq_x_pow_sub_c {K : Type*} (k : ℕ) [Field K] (M : Matrix n n K) :
    matPolyEquiv ((expand K k : K[X] →+* K[X]).mapMatrix (charmatrix (M ^ k))) =
      X ^ k - C (M ^ k) := by
  -- porting note: `i` and `j` are used later on, but were not mentioned in mathlib3
  ext m i j
  rw [coeff_sub, coeff_C, matPolyEquiv_coeff_apply, RingHom.mapMatrix_apply, Matrix.map_apply,
    AlgHom.coe_toRingHom, DMatrix.sub_apply, coeff_X_pow]
  by_cases hij : i = j
  · rw [hij, charmatrix_apply_eq, AlgHom.map_sub, expand_C, expand_X, coeff_sub, coeff_X_pow,
      coeff_C]
                             -- porting note: the second `Matrix.` was `DMatrix.`
    split_ifs with mp m0 <;> 

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✝ : Matrix n n R
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
K : Type u_1
k : ℕ
inst✝ : Field K
M : Matrix n n K
m : ℕ
i j : n
hij : i = j
mp : m = k
m0 : m = 0
⊢ 1 - (M ^ k) j j = OfNat.ofNat 1 j j - (M ^ k) j j

Next tactic:
simp only [Matrix.one_apply_eq, Matrix.zero_apply]
theorem matPolyEquiv_eq_x_pow_sub_c {K : Type*} (k : ℕ) [Field K] (M : Matrix n n K) :
    matPolyEquiv ((expand K k : K[X] →+* K[X]).mapMatrix (charmatrix (M ^ k))) =
      X ^ k - C (M ^ k) := by
  -- porting note: `i` and `j` are used later on, but were not mentioned in mathlib3
  ext m i j
  rw [coeff_sub, coeff_C, matPolyEquiv_coeff_apply, RingHom.mapMatrix_apply, Matrix.map_apply,
    AlgHom.coe_toRingHom, DMatrix.sub_apply, coeff_X_pow]
  by_cases hij : i = j
  · rw [hij, charmatrix_apply_eq, AlgHom.map_sub, expand_C, expand_X, coeff_sub, coeff_X_pow,
      coeff_C]
                             -- porting note: the second `Matrix.` was `DMatrix.`
    split_ifs with mp m0 <;> 

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
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
K : Type u_1
k : ℕ
inst✝ : Field K
M : Matrix n n K
m : ℕ
i j : n
hij : i = j
mp : m = k
m0 : ¬m = 0
⊢ 1 - 0 = OfNat.ofNat 1 j j - OfNat.ofNat 0 j j

Next tactic:
simp only [Matrix.one_apply_eq, Matrix.zero_apply]
theorem matPolyEquiv_eq_x_pow_sub_c {K : Type*} (k : ℕ) [Field K] (M : Matrix n n K) :
    matPolyEquiv ((expand K k : K[X] →+* K[X]).mapMatrix (charmatrix (M ^ k))) =
      X ^ k - C (M ^ k) := by
  -- porting note: `i` and `j` are used later on, but were not mentioned in mathlib3
  ext m i j
  rw [coeff_sub, coeff_C, matPolyEquiv_coeff_apply, RingHom.mapMatrix_apply, Matrix.map_apply,
    AlgHom.coe_toRingHom, DMatrix.sub_apply, coeff_X_pow]
  by_cases hij : i = j
  · rw [hij, charmatrix_apply_eq, AlgHom.map_sub, expand_C, expand_X, coeff_sub, coeff_X_pow,
      coeff_C]
                             -- porting note: the second `Matrix.` was `DMatrix.`
    split_ifs with mp m0 <;> 

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✝ : Matrix n n R
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
K : Type u_1
k : ℕ
inst✝ : Field K
M : Matrix n n K
m : ℕ
i j : n
hij : i = j
mp : ¬m = k
h✝ : m = 0
⊢ 0 - (M ^ k) j j = OfNat.ofNat 0 j j - (M ^ k) j j

Next tactic:
simp only [Matrix.one_apply_eq, Matrix.zero_apply]
theorem matPolyEquiv_eq_x_pow_sub_c {K : Type*} (k : ℕ) [Field K] (M : Matrix n n K) :
    matPolyEquiv ((expand K k : K[X] →+* K[X]).mapMatrix (charmatrix (M ^ k))) =
      X ^ k - C (M ^ k) := by
  -- porting note: `i` and `j` are used later on, but were not mentioned in mathlib3
  ext m i j
  rw [coeff_sub, coeff_C, matPolyEquiv_coeff_apply, RingHom.mapMatrix_apply, Matrix.map_apply,
    AlgHom.coe_toRingHom, DMatrix.sub_apply, coeff_X_pow]
  by_cases hij : i = j
  · rw [hij, charmatrix_apply_eq, AlgHom.map_sub, expand_C, expand_X, coeff_sub, coeff_X_pow,
      coeff_C]
                             -- porting note: the second `Matrix.` was `DMatrix.`
    split_ifs with mp m0 <;> 

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
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
K : Type u_1
k : ℕ
inst✝ : Field K
M : Matrix n n K
m : ℕ
i j : n
hij : i = j
mp : ¬m = k
h✝ : ¬m = 0
⊢ 0 - 0 = OfNat.ofNat 0 j j - OfNat.ofNat 0 j j

Next tactic:
simp only [Matrix.one_apply_eq, Matrix.zero_apply]
theorem matPolyEquiv_eq_x_pow_sub_c {K : Type*} (k : ℕ) [Field K] (M : Matrix n n K) :
    matPolyEquiv ((expand K k : K[X] →+* K[X]).mapMatrix (charmatrix (M ^ k))) =
      X ^ k - C (M ^ k) := by
  -- porting note: `i` and `j` are used later on, but were not mentioned in mathlib3
  ext m i j
  rw [coeff_sub, coeff_C, matPolyEquiv_coeff_apply, RingHom.mapMatrix_apply, Matrix.map_apply,
    AlgHom.coe_toRingHom, DMatrix.sub_apply, coeff_X_pow]
  by_cases hij : i = j
  · rw [hij, charmatrix_apply_eq, AlgHom.map_sub, expand_C, expand_X, coeff_sub, coeff_X_pow,
      coeff_C]
                             -- porting note: the second `Matrix.` was `DMatrix.`
    split_ifs with mp m0 <;> simp only [Matrix.one_apply_eq, Matrix.zero_apply]
  · 

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
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
K : Type u_1
k : ℕ
inst✝ : Field K
M : Matrix n n K
m : ℕ
i j : n
hij : ¬i = j
⊢ coeff ((expand K k) (charmatrix (M ^ k) i j)) m = ite (m = k) 1 0 i j - ite (m = 0) (M ^ k) 0 i j

Next tactic:
rw [charmatrix_apply_ne _ _ _ hij, AlgHom.map_neg, expand_C, coeff_neg, coeff_C]
theorem matPolyEquiv_eq_x_pow_sub_c {K : Type*} (k : ℕ) [Field K] (M : Matrix n n K) :
    matPolyEquiv ((expand K k : K[X] →+* K[X]).mapMatrix (charmatrix (M ^ k))) =
      X ^ k - C (M ^ k) := by
  -- porting note: `i` and `j` are used later on, but were not mentioned in mathlib3
  ext m i j
  rw [coeff_sub, coeff_C, matPolyEquiv_coeff_apply, RingHom.mapMatrix_apply, Matrix.map_apply,
    AlgHom.coe_toRingHom, DMatrix.sub_apply, coeff_X_pow]
  by_cases hij : i = j
  · rw [hij, charmatrix_apply_eq, AlgHom.map_sub, expand_C, expand_X, coeff_sub, coeff_X_pow,
      coeff_C]
                             -- porting note: the second `Matrix.` was `DMatrix.`
    split_ifs with mp m0 <;> simp only [Matrix.one_apply_eq, Matrix.zero_apply]
  · rw [charmatrix_apply_ne _ _ _ hij, AlgHom.map_neg, expand_C, coeff_neg, coeff_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✝ : Matrix n n R
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
K : Type u_1
k : ℕ
inst✝ : Field K
M : Matrix n n K
m : ℕ
i j : n
hij : ¬i = j
⊢ (-if m = 0 then (M ^ k) i j else 0) = ite (m = k) 1 0 i j - ite (m = 0) (M ^ k) 0 i j

Next tactic:
split_ifs with m0 mp
theorem matPolyEquiv_eq_x_pow_sub_c {K : Type*} (k : ℕ) [Field K] (M : Matrix n n K) :
    matPolyEquiv ((expand K k : K[X] →+* K[X]).mapMatrix (charmatrix (M ^ k))) =
      X ^ k - C (M ^ k) := by
  -- porting note: `i` and `j` are used later on, but were not mentioned in mathlib3
  ext m i j
  rw [coeff_sub, coeff_C, matPolyEquiv_coeff_apply, RingHom.mapMatrix_apply, Matrix.map_apply,
    AlgHom.coe_toRingHom, DMatrix.sub_apply, coeff_X_pow]
  by_cases hij : i = j
  · rw [hij, charmatrix_apply_eq, AlgHom.map_sub, expand_C, expand_X, coeff_sub, coeff_X_pow,
      coeff_C]
                             -- porting note: the second `Matrix.` was `DMatrix.`
    split_ifs with mp m0 <;> simp only [Matrix.one_apply_eq, Matrix.zero_apply]
  · rw [charmatrix_apply_ne _ _ _ hij, AlgHom.map_neg, expand_C, coeff_neg, coeff_C]
    split_ifs with m0 mp <;>
      -- porting note: again, the first `Matrix.` that was `DMatrix.`
      

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✝ : Matrix n n R
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
K : Type u_1
k : ℕ
inst✝ : Field K
M : Matrix n n K
m : ℕ
i j : n
hij : ¬i = j
m0 : m = 0
mp : m = k
⊢ -(M ^ k) i j = OfNat.ofNat 1 i j - (M ^ k) i j

Next tactic:
simp only [hij, zero_sub, Matrix.zero_apply, sub_zero, neg_zero, Matrix.one_apply_ne, Ne.def,
        not_false_iff]
theorem matPolyEquiv_eq_x_pow_sub_c {K : Type*} (k : ℕ) [Field K] (M : Matrix n n K) :
    matPolyEquiv ((expand K k : K[X] →+* K[X]).mapMatrix (charmatrix (M ^ k))) =
      X ^ k - C (M ^ k) := by
  -- porting note: `i` and `j` are used later on, but were not mentioned in mathlib3
  ext m i j
  rw [coeff_sub, coeff_C, matPolyEquiv_coeff_apply, RingHom.mapMatrix_apply, Matrix.map_apply,
    AlgHom.coe_toRingHom, DMatrix.sub_apply, coeff_X_pow]
  by_cases hij : i = j
  · rw [hij, charmatrix_apply_eq, AlgHom.map_sub, expand_C, expand_X, coeff_sub, coeff_X_pow,
      coeff_C]
                             -- porting note: the second `Matrix.` was `DMatrix.`
    split_ifs with mp m0 <;> simp only [Matrix.one_apply_eq, Matrix.zero_apply]
  · rw [charmatrix_apply_ne _ _ _ hij, AlgHom.map_neg, expand_C, coeff_neg, coeff_C]
    split_ifs with m0 mp <;>
      -- porting note: again, the first `Matrix.` that was `DMatrix.`
      

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
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
K : Type u_1
k : ℕ
inst✝ : Field K
M : Matrix n n K
m : ℕ
i j : n
hij : ¬i = j
m0 : m = 0
mp : ¬m = k
⊢ -(M ^ k) i j = OfNat.ofNat 0 i j - (M ^ k) i j

Next tactic:
simp only [hij, zero_sub, Matrix.zero_apply, sub_zero, neg_zero, Matrix.one_apply_ne, Ne.def,
        not_false_iff]
theorem matPolyEquiv_eq_x_pow_sub_c {K : Type*} (k : ℕ) [Field K] (M : Matrix n n K) :
    matPolyEquiv ((expand K k : K[X] →+* K[X]).mapMatrix (charmatrix (M ^ k))) =
      X ^ k - C (M ^ k) := by
  -- porting note: `i` and `j` are used later on, but were not mentioned in mathlib3
  ext m i j
  rw [coeff_sub, coeff_C, matPolyEquiv_coeff_apply, RingHom.mapMatrix_apply, Matrix.map_apply,
    AlgHom.coe_toRingHom, DMatrix.sub_apply, coeff_X_pow]
  by_cases hij : i = j
  · rw [hij, charmatrix_apply_eq, AlgHom.map_sub, expand_C, expand_X, coeff_sub, coeff_X_pow,
      coeff_C]
                             -- porting note: the second `Matrix.` was `DMatrix.`
    split_ifs with mp m0 <;> simp only [Matrix.one_apply_eq, Matrix.zero_apply]
  · rw [charmatrix_apply_ne _ _ _ hij, AlgHom.map_neg, expand_C, coeff_neg, coeff_C]
    split_ifs with m0 mp <;>
      -- porting note: again, the first `Matrix.` that was `DMatrix.`
      

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✝ : Matrix n n R
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
K : Type u_1
k : ℕ
inst✝ : Field K
M : Matrix n n K
m : ℕ
i j : n
hij : ¬i = j
m0 : ¬m = 0
h✝ : m = k
⊢ -0 = OfNat.ofNat 1 i j - OfNat.ofNat 0 i j

Next tactic:
simp only [hij, zero_sub, Matrix.zero_apply, sub_zero, neg_zero, Matrix.one_apply_ne, Ne.def,
        not_false_iff]
theorem matPolyEquiv_eq_x_pow_sub_c {K : Type*} (k : ℕ) [Field K] (M : Matrix n n K) :
    matPolyEquiv ((expand K k : K[X] →+* K[X]).mapMatrix (charmatrix (M ^ k))) =
      X ^ k - C (M ^ k) := by
  -- porting note: `i` and `j` are used later on, but were not mentioned in mathlib3
  ext m i j
  rw [coeff_sub, coeff_C, matPolyEquiv_coeff_apply, RingHom.mapMatrix_apply, Matrix.map_apply,
    AlgHom.coe_toRingHom, DMatrix.sub_apply, coeff_X_pow]
  by_cases hij : i = j
  · rw [hij, charmatrix_apply_eq, AlgHom.map_sub, expand_C, expand_X, coeff_sub, coeff_X_pow,
      coeff_C]
                             -- porting note: the second `Matrix.` was `DMatrix.`
    split_ifs with mp m0 <;> simp only [Matrix.one_apply_eq, Matrix.zero_apply]
  · rw [charmatrix_apply_ne _ _ _ hij, AlgHom.map_neg, expand_C, coeff_neg, coeff_C]
    split_ifs with m0 mp <;>
      -- porting note: again, the first `Matrix.` that was `DMatrix.`
      

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
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
K : Type u_1
k : ℕ
inst✝ : Field K
M : Matrix n n K
m : ℕ
i j : n
hij : ¬i = j
m0 : ¬m = 0
h✝ : ¬m = k
⊢ -0 = OfNat.ofNat 0 i j - OfNat.ofNat 0 i j

Next tactic:
simp only [hij, zero_sub, Matrix.zero_apply, sub_zero, neg_zero, Matrix.one_apply_ne, Ne.def,
        not_false_iff]
/-- Any matrix power can be computed as the sum of matrix powers less than `Fintype.card n`.

TODO: add the statement for negative powers phrased with `zpow`. -/
theorem pow_eq_aeval_mod_charpoly (M : Matrix n n R) (k : ℕ) :
    M ^ k = aeval M (X ^ k %ₘ M.charpoly) := 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
p : ℕ
inst✝ : Fact (Nat.Prime p)
M : Matrix n n R
k : ℕ
⊢ M ^ k = (aeval M) (X ^ k %ₘ charpoly M)

Next tactic:
rw [← aeval_eq_aeval_mod_charpoly, map_pow, aeval_X]
theorem coeff_charpoly_mem_ideal_pow {I : Ideal R} (h : ∀ i j, M i j ∈ I) (k : ℕ) :
    M.charpoly.coeff k ∈ I ^ (Fintype.card n - k) := 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
p : ℕ
inst✝ : Fact (Nat.Prime p)
I : Ideal R
h : ∀ (i j : n), M i j ∈ I
k : ℕ
⊢ coeff (charpoly M) k ∈ I ^ (Fintype.card n - k)

Next tactic:
delta charpoly
theorem coeff_charpoly_mem_ideal_pow {I : Ideal R} (h : ∀ i j, M i j ∈ I) (k : ℕ) :
    M.charpoly.coeff k ∈ I ^ (Fintype.card n - k) := by
  delta charpoly
  

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
p : ℕ
inst✝ : Fact (Nat.Prime p)
I : Ideal R
h : ∀ (i j : n), M i j ∈ I
k : ℕ
⊢ coeff (det (charmatrix M)) k ∈ I ^ (Fintype.card n - k)

Next tactic:
rw [Matrix.det_apply, finset_sum_coeff]
theorem coeff_charpoly_mem_ideal_pow {I : Ideal R} (h : ∀ i j, M i j ∈ I) (k : ℕ) :
    M.charpoly.coeff k ∈ I ^ (Fintype.card n - k) := by
  delta charpoly
  rw [Matrix.det_apply, finset_sum_coeff]
  

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
p : ℕ
inst✝ : Fact (Nat.Prime p)
I : Ideal R
h : ∀ (i j : n), M i j ∈ I
k : ℕ
⊢ ∑ b : Equiv.Perm n, coeff (Equiv.Perm.sign b • ∏ i : n, charmatrix M (b i) i) k ∈ I ^ (Fintype.card n - k)

Next tactic:
apply sum_mem
theorem coeff_charpoly_mem_ideal_pow {I : Ideal R} (h : ∀ i j, M i j ∈ I) (k : ℕ) :
    M.charpoly.coeff k ∈ I ^ (Fintype.card n - k) := by
  delta charpoly
  rw [Matrix.det_apply, finset_sum_coeff]
  apply sum_mem
  

Proof state:
case 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
p : ℕ
inst✝ : Fact (Nat.Prime p)
I : Ideal R
h : ∀ (i j : n), M i j ∈ I
k : ℕ
⊢ ∀ c ∈ univ, coeff (Equiv.Perm.sign c • ∏ i : n, charmatrix M (c i) i) k ∈ I ^ (Fintype.card n - k)

Next tactic:
rintro c -
theorem coeff_charpoly_mem_ideal_pow {I : Ideal R} (h : ∀ i j, M i j ∈ I) (k : ℕ) :
    M.charpoly.coeff k ∈ I ^ (Fintype.card n - k) := by
  delta charpoly
  rw [Matrix.det_apply, finset_sum_coeff]
  apply sum_mem
  rintro c -
  

Proof state:
case 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
p : ℕ
inst✝ : Fact (Nat.Prime p)
I : Ideal R
h : ∀ (i j : n), M i j ∈ I
k : ℕ
c : Equiv.Perm n
⊢ coeff (Equiv.Perm.sign c • ∏ i : n, charmatrix M (c i) i) k ∈ I ^ (Fintype.card n - k)

Next tactic:
rw [coeff_smul, Submodule.smul_mem_iff']
theorem coeff_charpoly_mem_ideal_pow {I : Ideal R} (h : ∀ i j, M i j ∈ I) (k : ℕ) :
    M.charpoly.coeff k ∈ I ^ (Fintype.card n - k) := by
  delta charpoly
  rw [Matrix.det_apply, finset_sum_coeff]
  apply sum_mem
  rintro c -
  rw [coeff_smul, Submodule.smul_mem_iff']
  

Proof state:
case 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
p : ℕ
inst✝ : Fact (Nat.Prime p)
I : Ideal R
h : ∀ (i j : n), M i j ∈ I
k : ℕ
c : Equiv.Perm n
⊢ coeff (∏ i : n, charmatrix M (c i) i) k ∈ I ^ (Fintype.card n - k)

Next tactic:
have : ∑ x : n, 1 = Fintype.card n := by rw [Finset.sum_const, card_univ, smul_eq_mul, mul_one]
theorem coeff_charpoly_mem_ideal_pow {I : Ideal R} (h : ∀ i j, M i j ∈ I) (k : ℕ) :
    M.charpoly.coeff k ∈ I ^ (Fintype.card n - k) := by
  delta charpoly
  rw [Matrix.det_apply, finset_sum_coeff]
  apply sum_mem
  rintro c -
  rw [coeff_smul, Submodule.smul_mem_iff']
  have : ∑ x : n, 1 = Fintype.card n := 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
p : ℕ
inst✝ : Fact (Nat.Prime p)
I : Ideal R
h : ∀ (i j : n), M i j ∈ I
k : ℕ
c : Equiv.Perm n
⊢ ∑ x : n, 1 = Fintype.card n

Next tactic:
rw [Finset.sum_const, card_univ, smul_eq_mul, mul_one]
theorem coeff_charpoly_mem_ideal_pow {I : Ideal R} (h : ∀ i j, M i j ∈ I) (k : ℕ) :
    M.charpoly.coeff k ∈ I ^ (Fintype.card n - k) := by
  delta charpoly
  rw [Matrix.det_apply, finset_sum_coeff]
  apply sum_mem
  rintro c -
  rw [coeff_smul, Submodule.smul_mem_iff']
  have : ∑ x : n, 1 = Fintype.card n := by rw [Finset.sum_const, card_univ, smul_eq_mul, mul_one]
  

Proof state:
case 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
p : ℕ
inst✝ : Fact (Nat.Prime p)
I : Ideal R
h : ∀ (i j : n), M i j ∈ I
k : ℕ
c : Equiv.Perm n
this : ∑ x : n, 1 = Fintype.card n
⊢ coeff (∏ i : n, charmatrix M (c i) i) k ∈ I ^ (Fintype.card n - k)

Next tactic:
rw [← this]
theorem coeff_charpoly_mem_ideal_pow {I : Ideal R} (h : ∀ i j, M i j ∈ I) (k : ℕ) :
    M.charpoly.coeff k ∈ I ^ (Fintype.card n - k) := by
  delta charpoly
  rw [Matrix.det_apply, finset_sum_coeff]
  apply sum_mem
  rintro c -
  rw [coeff_smul, Submodule.smul_mem_iff']
  have : ∑ x : n, 1 = Fintype.card n := by rw [Finset.sum_const, card_univ, smul_eq_mul, mul_one]
  rw [← this]
  

Proof state:
case 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
p : ℕ
inst✝ : Fact (Nat.Prime p)
I : Ideal R
h : ∀ (i j : n), M i j ∈ I
k : ℕ
c : Equiv.Perm n
this : ∑ x : n, 1 = Fintype.card n
⊢ coeff (∏ i : n, charmatrix M (c i) i) k ∈ I ^ (∑ x : n, 1 - k)

Next tactic:
apply coeff_prod_mem_ideal_pow_tsub
theorem coeff_charpoly_mem_ideal_pow {I : Ideal R} (h : ∀ i j, M i j ∈ I) (k : ℕ) :
    M.charpoly.coeff k ∈ I ^ (Fintype.card n - k) := by
  delta charpoly
  rw [Matrix.det_apply, finset_sum_coeff]
  apply sum_mem
  rintro c -
  rw [coeff_smul, Submodule.smul_mem_iff']
  have : ∑ x : n, 1 = Fintype.card n := by rw [Finset.sum_const, card_univ, smul_eq_mul, mul_one]
  rw [← this]
  apply coeff_prod_mem_ideal_pow_tsub
  

Proof state:
case h.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
p : ℕ
inst✝ : Fact (Nat.Prime p)
I : Ideal R
h : ∀ (i j : n), M i j ∈ I
k : ℕ
c : Equiv.Perm n
this : ∑ x : n, 1 = Fintype.card n
⊢ ∀ i ∈ univ, ∀ (k : ℕ), coeff (charmatrix M (c i) i) k ∈ I ^ (1 - k)

Next tactic:
rintro i - (_ | k)
theorem coeff_charpoly_mem_ideal_pow {I : Ideal R} (h : ∀ i j, M i j ∈ I) (k : ℕ) :
    M.charpoly.coeff k ∈ I ^ (Fintype.card n - k) := by
  delta charpoly
  rw [Matrix.det_apply, finset_sum_coeff]
  apply sum_mem
  rintro c -
  rw [coeff_smul, Submodule.smul_mem_iff']
  have : ∑ x : n, 1 = Fintype.card n := by rw [Finset.sum_const, card_univ, smul_eq_mul, mul_one]
  rw [← this]
  apply coeff_prod_mem_ideal_pow_tsub
  rintro i - (_ | k)
  · 

Proof state:
case h.h.zero
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
p : ℕ
inst✝ : Fact (Nat.Prime p)
I : Ideal R
h : ∀ (i j : n), M i j ∈ I
k : ℕ
c : Equiv.Perm n
this : ∑ x : n, 1 = Fintype.card n
i : n
⊢ coeff (charmatrix M (c i) i) Nat.zero ∈ I ^ (1 - Nat.zero)

Next tactic:
rw [Nat.zero_eq]
theorem coeff_charpoly_mem_ideal_pow {I : Ideal R} (h : ∀ i j, M i j ∈ I) (k : ℕ) :
    M.charpoly.coeff k ∈ I ^ (Fintype.card n - k) := by
  delta charpoly
  rw [Matrix.det_apply, finset_sum_coeff]
  apply sum_mem
  rintro c -
  rw [coeff_smul, Submodule.smul_mem_iff']
  have : ∑ x : n, 1 = Fintype.card n := by rw [Finset.sum_const, card_univ, smul_eq_mul, mul_one]
  rw [← this]
  apply coeff_prod_mem_ideal_pow_tsub
  rintro i - (_ | k)
  · rw [Nat.zero_eq]  -- porting note: `rw [Nat.zero_eq]` was not present
    

Proof state:
case h.h.zero
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
p : ℕ
inst✝ : Fact (Nat.Prime p)
I : Ideal R
h : ∀ (i j : n), M i j ∈ I
k : ℕ
c : Equiv.Perm n
this : ∑ x : n, 1 = Fintype.card n
i : n
⊢ coeff (charmatrix M (c i) i) 0 ∈ I ^ (1 - 0)

Next tactic:
rw [tsub_zero, pow_one, charmatrix_apply, coeff_sub, ← smul_one_eq_diagonal, smul_apply,
      smul_eq_mul, coeff_X_mul_zero, coeff_C_zero, zero_sub]