l3lab/ntp-mathlib huggingface dataset:
theorem coeff_divByMonic_X_sub_C (p : R[X]) (a : R) (n : ℕ) :
    (p /ₘ (X - C a)).coeff n = ∑ i in Icc (n + 1) p.natDegree, a ^ (i - (n + 1)) * p.coeff i := by
  wlog h : p.natDegree ≤ n generalizing n
  · refine Nat.decreasingInduction' (fun n hn _ ih ↦ ?_) (le_of_not_le h) ?_
    · rw [coeff_divByMonic_X_sub_C_rec, ih, eq_comm, Icc_eq_cons_Ioc (Nat.succ_le.mpr hn),
          sum_cons, Nat.sub_self, pow_zero, one_mul, mul_sum]
      congr 1; refine sum_congr ?_ fun i hi ↦ ?_
      · ext; 

Proof state:
case inr.refine_1.e_a.refine_1.a
R : Type u
S : Type v
T : Type w
A : Type z
a✝¹ b : R
n✝¹ : ℕ
inst✝ : Ring R
p✝ q p : R[X]
a : R
n✝ : ℕ
this :
  ∀ (n : ℕ),
    natDegree p ≤ n → coeff (p /ₘ (X - C a)) n = ∑ i in Icc (n + 1) (natDegree p), a ^ (i - (n + 1)) * coeff p i
h : ¬natDegree p ≤ n✝
n : ℕ
hn : n < natDegree p
x✝ : n✝ ≤ n
ih : coeff (p /ₘ (X - C a)) (n + 1) = ∑ i in Icc (n + 1 + 1) (natDegree p), a ^ (i - (n + 1 + 1)) * coeff p i
a✝ : ℕ
⊢ a✝ ∈ Ioc (Nat.succ n) (natDegree p) ↔ a✝ ∈ Icc (n + 1 + 1) (natDegree p)

Next tactic:
simp [Nat.succ_le]
theorem coeff_divByMonic_X_sub_C (p : R[X]) (a : R) (n : ℕ) :
    (p /ₘ (X - C a)).coeff n = ∑ i in Icc (n + 1) p.natDegree, a ^ (i - (n + 1)) * p.coeff i := by
  wlog h : p.natDegree ≤ n generalizing n
  · refine Nat.decreasingInduction' (fun n hn _ ih ↦ ?_) (le_of_not_le h) ?_
    · rw [coeff_divByMonic_X_sub_C_rec, ih, eq_comm, Icc_eq_cons_Ioc (Nat.succ_le.mpr hn),
          sum_cons, Nat.sub_self, pow_zero, one_mul, mul_sum]
      congr 1; refine sum_congr ?_ fun i hi ↦ ?_
      · ext; simp [Nat.succ_le]
      

Proof state:
case inr.refine_1.e_a.refine_2
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n✝¹ : ℕ
inst✝ : Ring R
p✝ q p : R[X]
a : R
n✝ : ℕ
this :
  ∀ (n : ℕ),
    natDegree p ≤ n → coeff (p /ₘ (X - C a)) n = ∑ i in Icc (n + 1) (natDegree p), a ^ (i - (n + 1)) * coeff p i
h : ¬natDegree p ≤ n✝
n : ℕ
hn : n < natDegree p
x✝ : n✝ ≤ n
ih : coeff (p /ₘ (X - C a)) (n + 1) = ∑ i in Icc (n + 1 + 1) (natDegree p), a ^ (i - (n + 1 + 1)) * coeff p i
i : ℕ
hi : i ∈ Icc (n + 1 + 1) (natDegree p)
⊢ a ^ (i - (n + 1)) * coeff p i = a * (a ^ (i - (n + 1 + 1)) * coeff p i)

