l3lab/ntp-mathlib huggingface dataset:
theorem ne_zero_of_mem_nthRootsFinset {η : R} (hη : η ∈ nthRootsFinset n R) : η ≠ 0 := by
  nontriviality R
  rintro rfl
  cases n with
  | zero =>
    simp only [Nat.zero_eq, nthRootsFinset_zero, not_mem_empty] at hη
  | succ n =>
    rw [mem_nthRootsFinset n.succ_pos, zero_pow n.succ_pos] at hη
    

Proof state:
case succ
R : Type u
S : Type v
T : Type w
a b : R
inst✝² : CommRing R
inst✝¹ : IsDomain R
p q : R[X]
inst✝ : Nontrivial R
n : ℕ
hη : 0 = 1
⊢ False

Next tactic:
exact zero_ne_one hη
theorem one_mem_nthRootsFinset (hn : 0 < n) : 1 ∈ nthRootsFinset n R := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
hn : 0 < n
⊢ 1 ∈ nthRootsFinset n R

Next tactic:
rw [mem_nthRootsFinset hn, one_pow]
theorem Monic.comp (hp : p.Monic) (hq : q.Monic) (h : q.natDegree ≠ 0) : (p.comp q).Monic := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
hp : Monic p
hq : Monic q
h : natDegree q ≠ 0
⊢ Monic (Polynomial.comp p q)

Next tactic:
rw [Monic.def, leadingCoeff_comp h, Monic.def.1 hp, Monic.def.1 hq, one_pow, one_mul]
theorem Monic.comp_X_add_C (hp : p.Monic) (r : R) : (p.comp (X + C r)).Monic := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
hp : Monic p
r : R
⊢ Monic (Polynomial.comp p (X + C r))

Next tactic:
refine' hp.comp (monic_X_add_C _) fun ha => _
theorem Monic.comp_X_add_C (hp : p.Monic) (r : R) : (p.comp (X + C r)).Monic := by
  refine' hp.comp (monic_X_add_C _) fun ha => _
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
hp : Monic p
r : R
ha : natDegree (X + C r) = 0
⊢ False

Next tactic:
rw [natDegree_X_add_C] at ha
theorem Monic.comp_X_add_C (hp : p.Monic) (r : R) : (p.comp (X + C r)).Monic := by
  refine' hp.comp (monic_X_add_C _) fun ha => _
  rw [natDegree_X_add_C] at ha
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
hp : Monic p
r : R
ha : 1 = 0
⊢ False

Next tactic:
exact one_ne_zero ha
theorem Monic.comp_X_sub_C (hp : p.Monic) (r : R) : (p.comp (X - C r)).Monic := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
hp : Monic p
r : R
⊢ Monic (Polynomial.comp p (X - C r))

Next tactic:
simpa using hp.comp_X_add_C (-r)
theorem units_coeff_zero_smul (c : R[X]ˣ) (p : R[X]) : (c : R[X]).coeff 0 • p = c * p := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p✝ q : R[X]
c : R[X]ˣ
p : R[X]
⊢ coeff (↑c) 0 • p = ↑c * p

