l3lab/ntp-mathlib huggingface dataset:
@[simp] theorem isRegular_X : IsRegular (X : R[X]) := by
  suffices : IsLeftRegular (X : R[X])
  · exact ⟨this, this.right_of_commute commute_X⟩
  intro P Q (hPQ : X * P = X * Q)
  

Proof state:
case this
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p q r P Q : R[X]
hPQ : X * P = X * Q
⊢ P = Q

Next tactic:
ext i
@[simp] theorem isRegular_X : IsRegular (X : R[X]) := by
  suffices : IsLeftRegular (X : R[X])
  · exact ⟨this, this.right_of_commute commute_X⟩
  intro P Q (hPQ : X * P = X * Q)
  ext i
  

Proof state:
case this.a
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p q r P Q : R[X]
hPQ : X * P = X * Q
i : ℕ
⊢ coeff P i = coeff Q i

Next tactic:
rw [← coeff_X_mul P i, hPQ, coeff_X_mul Q i]
theorem coeff_X_add_C_pow (r : R) (n k : ℕ) :
    ((X + C r) ^ n).coeff k = r ^ (n - k) * (n.choose k : R) := by
  

Proof state:
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
n k : ℕ
⊢ coeff ((X + C r) ^ n) k = r ^ (n - k) * ↑(Nat.choose n k)

Next tactic:
rw [(commute_X (C r : R[X])).add_pow, ← lcoeff_apply, map_sum]
theorem coeff_X_add_C_pow (r : R) (n k : ℕ) :
    ((X + C r) ^ n).coeff k = r ^ (n - k) * (n.choose k : R) := by
  rw [(commute_X (C r : R[X])).add_pow, ← lcoeff_apply, map_sum]
  

Proof state:
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
n k : ℕ
⊢ ∑ x in range (n + 1), (lcoeff R k) (X ^ x * C r ^ (n - x) * ↑(Nat.choose n x)) = r ^ (n - k) * ↑(Nat.choose n k)

Next tactic:
simp only [one_pow, mul_one, lcoeff_apply, ← C_eq_nat_cast, ← C_pow, coeff_mul_C, Nat.cast_id]
theorem coeff_X_add_C_pow (r : R) (n k : ℕ) :
    ((X + C r) ^ n).coeff k = r ^ (n - k) * (n.choose k : R) := by
  rw [(commute_X (C r : R[X])).add_pow, ← lcoeff_apply, map_sum]
  simp only [one_pow, mul_one, lcoeff_apply, ← C_eq_nat_cast, ← C_pow, coeff_mul_C, Nat.cast_id]
  

Proof state:
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
n k : ℕ
⊢ ∑ x in range (n + 1), coeff (X ^ x) k * r ^ (n - x) * ↑(Nat.choose n x) = r ^ (n - k) * ↑(Nat.choose n k)

Next tactic:
rw [Finset.sum_eq_single k, coeff_X_pow_self, one_mul]
theorem coeff_X_add_C_pow (r : R) (n k : ℕ) :
    ((X + C r) ^ n).coeff k = r ^ (n - k) * (n.choose k : R) := by
  rw [(commute_X (C r : R[X])).add_pow, ← lcoeff_apply, map_sum]
  simp only [one_pow, mul_one, lcoeff_apply, ← C_eq_nat_cast, ← C_pow, coeff_mul_C, Nat.cast_id]
  rw [Finset.sum_eq_single k, coeff_X_pow_self, one_mul]
  · 

Proof state:
case h₀
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
n k : ℕ
⊢ ∀ b ∈ range (n + 1), b ≠ k → coeff (X ^ b) k * r ^ (n - b) * ↑(Nat.choose n b) = 0

Next tactic:
intro _ _ h
theorem coeff_X_add_C_pow (r : R) (n k : ℕ) :
    ((X + C r) ^ n).coeff k = r ^ (n - k) * (n.choose k : R) := by
  rw [(commute_X (C r : R[X])).add_pow, ← lcoeff_apply, map_sum]
  simp only [one_pow, mul_one, lcoeff_apply, ← C_eq_nat_cast, ← C_pow, coeff_mul_C, Nat.cast_id]
  rw [Finset.sum_eq_single k, coeff_X_pow_self, one_mul]
  · intro _ _ h
    

Proof state:
case h₀
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
n k b✝ : ℕ
a✝ : b✝ ∈ range (n + 1)
h : b✝ ≠ k
⊢ coeff (X ^ b✝) k * r ^ (n - b✝) * ↑(Nat.choose n b✝) = 0

