l3lab/ntp-mathlib huggingface dataset:
set_option linter.deprecated false in
@[simp]
theorem bit0_comp : comp (bit0 p : R[X]) q = bit0 (p.comp q) := by 

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝ : Semiring R
p q r : R[X]
⊢ comp (bit0 p) q = bit0 (comp p q)

Next tactic:
simp only [bit0, add_comp]
set_option linter.deprecated false in
@[simp]
theorem bit1_comp : comp (bit1 p : R[X]) q = bit1 (p.comp q) := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝ : Semiring R
p q r : R[X]
⊢ comp (bit1 p) q = bit1 (comp p q)

Next tactic:
simp only [bit1, add_comp, bit0_comp, one_comp]
@[simp]
theorem smul_comp [Monoid S] [DistribMulAction S R] [IsScalarTower S R R] (s : S) (p q : R[X]) :
    (s • p).comp q = s • p.comp q := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝³ : Semiring R
p✝ q✝ r : R[X]
inst✝² : Monoid S
inst✝¹ : DistribMulAction S R
inst✝ : IsScalarTower S R R
s : S
p q : R[X]
⊢ comp (s • p) q = s • comp p q

Next tactic:
rw [← smul_one_smul R s p, comp, comp, eval₂_smul, ← smul_eq_C_mul, smul_assoc, one_smul]
theorem comp_assoc {R : Type*} [CommSemiring R] (φ ψ χ : R[X]) :
    (φ.comp ψ).comp χ = φ.comp (ψ.comp χ) := by
  

Proof state:
R✝ : Type u
S : Type v
T : Type w
ι : Type y
a b : R✝
m n : ℕ
inst✝¹ : Semiring R✝
p q r : R✝[X]
R : Type u_1
inst✝ : CommSemiring R
φ ψ χ : R[X]
⊢ comp (comp φ ψ) χ = comp φ (comp ψ χ)

Next tactic:
refine Polynomial.induction_on φ ?_ ?_ ?_
theorem comp_assoc {R : Type*} [CommSemiring R] (φ ψ χ : R[X]) :
    (φ.comp ψ).comp χ = φ.comp (ψ.comp χ) := by
  refine Polynomial.induction_on φ ?_ ?_ ?_ <;>
    · 

Proof state:
case refine_1
R✝ : Type u
S : Type v
T : Type w
ι : Type y
a b : R✝
m n : ℕ
inst✝¹ : Semiring R✝
p q r : R✝[X]
R : Type u_1
inst✝ : CommSemiring R
φ ψ χ : R[X]
⊢ ∀ (a : R), comp (comp (C a) ψ) χ = comp (C a) (comp ψ χ)

Next tactic:
intros
theorem comp_assoc {R : Type*} [CommSemiring R] (φ ψ χ : R[X]) :
    (φ.comp ψ).comp χ = φ.comp (ψ.comp χ) := by
  refine Polynomial.induction_on φ ?_ ?_ ?_ <;>
    · intros
      

Proof state:
case refine_1
R✝ : Type u
S : Type v
T : Type w
ι : Type y
a b : R✝
m n : ℕ
inst✝¹ : Semiring R✝
p q r : R✝[X]
R : Type u_1
inst✝ : CommSemiring R
φ ψ χ : R[X]
a✝ : R
⊢ comp (comp (C a✝) ψ) χ = comp (C a✝) (comp ψ χ)