Next tactic:
rw [← mul_assoc, ← pow_succ, eq_comm, i.sub_succ', Nat.sub_add_cancel]
theorem coeff_divByMonic_X_sub_C (p : R[X]) (a : R) (n : ℕ) :
    (p /ₘ (X - C a)).coeff n = ∑ i in Icc (n + 1) p.natDegree, a ^ (i - (n + 1)) * p.coeff i := by
  wlog h : p.natDegree ≤ n generalizing n
  · refine Nat.decreasingInduction' (fun n hn _ ih ↦ ?_) (le_of_not_le h) ?_
    · rw [coeff_divByMonic_X_sub_C_rec, ih, eq_comm, Icc_eq_cons_Ioc (Nat.succ_le.mpr hn),
          sum_cons, Nat.sub_self, pow_zero, one_mul, mul_sum]
      congr 1; refine sum_congr ?_ fun i hi ↦ ?_
      · ext; simp [Nat.succ_le]
      rw [← mul_assoc, ← pow_succ, eq_comm, i.sub_succ', Nat.sub_add_cancel]
      

Proof state:
case inr.refine_1.e_a.refine_2
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n✝¹ : ℕ
inst✝ : Ring R
p✝ q p : R[X]
a : R
n✝ : ℕ
this :
  ∀ (n : ℕ),
    natDegree p ≤ n → coeff (p /ₘ (X - C a)) n = ∑ i in Icc (n + 1) (natDegree p), a ^ (i - (n + 1)) * coeff p i
h : ¬natDegree p ≤ n✝
n : ℕ
hn : n < natDegree p
x✝ : n✝ ≤ n
ih : coeff (p /ₘ (X - C a)) (n + 1) = ∑ i in Icc (n + 1 + 1) (natDegree p), a ^ (i - (n + 1 + 1)) * coeff p i
i : ℕ
hi : i ∈ Icc (n + 1 + 1) (natDegree p)
⊢ 1 ≤ i - (n + 1)

Next tactic:
apply Nat.le_sub_of_add_le
theorem coeff_divByMonic_X_sub_C (p : R[X]) (a : R) (n : ℕ) :
    (p /ₘ (X - C a)).coeff n = ∑ i in Icc (n + 1) p.natDegree, a ^ (i - (n + 1)) * p.coeff i := by
  wlog h : p.natDegree ≤ n generalizing n
  · refine Nat.decreasingInduction' (fun n hn _ ih ↦ ?_) (le_of_not_le h) ?_
    · rw [coeff_divByMonic_X_sub_C_rec, ih, eq_comm, Icc_eq_cons_Ioc (Nat.succ_le.mpr hn),
          sum_cons, Nat.sub_self, pow_zero, one_mul, mul_sum]
      congr 1; refine sum_congr ?_ fun i hi ↦ ?_
      · ext; simp [Nat.succ_le]
      rw [← mul_assoc, ← pow_succ, eq_comm, i.sub_succ', Nat.sub_add_cancel]
      apply Nat.le_sub_of_add_le
      

Proof state:
case inr.refine_1.e_a.refine_2.h
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n✝¹ : ℕ
inst✝ : Ring R
p✝ q p : R[X]
a : R
n✝ : ℕ
this :
  ∀ (n : ℕ),
    natDegree p ≤ n → coeff (p /ₘ (X - C a)) n = ∑ i in Icc (n + 1) (natDegree p), a ^ (i - (n + 1)) * coeff p i
h : ¬natDegree p ≤ n✝
n : ℕ
hn : n < natDegree p
x✝ : n✝ ≤ n
ih : coeff (p /ₘ (X - C a)) (n + 1) = ∑ i in Icc (n + 1 + 1) (natDegree p), a ^ (i - (n + 1 + 1)) * coeff p i
i : ℕ
hi : i ∈ Icc (n + 1 + 1) (natDegree p)
⊢ 1 + (n + 1) ≤ i

Next tactic:
rw [add_comm]
theorem coeff_divByMonic_X_sub_C (p : R[X]) (a : R) (n : ℕ) :
    (p /ₘ (X - C a)).coeff n = ∑ i in Icc (n + 1) p.natDegree, a ^ (i - (n + 1)) * p.coeff i := by
  wlog h : p.natDegree ≤ n generalizing n
  · refine Nat.decreasingInduction' (fun n hn _ ih ↦ ?_) (le_of_not_le h) ?_
    · rw [coeff_divByMonic_X_sub_C_rec, ih, eq_comm, Icc_eq_cons_Ioc (Nat.succ_le.mpr hn),
          sum_cons, Nat.sub_self, pow_zero, one_mul, mul_sum]
      congr 1; refine sum_congr ?_ fun i hi ↦ ?_
      · ext; simp [Nat.succ_le]
      rw [← mul_assoc, ← pow_succ, eq_comm, i.sub_succ', Nat.sub_add_cancel]
      apply Nat.le_sub_of_add_le
      rw [add_comm]; 

Proof state:
case inr.refine_1.e_a.refine_2.h
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n✝¹ : ℕ
inst✝ : Ring R
p✝ q p : R[X]
a : R
n✝ : ℕ
this :
  ∀ (n : ℕ),
    natDegree p ≤ n → coeff (p /ₘ (X - C a)) n = ∑ i in Icc (n + 1) (natDegree p), a ^ (i - (n + 1)) * coeff p i
h : ¬natDegree p ≤ n✝
n : ℕ
hn : n < natDegree p
x✝ : n✝ ≤ n
ih : coeff (p /ₘ (X - C a)) (n + 1) = ∑ i in Icc (n + 1 + 1) (natDegree p), a ^ (i - (n + 1 + 1)) * coeff p i
i : ℕ
hi : i ∈ Icc (n + 1 + 1) (natDegree p)
⊢ n + 1 + 1 ≤ i

Next tactic:
exact (mem_Icc.mp hi).1
theorem coeff_divByMonic_X_sub_C (p : R[X]) (a : R) (n : ℕ) :
    (p /ₘ (X - C a)).coeff n = ∑ i in Icc (n + 1) p.natDegree, a ^ (i - (n + 1)) * p.coeff i := by
  wlog h : p.natDegree ≤ n generalizing n
  · refine Nat.decreasingInduction' (fun n hn _ ih ↦ ?_) (le_of_not_le h) ?_
    · rw [coeff_divByMonic_X_sub_C_rec, ih, eq_comm, Icc_eq_cons_Ioc (Nat.succ_le.mpr hn),
          sum_cons, Nat.sub_self, pow_zero, one_mul, mul_sum]
      congr 1; refine sum_congr ?_ fun i hi ↦ ?_
      · ext; simp [Nat.succ_le]
      rw [← mul_assoc, ← pow_succ, eq_comm, i.sub_succ', Nat.sub_add_cancel]
      apply Nat.le_sub_of_add_le
      rw [add_comm]; exact (mem_Icc.mp hi).1
    · 

Proof state:
case inr.refine_2
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n✝ : ℕ
inst✝ : Ring R
p✝ q p : R[X]
a : R
n : ℕ
this :
  ∀ (n : ℕ),
    natDegree p ≤ n → coeff (p /ₘ (X - C a)) n = ∑ i in Icc (n + 1) (natDegree p), a ^ (i - (n + 1)) * coeff p i
h : ¬natDegree p ≤ n
⊢ coeff (p /ₘ (X - C a)) (natDegree p) =
    ∑ i in Icc (natDegree p + 1) (natDegree p), a ^ (i - (natDegree p + 1)) * coeff p i

Next tactic:
exact this _ le_rfl
theorem coeff_divByMonic_X_sub_C (p : R[X]) (a : R) (n : ℕ) :
    (p /ₘ (X - C a)).coeff n = ∑ i in Icc (n + 1) p.natDegree, a ^ (i - (n + 1)) * p.coeff i := by
  wlog h : p.natDegree ≤ n generalizing n
  · refine Nat.decreasingInduction' (fun n hn _ ih ↦ ?_) (le_of_not_le h) ?_
    · rw [coeff_divByMonic_X_sub_C_rec, ih, eq_comm, Icc_eq_cons_Ioc (Nat.succ_le.mpr hn),
          sum_cons, Nat.sub_self, pow_zero, one_mul, mul_sum]
      congr 1; refine sum_congr ?_ fun i hi ↦ ?_
      · ext; simp [Nat.succ_le]
      rw [← mul_assoc, ← pow_succ, eq_comm, i.sub_succ', Nat.sub_add_cancel]
      apply Nat.le_sub_of_add_le
      rw [add_comm]; exact (mem_Icc.mp hi).1
    · exact this _ le_rfl
  

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n✝ : ℕ
inst✝ : Ring R
p✝ q p : R[X]
a : R
n : ℕ
h : natDegree p ≤ n
⊢ coeff (p /ₘ (X - C a)) n = ∑ i in Icc (n + 1) (natDegree p), a ^ (i - (n + 1)) * coeff p i

Next tactic:
rw [Icc_eq_empty (Nat.lt_succ.mpr h).not_le, sum_empty]
theorem coeff_divByMonic_X_sub_C (p : R[X]) (a : R) (n : ℕ) :
    (p /ₘ (X - C a)).coeff n = ∑ i in Icc (n + 1) p.natDegree, a ^ (i - (n + 1)) * p.coeff i := by
  wlog h : p.natDegree ≤ n generalizing n
  · refine Nat.decreasingInduction' (fun n hn _ ih ↦ ?_) (le_of_not_le h) ?_
    · rw [coeff_divByMonic_X_sub_C_rec, ih, eq_comm, Icc_eq_cons_Ioc (Nat.succ_le.mpr hn),
          sum_cons, Nat.sub_self, pow_zero, one_mul, mul_sum]
      congr 1; refine sum_congr ?_ fun i hi ↦ ?_
      · ext; simp [Nat.succ_le]
      rw [← mul_assoc, ← pow_succ, eq_comm, i.sub_succ', Nat.sub_add_cancel]
      apply Nat.le_sub_of_add_le
      rw [add_comm]; exact (mem_Icc.mp hi).1
    · exact this _ le_rfl
  rw [Icc_eq_empty (Nat.lt_succ.mpr h).not_le, sum_empty]
  

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n✝ : ℕ
inst✝ : Ring R
p✝ q p : R[X]
a : R
n : ℕ
h : natDegree p ≤ n
⊢ coeff (p /ₘ (X - C a)) n = 0

Next tactic:
nontriviality R
theorem coeff_divByMonic_X_sub_C (p : R[X]) (a : R) (n : ℕ) :
    (p /ₘ (X - C a)).coeff n = ∑ i in Icc (n + 1) p.natDegree, a ^ (i - (n + 1)) * p.coeff i := by
  wlog h : p.natDegree ≤ n generalizing n
  · refine Nat.decreasingInduction' (fun n hn _ ih ↦ ?_) (le_of_not_le h) ?_
    · rw [coeff_divByMonic_X_sub_C_rec, ih, eq_comm, Icc_eq_cons_Ioc (Nat.succ_le.mpr hn),
          sum_cons, Nat.sub_self, pow_zero, one_mul, mul_sum]
      congr 1; refine sum_congr ?_ fun i hi ↦ ?_
      · ext; simp [Nat.succ_le]
      rw [← mul_assoc, ← pow_succ, eq_comm, i.sub_succ', Nat.sub_add_cancel]
      apply Nat.le_sub_of_add_le
      rw [add_comm]; exact (mem_Icc.mp hi).1
    · exact this _ le_rfl
  rw [Icc_eq_empty (Nat.lt_succ.mpr h).not_le, sum_empty]
  nontriviality R
  

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n✝ : ℕ
inst✝ : Ring R
p✝ q p : R[X]
a : R
n : ℕ
h : natDegree p ≤ n
✝ : Nontrivial R
⊢ coeff (p /ₘ (X - C a)) n = 0

Next tactic:
by_cases hp : p.natDegree = 0
theorem coeff_divByMonic_X_sub_C (p : R[X]) (a : R) (n : ℕ) :
    (p /ₘ (X - C a)).coeff n = ∑ i in Icc (n + 1) p.natDegree, a ^ (i - (n + 1)) * p.coeff i := by
  wlog h : p.natDegree ≤ n generalizing n
  · refine Nat.decreasingInduction' (fun n hn _ ih ↦ ?_) (le_of_not_le h) ?_
    · rw [coeff_divByMonic_X_sub_C_rec, ih, eq_comm, Icc_eq_cons_Ioc (Nat.succ_le.mpr hn),
          sum_cons, Nat.sub_self, pow_zero, one_mul, mul_sum]
      congr 1; refine sum_congr ?_ fun i hi ↦ ?_
      · ext; simp [Nat.succ_le]
      rw [← mul_assoc, ← pow_succ, eq_comm, i.sub_succ', Nat.sub_add_cancel]
      apply Nat.le_sub_of_add_le
      rw [add_comm]; exact (mem_Icc.mp hi).1
    · exact this _ le_rfl
  rw [Icc_eq_empty (Nat.lt_succ.mpr h).not_le, sum_empty]
  nontriviality R
  by_cases hp : p.natDegree = 0
  · 

Proof state:
case pos
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n✝ : ℕ
inst✝ : Ring R
p✝ q p : R[X]
a : R
n : ℕ
h : natDegree p ≤ n
✝ : Nontrivial R
hp : natDegree p = 0
⊢ coeff (p /ₘ (X - C a)) n = 0

Next tactic:
rw [(divByMonic_eq_zero_iff <| monic_X_sub_C a).mpr, coeff_zero]
theorem coeff_divByMonic_X_sub_C (p : R[X]) (a : R) (n : ℕ) :
    (p /ₘ (X - C a)).coeff n = ∑ i in Icc (n + 1) p.natDegree, a ^ (i - (n + 1)) * p.coeff i := by
  wlog h : p.natDegree ≤ n generalizing n
  · refine Nat.decreasingInduction' (fun n hn _ ih ↦ ?_) (le_of_not_le h) ?_
    · rw [coeff_divByMonic_X_sub_C_rec, ih, eq_comm, Icc_eq_cons_Ioc (Nat.succ_le.mpr hn),
          sum_cons, Nat.sub_self, pow_zero, one_mul, mul_sum]
      congr 1; refine sum_congr ?_ fun i hi ↦ ?_
      · ext; simp [Nat.succ_le]
      rw [← mul_assoc, ← pow_succ, eq_comm, i.sub_succ', Nat.sub_add_cancel]
      apply Nat.le_sub_of_add_le
      rw [add_comm]; exact (mem_Icc.mp hi).1
    · exact this _ le_rfl
  rw [Icc_eq_empty (Nat.lt_succ.mpr h).not_le, sum_empty]
  nontriviality R
  by_cases hp : p.natDegree = 0
  · rw [(divByMonic_eq_zero_iff <| monic_X_sub_C a).mpr, coeff_zero]
    

Proof state:
case pos
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n✝ : ℕ
inst✝ : Ring R
p✝ q p : R[X]
a : R
n : ℕ
h : natDegree p ≤ n
✝ : Nontrivial R
hp : natDegree p = 0
⊢ degree p < degree (X - C a)

Next tactic:
apply degree_lt_degree
theorem coeff_divByMonic_X_sub_C (p : R[X]) (a : R) (n : ℕ) :
    (p /ₘ (X - C a)).coeff n = ∑ i in Icc (n + 1) p.natDegree, a ^ (i - (n + 1)) * p.coeff i := by
  wlog h : p.natDegree ≤ n generalizing n
  · refine Nat.decreasingInduction' (fun n hn _ ih ↦ ?_) (le_of_not_le h) ?_
    · rw [coeff_divByMonic_X_sub_C_rec, ih, eq_comm, Icc_eq_cons_Ioc (Nat.succ_le.mpr hn),
          sum_cons, Nat.sub_self, pow_zero, one_mul, mul_sum]
      congr 1; refine sum_congr ?_ fun i hi ↦ ?_
      · ext; simp [Nat.succ_le]
      rw [← mul_assoc, ← pow_succ, eq_comm, i.sub_succ', Nat.sub_add_cancel]
      apply Nat.le_sub_of_add_le
      rw [add_comm]; exact (mem_Icc.mp hi).1
    · exact this _ le_rfl
  rw [Icc_eq_empty (Nat.lt_succ.mpr h).not_le, sum_empty]
  nontriviality R
  by_cases hp : p.natDegree = 0
  · rw [(divByMonic_eq_zero_iff <| monic_X_sub_C a).mpr, coeff_zero]
    apply degree_lt_degree; 

Proof state:
case pos.h
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n✝ : ℕ
inst✝ : Ring R
p✝ q p : R[X]
a : R
n : ℕ
h : natDegree p ≤ n
✝ : Nontrivial R
hp : natDegree p = 0
⊢ natDegree p < natDegree (X - C a)

Next tactic:
rw [hp, natDegree_X_sub_C]
theorem coeff_divByMonic_X_sub_C (p : R[X]) (a : R) (n : ℕ) :
    (p /ₘ (X - C a)).coeff n = ∑ i in Icc (n + 1) p.natDegree, a ^ (i - (n + 1)) * p.coeff i := by
  wlog h : p.natDegree ≤ n generalizing n
  · refine Nat.decreasingInduction' (fun n hn _ ih ↦ ?_) (le_of_not_le h) ?_
    · rw [coeff_divByMonic_X_sub_C_rec, ih, eq_comm, Icc_eq_cons_Ioc (Nat.succ_le.mpr hn),
          sum_cons, Nat.sub_self, pow_zero, one_mul, mul_sum]
      congr 1; refine sum_congr ?_ fun i hi ↦ ?_
      · ext; simp [Nat.succ_le]
      rw [← mul_assoc, ← pow_succ, eq_comm, i.sub_succ', Nat.sub_add_cancel]
      apply Nat.le_sub_of_add_le
      rw [add_comm]; exact (mem_Icc.mp hi).1
    · exact this _ le_rfl
  rw [Icc_eq_empty (Nat.lt_succ.mpr h).not_le, sum_empty]
  nontriviality R
  by_cases hp : p.natDegree = 0
  · rw [(divByMonic_eq_zero_iff <| monic_X_sub_C a).mpr, coeff_zero]
    apply degree_lt_degree; rw [hp, natDegree_X_sub_C]; 

Proof state:
case pos.h
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n✝ : ℕ
inst✝ : Ring R
p✝ q p : R[X]
a : R
n : ℕ
h : natDegree p ≤ n
✝ : Nontrivial R
hp : natDegree p = 0
⊢ 0 < 1

Next tactic:
norm_num
theorem coeff_divByMonic_X_sub_C (p : R[X]) (a : R) (n : ℕ) :
    (p /ₘ (X - C a)).coeff n = ∑ i in Icc (n + 1) p.natDegree, a ^ (i - (n + 1)) * p.coeff i := by
  wlog h : p.natDegree ≤ n generalizing n
  · refine Nat.decreasingInduction' (fun n hn _ ih ↦ ?_) (le_of_not_le h) ?_
    · rw [coeff_divByMonic_X_sub_C_rec, ih, eq_comm, Icc_eq_cons_Ioc (Nat.succ_le.mpr hn),
          sum_cons, Nat.sub_self, pow_zero, one_mul, mul_sum]
      congr 1; refine sum_congr ?_ fun i hi ↦ ?_
      · ext; simp [Nat.succ_le]
      rw [← mul_assoc, ← pow_succ, eq_comm, i.sub_succ', Nat.sub_add_cancel]
      apply Nat.le_sub_of_add_le
      rw [add_comm]; exact (mem_Icc.mp hi).1
    · exact this _ le_rfl
  rw [Icc_eq_empty (Nat.lt_succ.mpr h).not_le, sum_empty]
  nontriviality R
  by_cases hp : p.natDegree = 0
  · rw [(divByMonic_eq_zero_iff <| monic_X_sub_C a).mpr, coeff_zero]
    apply degree_lt_degree; rw [hp, natDegree_X_sub_C]; norm_num
  · 

Proof state:
case neg
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n✝ : ℕ
inst✝ : Ring R
p✝ q p : R[X]
a : R
n : ℕ
h : natDegree p ≤ n
✝ : Nontrivial R
hp : ¬natDegree p = 0
⊢ coeff (p /ₘ (X - C a)) n = 0

Next tactic:
apply coeff_eq_zero_of_natDegree_lt
theorem coeff_divByMonic_X_sub_C (p : R[X]) (a : R) (n : ℕ) :
    (p /ₘ (X - C a)).coeff n = ∑ i in Icc (n + 1) p.natDegree, a ^ (i - (n + 1)) * p.coeff i := by
  wlog h : p.natDegree ≤ n generalizing n
  · refine Nat.decreasingInduction' (fun n hn _ ih ↦ ?_) (le_of_not_le h) ?_
    · rw [coeff_divByMonic_X_sub_C_rec, ih, eq_comm, Icc_eq_cons_Ioc (Nat.succ_le.mpr hn),
          sum_cons, Nat.sub_self, pow_zero, one_mul, mul_sum]
      congr 1; refine sum_congr ?_ fun i hi ↦ ?_
      · ext; simp [Nat.succ_le]
      rw [← mul_assoc, ← pow_succ, eq_comm, i.sub_succ', Nat.sub_add_cancel]
      apply Nat.le_sub_of_add_le
      rw [add_comm]; exact (mem_Icc.mp hi).1
    · exact this _ le_rfl
  rw [Icc_eq_empty (Nat.lt_succ.mpr h).not_le, sum_empty]
  nontriviality R
  by_cases hp : p.natDegree = 0
  · rw [(divByMonic_eq_zero_iff <| monic_X_sub_C a).mpr, coeff_zero]
    apply degree_lt_degree; rw [hp, natDegree_X_sub_C]; norm_num
  · apply coeff_eq_zero_of_natDegree_lt
    

Proof state:
case neg.h
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n✝ : ℕ
inst✝ : Ring R
p✝ q p : R[X]
a : R
n : ℕ
h : natDegree p ≤ n
✝ : Nontrivial R
hp : ¬natDegree p = 0
⊢ natDegree (p /ₘ (X - C a)) < n

Next tactic:
rw [natDegree_divByMonic p (monic_X_sub_C a), natDegree_X_sub_C]
theorem coeff_divByMonic_X_sub_C (p : R[X]) (a : R) (n : ℕ) :
    (p /ₘ (X - C a)).coeff n = ∑ i in Icc (n + 1) p.natDegree, a ^ (i - (n + 1)) * p.coeff i := by
  wlog h : p.natDegree ≤ n generalizing n
  · refine Nat.decreasingInduction' (fun n hn _ ih ↦ ?_) (le_of_not_le h) ?_
    · rw [coeff_divByMonic_X_sub_C_rec, ih, eq_comm, Icc_eq_cons_Ioc (Nat.succ_le.mpr hn),
          sum_cons, Nat.sub_self, pow_zero, one_mul, mul_sum]
      congr 1; refine sum_congr ?_ fun i hi ↦ ?_
      · ext; simp [Nat.succ_le]
      rw [← mul_assoc, ← pow_succ, eq_comm, i.sub_succ', Nat.sub_add_cancel]
      apply Nat.le_sub_of_add_le
      rw [add_comm]; exact (mem_Icc.mp hi).1
    · exact this _ le_rfl
  rw [Icc_eq_empty (Nat.lt_succ.mpr h).not_le, sum_empty]
  nontriviality R
  by_cases hp : p.natDegree = 0
  · rw [(divByMonic_eq_zero_iff <| monic_X_sub_C a).mpr, coeff_zero]
    apply degree_lt_degree; rw [hp, natDegree_X_sub_C]; norm_num
  · apply coeff_eq_zero_of_natDegree_lt
    rw [natDegree_divByMonic p (monic_X_sub_C a), natDegree_X_sub_C]
    

Proof state:
case neg.h
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n✝ : ℕ
inst✝ : Ring R
p✝ q p : R[X]
a : R
n : ℕ
h : natDegree p ≤ n
✝ : Nontrivial R
hp : ¬natDegree p = 0
⊢ natDegree p - 1 < n

Next tactic:
exact (Nat.pred_lt hp).trans_le h
variable (R) in
theorem not_isField : ¬IsField R[X] := by
  

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Ring R
p q : R[X]
⊢ ¬IsField R[X]

Next tactic:
nontriviality R
variable (R) in
theorem not_isField : ¬IsField R[X] := by
  nontriviality R
  

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Ring R
p q : R[X]
✝ : Nontrivial R
⊢ ¬IsField R[X]

Next tactic:
intro h
variable (R) in
theorem not_isField : ¬IsField R[X] := by
  nontriviality R
  intro h
  

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Ring R
p q : R[X]
✝ : Nontrivial R
h : IsField R[X]
⊢ False

Next tactic:
letI := h.toField
variable (R) in
theorem not_isField : ¬IsField R[X] := by
  nontriviality R
  intro h
  letI := h.toField
  

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Ring R
p q : R[X]
✝ : Nontrivial R
h : IsField R[X]
this : Field R[X] := IsField.toField h
⊢ False

Next tactic:
simpa using congr_arg natDegree (monic_X.eq_one_of_isUnit <| monic_X (R := R).ne_zero.isUnit)
theorem multiplicity_X_sub_C_finite (a : R) (h0 : p ≠ 0) : multiplicity.Finite (X - C a) p := by
  

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n : ℕ
inst✝ : Ring R
p q : R[X]
a : R
h0 : p ≠ 0
⊢ multiplicity.Finite (X - C a) p

Next tactic:
haveI := Nontrivial.of_polynomial_ne h0
theorem multiplicity_X_sub_C_finite (a : R) (h0 : p ≠ 0) : multiplicity.Finite (X - C a) p := by
  haveI := Nontrivial.of_polynomial_ne h0
  

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n : ℕ
inst✝ : Ring R
p q : R[X]
a : R
h0 : p ≠ 0
this : Nontrivial R
⊢ multiplicity.Finite (X - C a) p

Next tactic:
refine' multiplicity_finite_of_degree_pos_of_monic _ (monic_X_sub_C _) h0
theorem multiplicity_X_sub_C_finite (a : R) (h0 : p ≠ 0) : multiplicity.Finite (X - C a) p := by
  haveI := Nontrivial.of_polynomial_ne h0
  refine' multiplicity_finite_of_degree_pos_of_monic _ (monic_X_sub_C _) h0
  

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n : ℕ
inst✝ : Ring R
p q : R[X]
a : R
h0 : p ≠ 0
this : Nontrivial R
⊢ 0 < degree (X - C a)

Next tactic:
rw [degree_X_sub_C]
theorem multiplicity_X_sub_C_finite (a : R) (h0 : p ≠ 0) : multiplicity.Finite (X - C a) p := by
  haveI := Nontrivial.of_polynomial_ne h0
  refine' multiplicity_finite_of_degree_pos_of_monic _ (monic_X_sub_C _) h0
  rw [degree_X_sub_C]
  

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n : ℕ
inst✝ : Ring R
p q : R[X]
a : R
h0 : p ≠ 0
this : Nontrivial R
⊢ 0 < 1

Next tactic:
decide
theorem rootMultiplicity_eq_nat_find_of_nonzero [DecidableEq R] {p : R[X]} (p0 : p ≠ 0) {a : R} :
    letI : DecidablePred fun n : ℕ => ¬(X - C a) ^ (n + 1) ∣ p := fun n =>
      @Not.decidable _ (decidableDvdMonic p ((monic_X_sub_C a).pow (n + 1)))
    rootMultiplicity a p = Nat.find (multiplicity_X_sub_C_finite a p0) := by
  

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n : ℕ
inst✝¹ : Ring R
p✝ q : R[X]
inst✝ : DecidableEq R
p : R[X]
p0 : p ≠ 0
a : R
⊢ rootMultiplicity a p = Nat.find (_ : multiplicity.Finite (X - C a) p)

Next tactic:
dsimp [rootMultiplicity]
theorem rootMultiplicity_eq_nat_find_of_nonzero [DecidableEq R] {p : R[X]} (p0 : p ≠ 0) {a : R} :
    letI : DecidablePred fun n : ℕ => ¬(X - C a) ^ (n + 1) ∣ p := fun n =>
      @Not.decidable _ (decidableDvdMonic p ((monic_X_sub_C a).pow (n + 1)))
    rootMultiplicity a p = Nat.find (multiplicity_X_sub_C_finite a p0) := by
  dsimp [rootMultiplicity]
  

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n : ℕ
inst✝¹ : Ring R
p✝ q : R[X]
inst✝ : DecidableEq R
p : R[X]
p0 : p ≠ 0
a : R
⊢ (if h0 : p = 0 then 0 else Nat.find (_ : multiplicity.Finite (X - C a) p)) =
    Nat.find (_ : multiplicity.Finite (X - C a) p)

Next tactic:
cases Subsingleton.elim ‹DecidableEq R› (Classical.decEq R)
theorem rootMultiplicity_eq_nat_find_of_nonzero [DecidableEq R] {p : R[X]} (p0 : p ≠ 0) {a : R} :
    letI : DecidablePred fun n : ℕ => ¬(X - C a) ^ (n + 1) ∣ p := fun n =>
      @Not.decidable _ (decidableDvdMonic p ((monic_X_sub_C a).pow (n + 1)))
    rootMultiplicity a p = Nat.find (multiplicity_X_sub_C_finite a p0) := by
  dsimp [rootMultiplicity]
  cases Subsingleton.elim ‹DecidableEq R› (Classical.decEq R)
  

Proof state:
case refl
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n : ℕ
inst✝ : Ring R
p✝ q p : R[X]
p0 : p ≠ 0
a : R
⊢ (if h0 : p = 0 then 0 else Nat.find (_ : multiplicity.Finite (X - C a) p)) =
    Nat.find (_ : multiplicity.Finite (X - C a) p)

Next tactic:
rw [dif_neg p0]
theorem rootMultiplicity_eq_multiplicity [DecidableEq R] [@DecidableRel R[X] (· ∣ ·)]
    (p : R[X]) (a : R) :
    rootMultiplicity a p =
      if h0 : p = 0 then 0 else (multiplicity (X - C a) p).get (multiplicity_X_sub_C_finite a h0) :=
  by 

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n : ℕ
inst✝² : Ring R
p✝ q : R[X]
inst✝¹ : DecidableEq R
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p : R[X]
a : R
⊢ rootMultiplicity a p =
    if h0 : p = 0 then 0 else Part.get (multiplicity (X - C a) p) (_ : multiplicity.Finite (X - C a) p)

Next tactic:
simp [multiplicity, rootMultiplicity, Part.Dom]
theorem rootMultiplicity_eq_multiplicity [DecidableEq R] [@DecidableRel R[X] (· ∣ ·)]
    (p : R[X]) (a : R) :
    rootMultiplicity a p =
      if h0 : p = 0 then 0 else (multiplicity (X - C a) p).get (multiplicity_X_sub_C_finite a h0) :=
  by simp [multiplicity, rootMultiplicity, Part.Dom]; 

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n : ℕ
inst✝² : Ring R
p✝ q : R[X]
inst✝¹ : DecidableEq R
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p : R[X]
a : R
⊢ (if h : p = 0 then 0 else Nat.find (_ : multiplicity.Finite (X - C a) p)) =
    if h : p = 0 then 0 else Nat.find (_ : (PartENat.find fun n => ¬(X - C a) ^ (n + 1) ∣ p).Dom)

Next tactic:
congr