Next tactic:
simp [coeff_X_pow, h.symm]
theorem coeff_X_add_C_pow (r : R) (n k : ℕ) :
    ((X + C r) ^ n).coeff k = r ^ (n - k) * (n.choose k : R) := by
  rw [(commute_X (C r : R[X])).add_pow, ← lcoeff_apply, map_sum]
  simp only [one_pow, mul_one, lcoeff_apply, ← C_eq_nat_cast, ← C_pow, coeff_mul_C, Nat.cast_id]
  rw [Finset.sum_eq_single k, coeff_X_pow_self, one_mul]
  · intro _ _ h
    simp [coeff_X_pow, h.symm]
  · 

Proof state:
case h₁
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
n k : ℕ
⊢ k ∉ range (n + 1) → coeff (X ^ k) k * r ^ (n - k) * ↑(Nat.choose n k) = 0

Next tactic:
simp only [coeff_X_pow_self, one_mul, not_lt, Finset.mem_range]
theorem coeff_X_add_C_pow (r : R) (n k : ℕ) :
    ((X + C r) ^ n).coeff k = r ^ (n - k) * (n.choose k : R) := by
  rw [(commute_X (C r : R[X])).add_pow, ← lcoeff_apply, map_sum]
  simp only [one_pow, mul_one, lcoeff_apply, ← C_eq_nat_cast, ← C_pow, coeff_mul_C, Nat.cast_id]
  rw [Finset.sum_eq_single k, coeff_X_pow_self, one_mul]
  · intro _ _ h
    simp [coeff_X_pow, h.symm]
  · simp only [coeff_X_pow_self, one_mul, not_lt, Finset.mem_range]
    

Proof state:
case h₁
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
n k : ℕ
⊢ n + 1 ≤ k → r ^ (n - k) * ↑(Nat.choose n k) = 0

Next tactic:
intro h
theorem coeff_X_add_C_pow (r : R) (n k : ℕ) :
    ((X + C r) ^ n).coeff k = r ^ (n - k) * (n.choose k : R) := by
  rw [(commute_X (C r : R[X])).add_pow, ← lcoeff_apply, map_sum]
  simp only [one_pow, mul_one, lcoeff_apply, ← C_eq_nat_cast, ← C_pow, coeff_mul_C, Nat.cast_id]
  rw [Finset.sum_eq_single k, coeff_X_pow_self, one_mul]
  · intro _ _ h
    simp [coeff_X_pow, h.symm]
  · simp only [coeff_X_pow_self, one_mul, not_lt, Finset.mem_range]
    intro h
    

Proof state:
case h₁
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
n k : ℕ
h : n + 1 ≤ k
⊢ r ^ (n - k) * ↑(Nat.choose n k) = 0

Next tactic:
rw [Nat.choose_eq_zero_of_lt h, Nat.cast_zero, mul_zero]
theorem coeff_X_add_one_pow (R : Type*) [Semiring R] (n k : ℕ) :
    ((X + 1) ^ n).coeff k = (n.choose k : R) := by 

Proof state:
R✝ : Type u
S : Type v
a b : R✝
n✝ m : ℕ
inst✝¹ : Semiring R✝
p q r : R✝[X]
R : Type u_1
inst✝ : Semiring R
n k : ℕ
⊢ coeff ((X + 1) ^ n) k = ↑(Nat.choose n k)

Next tactic:
rw [← C_1, coeff_X_add_C_pow, one_pow, one_mul]
theorem coeff_one_add_X_pow (R : Type*) [Semiring R] (n k : ℕ) :
    ((1 + X) ^ n).coeff k = (n.choose k : R) := by 

Proof state:
R✝ : Type u
S : Type v
a b : R✝
n✝ m : ℕ
inst✝¹ : Semiring R✝
p q r : R✝[X]
R : Type u_1
inst✝ : Semiring R
n k : ℕ
⊢ coeff ((1 + X) ^ n) k = ↑(Nat.choose n k)

Next tactic:
rw [add_comm _ X, coeff_X_add_one_pow]
theorem C_dvd_iff_dvd_coeff (r : R) (φ : R[X]) : C r ∣ φ ↔ ∀ i, r ∣ φ.coeff i := by
  

Proof state:
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
φ : R[X]
⊢ C r ∣ φ ↔ ∀ (i : ℕ), r ∣ coeff φ i