Next tactic:
simp_all only [add_comp, mul_comp, C_comp, X_comp, pow_succ', ← mul_assoc]
theorem comp_assoc {R : Type*} [CommSemiring R] (φ ψ χ : R[X]) :
    (φ.comp ψ).comp χ = φ.comp (ψ.comp χ) := by
  refine Polynomial.induction_on φ ?_ ?_ ?_ <;>
    · 

Proof state:
case refine_2
R✝ : Type u
S : Type v
T : Type w
ι : Type y
a b : R✝
m n : ℕ
inst✝¹ : Semiring R✝
p q r : R✝[X]
R : Type u_1
inst✝ : CommSemiring R
φ ψ χ : R[X]
⊢ ∀ (p q : R[X]),
    comp (comp p ψ) χ = comp p (comp ψ χ) →
      comp (comp q ψ) χ = comp q (comp ψ χ) → comp (comp (p + q) ψ) χ = comp (p + q) (comp ψ χ)

Next tactic:
intros
theorem comp_assoc {R : Type*} [CommSemiring R] (φ ψ χ : R[X]) :
    (φ.comp ψ).comp χ = φ.comp (ψ.comp χ) := by
  refine Polynomial.induction_on φ ?_ ?_ ?_ <;>
    · intros
      

Proof state:
case refine_2
R✝ : Type u
S : Type v
T : Type w
ι : Type y
a b : R✝
m n : ℕ
inst✝¹ : Semiring R✝
p q r : R✝[X]
R : Type u_1
inst✝ : CommSemiring R
φ ψ χ p✝ q✝ : R[X]
a✝¹ : comp (comp p✝ ψ) χ = comp p✝ (comp ψ χ)
a✝ : comp (comp q✝ ψ) χ = comp q✝ (comp ψ χ)
⊢ comp (comp (p✝ + q✝) ψ) χ = comp (p✝ + q✝) (comp ψ χ)

Next tactic:
simp_all only [add_comp, mul_comp, C_comp, X_comp, pow_succ', ← mul_assoc]
theorem comp_assoc {R : Type*} [CommSemiring R] (φ ψ χ : R[X]) :
    (φ.comp ψ).comp χ = φ.comp (ψ.comp χ) := by
  refine Polynomial.induction_on φ ?_ ?_ ?_ <;>
    · 

Proof state:
case refine_3
R✝ : Type u
S : Type v
T : Type w
ι : Type y
a b : R✝
m n : ℕ
inst✝¹ : Semiring R✝
p q r : R✝[X]
R : Type u_1
inst✝ : CommSemiring R
φ ψ χ : R[X]
⊢ ∀ (n : ℕ) (a : R),
    comp (comp (C a * X ^ n) ψ) χ = comp (C a * X ^ n) (comp ψ χ) →
      comp (comp (C a * X ^ (n + 1)) ψ) χ = comp (C a * X ^ (n + 1)) (comp ψ χ)

Next tactic:
intros
theorem comp_assoc {R : Type*} [CommSemiring R] (φ ψ χ : R[X]) :
    (φ.comp ψ).comp χ = φ.comp (ψ.comp χ) := by
  refine Polynomial.induction_on φ ?_ ?_ ?_ <;>
    · intros
      

Proof state:
case refine_3
R✝ : Type u
S : Type v
T : Type w
ι : Type y
a b : R✝
m n : ℕ
inst✝¹ : Semiring R✝
p q r : R✝[X]
R : Type u_1
inst✝ : CommSemiring R
φ ψ χ : R[X]
n✝ : ℕ
a✝¹ : R
a✝ : comp (comp (C a✝¹ * X ^ n✝) ψ) χ = comp (C a✝¹ * X ^ n✝) (comp ψ χ)
⊢ comp (comp (C a✝¹ * X ^ (n✝ + 1)) ψ) χ = comp (C a✝¹ * X ^ (n✝ + 1)) (comp ψ χ)

Next tactic:
simp_all only [add_comp, mul_comp, C_comp, X_comp, pow_succ', ← mul_assoc]
theorem coeff_comp_degree_mul_degree (hqd0 : natDegree q ≠ 0) :
    coeff (p.comp q) (natDegree p * natDegree q) =
    leadingCoeff p * leadingCoeff q ^ natDegree p := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝ : Semiring R
p q r : R[X]
hqd0 : natDegree q ≠ 0
⊢ coeff (comp p q) (natDegree p * natDegree q) = leadingCoeff p * leadingCoeff q ^ natDegree p

Next tactic:
rw [comp, eval₂_def, coeff_sum]
theorem coeff_comp_degree_mul_degree (hqd0 : natDegree q ≠ 0) :
    coeff (p.comp q) (natDegree p * natDegree q) =
    leadingCoeff p * leadingCoeff q ^ natDegree p := by
  rw [comp, eval₂_def, coeff_sum]
  -- Porting note: `convert` → `refine`
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝ : Semiring R
p q r : R[X]
hqd0 : natDegree q ≠ 0
⊢ (sum p fun a b => coeff (C b * q ^ a) (natDegree p * natDegree q)) = leadingCoeff p * leadingCoeff q ^ natDegree p

Next tactic:
refine Eq.trans (Finset.sum_eq_single p.natDegree ?h₀ ?h₁) ?h₂
theorem coeff_comp_degree_mul_degree (hqd0 : natDegree q ≠ 0) :
    coeff (p.comp q) (natDegree p * natDegree q) =
    leadingCoeff p * leadingCoeff q ^ natDegree p := by
  rw [comp, eval₂_def, coeff_sum]
  -- Porting note: `convert` → `refine`
  refine Eq.trans (Finset.sum_eq_single p.natDegree ?h₀ ?h₁) ?h₂
  

Proof state:
case h₀
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝ : Semiring R
p q r : R[X]
hqd0 : natDegree q ≠ 0
⊢ ∀ b ∈ support p, b ≠ natDegree p → (fun a b => coeff (C b * q ^ a) (natDegree p * natDegree q)) b (coeff p b) = 0
case h₁
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝ : Semiring R
p q r : R[X]
hqd0 : natDegree q ≠ 0
⊢ natDegree p ∉ support p →
    (fun a b => coeff (C b * q ^ a) (natDegree p * natDegree q)) (natDegree p) (coeff p (natDegree p)) = 0
case h₂
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝ : Semiring R
p q r : R[X]
hqd0 : natDegree q ≠ 0
⊢ (fun a b => coeff (C b * q ^ a) (natDegree p * natDegree q)) (natDegree p) (coeff p (natDegree p)) =
    leadingCoeff p * leadingCoeff q ^ natDegree p

Next tactic:
case h₂ =>
    simp only [coeff_natDegree, coeff_C_mul, coeff_pow_mul_natDegree]
theorem coeff_comp_degree_mul_degree (hqd0 : natDegree q ≠ 0) :
    coeff (p.comp q) (natDegree p * natDegree q) =
    leadingCoeff p * leadingCoeff q ^ natDegree p := by
  rw [comp, eval₂_def, coeff_sum]
  -- Porting note: `convert` → `refine`
  refine Eq.trans (Finset.sum_eq_single p.natDegree ?h₀ ?h₁) ?h₂
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝ : Semiring R
p q r : R[X]
hqd0 : natDegree q ≠ 0
⊢ (fun a b => coeff (C b * q ^ a) (natDegree p * natDegree q)) (natDegree p) (coeff p (natDegree p)) =
    leadingCoeff p * leadingCoeff q ^ natDegree p

Next tactic:
case h₂ =>
    simp only [coeff_natDegree, coeff_C_mul, coeff_pow_mul_natDegree]
theorem coeff_comp_degree_mul_degree (hqd0 : natDegree q ≠ 0) :
    coeff (p.comp q) (natDegree p * natDegree q) =
    leadingCoeff p * leadingCoeff q ^ natDegree p := by
  rw [comp, eval₂_def, coeff_sum]
  -- Porting note: `convert` → `refine`
  refine Eq.trans (Finset.sum_eq_single p.natDegree ?h₀ ?h₁) ?h₂
  case h₂ =>
    

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝ : Semiring R
p q r : R[X]
hqd0 : natDegree q ≠ 0
⊢ (fun a b => coeff (C b * q ^ a) (natDegree p * natDegree q)) (natDegree p) (coeff p (natDegree p)) =
    leadingCoeff p * leadingCoeff q ^ natDegree p

Next tactic:
simp only [coeff_natDegree, coeff_C_mul, coeff_pow_mul_natDegree]
theorem coeff_comp_degree_mul_degree (hqd0 : natDegree q ≠ 0) :
    coeff (p.comp q) (natDegree p * natDegree q) =
    leadingCoeff p * leadingCoeff q ^ natDegree p := by
  rw [comp, eval₂_def, coeff_sum]
  -- Porting note: `convert` → `refine`
  refine Eq.trans (Finset.sum_eq_single p.natDegree ?h₀ ?h₁) ?h₂
  case h₂ =>
    simp only [coeff_natDegree, coeff_C_mul, coeff_pow_mul_natDegree]
  

Proof state:
case h₀
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝ : Semiring R
p q r : R[X]
hqd0 : natDegree q ≠ 0
⊢ ∀ b ∈ support p, b ≠ natDegree p → (fun a b => coeff (C b * q ^ a) (natDegree p * natDegree q)) b (coeff p b) = 0
case h₁
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝ : Semiring R
p q r : R[X]
hqd0 : natDegree q ≠ 0
⊢ natDegree p ∉ support p →
    (fun a b => coeff (C b * q ^ a) (natDegree p * natDegree q)) (natDegree p) (coeff p (natDegree p)) = 0

Next tactic:
case h₀ =>
    intro b hbs hbp
    refine' coeff_eq_zero_of_natDegree_lt (natDegree_mul_le.trans_lt _)
    rw [natDegree_C, zero_add]
    refine' natDegree_pow_le.trans_lt ((mul_lt_mul_right (pos_iff_ne_zero.mpr hqd0)).mpr _)
    exact lt_of_le_of_ne (le_natDegree_of_mem_supp _ hbs) hbp
theorem coeff_comp_degree_mul_degree (hqd0 : natDegree q ≠ 0) :
    coeff (p.comp q) (natDegree p * natDegree q) =
    leadingCoeff p * leadingCoeff q ^ natDegree p := by
  rw [comp, eval₂_def, coeff_sum]
  -- Porting note: `convert` → `refine`
  refine Eq.trans (Finset.sum_eq_single p.natDegree ?h₀ ?h₁) ?h₂
  case h₂ =>
    simp only [coeff_natDegree, coeff_C_mul, coeff_pow_mul_natDegree]
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝ : Semiring R
p q r : R[X]
hqd0 : natDegree q ≠ 0
⊢ ∀ b ∈ support p, b ≠ natDegree p → (fun a b => coeff (C b * q ^ a) (natDegree p * natDegree q)) b (coeff p b) = 0

Next tactic:
case h₀ =>
    intro b hbs hbp
    refine' coeff_eq_zero_of_natDegree_lt (natDegree_mul_le.trans_lt _)
    rw [natDegree_C, zero_add]
    refine' natDegree_pow_le.trans_lt ((mul_lt_mul_right (pos_iff_ne_zero.mpr hqd0)).mpr _)
    exact lt_of_le_of_ne (le_natDegree_of_mem_supp _ hbs) hbp
theorem coeff_comp_degree_mul_degree (hqd0 : natDegree q ≠ 0) :
    coeff (p.comp q) (natDegree p * natDegree q) =
    leadingCoeff p * leadingCoeff q ^ natDegree p := by
  rw [comp, eval₂_def, coeff_sum]
  -- Porting note: `convert` → `refine`
  refine Eq.trans (Finset.sum_eq_single p.natDegree ?h₀ ?h₁) ?h₂
  case h₂ =>
    simp only [coeff_natDegree, coeff_C_mul, coeff_pow_mul_natDegree]
  case h₀ =>
    

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝ : Semiring R
p q r : R[X]
hqd0 : natDegree q ≠ 0
⊢ ∀ b ∈ support p, b ≠ natDegree p → (fun a b => coeff (C b * q ^ a) (natDegree p * natDegree q)) b (coeff p b) = 0

Next tactic:
intro b hbs hbp
theorem coeff_comp_degree_mul_degree (hqd0 : natDegree q ≠ 0) :
    coeff (p.comp q) (natDegree p * natDegree q) =
    leadingCoeff p * leadingCoeff q ^ natDegree p := by
  rw [comp, eval₂_def, coeff_sum]
  -- Porting note: `convert` → `refine`
  refine Eq.trans (Finset.sum_eq_single p.natDegree ?h₀ ?h₁) ?h₂
  case h₂ =>
    simp only [coeff_natDegree, coeff_C_mul, coeff_pow_mul_natDegree]
  case h₀ =>
    intro b hbs hbp
    

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b✝ : R
m n : ℕ
inst✝ : Semiring R
p q r : R[X]
hqd0 : natDegree q ≠ 0
b : ℕ
hbs : b ∈ support p
hbp : b ≠ natDegree p
⊢ (fun a b => coeff (C b * q ^ a) (natDegree p * natDegree q)) b (coeff p b) = 0

Next tactic:
refine' coeff_eq_zero_of_natDegree_lt (natDegree_mul_le.trans_lt _)
theorem coeff_comp_degree_mul_degree (hqd0 : natDegree q ≠ 0) :
    coeff (p.comp q) (natDegree p * natDegree q) =
    leadingCoeff p * leadingCoeff q ^ natDegree p := by
  rw [comp, eval₂_def, coeff_sum]
  -- Porting note: `convert` → `refine`
  refine Eq.trans (Finset.sum_eq_single p.natDegree ?h₀ ?h₁) ?h₂
  case h₂ =>
    simp only [coeff_natDegree, coeff_C_mul, coeff_pow_mul_natDegree]
  case h₀ =>
    intro b hbs hbp
    refine' coeff_eq_zero_of_natDegree_lt (natDegree_mul_le.trans_lt _)
    

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b✝ : R
m n : ℕ
inst✝ : Semiring R
p q r : R[X]
hqd0 : natDegree q ≠ 0
b : ℕ
hbs : b ∈ support p
hbp : b ≠ natDegree p
⊢ natDegree (C (coeff p b)) + natDegree (q ^ b) < natDegree p * natDegree q

Next tactic:
rw [natDegree_C, zero_add]
theorem coeff_comp_degree_mul_degree (hqd0 : natDegree q ≠ 0) :
    coeff (p.comp q) (natDegree p * natDegree q) =
    leadingCoeff p * leadingCoeff q ^ natDegree p := by
  rw [comp, eval₂_def, coeff_sum]
  -- Porting note: `convert` → `refine`
  refine Eq.trans (Finset.sum_eq_single p.natDegree ?h₀ ?h₁) ?h₂
  case h₂ =>
    simp only [coeff_natDegree, coeff_C_mul, coeff_pow_mul_natDegree]
  case h₀ =>
    intro b hbs hbp
    refine' coeff_eq_zero_of_natDegree_lt (natDegree_mul_le.trans_lt _)
    rw [natDegree_C, zero_add]
    

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b✝ : R
m n : ℕ
inst✝ : Semiring R
p q r : R[X]
hqd0 : natDegree q ≠ 0
b : ℕ
hbs : b ∈ support p
hbp : b ≠ natDegree p
⊢ natDegree (q ^ b) < natDegree p * natDegree q

Next tactic:
refine' natDegree_pow_le.trans_lt ((mul_lt_mul_right (pos_iff_ne_zero.mpr hqd0)).mpr _)
theorem coeff_comp_degree_mul_degree (hqd0 : natDegree q ≠ 0) :
    coeff (p.comp q) (natDegree p * natDegree q) =
    leadingCoeff p * leadingCoeff q ^ natDegree p := by
  rw [comp, eval₂_def, coeff_sum]
  -- Porting note: `convert` → `refine`
  refine Eq.trans (Finset.sum_eq_single p.natDegree ?h₀ ?h₁) ?h₂
  case h₂ =>
    simp only [coeff_natDegree, coeff_C_mul, coeff_pow_mul_natDegree]
  case h₀ =>
    intro b hbs hbp
    refine' coeff_eq_zero_of_natDegree_lt (natDegree_mul_le.trans_lt _)
    rw [natDegree_C, zero_add]
    refine' natDegree_pow_le.trans_lt ((mul_lt_mul_right (pos_iff_ne_zero.mpr hqd0)).mpr _)
    

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b✝ : R
m n : ℕ
inst✝ : Semiring R
p q r : R[X]
hqd0 : natDegree q ≠ 0
b : ℕ
hbs : b ∈ support p
hbp : b ≠ natDegree p
⊢ b < natDegree p

Next tactic:
exact lt_of_le_of_ne (le_natDegree_of_mem_supp _ hbs) hbp
theorem coeff_comp_degree_mul_degree (hqd0 : natDegree q ≠ 0) :
    coeff (p.comp q) (natDegree p * natDegree q) =
    leadingCoeff p * leadingCoeff q ^ natDegree p := by
  rw [comp, eval₂_def, coeff_sum]
  -- Porting note: `convert` → `refine`
  refine Eq.trans (Finset.sum_eq_single p.natDegree ?h₀ ?h₁) ?h₂
  case h₂ =>
    simp only [coeff_natDegree, coeff_C_mul, coeff_pow_mul_natDegree]
  case h₀ =>
    intro b hbs hbp
    refine' coeff_eq_zero_of_natDegree_lt (natDegree_mul_le.trans_lt _)
    rw [natDegree_C, zero_add]
    refine' natDegree_pow_le.trans_lt ((mul_lt_mul_right (pos_iff_ne_zero.mpr hqd0)).mpr _)
    exact lt_of_le_of_ne (le_natDegree_of_mem_supp _ hbs) hbp
  

Proof state:
case h₁
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝ : Semiring R
p q r : R[X]
hqd0 : natDegree q ≠ 0
⊢ natDegree p ∉ support p →
    (fun a b => coeff (C b * q ^ a) (natDegree p * natDegree q)) (natDegree p) (coeff p (natDegree p)) = 0

Next tactic:
case h₁ =>
    simp (config := { contextual := true })
theorem coeff_comp_degree_mul_degree (hqd0 : natDegree q ≠ 0) :
    coeff (p.comp q) (natDegree p * natDegree q) =
    leadingCoeff p * leadingCoeff q ^ natDegree p := by
  rw [comp, eval₂_def, coeff_sum]
  -- Porting note: `convert` → `refine`
  refine Eq.trans (Finset.sum_eq_single p.natDegree ?h₀ ?h₁) ?h₂
  case h₂ =>
    simp only [coeff_natDegree, coeff_C_mul, coeff_pow_mul_natDegree]
  case h₀ =>
    intro b hbs hbp
    refine' coeff_eq_zero_of_natDegree_lt (natDegree_mul_le.trans_lt _)
    rw [natDegree_C, zero_add]
    refine' natDegree_pow_le.trans_lt ((mul_lt_mul_right (pos_iff_ne_zero.mpr hqd0)).mpr _)
    exact lt_of_le_of_ne (le_natDegree_of_mem_supp _ hbs) hbp
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝ : Semiring R
p q r : R[X]
hqd0 : natDegree q ≠ 0
⊢ natDegree p ∉ support p →
    (fun a b => coeff (C b * q ^ a) (natDegree p * natDegree q)) (natDegree p) (coeff p (natDegree p)) = 0

Next tactic:
case h₁ =>
    simp (config := { contextual := true })
theorem coeff_comp_degree_mul_degree (hqd0 : natDegree q ≠ 0) :
    coeff (p.comp q) (natDegree p * natDegree q) =
    leadingCoeff p * leadingCoeff q ^ natDegree p := by
  rw [comp, eval₂_def, coeff_sum]
  -- Porting note: `convert` → `refine`
  refine Eq.trans (Finset.sum_eq_single p.natDegree ?h₀ ?h₁) ?h₂
  case h₂ =>
    simp only [coeff_natDegree, coeff_C_mul, coeff_pow_mul_natDegree]
  case h₀ =>
    intro b hbs hbp
    refine' coeff_eq_zero_of_natDegree_lt (natDegree_mul_le.trans_lt _)
    rw [natDegree_C, zero_add]
    refine' natDegree_pow_le.trans_lt ((mul_lt_mul_right (pos_iff_ne_zero.mpr hqd0)).mpr _)
    exact lt_of_le_of_ne (le_natDegree_of_mem_supp _ hbs) hbp
  case h₁ =>
    

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝ : Semiring R
p q r : R[X]
hqd0 : natDegree q ≠ 0
⊢ natDegree p ∉ support p →
    (fun a b => coeff (C b * q ^ a) (natDegree p * natDegree q)) (natDegree p) (coeff p (natDegree p)) = 0

Next tactic:
simp (config := { contextual := true })
@[simp]
theorem map_monomial {n a} : (monomial n a).map f = monomial n (f a) := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a✝ b : R
m n✝ : ℕ
inst✝¹ : Semiring R
p q r : R[X]
inst✝ : Semiring S
f : R →+* S
n : ℕ
a : R
⊢ map f ((monomial n) a) = (monomial n) (f a)

Next tactic:
dsimp only [map]
@[simp]
theorem map_monomial {n a} : (monomial n a).map f = monomial n (f a) := by
  dsimp only [map]
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a✝ b : R
m n✝ : ℕ
inst✝¹ : Semiring R
p q r : R[X]
inst✝ : Semiring S
f : R →+* S
n : ℕ
a : R
⊢ eval₂ (RingHom.comp C f) X ((monomial n) a) = (monomial n) (f a)

Next tactic:
rw [eval₂_monomial, ← C_mul_X_pow_eq_monomial]
@[simp]
theorem map_monomial {n a} : (monomial n a).map f = monomial n (f a) := by
  dsimp only [map]
  rw [eval₂_monomial, ← C_mul_X_pow_eq_monomial]; 

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a✝ b : R
m n✝ : ℕ
inst✝¹ : Semiring R
p q r : R[X]
inst✝ : Semiring S
f : R →+* S
n : ℕ
a : R
⊢ (RingHom.comp C f) a * X ^ n = C (f a) * X ^ n

Next tactic:
rfl
@[simp]
protected theorem map_mul : (p * q).map f = p.map f * q.map f := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q r : R[X]
inst✝ : Semiring S
f : R →+* S
⊢ map f (p * q) = map f p * map f q

Next tactic:
rw [map, eval₂_mul_noncomm]
@[simp]
protected theorem map_mul : (p * q).map f = p.map f * q.map f := by
  rw [map, eval₂_mul_noncomm]
  

Proof state:
case hf
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q r : R[X]
inst✝ : Semiring S
f : R →+* S
⊢ ∀ (k : ℕ), Commute ((RingHom.comp C f) (coeff q k)) X

Next tactic:
exact fun k => (commute_X _).symm
@[simp]
protected theorem map_smul (r : R) : (r • p).map f = f r • p.map f := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q r✝ : R[X]
inst✝ : Semiring S
f : R →+* S
r : R
⊢ map f (r • p) = f r • map f p

Next tactic:
rw [map, eval₂_smul, RingHom.comp_apply, C_mul']
@[simp]
protected theorem map_ofNat (n : ℕ) [n.AtLeastTwo] :
    (no_index (OfNat.ofNat n) : R[X]).map f = OfNat.ofNat n :=
  show (n : R[X]).map f = n by 

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n✝ : ℕ
inst✝² : Semiring R
p q r : R[X]
inst✝¹ : Semiring S
f : R →+* S
n : ℕ
inst✝ : Nat.AtLeastTwo n
⊢ map f ↑n = ↑n

Next tactic:
rw [Polynomial.map_nat_cast]
@[simp]
theorem coeff_map (n : ℕ) : coeff (p.map f) n = f (coeff p n) := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n✝ : ℕ
inst✝¹ : Semiring R
p q r : R[X]
inst✝ : Semiring S
f : R →+* S
n : ℕ
⊢ coeff (map f p) n = f (coeff p n)

Next tactic:
rw [map, eval₂_def, coeff_sum, sum]
@[simp]
theorem coeff_map (n : ℕ) : coeff (p.map f) n = f (coeff p n) := by
  rw [map, eval₂_def, coeff_sum, sum]
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n✝ : ℕ
inst✝¹ : Semiring R
p q r : R[X]
inst✝ : Semiring S
f : R →+* S
n : ℕ
⊢ ∑ n_1 in support p, coeff ((RingHom.comp C f) (coeff p n_1) * X ^ n_1) n = f (coeff p n)

Next tactic:
conv_rhs => rw [← sum_C_mul_X_pow_eq p, coeff_sum, sum, map_sum]
@[simp]
theorem coeff_map (n : ℕ) : coeff (p.map f) n = f (coeff p n) := by
  rw [map, eval₂_def, coeff_sum, sum]
  conv_rhs => 

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n✝ : ℕ
inst✝¹ : Semiring R
p q r : R[X]
inst✝ : Semiring S
f : R →+* S
n : ℕ
| f (coeff p n)

Next tactic:
rw [← sum_C_mul_X_pow_eq p, coeff_sum, sum, map_sum]
@[simp]
theorem coeff_map (n : ℕ) : coeff (p.map f) n = f (coeff p n) := by
  rw [map, eval₂_def, coeff_sum, sum]
  conv_rhs => rw [← sum_C_mul_X_pow_eq p, coeff_sum, sum, map_sum]
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n✝ : ℕ
inst✝¹ : Semiring R
p q r : R[X]
inst✝ : Semiring S
f : R →+* S
n : ℕ
⊢ ∑ n_1 in support p, coeff ((RingHom.comp C f) (coeff p n_1) * X ^ n_1) n =
    ∑ x in support p, f (coeff (C (coeff p x) * X ^ x) n)

Next tactic:
refine' Finset.sum_congr rfl fun x _hx => _
@[simp]
theorem coeff_map (n : ℕ) : coeff (p.map f) n = f (coeff p n) := by
  rw [map, eval₂_def, coeff_sum, sum]
  conv_rhs => rw [← sum_C_mul_X_pow_eq p, coeff_sum, sum, map_sum]
  refine' Finset.sum_congr rfl fun x _hx => _
  -- Porting note: Was `simp [Function.comp, coeff_C_mul_X_pow, f.map_mul]`.
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n✝ : ℕ
inst✝¹ : Semiring R
p q r : R[X]
inst✝ : Semiring S
f : R →+* S
n x : ℕ
_hx : x ∈ support p
⊢ coeff ((RingHom.comp C f) (coeff p x) * X ^ x) n = f (coeff (C (coeff p x) * X ^ x) n)

Next tactic:
simp? [Function.comp, coeff_C_mul_X_pow, - map_mul, - coeff_C_mul] says
    simp only [RingHom.coe_comp, Function.comp_apply, coeff_C_mul_X_pow]
@[simp]
theorem coeff_map (n : ℕ) : coeff (p.map f) n = f (coeff p n) := by
  rw [map, eval₂_def, coeff_sum, sum]
  conv_rhs => rw [← sum_C_mul_X_pow_eq p, coeff_sum, sum, map_sum]
  refine' Finset.sum_congr rfl fun x _hx => _
  -- Porting note: Was `simp [Function.comp, coeff_C_mul_X_pow, f.map_mul]`.
  simp? [Function.comp, coeff_C_mul_X_pow, - map_mul, - coeff_C_mul] says
    

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n✝ : ℕ
inst✝¹ : Semiring R
p q r : R[X]
inst✝ : Semiring S
f : R →+* S
n x : ℕ
_hx : x ∈ support p
⊢ coeff ((RingHom.comp C f) (coeff p x) * X ^ x) n = f (coeff (C (coeff p x) * X ^ x) n)

Next tactic:
simp only [RingHom.coe_comp, Function.comp_apply, coeff_C_mul_X_pow]
@[simp]
theorem coeff_map (n : ℕ) : coeff (p.map f) n = f (coeff p n) := by
  rw [map, eval₂_def, coeff_sum, sum]
  conv_rhs => rw [← sum_C_mul_X_pow_eq p, coeff_sum, sum, map_sum]
  refine' Finset.sum_congr rfl fun x _hx => _
  -- Porting note: Was `simp [Function.comp, coeff_C_mul_X_pow, f.map_mul]`.
  simp? [Function.comp, coeff_C_mul_X_pow, - map_mul, - coeff_C_mul] says
    simp only [RingHom.coe_comp, Function.comp_apply, coeff_C_mul_X_pow]
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n✝ : ℕ
inst✝¹ : Semiring R
p q r : R[X]
inst✝ : Semiring S
f : R →+* S
n x : ℕ
_hx : x ∈ support p
⊢ (if n = x then f (coeff p x) else 0) = f (if n = x then coeff p x else 0)

Next tactic:
split_ifs
@[simp]
theorem coeff_map (n : ℕ) : coeff (p.map f) n = f (coeff p n) := by
  rw [map, eval₂_def, coeff_sum, sum]
  conv_rhs => rw [← sum_C_mul_X_pow_eq p, coeff_sum, sum, map_sum]
  refine' Finset.sum_congr rfl fun x _hx => _
  -- Porting note: Was `simp [Function.comp, coeff_C_mul_X_pow, f.map_mul]`.
  simp? [Function.comp, coeff_C_mul_X_pow, - map_mul, - coeff_C_mul] says
    simp only [RingHom.coe_comp, Function.comp_apply, coeff_C_mul_X_pow]
  split_ifs <;> 

Proof state:
case pos
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n✝ : ℕ
inst✝¹ : Semiring R
p q r : R[X]
inst✝ : Semiring S
f : R →+* S
n x : ℕ
_hx : x ∈ support p
h✝ : n = x
⊢ f (coeff p x) = f (coeff p x)

Next tactic:
simp [f.map_zero]