Next tactic:
rw [← Polynomial.C_mul', ← Polynomial.eq_C_of_degree_eq_zero (degree_coe_units c)]
theorem comp_eq_zero_iff : p.comp q = 0 ↔ p = 0 ∨ p.eval (q.coeff 0) = 0 ∧ q = C (q.coeff 0) := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
⊢ comp p q = 0 ↔ p = 0 ∨ eval (coeff q 0) p = 0 ∧ q = C (coeff q 0)

Next tactic:
constructor
theorem comp_eq_zero_iff : p.comp q = 0 ↔ p = 0 ∨ p.eval (q.coeff 0) = 0 ∧ q = C (q.coeff 0) := by
  constructor
  · 

Proof state:
case mp
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
⊢ comp p q = 0 → p = 0 ∨ eval (coeff q 0) p = 0 ∧ q = C (coeff q 0)

Next tactic:
intro h
theorem comp_eq_zero_iff : p.comp q = 0 ↔ p = 0 ∨ p.eval (q.coeff 0) = 0 ∧ q = C (q.coeff 0) := by
  constructor
  · intro h
    

Proof state:
case mp
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
h : comp p q = 0
⊢ p = 0 ∨ eval (coeff q 0) p = 0 ∧ q = C (coeff q 0)

Next tactic:
have key : p.natDegree = 0 ∨ q.natDegree = 0 := by
      rw [← mul_eq_zero, ← natDegree_comp, h, natDegree_zero]
theorem comp_eq_zero_iff : p.comp q = 0 ↔ p = 0 ∨ p.eval (q.coeff 0) = 0 ∧ q = C (q.coeff 0) := by
  constructor
  · intro h
    have key : p.natDegree = 0 ∨ q.natDegree = 0 := by
      

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
h : comp p q = 0
⊢ natDegree p = 0 ∨ natDegree q = 0

Next tactic:
rw [← mul_eq_zero, ← natDegree_comp, h, natDegree_zero]
theorem comp_eq_zero_iff : p.comp q = 0 ↔ p = 0 ∨ p.eval (q.coeff 0) = 0 ∧ q = C (q.coeff 0) := by
  constructor
  · intro h
    have key : p.natDegree = 0 ∨ q.natDegree = 0 := by
      rw [← mul_eq_zero, ← natDegree_comp, h, natDegree_zero]
    

Proof state:
case mp
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
h : comp p q = 0
key : natDegree p = 0 ∨ natDegree q = 0
⊢ p = 0 ∨ eval (coeff q 0) p = 0 ∧ q = C (coeff q 0)

Next tactic:
replace key := Or.imp eq_C_of_natDegree_eq_zero eq_C_of_natDegree_eq_zero key
theorem comp_eq_zero_iff : p.comp q = 0 ↔ p = 0 ∨ p.eval (q.coeff 0) = 0 ∧ q = C (q.coeff 0) := by
  constructor
  · intro h
    have key : p.natDegree = 0 ∨ q.natDegree = 0 := by
      rw [← mul_eq_zero, ← natDegree_comp, h, natDegree_zero]
    replace key := Or.imp eq_C_of_natDegree_eq_zero eq_C_of_natDegree_eq_zero key
    

Proof state:
case mp
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
h : comp p q = 0
key : p = C (coeff p 0) ∨ q = C (coeff q 0)
⊢ p = 0 ∨ eval (coeff q 0) p = 0 ∧ q = C (coeff q 0)

Next tactic:
cases' key with key key
theorem comp_eq_zero_iff : p.comp q = 0 ↔ p = 0 ∨ p.eval (q.coeff 0) = 0 ∧ q = C (q.coeff 0) := by
  constructor
  · intro h
    have key : p.natDegree = 0 ∨ q.natDegree = 0 := by
      rw [← mul_eq_zero, ← natDegree_comp, h, natDegree_zero]
    replace key := Or.imp eq_C_of_natDegree_eq_zero eq_C_of_natDegree_eq_zero key
    cases' key with key key
    · 

Proof state:
case mp.inl
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
h : comp p q = 0
key : p = C (coeff p 0)
⊢ p = 0 ∨ eval (coeff q 0) p = 0 ∧ q = C (coeff q 0)

Next tactic:
rw [key, C_comp] at h
theorem comp_eq_zero_iff : p.comp q = 0 ↔ p = 0 ∨ p.eval (q.coeff 0) = 0 ∧ q = C (q.coeff 0) := by
  constructor
  · intro h
    have key : p.natDegree = 0 ∨ q.natDegree = 0 := by
      rw [← mul_eq_zero, ← natDegree_comp, h, natDegree_zero]
    replace key := Or.imp eq_C_of_natDegree_eq_zero eq_C_of_natDegree_eq_zero key
    cases' key with key key
    · rw [key, C_comp] at h
      

Proof state:
case mp.inl
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
h : C (coeff p 0) = 0
key : p = C (coeff p 0)
⊢ p = 0 ∨ eval (coeff q 0) p = 0 ∧ q = C (coeff q 0)

Next tactic:
exact Or.inl (key.trans h)
theorem comp_eq_zero_iff : p.comp q = 0 ↔ p = 0 ∨ p.eval (q.coeff 0) = 0 ∧ q = C (q.coeff 0) := by
  constructor
  · intro h
    have key : p.natDegree = 0 ∨ q.natDegree = 0 := by
      rw [← mul_eq_zero, ← natDegree_comp, h, natDegree_zero]
    replace key := Or.imp eq_C_of_natDegree_eq_zero eq_C_of_natDegree_eq_zero key
    cases' key with key key
    · rw [key, C_comp] at h
      exact Or.inl (key.trans h)
    · 

Proof state:
case mp.inr
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
h : comp p q = 0
key : q = C (coeff q 0)
⊢ p = 0 ∨ eval (coeff q 0) p = 0 ∧ q = C (coeff q 0)

Next tactic:
rw [key, comp_C, C_eq_zero] at h
theorem comp_eq_zero_iff : p.comp q = 0 ↔ p = 0 ∨ p.eval (q.coeff 0) = 0 ∧ q = C (q.coeff 0) := by
  constructor
  · intro h
    have key : p.natDegree = 0 ∨ q.natDegree = 0 := by
      rw [← mul_eq_zero, ← natDegree_comp, h, natDegree_zero]
    replace key := Or.imp eq_C_of_natDegree_eq_zero eq_C_of_natDegree_eq_zero key
    cases' key with key key
    · rw [key, C_comp] at h
      exact Or.inl (key.trans h)
    · rw [key, comp_C, C_eq_zero] at h
      

Proof state:
case mp.inr
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
h : eval (coeff q 0) p = 0
key : q = C (coeff q 0)
⊢ p = 0 ∨ eval (coeff q 0) p = 0 ∧ q = C (coeff q 0)

Next tactic:
exact Or.inr ⟨h, key⟩
theorem comp_eq_zero_iff : p.comp q = 0 ↔ p = 0 ∨ p.eval (q.coeff 0) = 0 ∧ q = C (q.coeff 0) := by
  constructor
  · intro h
    have key : p.natDegree = 0 ∨ q.natDegree = 0 := by
      rw [← mul_eq_zero, ← natDegree_comp, h, natDegree_zero]
    replace key := Or.imp eq_C_of_natDegree_eq_zero eq_C_of_natDegree_eq_zero key
    cases' key with key key
    · rw [key, C_comp] at h
      exact Or.inl (key.trans h)
    · rw [key, comp_C, C_eq_zero] at h
      exact Or.inr ⟨h, key⟩
  · 

Proof state:
case mpr
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
⊢ p = 0 ∨ eval (coeff q 0) p = 0 ∧ q = C (coeff q 0) → comp p q = 0

Next tactic:
exact fun h =>
      Or.rec (fun h => by rw [h, zero_comp]) (fun h => by rw [h.2, comp_C, h.1, C_0]) h
theorem comp_eq_zero_iff : p.comp q = 0 ↔ p = 0 ∨ p.eval (q.coeff 0) = 0 ∧ q = C (q.coeff 0) := by
  constructor
  · intro h
    have key : p.natDegree = 0 ∨ q.natDegree = 0 := by
      rw [← mul_eq_zero, ← natDegree_comp, h, natDegree_zero]
    replace key := Or.imp eq_C_of_natDegree_eq_zero eq_C_of_natDegree_eq_zero key
    cases' key with key key
    · rw [key, C_comp] at h
      exact Or.inl (key.trans h)
    · rw [key, comp_C, C_eq_zero] at h
      exact Or.inr ⟨h, key⟩
  · exact fun h =>
      Or.rec (fun h => by 

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
h✝ : p = 0 ∨ eval (coeff q 0) p = 0 ∧ q = C (coeff q 0)
h : p = 0
⊢ comp p q = 0

Next tactic:
rw [h, zero_comp]
theorem comp_eq_zero_iff : p.comp q = 0 ↔ p = 0 ∨ p.eval (q.coeff 0) = 0 ∧ q = C (q.coeff 0) := by
  constructor
  · intro h
    have key : p.natDegree = 0 ∨ q.natDegree = 0 := by
      rw [← mul_eq_zero, ← natDegree_comp, h, natDegree_zero]
    replace key := Or.imp eq_C_of_natDegree_eq_zero eq_C_of_natDegree_eq_zero key
    cases' key with key key
    · rw [key, C_comp] at h
      exact Or.inl (key.trans h)
    · rw [key, comp_C, C_eq_zero] at h
      exact Or.inr ⟨h, key⟩
  · exact fun h =>
      Or.rec (fun h => by rw [h, zero_comp]) (fun h => by 

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
inst✝ : IsDomain R
p q : R[X]
h✝ : p = 0 ∨ eval (coeff q 0) p = 0 ∧ q = C (coeff q 0)
h : eval (coeff q 0) p = 0 ∧ q = C (coeff q 0)
⊢ comp p q = 0

Next tactic:
rw [h.2, comp_C, h.1, C_0]
theorem zero_of_eval_zero [Infinite R] (p : R[X]) (h : ∀ x, p.eval x = 0) : p = 0 := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
p✝ q : R[X]
inst✝ : Infinite R
p : R[X]
h : ∀ (x : R), eval x p = 0
⊢ p = 0

Next tactic:
classical
  by_contra hp
  refine @Fintype.false R _ ?_
  exact ⟨p.roots.toFinset, fun x => Multiset.mem_toFinset.mpr ((mem_roots hp).mpr (h _))⟩
theorem zero_of_eval_zero [Infinite R] (p : R[X]) (h : ∀ x, p.eval x = 0) : p = 0 := by
  classical
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
p✝ q : R[X]
inst✝ : Infinite R
p : R[X]
h : ∀ (x : R), eval x p = 0
⊢ p = 0

Next tactic:
by_contra hp
theorem zero_of_eval_zero [Infinite R] (p : R[X]) (h : ∀ x, p.eval x = 0) : p = 0 := by
  classical
  by_contra hp
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
p✝ q : R[X]
inst✝ : Infinite R
p : R[X]
h : ∀ (x : R), eval x p = 0
hp : ¬p = 0
⊢ False

Next tactic:
refine @Fintype.false R _ ?_
theorem zero_of_eval_zero [Infinite R] (p : R[X]) (h : ∀ x, p.eval x = 0) : p = 0 := by
  classical
  by_contra hp
  refine @Fintype.false R _ ?_
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
p✝ q : R[X]
inst✝ : Infinite R
p : R[X]
h : ∀ (x : R), eval x p = 0
hp : ¬p = 0
⊢ Fintype R

Next tactic:
exact ⟨p.roots.toFinset, fun x => Multiset.mem_toFinset.mpr ((mem_roots hp).mpr (h _))⟩
theorem funext [Infinite R] {p q : R[X]} (ext : ∀ r : R, p.eval r = q.eval r) : p = q := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
p✝ q✝ : R[X]
inst✝ : Infinite R
p q : R[X]
ext : ∀ (r : R), eval r p = eval r q
⊢ p = q

Next tactic:
rw [← sub_eq_zero]
theorem funext [Infinite R] {p q : R[X]} (ext : ∀ r : R, p.eval r = q.eval r) : p = q := by
  rw [← sub_eq_zero]
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
p✝ q✝ : R[X]
inst✝ : Infinite R
p q : R[X]
ext : ∀ (r : R), eval r p = eval r q
⊢ p - q = 0

Next tactic:
apply zero_of_eval_zero
theorem funext [Infinite R] {p q : R[X]} (ext : ∀ r : R, p.eval r = q.eval r) : p = q := by
  rw [← sub_eq_zero]
  apply zero_of_eval_zero
  

Proof state:
case h
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
p✝ q✝ : R[X]
inst✝ : Infinite R
p q : R[X]
ext : ∀ (r : R), eval r p = eval r q
⊢ ∀ (x : R), eval x (p - q) = 0

Next tactic:
intro x
theorem funext [Infinite R] {p q : R[X]} (ext : ∀ r : R, p.eval r = q.eval r) : p = q := by
  rw [← sub_eq_zero]
  apply zero_of_eval_zero
  intro x
  

Proof state:
case h
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝² : CommRing R
inst✝¹ : IsDomain R
p✝ q✝ : R[X]
inst✝ : Infinite R
p q : R[X]
ext : ∀ (r : R), eval r p = eval r q
x : R
⊢ eval x (p - q) = 0

Next tactic:
rw [eval_sub, sub_eq_zero, ext]
theorem mem_aroots' [CommRing S] [IsDomain S] [Algebra T S] {p : T[X]} {a : S} :
    a ∈ p.aroots S ↔ p.map (algebraMap T S) ≠ 0 ∧ aeval a p = 0 := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a✝ b : R
n : ℕ
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
p✝ q : R[X]
inst✝³ : CommRing T
inst✝² : CommRing S
inst✝¹ : IsDomain S
inst✝ : Algebra T S
p : T[X]
a : S
⊢ a ∈ aroots p S ↔ map (algebraMap T S) p ≠ 0 ∧ (aeval a) p = 0

Next tactic:
rw [mem_roots', IsRoot.def, ← eval₂_eq_eval_map, aeval_def]
theorem mem_aroots [CommRing S] [IsDomain S] [Algebra T S]
    [NoZeroSMulDivisors T S] {p : T[X]} {a : S} : a ∈ p.aroots S ↔ p ≠ 0 ∧ aeval a p = 0 := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a✝ b : R
n : ℕ
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
p✝ q : R[X]
inst✝⁴ : CommRing T
inst✝³ : CommRing S
inst✝² : IsDomain S
inst✝¹ : Algebra T S
inst✝ : NoZeroSMulDivisors T S
p : T[X]
a : S
⊢ a ∈ aroots p S ↔ p ≠ 0 ∧ (aeval a) p = 0

Next tactic:
rw [mem_aroots', Polynomial.map_ne_zero_iff]
theorem mem_aroots [CommRing S] [IsDomain S] [Algebra T S]
    [NoZeroSMulDivisors T S] {p : T[X]} {a : S} : a ∈ p.aroots S ↔ p ≠ 0 ∧ aeval a p = 0 := by
  rw [mem_aroots', Polynomial.map_ne_zero_iff]
  

Proof state:
R : Type u
S : Type v
T : Type w
a✝ b : R
n : ℕ
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
p✝ q : R[X]
inst✝⁴ : CommRing T
inst✝³ : CommRing S
inst✝² : IsDomain S
inst✝¹ : Algebra T S
inst✝ : NoZeroSMulDivisors T S
p : T[X]
a : S
⊢ Function.Injective ⇑(algebraMap T S)

Next tactic:
exact NoZeroSMulDivisors.algebraMap_injective T S
theorem aroots_mul [CommRing S] [IsDomain S] [Algebra T S]
    [NoZeroSMulDivisors T S] {p q : T[X]} (hpq : p * q ≠ 0) :
    (p * q).aroots S = p.aroots S + q.aroots S := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
p✝ q✝ : R[X]
inst✝⁴ : CommRing T
inst✝³ : CommRing S
inst✝² : IsDomain S
inst✝¹ : Algebra T S
inst✝ : NoZeroSMulDivisors T S
p q : T[X]
hpq : p * q ≠ 0
⊢ aroots (p * q) S = aroots p S + aroots q S

Next tactic:
suffices : map (algebraMap T S) p * map (algebraMap T S) q ≠ 0
theorem aroots_mul [CommRing S] [IsDomain S] [Algebra T S]
    [NoZeroSMulDivisors T S] {p q : T[X]} (hpq : p * q ≠ 0) :
    (p * q).aroots S = p.aroots S + q.aroots S := by
  suffices : map (algebraMap T S) p * map (algebraMap T S) q ≠ 0
  · 

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
p✝ q✝ : R[X]
inst✝⁴ : CommRing T
inst✝³ : CommRing S
inst✝² : IsDomain S
inst✝¹ : Algebra T S
inst✝ : NoZeroSMulDivisors T S
p q : T[X]
hpq : p * q ≠ 0
this : map (algebraMap T S) p * map (algebraMap T S) q ≠ 0
⊢ aroots (p * q) S = aroots p S + aroots q S

Next tactic:
rw [aroots_def, Polynomial.map_mul, roots_mul this]
theorem aroots_mul [CommRing S] [IsDomain S] [Algebra T S]
    [NoZeroSMulDivisors T S] {p q : T[X]} (hpq : p * q ≠ 0) :
    (p * q).aroots S = p.aroots S + q.aroots S := by
  suffices : map (algebraMap T S) p * map (algebraMap T S) q ≠ 0
  · rw [aroots_def, Polynomial.map_mul, roots_mul this]
  

Proof state:
case this
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
p✝ q✝ : R[X]
inst✝⁴ : CommRing T
inst✝³ : CommRing S
inst✝² : IsDomain S
inst✝¹ : Algebra T S
inst✝ : NoZeroSMulDivisors T S
p q : T[X]
hpq : p * q ≠ 0
⊢ map (algebraMap T S) p * map (algebraMap T S) q ≠ 0

Next tactic:
rwa [← Polynomial.map_mul, Polynomial.map_ne_zero_iff
    (NoZeroSMulDivisors.algebraMap_injective T S)]
@[simp]
theorem aroots_X_sub_C [CommRing S] [IsDomain S] [Algebra T S]
    (r : T) : aroots (X - C r) S = {algebraMap T S r} := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
p q : R[X]
inst✝³ : CommRing T
inst✝² : CommRing S
inst✝¹ : IsDomain S
inst✝ : Algebra T S
r : T
⊢ aroots (X - C r) S = {(algebraMap T S) r}

Next tactic:
rw [aroots_def, Polynomial.map_sub, map_X, map_C, roots_X_sub_C]
@[simp]
theorem aroots_X [CommRing S] [IsDomain S] [Algebra T S] :
    aroots (X : T[X]) S = {0} := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
p q : R[X]
inst✝³ : CommRing T
inst✝² : CommRing S
inst✝¹ : IsDomain S
inst✝ : Algebra T S
⊢ aroots X S = {0}

Next tactic:
rw [aroots_def, map_X, roots_X]
@[simp]
theorem aroots_C [CommRing S] [IsDomain S] [Algebra T S] (a : T) : (C a).aroots S = 0 := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a✝ b : R
n : ℕ
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
p q : R[X]
inst✝³ : CommRing T
inst✝² : CommRing S
inst✝¹ : IsDomain S
inst✝ : Algebra T S
a : T
⊢ aroots (C a) S = 0

Next tactic:
rw [aroots_def, map_C, roots_C]
@[simp]
theorem aroots_zero (S) [CommRing S] [IsDomain S] [Algebra T S] : (0 : T[X]).aroots S = 0 := by
  

Proof state:
R : Type u
S✝ : Type v
T : Type w
a b : R
n : ℕ
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
p q : R[X]
inst✝³ : CommRing T
S : Type u_1
inst✝² : CommRing S
inst✝¹ : IsDomain S
inst✝ : Algebra T S
⊢ aroots 0 S = 0

Next tactic:
rw [← C_0, aroots_C]
@[simp]
theorem aroots_neg [CommRing S] [IsDomain S] [Algebra T S] (p : T[X]) :
    (-p).aroots S = p.aroots S :=
  by 

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
p✝ q : R[X]
inst✝³ : CommRing T
inst✝² : CommRing S
inst✝¹ : IsDomain S
inst✝ : Algebra T S
p : T[X]
⊢ aroots (-p) S = aroots p S

Next tactic:
rw [aroots, Polynomial.map_neg, roots_neg]
@[simp]
theorem aroots_C_mul [CommRing S] [IsDomain S] [Algebra T S]
    [NoZeroSMulDivisors T S] {a : T} (p : T[X]) (ha : a ≠ 0) :
    (C a * p).aroots S = p.aroots S := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a✝ b : R
n : ℕ
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
p✝ q : R[X]
inst✝⁴ : CommRing T
inst✝³ : CommRing S
inst✝² : IsDomain S
inst✝¹ : Algebra T S
inst✝ : NoZeroSMulDivisors T S
a : T
p : T[X]
ha : a ≠ 0
⊢ aroots (C a * p) S = aroots p S

Next tactic:
rw [aroots_def, Polynomial.map_mul, map_C, roots_C_mul]
@[simp]
theorem aroots_C_mul [CommRing S] [IsDomain S] [Algebra T S]
    [NoZeroSMulDivisors T S] {a : T} (p : T[X]) (ha : a ≠ 0) :
    (C a * p).aroots S = p.aroots S := by
  rw [aroots_def, Polynomial.map_mul, map_C, roots_C_mul]
  

Proof state:
case ha
R : Type u
S : Type v
T : Type w
a✝ b : R
n : ℕ
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
p✝ q : R[X]
inst✝⁴ : CommRing T
inst✝³ : CommRing S
inst✝² : IsDomain S
inst✝¹ : Algebra T S
inst✝ : NoZeroSMulDivisors T S
a : T
p : T[X]
ha : a ≠ 0
⊢ (algebraMap T S) a ≠ 0

Next tactic:
rwa [map_ne_zero_iff]
@[simp]
theorem aroots_C_mul [CommRing S] [IsDomain S] [Algebra T S]
    [NoZeroSMulDivisors T S] {a : T} (p : T[X]) (ha : a ≠ 0) :
    (C a * p).aroots S = p.aroots S := by
  rw [aroots_def, Polynomial.map_mul, map_C, roots_C_mul]
  rwa [map_ne_zero_iff]
  

Proof state:
case ha.hf
R : Type u
S : Type v
T : Type w
a✝ b : R
n : ℕ
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
p✝ q : R[X]
inst✝⁴ : CommRing T
inst✝³ : CommRing S
inst✝² : IsDomain S
inst✝¹ : Algebra T S
inst✝ : NoZeroSMulDivisors T S
a : T
p : T[X]
ha : a ≠ 0
⊢ Function.Injective ⇑(algebraMap T S)

Next tactic:
exact NoZeroSMulDivisors.algebraMap_injective T S
@[simp]
theorem aroots_smul_nonzero [CommRing S] [IsDomain S] [Algebra T S]
    [NoZeroSMulDivisors T S] {a : T} (p : T[X]) (ha : a ≠ 0) :
    (a • p).aroots S = p.aroots S := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a✝ b : R
n : ℕ
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
p✝ q : R[X]
inst✝⁴ : CommRing T
inst✝³ : CommRing S
inst✝² : IsDomain S
inst✝¹ : Algebra T S
inst✝ : NoZeroSMulDivisors T S
a : T
p : T[X]
ha : a ≠ 0
⊢ aroots (a • p) S = aroots p S

Next tactic:
rw [smul_eq_C_mul, aroots_C_mul _ ha]
@[simp]
theorem aroots_pow [CommRing S] [IsDomain S] [Algebra T S] (p : T[X]) (n : ℕ) :
    (p ^ n).aroots S = n • p.aroots S := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n✝ : ℕ
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
p✝ q : R[X]
inst✝³ : CommRing T
inst✝² : CommRing S
inst✝¹ : IsDomain S
inst✝ : Algebra T S
p : T[X]
n : ℕ
⊢ aroots (p ^ n) S = n • aroots p S

Next tactic:
rw [aroots_def, Polynomial.map_pow, roots_pow]
theorem aroots_X_pow [CommRing S] [IsDomain S] [Algebra T S] (n : ℕ) :
    (X ^ n : T[X]).aroots S = n • ({0} : Multiset S) := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n✝ : ℕ
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
p q : R[X]
inst✝³ : CommRing T
inst✝² : CommRing S
inst✝¹ : IsDomain S
inst✝ : Algebra T S
n : ℕ
⊢ aroots (X ^ n) S = n • {0}

Next tactic:
rw [aroots_pow, aroots_X]
theorem aroots_C_mul_X_pow [CommRing S] [IsDomain S] [Algebra T S]
    [NoZeroSMulDivisors T S] {a : T} (ha : a ≠ 0) (n : ℕ) :
    (C a * X ^ n : T[X]).aroots S = n • ({0} : Multiset S) := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a✝ b : R
n✝ : ℕ
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
p q : R[X]
inst✝⁴ : CommRing T
inst✝³ : CommRing S
inst✝² : IsDomain S
inst✝¹ : Algebra T S
inst✝ : NoZeroSMulDivisors T S
a : T
ha : a ≠ 0
n : ℕ
⊢ aroots (C a * X ^ n) S = n • {0}

Next tactic:
rw [aroots_C_mul _ ha, aroots_X_pow]
@[simp]
theorem aroots_monomial [CommRing S] [IsDomain S] [Algebra T S]
    [NoZeroSMulDivisors T S] {a : T} (ha : a ≠ 0) (n : ℕ) :
    (monomial n a).aroots S = n • ({0} : Multiset S) := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a✝ b : R
n✝ : ℕ
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
p q : R[X]
inst✝⁴ : CommRing T
inst✝³ : CommRing S
inst✝² : IsDomain S
inst✝¹ : Algebra T S
inst✝ : NoZeroSMulDivisors T S
a : T
ha : a ≠ 0
n : ℕ
⊢ aroots ((monomial n) a) S = n • {0}

Next tactic:
rw [← C_mul_X_pow_eq_monomial, aroots_C_mul_X_pow ha]
theorem rootSet_def (p : T[X]) (S) [CommRing S] [IsDomain S] [Algebra T S] [DecidableEq S] :
    p.rootSet S = (p.aroots S).toFinset := by
  

Proof state:
R : Type u
S✝ : Type v
T : Type w
a b : R
n : ℕ
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
p✝ q : R[X]
inst✝⁴ : CommRing T
p : T[X]
S : Type u_1
inst✝³ : CommRing S
inst✝² : IsDomain S
inst✝¹ : Algebra T S
inst✝ : DecidableEq S
⊢ rootSet p S = ↑(toFinset (aroots p S))

Next tactic:
rw [rootSet]
theorem rootSet_def (p : T[X]) (S) [CommRing S] [IsDomain S] [Algebra T S] [DecidableEq S] :
    p.rootSet S = (p.aroots S).toFinset := by
  rw [rootSet]
  

Proof state:
R : Type u
S✝ : Type v
T : Type w
a b : R
n : ℕ
inst✝⁶ : CommRing R
inst✝⁵ : IsDomain R
p✝ q : R[X]
inst✝⁴ : CommRing T
p : T[X]
S : Type u_1
inst✝³ : CommRing S
inst✝² : IsDomain S
inst✝¹ : Algebra T S
inst✝ : DecidableEq S
⊢ ↑(toFinset (aroots p S)) = ↑(toFinset (aroots p S))

Next tactic:
convert rfl
@[simp]
theorem rootSet_C [CommRing S] [IsDomain S] [Algebra T S] (a : T) : (C a).rootSet S = ∅ := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a✝ b : R
n : ℕ
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
p q : R[X]
inst✝³ : CommRing T
inst✝² : CommRing S
inst✝¹ : IsDomain S
inst✝ : Algebra T S
a : T
⊢ rootSet (C a) S = ∅

Next tactic:
classical
  rw [rootSet_def, aroots_C, Multiset.toFinset_zero, Finset.coe_empty]