Next tactic:
constructor
theorem C_dvd_iff_dvd_coeff (r : R) (φ : R[X]) : C r ∣ φ ↔ ∀ i, r ∣ φ.coeff i := by
  constructor
  · 

Proof state:
case mp
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
φ : R[X]
⊢ C r ∣ φ → ∀ (i : ℕ), r ∣ coeff φ i

Next tactic:
rintro ⟨φ, rfl⟩ c
theorem C_dvd_iff_dvd_coeff (r : R) (φ : R[X]) : C r ∣ φ ↔ ∀ i, r ∣ φ.coeff i := by
  constructor
  · rintro ⟨φ, rfl⟩ c
    

Proof state:
case mp.intro
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
φ : R[X]
c : ℕ
⊢ r ∣ coeff (C r * φ) c

Next tactic:
rw [coeff_C_mul]
theorem C_dvd_iff_dvd_coeff (r : R) (φ : R[X]) : C r ∣ φ ↔ ∀ i, r ∣ φ.coeff i := by
  constructor
  · rintro ⟨φ, rfl⟩ c
    rw [coeff_C_mul]
    

Proof state:
case mp.intro
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
φ : R[X]
c : ℕ
⊢ r ∣ r * coeff φ c

Next tactic:
apply dvd_mul_right
theorem C_dvd_iff_dvd_coeff (r : R) (φ : R[X]) : C r ∣ φ ↔ ∀ i, r ∣ φ.coeff i := by
  constructor
  · rintro ⟨φ, rfl⟩ c
    rw [coeff_C_mul]
    apply dvd_mul_right
  · 

Proof state:
case mpr
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
φ : R[X]
⊢ (∀ (i : ℕ), r ∣ coeff φ i) → C r ∣ φ

Next tactic:
intro h
theorem C_dvd_iff_dvd_coeff (r : R) (φ : R[X]) : C r ∣ φ ↔ ∀ i, r ∣ φ.coeff i := by
  constructor
  · rintro ⟨φ, rfl⟩ c
    rw [coeff_C_mul]
    apply dvd_mul_right
  · intro h
    

Proof state:
case mpr
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
φ : R[X]
h : ∀ (i : ℕ), r ∣ coeff φ i
⊢ C r ∣ φ

Next tactic:
choose c hc using h
theorem C_dvd_iff_dvd_coeff (r : R) (φ : R[X]) : C r ∣ φ ↔ ∀ i, r ∣ φ.coeff i := by
  constructor
  · rintro ⟨φ, rfl⟩ c
    rw [coeff_C_mul]
    apply dvd_mul_right
  · intro h
    choose c hc using h
    

Proof state:
case mpr
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
φ : R[X]
c : ℕ → R
hc : ∀ (i : ℕ), coeff φ i = r * c i
⊢ C r ∣ φ

