l3lab/ntp-mathlib huggingface dataset:
theorem scaleRoots_ne_zero {p : R[X]} (hp : p ≠ 0) (s : R) : scaleRoots p s ≠ 0 := by
  intro h
  have : p.coeff p.natDegree ≠ 0 := mt leadingCoeff_eq_zero.mp hp
  have : (scaleRoots p s).coeff p.natDegree = 0 :=
    congr_fun (congr_arg (coeff : R[X] → ℕ → R) h) p.natDegree
  

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
hp : p ≠ 0
s : R
h : scaleRoots p s = 0
this✝ : coeff p (natDegree p) ≠ 0
this : coeff (scaleRoots p s) (natDegree p) = 0
⊢ False

Next tactic:
rw [coeff_scaleRoots_natDegree] at this
theorem scaleRoots_ne_zero {p : R[X]} (hp : p ≠ 0) (s : R) : scaleRoots p s ≠ 0 := by
  intro h
  have : p.coeff p.natDegree ≠ 0 := mt leadingCoeff_eq_zero.mp hp
  have : (scaleRoots p s).coeff p.natDegree = 0 :=
    congr_fun (congr_arg (coeff : R[X] → ℕ → R) h) p.natDegree
  rw [coeff_scaleRoots_natDegree] at this
  

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
hp : p ≠ 0
s : R
h : scaleRoots p s = 0
this✝ : coeff p (natDegree p) ≠ 0
this : leadingCoeff p = 0
⊢ False

Next tactic:
contradiction
theorem support_scaleRoots_le (p : R[X]) (s : R) : (scaleRoots p s).support ≤ p.support := by
  

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
s : R
⊢ support (scaleRoots p s) ≤ support p

Next tactic:
intro
theorem support_scaleRoots_le (p : R[X]) (s : R) : (scaleRoots p s).support ≤ p.support := by
  intro
  

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
s : R
a✝ : ℕ
⊢ a✝ ∈ support (scaleRoots p s) → a✝ ∈ support p

