l3lab/ntp-mathlib huggingface dataset:
@[to_additive Set.AddAntidiagonal.finite_of_isPwo]
theorem finite_of_isPwo (hs : s.IsPwo) (ht : t.IsPwo) (a) : (mulAntidiagonal s t a).Finite := by
  

Proof state:
α : Type u_1
inst✝ : OrderedCancelCommMonoid α
s t : Set α
a✝ : α
x y : ↑(mulAntidiagonal s t a✝)
hs : IsPwo s
ht : IsPwo t
a : α
⊢ Set.Finite (mulAntidiagonal s t a)

Next tactic:
refine' not_infinite.1 fun h => _
@[to_additive Set.AddAntidiagonal.finite_of_isPwo]
theorem finite_of_isPwo (hs : s.IsPwo) (ht : t.IsPwo) (a) : (mulAntidiagonal s t a).Finite := by
  refine' not_infinite.1 fun h => _
  

Proof state:
α : Type u_1
inst✝ : OrderedCancelCommMonoid α
s t : Set α
a✝ : α
x y : ↑(mulAntidiagonal s t a✝)
hs : IsPwo s
ht : IsPwo t
a : α
h : Set.Infinite (mulAntidiagonal s t a)
⊢ False

Next tactic:
have h1 : (mulAntidiagonal s t a).PartiallyWellOrderedOn (Prod.fst ⁻¹'o (· ≤ ·)) := fun f hf =>
    hs (Prod.fst ∘ f) fun n => (mem_mulAntidiagonal.1 (hf n)).1
@[to_additive Set.AddAntidiagonal.finite_of_isPwo]
theorem finite_of_isPwo (hs : s.IsPwo) (ht : t.IsPwo) (a) : (mulAntidiagonal s t a).Finite := by
  refine' not_infinite.1 fun h => _
  have h1 : (mulAntidiagonal s t a).PartiallyWellOrderedOn (Prod.fst ⁻¹'o (· ≤ ·)) := fun f hf =>
    hs (Prod.fst ∘ f) fun n => (mem_mulAntidiagonal.1 (hf n)).1
  

Proof state:
α : Type u_1
inst✝ : OrderedCancelCommMonoid α
s t : Set α
a✝ : α
x y : ↑(mulAntidiagonal s t a✝)
hs : IsPwo s
ht : IsPwo t
a : α
h : Set.Infinite (mulAntidiagonal s t a)
h1 : PartiallyWellOrderedOn (mulAntidiagonal s t a) (Prod.fst ⁻¹'o fun x x_1 => x ≤ x_1)
⊢ False

Next tactic:
have h2 : (mulAntidiagonal s t a).PartiallyWellOrderedOn (Prod.snd ⁻¹'o (· ≤ ·)) := fun f hf =>
    ht (Prod.snd ∘ f) fun n => (mem_mulAntidiagonal.1 (hf n)).2.1
@[to_additive Set.AddAntidiagonal.finite_of_isPwo]
theorem finite_of_isPwo (hs : s.IsPwo) (ht : t.IsPwo) (a) : (mulAntidiagonal s t a).Finite := by
  refine' not_infinite.1 fun h => _
  have h1 : (mulAntidiagonal s t a).PartiallyWellOrderedOn (Prod.fst ⁻¹'o (· ≤ ·)) := fun f hf =>
    hs (Prod.fst ∘ f) fun n => (mem_mulAntidiagonal.1 (hf n)).1
  have h2 : (mulAntidiagonal s t a).PartiallyWellOrderedOn (Prod.snd ⁻¹'o (· ≤ ·)) := fun f hf =>
    ht (Prod.snd ∘ f) fun n => (mem_mulAntidiagonal.1 (hf n)).2.1
  

Proof state:
α : Type u_1
inst✝ : OrderedCancelCommMonoid α
s t : Set α
a✝ : α
x y : ↑(mulAntidiagonal s t a✝)
hs : IsPwo s
ht : IsPwo t
a : α
h : Set.Infinite (mulAntidiagonal s t a)
h1 : PartiallyWellOrderedOn (mulAntidiagonal s t a) (Prod.fst ⁻¹'o fun x x_1 => x ≤ x_1)
h2 : PartiallyWellOrderedOn (mulAntidiagonal s t a) (Prod.snd ⁻¹'o fun x x_1 => x ≤ x_1)
⊢ False

Next tactic:
obtain ⟨g, hg⟩ :=
    h1.exists_monotone_subseq (fun n => h.natEmbedding _ n) fun n => (h.natEmbedding _ n).2
@[to_additive Set.AddAntidiagonal.finite_of_isPwo]
theorem finite_of_isPwo (hs : s.IsPwo) (ht : t.IsPwo) (a) : (mulAntidiagonal s t a).Finite := by
  refine' not_infinite.1 fun h => _
  have h1 : (mulAntidiagonal s t a).PartiallyWellOrderedOn (Prod.fst ⁻¹'o (· ≤ ·)) := fun f hf =>
    hs (Prod.fst ∘ f) fun n => (mem_mulAntidiagonal.1 (hf n)).1
  have h2 : (mulAntidiagonal s t a).PartiallyWellOrderedOn (Prod.snd ⁻¹'o (· ≤ ·)) := fun f hf =>
    ht (Prod.snd ∘ f) fun n => (mem_mulAntidiagonal.1 (hf n)).2.1
  obtain ⟨g, hg⟩ :=
    h1.exists_monotone_subseq (fun n => h.natEmbedding _ n) fun n => (h.natEmbedding _ n).2
  

Proof state:
case intro
α : Type u_1
inst✝ : OrderedCancelCommMonoid α
s t : Set α
a✝ : α
x y : ↑(mulAntidiagonal s t a✝)
hs : IsPwo s
ht : IsPwo t
a : α
h : Set.Infinite (mulAntidiagonal s t a)
h1 : PartiallyWellOrderedOn (mulAntidiagonal s t a) (Prod.fst ⁻¹'o fun x x_1 => x ≤ x_1)
h2 : PartiallyWellOrderedOn (mulAntidiagonal s t a) (Prod.snd ⁻¹'o fun x x_1 => x ≤ x_1)
g : ℕ ↪o ℕ
hg :
  ∀ (m n : ℕ),
    m ≤ n →
      (Prod.fst ⁻¹'o fun x x_1 => x ≤ x_1) ↑((Infinite.natEmbedding (mulAntidiagonal s t a) h) (g m))
        ↑((Infinite.natEmbedding (mulAntidiagonal s t a) h) (g n))
⊢ False

Next tactic:
obtain ⟨m, n, mn, h2'⟩ := h2 (fun x => (h.natEmbedding _) (g x)) fun n => (h.natEmbedding _ _).2
@[to_additive Set.AddAntidiagonal.finite_of_isPwo]
theorem finite_of_isPwo (hs : s.IsPwo) (ht : t.IsPwo) (a) : (mulAntidiagonal s t a).Finite := by
  refine' not_infinite.1 fun h => _
  have h1 : (mulAntidiagonal s t a).PartiallyWellOrderedOn (Prod.fst ⁻¹'o (· ≤ ·)) := fun f hf =>
    hs (Prod.fst ∘ f) fun n => (mem_mulAntidiagonal.1 (hf n)).1
  have h2 : (mulAntidiagonal s t a).PartiallyWellOrderedOn (Prod.snd ⁻¹'o (· ≤ ·)) := fun f hf =>
    ht (Prod.snd ∘ f) fun n => (mem_mulAntidiagonal.1 (hf n)).2.1
  obtain ⟨g, hg⟩ :=
    h1.exists_monotone_subseq (fun n => h.natEmbedding _ n) fun n => (h.natEmbedding _ n).2
  obtain ⟨m, n, mn, h2'⟩ := h2 (fun x => (h.natEmbedding _) (g x)) fun n => (h.natEmbedding _ _).2
  

Proof state:
case intro.intro.intro.intro
α : Type u_1
inst✝ : OrderedCancelCommMonoid α
s t : Set α
a✝ : α
x y : ↑(mulAntidiagonal s t a✝)
hs : IsPwo s
ht : IsPwo t
a : α
h : Set.Infinite (mulAntidiagonal s t a)
h1 : PartiallyWellOrderedOn (mulAntidiagonal s t a) (Prod.fst ⁻¹'o fun x x_1 => x ≤ x_1)
h2 : PartiallyWellOrderedOn (mulAntidiagonal s t a) (Prod.snd ⁻¹'o fun x x_1 => x ≤ x_1)
g : ℕ ↪o ℕ
hg :
  ∀ (m n : ℕ),
    m ≤ n →
      (Prod.fst ⁻¹'o fun x x_1 => x ≤ x_1) ↑((Infinite.natEmbedding (mulAntidiagonal s t a) h) (g m))
        ↑((Infinite.natEmbedding (mulAntidiagonal s t a) h) (g n))
m n : ℕ
mn : m < n
h2' :
  (Prod.snd ⁻¹'o fun x x_1 => x ≤ x_1) ↑((Infinite.natEmbedding (mulAntidiagonal s t a) h) (g m))
    ↑((Infinite.natEmbedding (mulAntidiagonal s t a) h) (g n))
⊢ False

Next tactic:
refine' mn.ne (g.injective <| (h.natEmbedding _).injective _)
@[to_additive Set.AddAntidiagonal.finite_of_isPwo]
theorem finite_of_isPwo (hs : s.IsPwo) (ht : t.IsPwo) (a) : (mulAntidiagonal s t a).Finite := by
  refine' not_infinite.1 fun h => _
  have h1 : (mulAntidiagonal s t a).PartiallyWellOrderedOn (Prod.fst ⁻¹'o (· ≤ ·)) := fun f hf =>
    hs (Prod.fst ∘ f) fun n => (mem_mulAntidiagonal.1 (hf n)).1
  have h2 : (mulAntidiagonal s t a).PartiallyWellOrderedOn (Prod.snd ⁻¹'o (· ≤ ·)) := fun f hf =>
    ht (Prod.snd ∘ f) fun n => (mem_mulAntidiagonal.1 (hf n)).2.1
  obtain ⟨g, hg⟩ :=
    h1.exists_monotone_subseq (fun n => h.natEmbedding _ n) fun n => (h.natEmbedding _ n).2
  obtain ⟨m, n, mn, h2'⟩ := h2 (fun x => (h.natEmbedding _) (g x)) fun n => (h.natEmbedding _ _).2
  refine' mn.ne (g.injective <| (h.natEmbedding _).injective _)
  

Proof state:
case intro.intro.intro.intro
α : Type u_1
inst✝ : OrderedCancelCommMonoid α
s t : Set α
a✝ : α
x y : ↑(mulAntidiagonal s t a✝)
hs : IsPwo s
ht : IsPwo t
a : α
h : Set.Infinite (mulAntidiagonal s t a)
h1 : PartiallyWellOrderedOn (mulAntidiagonal s t a) (Prod.fst ⁻¹'o fun x x_1 => x ≤ x_1)
h2 : PartiallyWellOrderedOn (mulAntidiagonal s t a) (Prod.snd ⁻¹'o fun x x_1 => x ≤ x_1)
g : ℕ ↪o ℕ
hg :
  ∀ (m n : ℕ),
    m ≤ n →
      (Prod.fst ⁻¹'o fun x x_1 => x ≤ x_1) ↑((Infinite.natEmbedding (mulAntidiagonal s t a) h) (g m))
        ↑((Infinite.natEmbedding (mulAntidiagonal s t a) h) (g n))
m n : ℕ
mn : m < n
h2' :
  (Prod.snd ⁻¹'o fun x x_1 => x ≤ x_1) ↑((Infinite.natEmbedding (mulAntidiagonal s t a) h) (g m))
    ↑((Infinite.natEmbedding (mulAntidiagonal s t a) h) (g n))
⊢ (Infinite.natEmbedding (mulAntidiagonal s t a) h) (g m) = (Infinite.natEmbedding (mulAntidiagonal s t a) h) (g n)

Next tactic:
exact eq_of_fst_le_fst_of_snd_le_snd _ _ _ (hg _ _ mn.le) h2'
theorem charmatrix_apply_natDegree [Nontrivial R] (i j : n) :
    (charmatrix M i j).natDegree = ite (i = j) 1 0 := 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✝ : Nontrivial R
i j : n
⊢ natDegree (charmatrix M i j) = if i = j then 1 else 0

Next tactic:
by_cases h : i = j
theorem charmatrix_apply_natDegree [Nontrivial R] (i j : n) :
    (charmatrix M i j).natDegree = ite (i = j) 1 0 := by
  by_cases h : 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
inst✝ : Nontrivial R
i j : n
h : i = j
⊢ natDegree (charmatrix M i j) = if i = j then 1 else 0

Next tactic:
simp [h, ← degree_eq_iff_natDegree_eq_of_pos (Nat.succ_pos 0)]
theorem charmatrix_apply_natDegree [Nontrivial R] (i j : n) :
    (charmatrix M i j).natDegree = ite (i = j) 1 0 := by
  by_cases h : i = j <;> 

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
i j : n
h : ¬i = j
⊢ natDegree (charmatrix M i j) = if i = j then 1 else 0

Next tactic:
simp [h, ← degree_eq_iff_natDegree_eq_of_pos (Nat.succ_pos 0)]
theorem charmatrix_apply_natDegree_le (i j : n) :
    (charmatrix M i j).natDegree ≤ ite (i = j) 1 0 := 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
i j : n
⊢ natDegree (charmatrix M i j) ≤ if i = j then 1 else 0

Next tactic:
split_ifs with h
theorem charmatrix_apply_natDegree_le (i j : n) :
    (charmatrix M i j).natDegree ≤ ite (i = j) 1 0 := by
  split_ifs with 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 : Matrix n n R
i j : n
h : i = j
⊢ natDegree (charmatrix M i j) ≤ 1

Next tactic:
simp [h, natDegree_X_le]
theorem charmatrix_apply_natDegree_le (i j : n) :
    (charmatrix M i j).natDegree ≤ ite (i = j) 1 0 := by
  split_ifs with h <;> 

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
i j : n
h : ¬i = j
⊢ natDegree (charmatrix M i j) ≤ 0

Next tactic:
simp [h, natDegree_X_le]
theorem charpoly_sub_diagonal_degree_lt :
    (M.charpoly - ∏ i : n, (X - C (M i i))).degree < ↑(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
⊢ degree (charpoly M - ∏ i : n, (X - C (M i i))) < ↑(Fintype.card n - 1)

Next tactic:
rw [charpoly, det_apply', ← insert_erase (mem_univ (Equiv.refl n)),
    sum_insert (not_mem_erase (Equiv.refl n) univ), add_comm]
theorem charpoly_sub_diagonal_degree_lt :
    (M.charpoly - ∏ i : n, (X - C (M i i))).degree < ↑(Fintype.card n - 1) := by
  rw [charpoly, det_apply', ← insert_erase (mem_univ (Equiv.refl n)),
    sum_insert (not_mem_erase (Equiv.refl n) univ), add_comm]
  

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
⊢ degree
      (∑ x in Finset.erase univ (Equiv.refl n), ↑↑(Equiv.Perm.sign x) * ∏ i : n, charmatrix M (x i) i +
          ↑↑(Equiv.Perm.sign (Equiv.refl n)) * ∏ i : n, charmatrix M ((Equiv.refl n) i) i -
        ∏ i : n, (X - C (M i i))) <
    ↑(Fintype.card n - 1)

Next tactic:
simp only [charmatrix_apply_eq, one_mul, Equiv.Perm.sign_refl, id.def, Int.cast_one,
    Units.val_one, add_sub_cancel, Equiv.coe_refl]
theorem charpoly_sub_diagonal_degree_lt :
    (M.charpoly - ∏ i : n, (X - C (M i i))).degree < ↑(Fintype.card n - 1) := by
  rw [charpoly, det_apply', ← insert_erase (mem_univ (Equiv.refl n)),
    sum_insert (not_mem_erase (Equiv.refl n) univ), add_comm]
  simp only [charmatrix_apply_eq, one_mul, Equiv.Perm.sign_refl, id.def, Int.cast_one,
    Units.val_one, add_sub_cancel, Equiv.coe_refl]
  

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
⊢ degree (∑ x in Finset.erase univ (Equiv.refl n), ↑↑(Equiv.Perm.sign x) * ∏ i : n, charmatrix M (x i) i) <
    ↑(Fintype.card n - 1)

Next tactic:
rw [← mem_degreeLT]
theorem charpoly_sub_diagonal_degree_lt :
    (M.charpoly - ∏ i : n, (X - C (M i i))).degree < ↑(Fintype.card n - 1) := by
  rw [charpoly, det_apply', ← insert_erase (mem_univ (Equiv.refl n)),
    sum_insert (not_mem_erase (Equiv.refl n) univ), add_comm]
  simp only [charmatrix_apply_eq, one_mul, Equiv.Perm.sign_refl, id.def, Int.cast_one,
    Units.val_one, add_sub_cancel, Equiv.coe_refl]
  rw [← mem_degreeLT]
  

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
⊢ ∑ x in Finset.erase univ (Equiv.refl n), ↑↑(Equiv.Perm.sign x) * ∏ i : n, charmatrix M (x i) i ∈
    degreeLT R (Fintype.card n - 1)

Next tactic:
apply Submodule.sum_mem (degreeLT R (Fintype.card n - 1))
theorem charpoly_sub_diagonal_degree_lt :
    (M.charpoly - ∏ i : n, (X - C (M i i))).degree < ↑(Fintype.card n - 1) := by
  rw [charpoly, det_apply', ← insert_erase (mem_univ (Equiv.refl n)),
    sum_insert (not_mem_erase (Equiv.refl n) univ), add_comm]
  simp only [charmatrix_apply_eq, one_mul, Equiv.Perm.sign_refl, id.def, Int.cast_one,
    Units.val_one, add_sub_cancel, Equiv.coe_refl]
  rw [← mem_degreeLT]
  apply Submodule.sum_mem (degreeLT R (Fintype.card n - 1))
  

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
⊢ ∀ c ∈ Finset.erase univ (Equiv.refl n),
    ↑↑(Equiv.Perm.sign c) * ∏ i : n, charmatrix M (c i) i ∈ degreeLT R (Fintype.card n - 1)

Next tactic:
intro c hc
theorem charpoly_sub_diagonal_degree_lt :
    (M.charpoly - ∏ i : n, (X - C (M i i))).degree < ↑(Fintype.card n - 1) := by
  rw [charpoly, det_apply', ← insert_erase (mem_univ (Equiv.refl n)),
    sum_insert (not_mem_erase (Equiv.refl n) univ), add_comm]
  simp only [charmatrix_apply_eq, one_mul, Equiv.Perm.sign_refl, id.def, Int.cast_one,
    Units.val_one, add_sub_cancel, Equiv.coe_refl]
  rw [← mem_degreeLT]
  apply Submodule.sum_mem (degreeLT R (Fintype.card n - 1))
  intro c hc; 

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
c : n ≃ n
hc : c ∈ Finset.erase univ (Equiv.refl n)
⊢ ↑↑(Equiv.Perm.sign c) * ∏ i : n, charmatrix M (c i) i ∈ degreeLT R (Fintype.card n - 1)

Next tactic:
rw [← C_eq_int_cast, C_mul']
theorem charpoly_sub_diagonal_degree_lt :
    (M.charpoly - ∏ i : n, (X - C (M i i))).degree < ↑(Fintype.card n - 1) := by
  rw [charpoly, det_apply', ← insert_erase (mem_univ (Equiv.refl n)),
    sum_insert (not_mem_erase (Equiv.refl n) univ), add_comm]
  simp only [charmatrix_apply_eq, one_mul, Equiv.Perm.sign_refl, id.def, Int.cast_one,
    Units.val_one, add_sub_cancel, Equiv.coe_refl]
  rw [← mem_degreeLT]
  apply Submodule.sum_mem (degreeLT R (Fintype.card n - 1))
  intro c hc; rw [← C_eq_int_cast, C_mul']
  

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
c : n ≃ n
hc : c ∈ Finset.erase univ (Equiv.refl n)
⊢ ↑↑(Equiv.Perm.sign c) • ∏ i : n, charmatrix M (c i) i ∈ degreeLT R (Fintype.card n - 1)

Next tactic:
apply Submodule.smul_mem (degreeLT R (Fintype.card n - 1)) ↑↑(Equiv.Perm.sign c)
theorem charpoly_sub_diagonal_degree_lt :
    (M.charpoly - ∏ i : n, (X - C (M i i))).degree < ↑(Fintype.card n - 1) := by
  rw [charpoly, det_apply', ← insert_erase (mem_univ (Equiv.refl n)),
    sum_insert (not_mem_erase (Equiv.refl n) univ), add_comm]
  simp only [charmatrix_apply_eq, one_mul, Equiv.Perm.sign_refl, id.def, Int.cast_one,
    Units.val_one, add_sub_cancel, Equiv.coe_refl]
  rw [← mem_degreeLT]
  apply Submodule.sum_mem (degreeLT R (Fintype.card n - 1))
  intro c hc; rw [← C_eq_int_cast, C_mul']
  apply Submodule.smul_mem (degreeLT R (Fintype.card n - 1)) ↑↑(Equiv.Perm.sign c)
  

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
c : n ≃ n
hc : c ∈ Finset.erase univ (Equiv.refl n)
⊢ ∏ i : n, charmatrix M (c i) i ∈ degreeLT R (Fintype.card n - 1)

Next tactic:
rw [mem_degreeLT]
theorem charpoly_sub_diagonal_degree_lt :
    (M.charpoly - ∏ i : n, (X - C (M i i))).degree < ↑(Fintype.card n - 1) := by
  rw [charpoly, det_apply', ← insert_erase (mem_univ (Equiv.refl n)),
    sum_insert (not_mem_erase (Equiv.refl n) univ), add_comm]
  simp only [charmatrix_apply_eq, one_mul, Equiv.Perm.sign_refl, id.def, Int.cast_one,
    Units.val_one, add_sub_cancel, Equiv.coe_refl]
  rw [← mem_degreeLT]
  apply Submodule.sum_mem (degreeLT R (Fintype.card n - 1))
  intro c hc; rw [← C_eq_int_cast, C_mul']
  apply Submodule.smul_mem (degreeLT R (Fintype.card n - 1)) ↑↑(Equiv.Perm.sign c)
  rw [mem_degreeLT]
  

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
c : n ≃ n
hc : c ∈ Finset.erase univ (Equiv.refl n)
⊢ degree (∏ i : n, charmatrix M (c i) i) < ↑(Fintype.card n - 1)

Next tactic:
apply lt_of_le_of_lt degree_le_natDegree _
theorem charpoly_sub_diagonal_degree_lt :
    (M.charpoly - ∏ i : n, (X - C (M i i))).degree < ↑(Fintype.card n - 1) := by
  rw [charpoly, det_apply', ← insert_erase (mem_univ (Equiv.refl n)),
    sum_insert (not_mem_erase (Equiv.refl n) univ), add_comm]
  simp only [charmatrix_apply_eq, one_mul, Equiv.Perm.sign_refl, id.def, Int.cast_one,
    Units.val_one, add_sub_cancel, Equiv.coe_refl]
  rw [← mem_degreeLT]
  apply Submodule.sum_mem (degreeLT R (Fintype.card n - 1))
  intro c hc; rw [← C_eq_int_cast, C_mul']
  apply Submodule.smul_mem (degreeLT R (Fintype.card n - 1)) ↑↑(Equiv.Perm.sign c)
  rw [mem_degreeLT]
  apply lt_of_le_of_lt degree_le_natDegree _
  

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
c : n ≃ n
hc : c ∈ Finset.erase univ (Equiv.refl n)
⊢ ↑(natDegree (∏ i : n, charmatrix M (c i) i)) < ↑(Fintype.card n - 1)

Next tactic:
rw [Nat.cast_lt]
theorem charpoly_sub_diagonal_degree_lt :
    (M.charpoly - ∏ i : n, (X - C (M i i))).degree < ↑(Fintype.card n - 1) := by
  rw [charpoly, det_apply', ← insert_erase (mem_univ (Equiv.refl n)),
    sum_insert (not_mem_erase (Equiv.refl n) univ), add_comm]
  simp only [charmatrix_apply_eq, one_mul, Equiv.Perm.sign_refl, id.def, Int.cast_one,
    Units.val_one, add_sub_cancel, Equiv.coe_refl]
  rw [← mem_degreeLT]
  apply Submodule.sum_mem (degreeLT R (Fintype.card n - 1))
  intro c hc; rw [← C_eq_int_cast, C_mul']
  apply Submodule.smul_mem (degreeLT R (Fintype.card n - 1)) ↑↑(Equiv.Perm.sign c)
  rw [mem_degreeLT]
  apply lt_of_le_of_lt degree_le_natDegree _
  rw [Nat.cast_lt]
  

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
c : n ≃ n
hc : c ∈ Finset.erase univ (Equiv.refl n)
⊢ natDegree (∏ i : n, charmatrix M (c i) i) < Fintype.card n - 1

Next tactic:
apply lt_of_le_of_lt _ (Equiv.Perm.fixed_point_card_lt_of_ne_one (ne_of_mem_erase hc))
theorem charpoly_sub_diagonal_degree_lt :
    (M.charpoly - ∏ i : n, (X - C (M i i))).degree < ↑(Fintype.card n - 1) := by
  rw [charpoly, det_apply', ← insert_erase (mem_univ (Equiv.refl n)),
    sum_insert (not_mem_erase (Equiv.refl n) univ), add_comm]
  simp only [charmatrix_apply_eq, one_mul, Equiv.Perm.sign_refl, id.def, Int.cast_one,
    Units.val_one, add_sub_cancel, Equiv.coe_refl]
  rw [← mem_degreeLT]
  apply Submodule.sum_mem (degreeLT R (Fintype.card n - 1))
  intro c hc; rw [← C_eq_int_cast, C_mul']
  apply Submodule.smul_mem (degreeLT R (Fintype.card n - 1)) ↑↑(Equiv.Perm.sign c)
  rw [mem_degreeLT]
  apply lt_of_le_of_lt degree_le_natDegree _
  rw [Nat.cast_lt]
  apply lt_of_le_of_lt _ (Equiv.Perm.fixed_point_card_lt_of_ne_one (ne_of_mem_erase hc))
  

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
c : n ≃ n
hc : c ∈ Finset.erase univ (Equiv.refl n)
⊢ natDegree (∏ i : n, charmatrix M (c i) i) ≤ card (filter (fun x => c x = x) univ)

Next tactic:
apply le_trans (Polynomial.natDegree_prod_le univ fun i : n => charmatrix M (c i) i) _
theorem charpoly_sub_diagonal_degree_lt :
    (M.charpoly - ∏ i : n, (X - C (M i i))).degree < ↑(Fintype.card n - 1) := by
  rw [charpoly, det_apply', ← insert_erase (mem_univ (Equiv.refl n)),
    sum_insert (not_mem_erase (Equiv.refl n) univ), add_comm]
  simp only [charmatrix_apply_eq, one_mul, Equiv.Perm.sign_refl, id.def, Int.cast_one,
    Units.val_one, add_sub_cancel, Equiv.coe_refl]
  rw [← mem_degreeLT]
  apply Submodule.sum_mem (degreeLT R (Fintype.card n - 1))
  intro c hc; rw [← C_eq_int_cast, C_mul']
  apply Submodule.smul_mem (degreeLT R (Fintype.card n - 1)) ↑↑(Equiv.Perm.sign c)
  rw [mem_degreeLT]
  apply lt_of_le_of_lt degree_le_natDegree _
  rw [Nat.cast_lt]
  apply lt_of_le_of_lt _ (Equiv.Perm.fixed_point_card_lt_of_ne_one (ne_of_mem_erase hc))
  apply le_trans (Polynomial.natDegree_prod_le univ fun i : n => charmatrix M (c 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 : Matrix n n R
c : n ≃ n
hc : c ∈ Finset.erase univ (Equiv.refl n)
⊢ ∑ i : n, natDegree (charmatrix M (c i) i) ≤ card (filter (fun x => c x = x) univ)

Next tactic:
rw [card_eq_sum_ones]
theorem charpoly_sub_diagonal_degree_lt :
    (M.charpoly - ∏ i : n, (X - C (M i i))).degree < ↑(Fintype.card n - 1) := by
  rw [charpoly, det_apply', ← insert_erase (mem_univ (Equiv.refl n)),
    sum_insert (not_mem_erase (Equiv.refl n) univ), add_comm]
  simp only [charmatrix_apply_eq, one_mul, Equiv.Perm.sign_refl, id.def, Int.cast_one,
    Units.val_one, add_sub_cancel, Equiv.coe_refl]
  rw [← mem_degreeLT]
  apply Submodule.sum_mem (degreeLT R (Fintype.card n - 1))
  intro c hc; rw [← C_eq_int_cast, C_mul']
  apply Submodule.smul_mem (degreeLT R (Fintype.card n - 1)) ↑↑(Equiv.Perm.sign c)
  rw [mem_degreeLT]
  apply lt_of_le_of_lt degree_le_natDegree _
  rw [Nat.cast_lt]
  apply lt_of_le_of_lt _ (Equiv.Perm.fixed_point_card_lt_of_ne_one (ne_of_mem_erase hc))
  apply le_trans (Polynomial.natDegree_prod_le univ fun i : n => charmatrix M (c i) i) _
  rw [card_eq_sum_ones]; 

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
c : n ≃ n
hc : c ∈ Finset.erase univ (Equiv.refl n)
⊢ ∑ i : n, natDegree (charmatrix M (c i) i) ≤ ∑ x in filter (fun x => c x = x) univ, 1

Next tactic:
rw [sum_filter]
theorem charpoly_sub_diagonal_degree_lt :
    (M.charpoly - ∏ i : n, (X - C (M i i))).degree < ↑(Fintype.card n - 1) := by
  rw [charpoly, det_apply', ← insert_erase (mem_univ (Equiv.refl n)),
    sum_insert (not_mem_erase (Equiv.refl n) univ), add_comm]
  simp only [charmatrix_apply_eq, one_mul, Equiv.Perm.sign_refl, id.def, Int.cast_one,
    Units.val_one, add_sub_cancel, Equiv.coe_refl]
  rw [← mem_degreeLT]
  apply Submodule.sum_mem (degreeLT R (Fintype.card n - 1))
  intro c hc; rw [← C_eq_int_cast, C_mul']
  apply Submodule.smul_mem (degreeLT R (Fintype.card n - 1)) ↑↑(Equiv.Perm.sign c)
  rw [mem_degreeLT]
  apply lt_of_le_of_lt degree_le_natDegree _
  rw [Nat.cast_lt]
  apply lt_of_le_of_lt _ (Equiv.Perm.fixed_point_card_lt_of_ne_one (ne_of_mem_erase hc))
  apply le_trans (Polynomial.natDegree_prod_le univ fun i : n => charmatrix M (c i) i) _
  rw [card_eq_sum_ones]; rw [sum_filter]; 

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
c : n ≃ n
hc : c ∈ Finset.erase univ (Equiv.refl n)
⊢ ∑ i : n, natDegree (charmatrix M (c i) i) ≤ ∑ a : n, if c a = a then 1 else 0

Next tactic:
apply sum_le_sum