Next tactic:
classical
      let c' : ℕ → R := fun i => if i ∈ φ.support then c i else 0
      let ψ : R[X] := ∑ i in φ.support, monomial i (c' i)
      use ψ
      ext i
      simp only [coeff_C_mul, mem_support_iff, coeff_monomial, finset_sum_coeff,
        Finset.sum_ite_eq']
      split_ifs with hi
      · rw [hc]
      · rw [Classical.not_not] at hi
        rwa [mul_zero]
theorem C_dvd_iff_dvd_coeff (r : R) (φ : R[X]) : C r ∣ φ ↔ ∀ i, r ∣ φ.coeff i := by
  constructor
  · rintro ⟨φ, rfl⟩ c
    rw [coeff_C_mul]
    apply dvd_mul_right
  · intro h
    choose c hc using h
    classical
      

Proof state:
case mpr
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
φ : R[X]
c : ℕ → R
hc : ∀ (i : ℕ), coeff φ i = r * c i
⊢ C r ∣ φ

Next tactic:
let c' : ℕ → R := fun i => if i ∈ φ.support then c i else 0
theorem C_dvd_iff_dvd_coeff (r : R) (φ : R[X]) : C r ∣ φ ↔ ∀ i, r ∣ φ.coeff i := by
  constructor
  · rintro ⟨φ, rfl⟩ c
    rw [coeff_C_mul]
    apply dvd_mul_right
  · intro h
    choose c hc using h
    classical
      let c' : ℕ → R := fun i => if i ∈ φ.support then c i else 0
      

Proof state:
case mpr
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
φ : R[X]
c : ℕ → R
hc : ∀ (i : ℕ), coeff φ i = r * c i
c' : ℕ → R := fun i => if i ∈ support φ then c i else 0
⊢ C r ∣ φ

Next tactic:
let ψ : R[X] := ∑ i in φ.support, monomial i (c' i)
theorem C_dvd_iff_dvd_coeff (r : R) (φ : R[X]) : C r ∣ φ ↔ ∀ i, r ∣ φ.coeff i := by
  constructor
  · rintro ⟨φ, rfl⟩ c
    rw [coeff_C_mul]
    apply dvd_mul_right
  · intro h
    choose c hc using h
    classical
      let c' : ℕ → R := fun i => if i ∈ φ.support then c i else 0
      let ψ : R[X] := ∑ i in φ.support, monomial i (c' i)
      

Proof state:
case mpr
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
φ : R[X]
c : ℕ → R
hc : ∀ (i : ℕ), coeff φ i = r * c i
c' : ℕ → R := fun i => if i ∈ support φ then c i else 0
ψ : R[X] := ∑ i in support φ, (monomial i) (c' i)
⊢ C r ∣ φ

Next tactic:
use ψ
theorem C_dvd_iff_dvd_coeff (r : R) (φ : R[X]) : C r ∣ φ ↔ ∀ i, r ∣ φ.coeff i := by
  constructor
  · rintro ⟨φ, rfl⟩ c
    rw [coeff_C_mul]
    apply dvd_mul_right
  · intro h
    choose c hc using h
    classical
      let c' : ℕ → R := fun i => if i ∈ φ.support then c i else 0
      let ψ : R[X] := ∑ i in φ.support, monomial i (c' i)
      use ψ
      

Proof state:
case h
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
φ : R[X]
c : ℕ → R
hc : ∀ (i : ℕ), coeff φ i = r * c i
c' : ℕ → R := fun i => if i ∈ support φ then c i else 0
ψ : R[X] := ∑ i in support φ, (monomial i) (c' i)
⊢ φ = C r * ψ

Next tactic:
ext i
theorem C_dvd_iff_dvd_coeff (r : R) (φ : R[X]) : C r ∣ φ ↔ ∀ i, r ∣ φ.coeff i := by
  constructor
  · rintro ⟨φ, rfl⟩ c
    rw [coeff_C_mul]
    apply dvd_mul_right
  · intro h
    choose c hc using h
    classical
      let c' : ℕ → R := fun i => if i ∈ φ.support then c i else 0
      let ψ : R[X] := ∑ i in φ.support, monomial i (c' i)
      use ψ
      ext i
      

Proof state:
case h.a
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
φ : R[X]
c : ℕ → R
hc : ∀ (i : ℕ), coeff φ i = r * c i
c' : ℕ → R := fun i => if i ∈ support φ then c i else 0
ψ : R[X] := ∑ i in support φ, (monomial i) (c' i)
i : ℕ
⊢ coeff φ i = coeff (C r * ψ) i

Next tactic:
simp only [coeff_C_mul, mem_support_iff, coeff_monomial, finset_sum_coeff,
        Finset.sum_ite_eq']
theorem C_dvd_iff_dvd_coeff (r : R) (φ : R[X]) : C r ∣ φ ↔ ∀ i, r ∣ φ.coeff i := by
  constructor
  · rintro ⟨φ, rfl⟩ c
    rw [coeff_C_mul]
    apply dvd_mul_right
  · intro h
    choose c hc using h
    classical
      let c' : ℕ → R := fun i => if i ∈ φ.support then c i else 0
      let ψ : R[X] := ∑ i in φ.support, monomial i (c' i)
      use ψ
      ext i
      simp only [coeff_C_mul, mem_support_iff, coeff_monomial, finset_sum_coeff,
        Finset.sum_ite_eq']
      

Proof state:
case h.a
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
φ : R[X]
c : ℕ → R
hc : ∀ (i : ℕ), coeff φ i = r * c i
c' : ℕ → R := fun i => if i ∈ support φ then c i else 0
ψ : R[X] := ∑ i in support φ, (monomial i) (c' i)
i : ℕ
⊢ coeff φ i = r * if coeff φ i ≠ 0 then if coeff φ i ≠ 0 then c i else 0 else 0

Next tactic:
split_ifs with hi
theorem C_dvd_iff_dvd_coeff (r : R) (φ : R[X]) : C r ∣ φ ↔ ∀ i, r ∣ φ.coeff i := by
  constructor
  · rintro ⟨φ, rfl⟩ c
    rw [coeff_C_mul]
    apply dvd_mul_right
  · intro h
    choose c hc using h
    classical
      let c' : ℕ → R := fun i => if i ∈ φ.support then c i else 0
      let ψ : R[X] := ∑ i in φ.support, monomial i (c' i)
      use ψ
      ext i
      simp only [coeff_C_mul, mem_support_iff, coeff_monomial, finset_sum_coeff,
        Finset.sum_ite_eq']
      split_ifs with hi
      · 

Proof state:
case pos
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
φ : R[X]
c : ℕ → R
hc : ∀ (i : ℕ), coeff φ i = r * c i
c' : ℕ → R := fun i => if i ∈ support φ then c i else 0
ψ : R[X] := ∑ i in support φ, (monomial i) (c' i)
i : ℕ
hi : coeff φ i ≠ 0
⊢ coeff φ i = r * c i

Next tactic:
rw [hc]
theorem C_dvd_iff_dvd_coeff (r : R) (φ : R[X]) : C r ∣ φ ↔ ∀ i, r ∣ φ.coeff i := by
  constructor
  · rintro ⟨φ, rfl⟩ c
    rw [coeff_C_mul]
    apply dvd_mul_right
  · intro h
    choose c hc using h
    classical
      let c' : ℕ → R := fun i => if i ∈ φ.support then c i else 0
      let ψ : R[X] := ∑ i in φ.support, monomial i (c' i)
      use ψ
      ext i
      simp only [coeff_C_mul, mem_support_iff, coeff_monomial, finset_sum_coeff,
        Finset.sum_ite_eq']
      split_ifs with hi
      · rw [hc]
      · 

Proof state:
case neg
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
φ : R[X]
c : ℕ → R
hc : ∀ (i : ℕ), coeff φ i = r * c i
c' : ℕ → R := fun i => if i ∈ support φ then c i else 0
ψ : R[X] := ∑ i in support φ, (monomial i) (c' i)
i : ℕ
hi : ¬coeff φ i ≠ 0
⊢ coeff φ i = r * 0

Next tactic:
rw [Classical.not_not] at hi
theorem C_dvd_iff_dvd_coeff (r : R) (φ : R[X]) : C r ∣ φ ↔ ∀ i, r ∣ φ.coeff i := by
  constructor
  · rintro ⟨φ, rfl⟩ c
    rw [coeff_C_mul]
    apply dvd_mul_right
  · intro h
    choose c hc using h
    classical
      let c' : ℕ → R := fun i => if i ∈ φ.support then c i else 0
      let ψ : R[X] := ∑ i in φ.support, monomial i (c' i)
      use ψ
      ext i
      simp only [coeff_C_mul, mem_support_iff, coeff_monomial, finset_sum_coeff,
        Finset.sum_ite_eq']
      split_ifs with hi
      · rw [hc]
      · rw [Classical.not_not] at hi
        

Proof state:
case neg
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p q r✝ : R[X]
r : R
φ : R[X]
c : ℕ → R
hc : ∀ (i : ℕ), coeff φ i = r * c i
c' : ℕ → R := fun i => if i ∈ support φ then c i else 0
ψ : R[X] := ∑ i in support φ, (monomial i) (c' i)
i : ℕ
hi : coeff φ i = 0
⊢ coeff φ i = r * 0

Next tactic:
rwa [mul_zero]
set_option linter.deprecated false in
theorem coeff_bit0_mul (P Q : R[X]) (n : ℕ) : coeff (bit0 P * Q) n = 2 * coeff (P * Q) n := by
  -- Porting note: `two_mul` is required.
  

Proof state:
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p q r P Q : R[X]
n : ℕ
⊢ coeff (bit0 P * Q) n = 2 * coeff (P * Q) n

Next tactic:
simp [bit0, add_mul, two_mul]
set_option linter.deprecated false in
theorem coeff_bit1_mul (P Q : R[X]) (n : ℕ) :
    coeff (bit1 P * Q) n = 2 * coeff (P * Q) n + coeff Q n := by
  

Proof state:
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p q r P Q : R[X]
n : ℕ
⊢ coeff (bit1 P * Q) n = 2 * coeff (P * Q) n + coeff Q n

Next tactic:
simp [bit1, add_mul, coeff_bit0_mul]
theorem smul_eq_C_mul (a : R) : a • p = C a * p := by 

Proof state:
R : Type u
S : Type v
a✝ b : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
a : R
⊢ a • p = C a * p

Next tactic:
simp [ext_iff]
theorem update_eq_add_sub_coeff {R : Type*} [Ring R] (p : R[X]) (n : ℕ) (a : R) :
    p.update n a = p + Polynomial.C (a - p.coeff n) * Polynomial.X ^ n := by
  

Proof state:
R✝ : Type u
S : Type v
a✝ b : R✝
n✝ m : ℕ
inst✝¹ : Semiring R✝
p✝ q r : R✝[X]
R : Type u_1
inst✝ : Ring R
p : R[X]
n : ℕ
a : R
⊢ update p n a = p + C (a - coeff p n) * X ^ n

Next tactic:
ext
theorem update_eq_add_sub_coeff {R : Type*} [Ring R] (p : R[X]) (n : ℕ) (a : R) :
    p.update n a = p + Polynomial.C (a - p.coeff n) * Polynomial.X ^ n := by
  ext
  

Proof state:
case a
R✝ : Type u
S : Type v
a✝ b : R✝
n✝¹ m : ℕ
inst✝¹ : Semiring R✝
p✝ q r : R✝[X]
R : Type u_1
inst✝ : Ring R
p : R[X]
n : ℕ
a : R
n✝ : ℕ
⊢ coeff (update p n a) n✝ = coeff (p + C (a - coeff p n) * X ^ n) n✝

Next tactic:
rw [coeff_update_apply, coeff_add, coeff_C_mul_X_pow]
theorem update_eq_add_sub_coeff {R : Type*} [Ring R] (p : R[X]) (n : ℕ) (a : R) :
    p.update n a = p + Polynomial.C (a - p.coeff n) * Polynomial.X ^ n := by
  ext
  rw [coeff_update_apply, coeff_add, coeff_C_mul_X_pow]
  

Proof state:
case a
R✝ : Type u
S : Type v
a✝ b : R✝
n✝¹ m : ℕ
inst✝¹ : Semiring R✝
p✝ q r : R✝[X]
R : Type u_1
inst✝ : Ring R
p : R[X]
n : ℕ
a : R
n✝ : ℕ
⊢ (if n✝ = n then a else coeff p n✝) = coeff p n✝ + if n✝ = n then a - coeff p n else 0

Next tactic:
split_ifs with h
theorem update_eq_add_sub_coeff {R : Type*} [Ring R] (p : R[X]) (n : ℕ) (a : R) :
    p.update n a = p + Polynomial.C (a - p.coeff n) * Polynomial.X ^ n := by
  ext
  rw [coeff_update_apply, coeff_add, coeff_C_mul_X_pow]
  split_ifs with h <;> 

Proof state:
case pos
R✝ : Type u
S : Type v
a✝ b : R✝
n✝¹ m : ℕ
inst✝¹ : Semiring R✝
p✝ q r : R✝[X]
R : Type u_1
inst✝ : Ring R
p : R[X]
n : ℕ
a : R
n✝ : ℕ
h : n✝ = n
⊢ a = coeff p n✝ + (a - coeff p n)

Next tactic:
simp [h]
theorem update_eq_add_sub_coeff {R : Type*} [Ring R] (p : R[X]) (n : ℕ) (a : R) :
    p.update n a = p + Polynomial.C (a - p.coeff n) * Polynomial.X ^ n := by
  ext
  rw [coeff_update_apply, coeff_add, coeff_C_mul_X_pow]
  split_ifs with h <;> 

Proof state:
case neg
R✝ : Type u
S : Type v
a✝ b : R✝
n✝¹ m : ℕ
inst✝¹ : Semiring R✝
p✝ q r : R✝[X]
R : Type u_1
inst✝ : Ring R
p : R[X]
n : ℕ
a : R
n✝ : ℕ
h : ¬n✝ = n
⊢ coeff p n✝ = coeff p n✝ + 0

Next tactic:
simp [h]
theorem nat_cast_coeff_zero {n : ℕ} {R : Type*} [Semiring R] : (n : R[X]).coeff 0 = n := by
  

Proof state:
R✝ : Type u
S : Type v
a b : R✝
n✝ m : ℕ
inst✝¹ : Semiring R✝
p q r : R✝[X]
n : ℕ
R : Type u_1
inst✝ : Semiring R
⊢ coeff (↑n) 0 = ↑n

Next tactic:
simp only [coeff_nat_cast_ite, ite_true]
@[norm_cast] -- @[simp] -- Porting note: simp can prove this
theorem nat_cast_inj {m n : ℕ} {R : Type*} [Semiring R] [CharZero R] :
    (↑m : R[X]) = ↑n ↔ m = n := by
  

Proof state:
R✝ : Type u
S : Type v
a b : R✝
n✝ m✝ : ℕ
inst✝² : Semiring R✝
p q r : R✝[X]
m n : ℕ
R : Type u_1
inst✝¹ : Semiring R
inst✝ : CharZero R
⊢ ↑m = ↑n ↔ m = n

Next tactic:
constructor
@[norm_cast] -- @[simp] -- Porting note: simp can prove this
theorem nat_cast_inj {m n : ℕ} {R : Type*} [Semiring R] [CharZero R] :
    (↑m : R[X]) = ↑n ↔ m = n := by
  constructor
  · 

Proof state:
case mp
R✝ : Type u
S : Type v
a b : R✝
n✝ m✝ : ℕ
inst✝² : Semiring R✝
p q r : R✝[X]
m n : ℕ
R : Type u_1
inst✝¹ : Semiring R
inst✝ : CharZero R
⊢ ↑m = ↑n → m = n

Next tactic:
intro h
@[norm_cast] -- @[simp] -- Porting note: simp can prove this
theorem nat_cast_inj {m n : ℕ} {R : Type*} [Semiring R] [CharZero R] :
    (↑m : R[X]) = ↑n ↔ m = n := by
  constructor
  · intro h
    

Proof state:
case mp
R✝ : Type u
S : Type v
a b : R✝
n✝ m✝ : ℕ
inst✝² : Semiring R✝
p q r : R✝[X]
m n : ℕ
R : Type u_1
inst✝¹ : Semiring R
inst✝ : CharZero R
h : ↑m = ↑n
⊢ m = n

Next tactic:
apply_fun fun p => p.coeff 0 at h
@[norm_cast] -- @[simp] -- Porting note: simp can prove this
theorem nat_cast_inj {m n : ℕ} {R : Type*} [Semiring R] [CharZero R] :
    (↑m : R[X]) = ↑n ↔ m = n := by
  constructor
  · intro h
    apply_fun fun p => p.coeff 0 at h
    

Proof state:
case mp
R✝ : Type u
S : Type v
a b : R✝
n✝ m✝ : ℕ
inst✝² : Semiring R✝
p q r : R✝[X]
m n : ℕ
R : Type u_1
inst✝¹ : Semiring R
inst✝ : CharZero R
h : coeff (↑m) 0 = coeff (↑n) 0
⊢ m = n

Next tactic:
simpa using h
@[norm_cast] -- @[simp] -- Porting note: simp can prove this
theorem nat_cast_inj {m n : ℕ} {R : Type*} [Semiring R] [CharZero R] :
    (↑m : R[X]) = ↑n ↔ m = n := by
  constructor
  · intro h
    apply_fun fun p => p.coeff 0 at h
    simpa using h
  · 

Proof state:
case mpr
R✝ : Type u
S : Type v
a b : R✝
n✝ m✝ : ℕ
inst✝² : Semiring R✝
p q r : R✝[X]
m n : ℕ
R : Type u_1
inst✝¹ : Semiring R
inst✝ : CharZero R
⊢ m = n → ↑m = ↑n

Next tactic:
rintro rfl
@[norm_cast] -- @[simp] -- Porting note: simp can prove this
theorem nat_cast_inj {m n : ℕ} {R : Type*} [Semiring R] [CharZero R] :
    (↑m : R[X]) = ↑n ↔ m = n := by
  constructor
  · intro h
    apply_fun fun p => p.coeff 0 at h
    simpa using h
  · rintro rfl
    

Proof state:
case mpr
R✝ : Type u
S : Type v
a b : R✝
n m✝ : ℕ
inst✝² : Semiring R✝
p q r : R✝[X]
m : ℕ
R : Type u_1
inst✝¹ : Semiring R
inst✝ : CharZero R
⊢ ↑m = ↑m

Next tactic:
rfl
@[simp]
theorem int_cast_coeff_zero {i : ℤ} {R : Type*} [Ring R] : (i : R[X]).coeff 0 = i := by
  

Proof state:
R✝ : Type u
S : Type v
a b : R✝
n m : ℕ
inst✝¹ : Semiring R✝
p q r : R✝[X]
i : ℤ
R : Type u_1
inst✝ : Ring R
⊢ coeff (↑i) 0 = ↑i

Next tactic:
cases i
@[simp]
theorem int_cast_coeff_zero {i : ℤ} {R : Type*} [Ring R] : (i : R[X]).coeff 0 = i := by
  cases i <;> 

Proof state:
case ofNat
R✝ : Type u
S : Type v
a b : R✝
n m : ℕ
inst✝¹ : Semiring R✝
p q r : R✝[X]
R : Type u_1
inst✝ : Ring R
a✝ : ℕ
⊢ coeff (↑(Int.ofNat a✝)) 0 = ↑(Int.ofNat a✝)

Next tactic:
simp
@[simp]
theorem int_cast_coeff_zero {i : ℤ} {R : Type*} [Ring R] : (i : R[X]).coeff 0 = i := by
  cases i <;> 

Proof state:
case negSucc
R✝ : Type u
S : Type v
a b : R✝
n m : ℕ
inst✝¹ : Semiring R✝
p q r : R✝[X]
R : Type u_1
inst✝ : Ring R
a✝ : ℕ
⊢ coeff (↑(Int.negSucc a✝)) 0 = ↑(Int.negSucc a✝)

Next tactic:
simp
@[norm_cast] -- @[simp] -- Porting note: simp can prove this
theorem int_cast_inj {m n : ℤ} {R : Type*} [Ring R] [CharZero R] : (↑m : R[X]) = ↑n ↔ m = n := by
  

Proof state:
R✝ : Type u
S : Type v
a b : R✝
n✝ m✝ : ℕ
inst✝² : Semiring R✝
p q r : R✝[X]
m n : ℤ
R : Type u_1
inst✝¹ : Ring R
inst✝ : CharZero R
⊢ ↑m = ↑n ↔ m = n

Next tactic:
constructor
@[norm_cast] -- @[simp] -- Porting note: simp can prove this
theorem int_cast_inj {m n : ℤ} {R : Type*} [Ring R] [CharZero R] : (↑m : R[X]) = ↑n ↔ m = n := by
  constructor
  · 

Proof state:
case mp
R✝ : Type u
S : Type v
a b : R✝
n✝ m✝ : ℕ
inst✝² : Semiring R✝
p q r : R✝[X]
m n : ℤ
R : Type u_1
inst✝¹ : Ring R
inst✝ : CharZero R
⊢ ↑m = ↑n → m = n

Next tactic:
intro h
@[norm_cast] -- @[simp] -- Porting note: simp can prove this
theorem int_cast_inj {m n : ℤ} {R : Type*} [Ring R] [CharZero R] : (↑m : R[X]) = ↑n ↔ m = n := by
  constructor
  · intro h
    

Proof state:
case mp
R✝ : Type u
S : Type v
a b : R✝
n✝ m✝ : ℕ
inst✝² : Semiring R✝
p q r : R✝[X]
m n : ℤ
R : Type u_1
inst✝¹ : Ring R
inst✝ : CharZero R
h : ↑m = ↑n
⊢ m = n

Next tactic:
apply_fun fun p => p.coeff 0 at h
@[norm_cast] -- @[simp] -- Porting note: simp can prove this
theorem int_cast_inj {m n : ℤ} {R : Type*} [Ring R] [CharZero R] : (↑m : R[X]) = ↑n ↔ m = n := by
  constructor
  · intro h
    apply_fun fun p => p.coeff 0 at h
    

Proof state:
case mp
R✝ : Type u
S : Type v
a b : R✝
n✝ m✝ : ℕ
inst✝² : Semiring R✝
p q r : R✝[X]
m n : ℤ
R : Type u_1
inst✝¹ : Ring R
inst✝ : CharZero R
h : coeff (↑m) 0 = coeff (↑n) 0
⊢ m = n

Next tactic:
simpa using h
@[norm_cast] -- @[simp] -- Porting note: simp can prove this
theorem int_cast_inj {m n : ℤ} {R : Type*} [Ring R] [CharZero R] : (↑m : R[X]) = ↑n ↔ m = n := by
  constructor
  · intro h
    apply_fun fun p => p.coeff 0 at h
    simpa using h
  · 

Proof state:
case mpr
R✝ : Type u
S : Type v
a b : R✝
n✝ m✝ : ℕ
inst✝² : Semiring R✝
p q r : R✝[X]
m n : ℤ
R : Type u_1
inst✝¹ : Ring R
inst✝ : CharZero R
⊢ m = n → ↑m = ↑n

Next tactic:
rintro rfl