Next tactic:
simpa using left_ne_zero_of_mul
theorem support_scaleRoots_eq (p : R[X]) {s : R} (hs : s ∈ nonZeroDivisors R) :
    (scaleRoots p s).support = p.support :=
  le_antisymm (support_scaleRoots_le p s)
    (by 

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
s : R
hs : s ∈ nonZeroDivisors R
⊢ support p ≤ support (scaleRoots p s)

Next tactic:
intro i
theorem support_scaleRoots_eq (p : R[X]) {s : R} (hs : s ∈ nonZeroDivisors R) :
    (scaleRoots p s).support = p.support :=
  le_antisymm (support_scaleRoots_le p s)
    (by intro i
        

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
s : R
hs : s ∈ nonZeroDivisors R
i : ℕ
⊢ i ∈ support p → i ∈ support (scaleRoots p s)

Next tactic:
simp only [coeff_scaleRoots, Polynomial.mem_support_iff]
theorem support_scaleRoots_eq (p : R[X]) {s : R} (hs : s ∈ nonZeroDivisors R) :
    (scaleRoots p s).support = p.support :=
  le_antisymm (support_scaleRoots_le p s)
    (by intro i
        simp only [coeff_scaleRoots, Polynomial.mem_support_iff]
        

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
s : R
hs : s ∈ nonZeroDivisors R
i : ℕ
⊢ coeff p i ≠ 0 → coeff p i * s ^ (natDegree p - i) ≠ 0

Next tactic:
intro p_ne_zero ps_zero
theorem support_scaleRoots_eq (p : R[X]) {s : R} (hs : s ∈ nonZeroDivisors R) :
    (scaleRoots p s).support = p.support :=
  le_antisymm (support_scaleRoots_le p s)
    (by intro i
        simp only [coeff_scaleRoots, Polynomial.mem_support_iff]
        intro p_ne_zero ps_zero
        

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
s : R
hs : s ∈ nonZeroDivisors R
i : ℕ
p_ne_zero : coeff p i ≠ 0
ps_zero : coeff p i * s ^ (natDegree p - i) = 0
⊢ False

Next tactic:
have := pow_mem hs (p.natDegree - i) _ ps_zero
theorem support_scaleRoots_eq (p : R[X]) {s : R} (hs : s ∈ nonZeroDivisors R) :
    (scaleRoots p s).support = p.support :=
  le_antisymm (support_scaleRoots_le p s)
    (by intro i
        simp only [coeff_scaleRoots, Polynomial.mem_support_iff]
        intro p_ne_zero ps_zero
        have := pow_mem hs (p.natDegree - i) _ ps_zero
        

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
s : R
hs : s ∈ nonZeroDivisors R
i : ℕ
p_ne_zero : coeff p i ≠ 0
ps_zero : coeff p i * s ^ (natDegree p - i) = 0
this : coeff p i = 0
⊢ False

Next tactic:
contradiction
@[simp]
theorem degree_scaleRoots (p : R[X]) {s : R} : degree (scaleRoots p s) = degree p := by
  

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
s : R
⊢ degree (scaleRoots p s) = degree p

Next tactic:
haveI := Classical.propDecidable
@[simp]
theorem degree_scaleRoots (p : R[X]) {s : R} : degree (scaleRoots p s) = degree p := by
  haveI := Classical.propDecidable
  

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
s : R
this : (a : Prop) → Decidable a
⊢ degree (scaleRoots p s) = degree p

Next tactic:
by_cases hp : p = 0
@[simp]
theorem degree_scaleRoots (p : R[X]) {s : R} : degree (scaleRoots p s) = degree p := by
  haveI := Classical.propDecidable
  by_cases hp : p = 0
  · 

Proof state:
case pos
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
s : R
this : (a : Prop) → Decidable a
hp : p = 0
⊢ degree (scaleRoots p s) = degree p

Next tactic:
rw [hp, zero_scaleRoots]
@[simp]
theorem degree_scaleRoots (p : R[X]) {s : R} : degree (scaleRoots p s) = degree p := by
  haveI := Classical.propDecidable
  by_cases hp : p = 0
  · rw [hp, zero_scaleRoots]
  

Proof state:
case neg
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
s : R
this : (a : Prop) → Decidable a
hp : ¬p = 0
⊢ degree (scaleRoots p s) = degree p

Next tactic:
refine' le_antisymm (Finset.sup_mono (support_scaleRoots_le p s)) (degree_le_degree _)
@[simp]
theorem degree_scaleRoots (p : R[X]) {s : R} : degree (scaleRoots p s) = degree p := by
  haveI := Classical.propDecidable
  by_cases hp : p = 0
  · rw [hp, zero_scaleRoots]
  refine' le_antisymm (Finset.sup_mono (support_scaleRoots_le p s)) (degree_le_degree _)
  

Proof state:
case neg
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
s : R
this : (a : Prop) → Decidable a
hp : ¬p = 0
⊢ coeff (scaleRoots p s) (natDegree p) ≠ 0

Next tactic:
rw [coeff_scaleRoots_natDegree]
@[simp]
theorem degree_scaleRoots (p : R[X]) {s : R} : degree (scaleRoots p s) = degree p := by
  haveI := Classical.propDecidable
  by_cases hp : p = 0
  · rw [hp, zero_scaleRoots]
  refine' le_antisymm (Finset.sup_mono (support_scaleRoots_le p s)) (degree_le_degree _)
  rw [coeff_scaleRoots_natDegree]
  

Proof state:
case neg
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
s : R
this : (a : Prop) → Decidable a
hp : ¬p = 0
⊢ leadingCoeff p ≠ 0

Next tactic:
intro h
@[simp]
theorem degree_scaleRoots (p : R[X]) {s : R} : degree (scaleRoots p s) = degree p := by
  haveI := Classical.propDecidable
  by_cases hp : p = 0
  · rw [hp, zero_scaleRoots]
  refine' le_antisymm (Finset.sup_mono (support_scaleRoots_le p s)) (degree_le_degree _)
  rw [coeff_scaleRoots_natDegree]
  intro h
  

Proof state:
case neg
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
s : R
this : (a : Prop) → Decidable a
hp : ¬p = 0
h : leadingCoeff p = 0
⊢ False

Next tactic:
have := leadingCoeff_eq_zero.mp h
@[simp]
theorem degree_scaleRoots (p : R[X]) {s : R} : degree (scaleRoots p s) = degree p := by
  haveI := Classical.propDecidable
  by_cases hp : p = 0
  · rw [hp, zero_scaleRoots]
  refine' le_antisymm (Finset.sup_mono (support_scaleRoots_le p s)) (degree_le_degree _)
  rw [coeff_scaleRoots_natDegree]
  intro h
  have := leadingCoeff_eq_zero.mp h
  

Proof state:
case neg
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
s : R
this✝ : (a : Prop) → Decidable a
hp : ¬p = 0
h : leadingCoeff p = 0
this : p = 0
⊢ False

Next tactic:
contradiction
@[simp]
theorem natDegree_scaleRoots (p : R[X]) (s : R) : natDegree (scaleRoots p s) = natDegree p := by
  

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
s : R
⊢ natDegree (scaleRoots p s) = natDegree p

Next tactic:
simp only [natDegree, degree_scaleRoots]
theorem monic_scaleRoots_iff {p : R[X]} (s : R) : Monic (scaleRoots p s) ↔ Monic p := by
  

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
s : R
⊢ Monic (scaleRoots p s) ↔ Monic p

Next tactic:
simp only [Monic, leadingCoeff, natDegree_scaleRoots, coeff_scaleRoots_natDegree]
theorem map_scaleRoots (p : R[X]) (x : R) (f : R →+* S) (h : f p.leadingCoeff ≠ 0) :
    (p.scaleRoots x).map f = (p.map f).scaleRoots (f x) := by
  

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
x : R
f : R →+* S
h : f (leadingCoeff p) ≠ 0
⊢ map f (scaleRoots p x) = scaleRoots (map f p) (f x)

Next tactic:
ext
theorem map_scaleRoots (p : R[X]) (x : R) (f : R →+* S) (h : f p.leadingCoeff ≠ 0) :
    (p.scaleRoots x).map f = (p.map f).scaleRoots (f x) := by
  ext
  

Proof state:
case a
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
x : R
f : R →+* S
h : f (leadingCoeff p) ≠ 0
n✝ : ℕ
⊢ coeff (map f (scaleRoots p x)) n✝ = coeff (scaleRoots (map f p) (f x)) n✝

Next tactic:
simp [Polynomial.natDegree_map_of_leadingCoeff_ne_zero _ h]
@[simp]
lemma scaleRoots_C (r c : R) : (C c).scaleRoots r = C c := by
  

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
r c : R
⊢ scaleRoots (C c) r = C c

Next tactic:
ext
@[simp]
lemma scaleRoots_C (r c : R) : (C c).scaleRoots r = C c := by
  ext; 

Proof state:
case a
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
r c : R
n✝ : ℕ
⊢ coeff (scaleRoots (C c) r) n✝ = coeff (C c) n✝

Next tactic:
simp
@[simp]
lemma scaleRoots_one (p : R[X]) :
    p.scaleRoots 1 = p := by 

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
⊢ scaleRoots p 1 = p

Next tactic:
ext
@[simp]
lemma scaleRoots_one (p : R[X]) :
    p.scaleRoots 1 = p := by ext; 

Proof state:
case a
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
n✝ : ℕ
⊢ coeff (scaleRoots p 1) n✝ = coeff p n✝

Next tactic:
simp
@[simp]
lemma scaleRoots_zero (p : R[X]) :
    p.scaleRoots 0 = p.leadingCoeff • X ^ p.natDegree := by
  

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
⊢ scaleRoots p 0 = leadingCoeff p • X ^ natDegree p

Next tactic:
ext n
@[simp]
lemma scaleRoots_zero (p : R[X]) :
    p.scaleRoots 0 = p.leadingCoeff • X ^ p.natDegree := by
  ext n
  

Proof state:
case a
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
n : ℕ
⊢ coeff (scaleRoots p 0) n = coeff (leadingCoeff p • X ^ natDegree p) n

Next tactic:
simp only [coeff_scaleRoots, ge_iff_le, ne_eq, tsub_eq_zero_iff_le, not_le, zero_pow_eq, mul_ite,
    mul_one, mul_zero, coeff_smul, coeff_X_pow, smul_eq_mul]
@[simp]
lemma scaleRoots_zero (p : R[X]) :
    p.scaleRoots 0 = p.leadingCoeff • X ^ p.natDegree := by
  ext n
  simp only [coeff_scaleRoots, ge_iff_le, ne_eq, tsub_eq_zero_iff_le, not_le, zero_pow_eq, mul_ite,
    mul_one, mul_zero, coeff_smul, coeff_X_pow, smul_eq_mul]
  

Proof state:
case a
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
n : ℕ
⊢ (if natDegree p ≤ n then coeff p n else 0) = if n = natDegree p then leadingCoeff p else 0

Next tactic:
split_ifs with h₁ h₂ h₂
@[simp]
lemma scaleRoots_zero (p : R[X]) :
    p.scaleRoots 0 = p.leadingCoeff • X ^ p.natDegree := by
  ext n
  simp only [coeff_scaleRoots, ge_iff_le, ne_eq, tsub_eq_zero_iff_le, not_le, zero_pow_eq, mul_ite,
    mul_one, mul_zero, coeff_smul, coeff_X_pow, smul_eq_mul]
  split_ifs with h₁ h₂ h₂
  · 

Proof state:
case pos
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
n : ℕ
h₁ : natDegree p ≤ n
h₂ : n = natDegree p
⊢ coeff p n = leadingCoeff p

Next tactic:
subst h₂
@[simp]
lemma scaleRoots_zero (p : R[X]) :
    p.scaleRoots 0 = p.leadingCoeff • X ^ p.natDegree := by
  ext n
  simp only [coeff_scaleRoots, ge_iff_le, ne_eq, tsub_eq_zero_iff_le, not_le, zero_pow_eq, mul_ite,
    mul_one, mul_zero, coeff_smul, coeff_X_pow, smul_eq_mul]
  split_ifs with h₁ h₂ h₂
  · subst h₂; 

Proof state:
case pos
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
h₁ : natDegree p ≤ natDegree p
⊢ coeff p (natDegree p) = leadingCoeff p

Next tactic:
rfl
@[simp]
lemma scaleRoots_zero (p : R[X]) :
    p.scaleRoots 0 = p.leadingCoeff • X ^ p.natDegree := by
  ext n
  simp only [coeff_scaleRoots, ge_iff_le, ne_eq, tsub_eq_zero_iff_le, not_le, zero_pow_eq, mul_ite,
    mul_one, mul_zero, coeff_smul, coeff_X_pow, smul_eq_mul]
  split_ifs with h₁ h₂ h₂
  · subst h₂; rfl
  · 

Proof state:
case neg
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
n : ℕ
h₁ : natDegree p ≤ n
h₂ : ¬n = natDegree p
⊢ coeff p n = 0

Next tactic:
exact coeff_eq_zero_of_natDegree_lt (lt_of_le_of_ne h₁ (Ne.symm h₂))
@[simp]
lemma scaleRoots_zero (p : R[X]) :
    p.scaleRoots 0 = p.leadingCoeff • X ^ p.natDegree := by
  ext n
  simp only [coeff_scaleRoots, ge_iff_le, ne_eq, tsub_eq_zero_iff_le, not_le, zero_pow_eq, mul_ite,
    mul_one, mul_zero, coeff_smul, coeff_X_pow, smul_eq_mul]
  split_ifs with h₁ h₂ h₂
  · subst h₂; rfl
  · exact coeff_eq_zero_of_natDegree_lt (lt_of_le_of_ne h₁ (Ne.symm h₂))
  · 

Proof state:
case pos
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
n : ℕ
h₁ : ¬natDegree p ≤ n
h₂ : n = natDegree p
⊢ 0 = leadingCoeff p

Next tactic:
exact (h₁ h₂.ge).elim
@[simp]
lemma scaleRoots_zero (p : R[X]) :
    p.scaleRoots 0 = p.leadingCoeff • X ^ p.natDegree := by
  ext n
  simp only [coeff_scaleRoots, ge_iff_le, ne_eq, tsub_eq_zero_iff_le, not_le, zero_pow_eq, mul_ite,
    mul_one, mul_zero, coeff_smul, coeff_X_pow, smul_eq_mul]
  split_ifs with h₁ h₂ h₂
  · subst h₂; rfl
  · exact coeff_eq_zero_of_natDegree_lt (lt_of_le_of_ne h₁ (Ne.symm h₂))
  · exact (h₁ h₂.ge).elim
  · 

Proof state:
case neg
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
n : ℕ
h₁ : ¬natDegree p ≤ n
h₂ : ¬n = natDegree p
⊢ 0 = 0

Next tactic:
rfl
@[simp]
lemma one_scaleRoots (r : R) :
    (1 : R[X]).scaleRoots r = 1 := by 

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
r : R
⊢ scaleRoots 1 r = 1

Next tactic:
ext
@[simp]
lemma one_scaleRoots (r : R) :
    (1 : R[X]).scaleRoots r = 1 := by ext; 

Proof state:
case a
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝¹ : Semiring R
inst✝ : Semiring S
r : R
n✝ : ℕ
⊢ coeff (scaleRoots 1 r) n✝ = coeff 1 n✝

Next tactic:
simp
theorem scaleRoots_eval₂_mul_of_commute {p : S[X]} (f : S →+* A) (a : A) (s : S)
    (hsa : Commute (f s) a) (hf : ∀ s₁ s₂, Commute (f s₁) (f s₂)) :
    eval₂ f (f s * a) (scaleRoots p s) = f s ^ p.natDegree * eval₂ f a p := by
   

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝³ : Semiring S
inst✝² : CommSemiring R
inst✝¹ : Semiring A
inst✝ : Field K
p : S[X]
f : S →+* A
a : A
s : S
hsa : Commute (f s) a
hf : ∀ (s₁ s₂ : S), Commute (f s₁) (f s₂)
⊢ eval₂ f (f s * a) (scaleRoots p s) = f s ^ natDegree p * eval₂ f a p

Next tactic:
calc
    _ = (scaleRoots p s).support.sum fun i =>
          f (coeff p i * s ^ (p.natDegree - i)) * (f s * a) ^ i :=
      by simp [eval₂_eq_sum, sum_def]
    _ = p.support.sum fun i => f (coeff p i * s ^ (p.natDegree - i)) * (f s * a) ^ i :=
      (Finset.sum_subset (support_scaleRoots_le p s) fun i _hi hi' => by
        let this : coeff p i * s ^ (p.natDegree - i) = 0 := by simpa using hi'
        simp [this])
    _ = p.support.sum fun i : ℕ => f (p.coeff i) * f s ^ (p.natDegree - i + i) * a ^ i :=
      (Finset.sum_congr rfl fun i _hi => by
        simp_rw [f.map_mul, f.map_pow, pow_add, hsa.mul_pow, mul_assoc])
    _ = p.support.sum fun i : ℕ => f s ^ p.natDegree * (f (p.coeff i) * a ^ i) :=
      (Finset.sum_congr rfl fun i hi => by
        rw [mul_assoc, ← map_pow, (hf _ _).left_comm, map_pow, tsub_add_cancel_of_le]
        exact le_natDegree_of_ne_zero (Polynomial.mem_support_iff.mp hi))
    _ = f s ^ p.natDegree * p.support.sum fun i : ℕ => f (p.coeff i) * a ^ i := Finset.mul_sum.symm
    _ = f s ^ p.natDegree * eval₂ f a p := by simp [eval₂_eq_sum, sum_def]
theorem scaleRoots_eval₂_mul_of_commute {p : S[X]} (f : S →+* A) (a : A) (s : S)
    (hsa : Commute (f s) a) (hf : ∀ s₁ s₂, Commute (f s₁) (f s₂)) :
    eval₂ f (f s * a) (scaleRoots p s) = f s ^ p.natDegree * eval₂ f a p := by
   calc
    _ = (scaleRoots p s).support.sum fun i =>
          f (coeff p i * s ^ (p.natDegree - i)) * (f s * a) ^ i :=
      by 

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝³ : Semiring S
inst✝² : CommSemiring R
inst✝¹ : Semiring A
inst✝ : Field K
p : S[X]
f : S →+* A
a : A
s : S
hsa : Commute (f s) a
hf : ∀ (s₁ s₂ : S), Commute (f s₁) (f s₂)
⊢ eval₂ f (f s * a) (scaleRoots p s) =
    ∑ i in support (scaleRoots p s), f (coeff p i * s ^ (natDegree p - i)) * (f s * a) ^ i

Next tactic:
simp [eval₂_eq_sum, sum_def]
theorem scaleRoots_eval₂_mul_of_commute {p : S[X]} (f : S →+* A) (a : A) (s : S)
    (hsa : Commute (f s) a) (hf : ∀ s₁ s₂, Commute (f s₁) (f s₂)) :
    eval₂ f (f s * a) (scaleRoots p s) = f s ^ p.natDegree * eval₂ f a p := by
   calc
    _ = (scaleRoots p s).support.sum fun i =>
          f (coeff p i * s ^ (p.natDegree - i)) * (f s * a) ^ i :=
      by simp [eval₂_eq_sum, sum_def]
    _ = p.support.sum fun i => f (coeff p i * s ^ (p.natDegree - i)) * (f s * a) ^ i :=
      (Finset.sum_subset (support_scaleRoots_le p s) fun i _hi hi' => by
        

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝³ : Semiring S
inst✝² : CommSemiring R
inst✝¹ : Semiring A
inst✝ : Field K
p : S[X]
f : S →+* A
a : A
s : S
hsa : Commute (f s) a
hf : ∀ (s₁ s₂ : S), Commute (f s₁) (f s₂)
i : ℕ
_hi : i ∈ support p
hi' : i ∉ support (scaleRoots p s)
⊢ f (coeff p i * s ^ (natDegree p - i)) * (f s * a) ^ i = 0

Next tactic:
let this : coeff p i * s ^ (p.natDegree - i) = 0 := by simpa using hi'
theorem scaleRoots_eval₂_mul_of_commute {p : S[X]} (f : S →+* A) (a : A) (s : S)
    (hsa : Commute (f s) a) (hf : ∀ s₁ s₂, Commute (f s₁) (f s₂)) :
    eval₂ f (f s * a) (scaleRoots p s) = f s ^ p.natDegree * eval₂ f a p := by
   calc
    _ = (scaleRoots p s).support.sum fun i =>
          f (coeff p i * s ^ (p.natDegree - i)) * (f s * a) ^ i :=
      by simp [eval₂_eq_sum, sum_def]
    _ = p.support.sum fun i => f (coeff p i * s ^ (p.natDegree - i)) * (f s * a) ^ i :=
      (Finset.sum_subset (support_scaleRoots_le p s) fun i _hi hi' => by
        let this : coeff p i * s ^ (p.natDegree - i) = 0 := by 

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝³ : Semiring S
inst✝² : CommSemiring R
inst✝¹ : Semiring A
inst✝ : Field K
p : S[X]
f : S →+* A
a : A
s : S
hsa : Commute (f s) a
hf : ∀ (s₁ s₂ : S), Commute (f s₁) (f s₂)
i : ℕ
_hi : i ∈ support p
hi' : i ∉ support (scaleRoots p s)
⊢ coeff p i * s ^ (natDegree p - i) = 0

Next tactic:
simpa using hi'
theorem scaleRoots_eval₂_mul_of_commute {p : S[X]} (f : S →+* A) (a : A) (s : S)
    (hsa : Commute (f s) a) (hf : ∀ s₁ s₂, Commute (f s₁) (f s₂)) :
    eval₂ f (f s * a) (scaleRoots p s) = f s ^ p.natDegree * eval₂ f a p := by
   calc
    _ = (scaleRoots p s).support.sum fun i =>
          f (coeff p i * s ^ (p.natDegree - i)) * (f s * a) ^ i :=
      by simp [eval₂_eq_sum, sum_def]
    _ = p.support.sum fun i => f (coeff p i * s ^ (p.natDegree - i)) * (f s * a) ^ i :=
      (Finset.sum_subset (support_scaleRoots_le p s) fun i _hi hi' => by
        let this : coeff p i * s ^ (p.natDegree - i) = 0 := by simpa using hi'
        

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝³ : Semiring S
inst✝² : CommSemiring R
inst✝¹ : Semiring A
inst✝ : Field K
p : S[X]
f : S →+* A
a : A
s : S
hsa : Commute (f s) a
hf : ∀ (s₁ s₂ : S), Commute (f s₁) (f s₂)
i : ℕ
_hi : i ∈ support p
hi' : i ∉ support (scaleRoots p s)
this : coeff p i * s ^ (natDegree p - i) = 0 :=
  Eq.mp
    ((congrArg Not
          (Mathlib.Data.Polynomial.Basic._auxLemma.18.trans (congrFun (congrArg Ne (coeff_scaleRoots p s i)) 0))).trans
      Mathlib.Logic.Basic._auxLemma.10)
    hi'
⊢ f (coeff p i * s ^ (natDegree p - i)) * (f s * a) ^ i = 0

Next tactic:
simp [this]
theorem scaleRoots_eval₂_mul_of_commute {p : S[X]} (f : S →+* A) (a : A) (s : S)
    (hsa : Commute (f s) a) (hf : ∀ s₁ s₂, Commute (f s₁) (f s₂)) :
    eval₂ f (f s * a) (scaleRoots p s) = f s ^ p.natDegree * eval₂ f a p := by
   calc
    _ = (scaleRoots p s).support.sum fun i =>
          f (coeff p i * s ^ (p.natDegree - i)) * (f s * a) ^ i :=
      by simp [eval₂_eq_sum, sum_def]
    _ = p.support.sum fun i => f (coeff p i * s ^ (p.natDegree - i)) * (f s * a) ^ i :=
      (Finset.sum_subset (support_scaleRoots_le p s) fun i _hi hi' => by
        let this : coeff p i * s ^ (p.natDegree - i) = 0 := by simpa using hi'
        simp [this])
    _ = p.support.sum fun i : ℕ => f (p.coeff i) * f s ^ (p.natDegree - i + i) * a ^ i :=
      (Finset.sum_congr rfl fun i _hi => by
        

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝³ : Semiring S
inst✝² : CommSemiring R
inst✝¹ : Semiring A
inst✝ : Field K
p : S[X]
f : S →+* A
a : A
s : S
hsa : Commute (f s) a
hf : ∀ (s₁ s₂ : S), Commute (f s₁) (f s₂)
i : ℕ
_hi : i ∈ support p
⊢ f (coeff p i * s ^ (natDegree p - i)) * (f s * a) ^ i = f (coeff p i) * f s ^ (natDegree p - i + i) * a ^ i

Next tactic:
simp_rw [f.map_mul, f.map_pow, pow_add, hsa.mul_pow, mul_assoc]
theorem scaleRoots_eval₂_mul_of_commute {p : S[X]} (f : S →+* A) (a : A) (s : S)
    (hsa : Commute (f s) a) (hf : ∀ s₁ s₂, Commute (f s₁) (f s₂)) :
    eval₂ f (f s * a) (scaleRoots p s) = f s ^ p.natDegree * eval₂ f a p := by
   calc
    _ = (scaleRoots p s).support.sum fun i =>
          f (coeff p i * s ^ (p.natDegree - i)) * (f s * a) ^ i :=
      by simp [eval₂_eq_sum, sum_def]
    _ = p.support.sum fun i => f (coeff p i * s ^ (p.natDegree - i)) * (f s * a) ^ i :=
      (Finset.sum_subset (support_scaleRoots_le p s) fun i _hi hi' => by
        let this : coeff p i * s ^ (p.natDegree - i) = 0 := by simpa using hi'
        simp [this])
    _ = p.support.sum fun i : ℕ => f (p.coeff i) * f s ^ (p.natDegree - i + i) * a ^ i :=
      (Finset.sum_congr rfl fun i _hi => by
        simp_rw [f.map_mul, f.map_pow, pow_add, hsa.mul_pow, mul_assoc])
    _ = p.support.sum fun i : ℕ => f s ^ p.natDegree * (f (p.coeff i) * a ^ i) :=
      (Finset.sum_congr rfl fun i hi => by
        

Proof state:
R : Type u_1
S : Type u_2
A : Type u_3
K : Type u_4
inst✝³ : Semiring S
inst✝² : CommSemiring R
inst✝¹ : Semiring A
inst✝ : Field K
p : S[X]
f : S →+* A
a : A
s : S
hsa : Commute (f s) a
hf : ∀ (s₁ s₂ : S), Commute (f s₁) (f s₂)
i : ℕ
hi : i ∈ support p
⊢ f (coeff p i) * f s ^ (natDegree p - i + i) * a ^ i = f s ^ natDegree p * (f (coeff p i) * a ^ i)

Next tactic:
rw [mul_assoc, ← map_pow, (hf _ _).left_comm, map_pow, tsub_add_cancel_of_le]