File: Mathlib/Algebra/Polynomial/Roots.lean

full_name: Polynomial.roots
code: /-- `roots p` noncomputably gives a multiset containing all the roots of `p`,
including their multiplicities. -/
noncomputable def roots (p : R[X]) : Multiset R 
goal: Multiset R

full_name: Polynomial.roots_def
code: theorem roots_def [DecidableEq R] (p : R[X]) [Decidable (p = 0)] :
    p.roots = if h : p = 0 then ∅ else Classical.choose (exists_multiset_roots h) 
goal: p.roots = if h : p = 0 then ∅ else Classical.choose ⋯

full_name: Polynomial.roots_zero
code: @[simp]
theorem roots_zero : (0 : R[X]).roots = 0 
goal: Polynomial.roots 0 = 0

full_name: Polynomial.card_roots
code: theorem card_roots (hp0 : p ≠ 0) : (Multiset.card (roots p) : WithBot ℕ) ≤ degree p 
goal: ↑(Multiset.card p.roots) ≤ p.degree

full_name: Polynomial.card_roots'
code: theorem card_roots' (p : R[X]) : Multiset.card p.roots ≤ natDegree p 
goal: Multiset.card p.roots ≤ p.natDegree

full_name: Polynomial.card_roots_sub_C
code: theorem card_roots_sub_C {p : R[X]} {a : R} (hp0 : 0 < degree p) :
    (Multiset.card (p - C a).roots : WithBot ℕ) ≤ degree p 
goal: ↑(Multiset.card (p - Polynomial.C a).roots) ≤ p.degree

full_name: Polynomial.card_roots_sub_C'
code: theorem card_roots_sub_C' {p : R[X]} {a : R} (hp0 : 0 < degree p) :
    Multiset.card (p - C a).roots ≤ natDegree p 
goal: Multiset.card (p - Polynomial.C a).roots ≤ p.natDegree

full_name: Polynomial.count_roots
code: @[simp]
theorem count_roots [DecidableEq R] (p : R[X]) : p.roots.count a = rootMultiplicity a p 
goal: Multiset.count a p.roots = Polynomial.rootMultiplicity a p

full_name: Polynomial.mem_roots'
code: @[simp]
theorem mem_roots' : a ∈ p.roots ↔ p ≠ 0 ∧ IsRoot p a 
goal: a ∈ p.roots ↔ p ≠ 0 ∧ p.IsRoot a

full_name: Polynomial.mem_roots
code: theorem mem_roots (hp : p ≠ 0) : a ∈ p.roots ↔ IsRoot p a 
goal: a ∈ p.roots ↔ p.IsRoot a

full_name: Polynomial.ne_zero_of_mem_roots
code: theorem ne_zero_of_mem_roots (h : a ∈ p.roots) : p ≠ 0 
goal: p ≠ 0

full_name: Polynomial.isRoot_of_mem_roots
code: theorem isRoot_of_mem_roots (h : a ∈ p.roots) : IsRoot p a 
goal: p.IsRoot a

full_name: Polynomial.mem_roots_iff_aeval_eq_zero
code: lemma mem_roots_iff_aeval_eq_zero {x : R} (w : p ≠ 0) : x ∈ roots p ↔ aeval x p = 0 
goal: x ∈ p.roots ↔ (Polynomial.aeval x) p = 0

full_name: Polynomial.card_le_degree_of_subset_roots
code: theorem card_le_degree_of_subset_roots {p : R[X]} {Z : Finset R} (h : Z.val ⊆ p.roots) :
    Z.card ≤ p.natDegree 
goal: Z.card ≤ p.natDegree

full_name: Polynomial.finite_setOf_isRoot
code: theorem finite_setOf_isRoot {p : R[X]} (hp : p ≠ 0) : Set.Finite { x | IsRoot p x } 
goal: {x | p.IsRoot x}.Finite

full_name: Polynomial.eq_zero_of_infinite_isRoot
code: theorem eq_zero_of_infinite_isRoot (p : R[X]) (h : Set.Infinite { x | IsRoot p x }) : p = 0 
goal: p = 0

full_name: Polynomial.exists_max_root
code: theorem exists_max_root [LinearOrder R] (p : R[X]) (hp : p ≠ 0) : ∃ x₀, ∀ x, p.IsRoot x → x ≤ x₀ 
goal: ∃ x₀, ∀ (x : R), p.IsRoot x → x ≤ x₀

full_name: Polynomial.exists_min_root
code: theorem exists_min_root [LinearOrder R] (p : R[X]) (hp : p ≠ 0) : ∃ x₀, ∀ x, p.IsRoot x → x₀ ≤ x 
goal: ∃ x₀, ∀ (x : R), p.IsRoot x → x₀ ≤ x

full_name: Polynomial.eq_of_infinite_eval_eq
code: theorem eq_of_infinite_eval_eq (p q : R[X]) (h : Set.Infinite { x | eval x p = eval x q }) :
    p = q 
goal: p = q

full_name: Polynomial.roots_mul
code: theorem roots_mul {p q : R[X]} (hpq : p * q ≠ 0) : (p * q).roots = p.roots + q.roots 
goal: (p * q).roots = p.roots + q.roots

full_name: Polynomial.roots.le_of_dvd
code: theorem roots.le_of_dvd (h : q ≠ 0) : p ∣ q → roots p ≤ roots q 
goal: p ∣ q → p.roots ≤ q.roots

full_name: Polynomial.mem_roots_sub_C'
code: theorem mem_roots_sub_C' {p : R[X]} {a x : R} : x ∈ (p - C a).roots ↔ p ≠ C a ∧ p.eval x = a 
goal: x ∈ (p - Polynomial.C a).roots ↔ p ≠ Polynomial.C a ∧ Polynomial.eval x p = a

full_name: Polynomial.mem_roots_sub_C
code: theorem mem_roots_sub_C {p : R[X]} {a x : R} (hp0 : 0 < degree p) :
    x ∈ (p - C a).roots ↔ p.eval x = a 
goal: x ∈ (p - Polynomial.C a).roots ↔ Polynomial.eval x p = a

full_name: Polynomial.roots_X_sub_C
code: @[simp]
theorem roots_X_sub_C (r : R) : roots (X - C r) = {r} 
goal: (Polynomial.X - Polynomial.C r).roots = {r}

full_name: Polynomial.roots_X
code: @[simp]
theorem roots_X : roots (X : R[X]) = {0} 
goal: Polynomial.X.roots = {0}

full_name: Polynomial.roots_C
code: @[simp]
theorem roots_C (x : R) : (C x).roots = 0 
goal: (Polynomial.C x).roots = 0

full_name: Polynomial.roots_one
code: @[simp]
theorem roots_one : (1 : R[X]).roots = ∅ 
goal: Polynomial.roots 1 = ∅

full_name: Polynomial.roots_C_mul
code: @[simp]
theorem roots_C_mul (p : R[X]) (ha : a ≠ 0) : (C a * p).roots = p.roots 
goal: (Polynomial.C a * p).roots = p.roots

full_name: Polynomial.roots_smul_nonzero
code: @[simp]
theorem roots_smul_nonzero (p : R[X]) (ha : a ≠ 0) : (a • p).roots = p.roots 
goal: (a • p).roots = p.roots

full_name: Polynomial.roots_neg
code: @[simp]
lemma roots_neg (p : R[X]) : (-p).roots = p.roots 
goal: (-p).roots = p.roots

full_name: Polynomial.roots_list_prod
code: theorem roots_list_prod (L : List R[X]) :
    (0 : R[X]) ∉ L → L.prod.roots = (L : Multiset R[X]).bind roots 
goal: 0 ∉ L → L.prod.roots = (↑L).bind Polynomial.roots

full_name: Polynomial.roots_multiset_prod
code: theorem roots_multiset_prod (m : Multiset R[X]) : (0 : R[X]) ∉ m → m.prod.roots = m.bind roots 
goal: 0 ∉ m → m.prod.roots = m.bind Polynomial.roots

full_name: Polynomial.roots_prod
code: theorem roots_prod {ι : Type*} (f : ι → R[X]) (s : Finset ι) :
    s.prod f ≠ 0 → (s.prod f).roots = s.val.bind fun i => roots (f i) 
goal: s.prod f ≠ 0 → (s.prod f).roots = s.val.bind fun i => (f i).roots

full_name: Polynomial.roots_pow
code: @[simp]
theorem roots_pow (p : R[X]) (n : ℕ) : (p ^ n).roots = n • p.roots 
goal: (p ^ n).roots = n • p.roots

full_name: Polynomial.roots_X_pow
code: theorem roots_X_pow (n : ℕ) : (X ^ n : R[X]).roots = n • ({0} : Multiset R) 
goal: (Polynomial.X ^ n).roots = n • {0}

full_name: Polynomial.roots_C_mul_X_pow
code: theorem roots_C_mul_X_pow (ha : a ≠ 0) (n : ℕ) :
    Polynomial.roots (C a * X ^ n) = n • ({0} : Multiset R) 
goal: (Polynomial.C a * Polynomial.X ^ n).roots = n • {0}

full_name: Polynomial.roots_monomial
code: @[simp]
theorem roots_monomial (ha : a ≠ 0) (n : ℕ) : (monomial n a).roots = n • ({0} : Multiset R) 
goal: ((Polynomial.monomial n) a).roots = n • {0}

full_name: Polynomial.roots_prod_X_sub_C
code: theorem roots_prod_X_sub_C (s : Finset R) : (s.prod fun a => X - C a).roots = s.val 
goal: (∏ a ∈ s, (Polynomial.X - Polynomial.C a)).roots = s.val

full_name: Polynomial.roots_multiset_prod_X_sub_C
code: @[simp]
theorem roots_multiset_prod_X_sub_C (s : Multiset R) : (s.map fun a => X - C a).prod.roots = s 
goal: (Multiset.map (fun a => Polynomial.X - Polynomial.C a) s).prod.roots = s

full_name: Polynomial.card_roots_X_pow_sub_C
code: theorem card_roots_X_pow_sub_C {n : ℕ} (hn : 0 < n) (a : R) :
    Multiset.card (roots ((X : R[X]) ^ n - C a)) ≤ n 
goal: Multiset.card (Polynomial.X ^ n - Polynomial.C a).roots ≤ n

full_name: Polynomial.nthRoots
code: /-- `nthRoots n a` noncomputably returns the solutions to `x ^ n = a`-/
def nthRoots (n : ℕ) (a : R) : Multiset R 
goal: Multiset R

full_name: Polynomial.mem_nthRoots
code: @[simp]
theorem mem_nthRoots {n : ℕ} (hn : 0 < n) {a x : R} : x ∈ nthRoots n a ↔ x ^ n = a 
goal: x ∈ Polynomial.nthRoots n a ↔ x ^ n = a

full_name: Polynomial.nthRoots_zero
code: @[simp]
theorem nthRoots_zero (r : R) : nthRoots 0 r = 0 
goal: Polynomial.nthRoots 0 r = 0

full_name: Polynomial.nthRoots_zero_right
code: @[simp]
theorem nthRoots_zero_right {R} [CommRing R] [IsDomain R] (n : ℕ) :
    nthRoots n (0 : R) = Multiset.replicate n 0 
goal: Polynomial.nthRoots n 0 = Multiset.replicate n 0

full_name: Polynomial.card_nthRoots
code: theorem card_nthRoots (n : ℕ) (a : R) : Multiset.card (nthRoots n a) ≤ n 
goal: Multiset.card (Polynomial.nthRoots n a) ≤ n

full_name: Polynomial.nthRoots_two_eq_zero_iff
code: @[simp]
theorem nthRoots_two_eq_zero_iff {r : R} : nthRoots 2 r = 0 ↔ ¬IsSquare r 
goal: Polynomial.nthRoots 2 r = 0 ↔ ¬IsSquare r

full_name: Polynomial.nthRootsFinset
code: /-- The multiset `nthRoots ↑n (1 : R)` as a Finset. -/
def nthRootsFinset (n : ℕ) (R : Type*) [CommRing R] [IsDomain R] : Finset R 
goal: Finset R

full_name: Polynomial.nthRootsFinset_def
code: lemma nthRootsFinset_def (n : ℕ) (R : Type*) [CommRing R] [IsDomain R] [DecidableEq R] :
    nthRootsFinset n R = Multiset.toFinset (nthRoots n (1 : R)) 
goal: Polynomial.nthRootsFinset n R = (Polynomial.nthRoots n 1).toFinset

full_name: Polynomial.mem_nthRootsFinset
code: @[simp]
theorem mem_nthRootsFinset {n : ℕ} (h : 0 < n) {x : R} :
    x ∈ nthRootsFinset n R ↔ x ^ (n : ℕ) = 1 
goal: x ∈ Polynomial.nthRootsFinset n R ↔ x ^ n = 1

full_name: Polynomial.nthRootsFinset_zero
code: @[simp]
theorem nthRootsFinset_zero : nthRootsFinset 0 R = ∅ 
goal: Polynomial.nthRootsFinset 0 R = ∅

full_name: Polynomial.mul_mem_nthRootsFinset
code: theorem mul_mem_nthRootsFinset
    {η₁ η₂ : R} (hη₁ : η₁ ∈ nthRootsFinset n R) (hη₂ : η₂ ∈ nthRootsFinset n R) :
    η₁ * η₂ ∈ nthRootsFinset n R 
goal: η₁ * η₂ ∈ Polynomial.nthRootsFinset n R

full_name: Polynomial.ne_zero_of_mem_nthRootsFinset
code: theorem ne_zero_of_mem_nthRootsFinset {η : R} (hη : η ∈ nthRootsFinset n R) : η ≠ 0 
goal: η ≠ 0

full_name: Polynomial.one_mem_nthRootsFinset
code: theorem one_mem_nthRootsFinset (hn : 0 < n) : 1 ∈ nthRootsFinset n R 
goal: 1 ∈ Polynomial.nthRootsFinset n R

full_name: Polynomial.zero_of_eval_zero
code: theorem zero_of_eval_zero [Infinite R] (p : R[X]) (h : ∀ x, p.eval x = 0) : p = 0 
goal: p = 0

full_name: Polynomial.funext
code: theorem funext [Infinite R] {p q : R[X]} (ext : ∀ r : R, p.eval r = q.eval r) : p = q 
goal: p = q

full_name: Polynomial.aroots
code: /-- Given a polynomial `p` with coefficients in a ring `T` and a `T`-algebra `S`, `aroots p S` is
the multiset of roots of `p` regarded as a polynomial over `S`. -/
noncomputable abbrev aroots (p : T[X]) (S) [CommRing S] [IsDomain S] [Algebra T S] : Multiset S 
goal: Multiset S

full_name: Polynomial.aroots_def
code: theorem aroots_def (p : T[X]) (S) [CommRing S] [IsDomain S] [Algebra T S] :
    p.aroots S = (p.map (algebraMap T S)).roots 
goal: p.aroots S = (Polynomial.map (algebraMap T S) p).roots

full_name: Polynomial.mem_aroots'
code: 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 
goal: a ∈ p.aroots S ↔ Polynomial.map (algebraMap T S) p ≠ 0 ∧ (Polynomial.aeval a) p = 0

full_name: Polynomial.mem_aroots
code: 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 
goal: a ∈ p.aroots S ↔ p ≠ 0 ∧ (Polynomial.aeval a) p = 0

full_name: Polynomial.aroots_mul
code: 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 
goal: (p * q).aroots S = p.aroots S + q.aroots S

full_name: Polynomial.aroots_X_sub_C
code: @[simp]
theorem aroots_X_sub_C [CommRing S] [IsDomain S] [Algebra T S]
    (r : T) : aroots (X - C r) S = {algebraMap T S r} 
goal: (Polynomial.X - Polynomial.C r).aroots S = {(algebraMap T S) r}

full_name: Polynomial.aroots_X
code: @[simp]
theorem aroots_X [CommRing S] [IsDomain S] [Algebra T S] :
    aroots (X : T[X]) S = {0} 
goal: Polynomial.X.aroots S = {0}

full_name: Polynomial.aroots_C
code: @[simp]
theorem aroots_C [CommRing S] [IsDomain S] [Algebra T S] (a : T) : (C a).aroots S = 0 
goal: (Polynomial.C a).aroots S = 0

full_name: Polynomial.aroots_zero
code: @[simp]
theorem aroots_zero (S) [CommRing S] [IsDomain S] [Algebra T S] : (0 : T[X]).aroots S = 0 
goal: Polynomial.aroots 0 S = 0

full_name: Polynomial.aroots_one
code: @[simp]
theorem aroots_one [CommRing S] [IsDomain S] [Algebra T S] :
    (1 : T[X]).aroots S = 0 
goal: Polynomial.aroots 1 S = 0

full_name: Polynomial.aroots_neg
code: @[simp]
theorem aroots_neg [CommRing S] [IsDomain S] [Algebra T S] (p : T[X]) :
    (-p).aroots S = p.aroots S 
goal: (-p).aroots S = p.aroots S

full_name: Polynomial.aroots_C_mul
code: @[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 
goal: (Polynomial.C a * p).aroots S = p.aroots S

full_name: Polynomial.aroots_smul_nonzero
code: @[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 
goal: (a • p).aroots S = p.aroots S

full_name: Polynomial.aroots_pow
code: @[simp]
theorem aroots_pow [CommRing S] [IsDomain S] [Algebra T S] (p : T[X]) (n : ℕ) :
    (p ^ n).aroots S = n • p.aroots S 
goal: (p ^ n).aroots S = n • p.aroots S

full_name: Polynomial.aroots_X_pow
code: theorem aroots_X_pow [CommRing S] [IsDomain S] [Algebra T S] (n : ℕ) :
    (X ^ n : T[X]).aroots S = n • ({0} : Multiset S) 
goal: (Polynomial.X ^ n).aroots S = n • {0}

full_name: Polynomial.aroots_C_mul_X_pow
code: 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) 
goal: (Polynomial.C a * Polynomial.X ^ n).aroots S = n • {0}

full_name: Polynomial.aroots_monomial
code: @[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) 
goal: ((Polynomial.monomial n) a).aroots S = n • {0}

full_name: Polynomial.rootSet
code: /-- The set of distinct roots of `p` in `S`.

If you have a non-separable polynomial, use `Polynomial.aroots` for the multiset
where multiple roots have the appropriate multiplicity. -/
def rootSet (p : T[X]) (S) [CommRing S] [IsDomain S] [Algebra T S] : Set S 
goal: Set S

full_name: Polynomial.rootSet_def
code: theorem rootSet_def (p : T[X]) (S) [CommRing S] [IsDomain S] [Algebra T S] [DecidableEq S] :
    p.rootSet S = (p.aroots S).toFinset 
goal: p.rootSet S = ↑(p.aroots S).toFinset

full_name: Polynomial.rootSet_C
code: @[simp]
theorem rootSet_C [CommRing S] [IsDomain S] [Algebra T S] (a : T) : (C a).rootSet S = ∅ 
goal: (Polynomial.C a).rootSet S = ∅

full_name: Polynomial.rootSet_zero
code: @[simp]
theorem rootSet_zero (S) [CommRing S] [IsDomain S] [Algebra T S] : (0 : T[X]).rootSet S = ∅ 
goal: Polynomial.rootSet 0 S = ∅

full_name: Polynomial.rootSet_one
code: @[simp]
theorem rootSet_one (S) [CommRing S] [IsDomain S] [Algebra T S] : (1 : T[X]).rootSet S = ∅ 
goal: Polynomial.rootSet 1 S = ∅

full_name: Polynomial.rootSet_neg
code: @[simp]
theorem rootSet_neg (p : T[X]) (S) [CommRing S] [IsDomain S] [Algebra T S] :
    (-p).rootSet S = p.rootSet S 
goal: (-p).rootSet S = p.rootSet S

full_name: Polynomial.rootSetFintype
code: instance rootSetFintype (p : T[X]) (S : Type*) [CommRing S] [IsDomain S] [Algebra T S] :
    Fintype (p.rootSet S) 
goal: Fintype ↑(p.rootSet S)

full_name: Polynomial.rootSet_finite
code: theorem rootSet_finite (p : T[X]) (S : Type*) [CommRing S] [IsDomain S] [Algebra T S] :
    (p.rootSet S).Finite 
goal: (p.rootSet S).Finite

full_name: Polynomial.bUnion_roots_finite
code: /-- The set of roots of all polynomials of bounded degree and having coefficients in a finite set
is finite. -/
theorem bUnion_roots_finite {R S : Type*} [Semiring R] [CommRing S] [IsDomain S] [DecidableEq S]
    (m : R →+* S) (d : ℕ) {U : Set R} (h : U.Finite) :
    (⋃ (f : R[X]) (_ : f.natDegree ≤ d ∧ ∀ i, f.coeff i ∈ U),
        ((f.map m).roots.toFinset.toSet : Set S)).Finite 
goal: (⋃ f, ⋃ (_ : f.natDegree ≤ d ∧ ∀ (i : ℕ), f.coeff i ∈ U), ↑(Polynomial.map m f).roots.toFinset).Finite

full_name: Polynomial.mem_rootSet'
code: theorem mem_rootSet' {p : T[X]} {S : Type*} [CommRing S] [IsDomain S] [Algebra T S] {a : S} :
    a ∈ p.rootSet S ↔ p.map (algebraMap T S) ≠ 0 ∧ aeval a p = 0 
goal: a ∈ p.rootSet S ↔ Polynomial.map (algebraMap T S) p ≠ 0 ∧ (Polynomial.aeval a) p = 0

full_name: Polynomial.mem_rootSet
code: theorem mem_rootSet {p : T[X]} {S : Type*} [CommRing S] [IsDomain S] [Algebra T S]
    [NoZeroSMulDivisors T S] {a : S} : a ∈ p.rootSet S ↔ p ≠ 0 ∧ aeval a p = 0 
goal: a ∈ p.rootSet S ↔ p ≠ 0 ∧ (Polynomial.aeval a) p = 0

full_name: Polynomial.mem_rootSet_of_ne
code: theorem mem_rootSet_of_ne {p : T[X]} {S : Type*} [CommRing S] [IsDomain S] [Algebra T S]
    [NoZeroSMulDivisors T S] (hp : p ≠ 0) {a : S} : a ∈ p.rootSet S ↔ aeval a p = 0 
goal: a ∈ p.rootSet S ↔ (Polynomial.aeval a) p = 0

full_name: Polynomial.rootSet_maps_to'
code: theorem rootSet_maps_to' {p : T[X]} {S S'} [CommRing S] [IsDomain S] [Algebra T S] [CommRing S']
    [IsDomain S'] [Algebra T S'] (hp : p.map (algebraMap T S') = 0 → p.map (algebraMap T S) = 0)
    (f : S →ₐ[T] S') : (p.rootSet S).MapsTo f (p.rootSet S') 
goal: Set.MapsTo (⇑f) (p.rootSet S) (p.rootSet S')

full_name: Polynomial.ne_zero_of_mem_rootSet
code: theorem ne_zero_of_mem_rootSet {p : T[X]} [CommRing S] [IsDomain S] [Algebra T S] {a : S}
    (h : a ∈ p.rootSet S) : p ≠ 0 
goal: p ≠ 0

full_name: Polynomial.aeval_eq_zero_of_mem_rootSet
code: theorem aeval_eq_zero_of_mem_rootSet {p : T[X]} [CommRing S] [IsDomain S] [Algebra T S] {a : S}
    (hx : a ∈ p.rootSet S) : aeval a p = 0 
goal: (Polynomial.aeval a) p = 0

full_name: Polynomial.rootSet_mapsTo
code: theorem rootSet_mapsTo {p : T[X]} {S S'} [CommRing S] [IsDomain S] [Algebra T S] [CommRing S']
    [IsDomain S'] [Algebra T S'] [NoZeroSMulDivisors T S'] (f : S →ₐ[T] S') :
    (p.rootSet S).MapsTo f (p.rootSet S') 
goal: Set.MapsTo (⇑f) (p.rootSet S) (p.rootSet S')

full_name: Polynomial.eq_zero_of_natDegree_lt_card_of_eval_eq_zero
code: lemma eq_zero_of_natDegree_lt_card_of_eval_eq_zero {R} [CommRing R] [IsDomain R]
    (p : R[X]) {ι} [Fintype ι] {f : ι → R} (hf : Function.Injective f)
    (heval : ∀ i, p.eval (f i) = 0) (hcard : natDegree p < Fintype.card ι) : p = 0 
goal: p = 0

full_name: Polynomial.eq_zero_of_natDegree_lt_card_of_eval_eq_zero'
code: lemma eq_zero_of_natDegree_lt_card_of_eval_eq_zero' {R} [CommRing R] [IsDomain R]
    (p : R[X]) (s : Finset R) (heval : ∀ i ∈ s, p.eval i = 0) (hcard : natDegree p < s.card) :
    p = 0 
goal: p = 0

full_name: Polynomial.eq_zero_of_forall_eval_zero_of_natDegree_lt_card
code: lemma eq_zero_of_forall_eval_zero_of_natDegree_lt_card
    (f : R[X]) (hf : ∀ r, f.eval r = 0) (hfR : f.natDegree < #R) : f = 0 
goal: f = 0

full_name: Polynomial.exists_eval_ne_zero_of_natDegree_lt_card
code: lemma exists_eval_ne_zero_of_natDegree_lt_card (f : R[X]) (hf : f ≠ 0) (hfR : f.natDegree < #R) :
    ∃ r, f.eval r ≠ 0 
goal: ∃ r, Polynomial.eval r f ≠ 0

full_name: Polynomial.monic_prod_multiset_X_sub_C
code: theorem monic_prod_multiset_X_sub_C : Monic (p.roots.map fun a => X - C a).prod 
goal: (Multiset.map (fun a => Polynomial.X - Polynomial.C a) p.roots).prod.Monic

full_name: Polynomial.prod_multiset_root_eq_finset_root
code: theorem prod_multiset_root_eq_finset_root [DecidableEq R] :
    (p.roots.map fun a => X - C a).prod =
      p.roots.toFinset.prod fun a => (X - C a) ^ rootMultiplicity a p 
goal: (Multiset.map (fun a => Polynomial.X - Polynomial.C a) p.roots).prod =
  ∏ a ∈ p.roots.toFinset, (Polynomial.X - Polynomial.C a) ^ Polynomial.rootMultiplicity a p

full_name: Polynomial.prod_multiset_X_sub_C_dvd
code: /-- The product `∏ (X - a)` for `a` inside the multiset `p.roots` divides `p`. -/
theorem prod_multiset_X_sub_C_dvd (p : R[X]) : (p.roots.map fun a => X - C a).prod ∣ p 
goal: (Multiset.map (fun a => Polynomial.X - Polynomial.C a) p.roots).prod ∣ p

full_name: Multiset.prod_X_sub_C_dvd_iff_le_roots
code: /-- A Galois connection. -/
theorem _root_.Multiset.prod_X_sub_C_dvd_iff_le_roots {p : R[X]} (hp : p ≠ 0) (s : Multiset R) :
    (s.map fun a => X - C a).prod ∣ p ↔ s ≤ p.roots 
goal: (Multiset.map (fun a => Polynomial.X - Polynomial.C a) s).prod ∣ p ↔ s ≤ p.roots

full_name: Polynomial.exists_prod_multiset_X_sub_C_mul
code: theorem exists_prod_multiset_X_sub_C_mul (p : R[X]) :
    ∃ q,
      (p.roots.map fun a => X - C a).prod * q = p ∧
        Multiset.card p.roots + q.natDegree = p.natDegree ∧ q.roots = 0 
goal: ∃ q,
  (Multiset.map (fun a => Polynomial.X - Polynomial.C a) p.roots).prod * q = p ∧
    Multiset.card p.roots + q.natDegree = p.natDegree ∧ q.roots = 0

full_name: Polynomial.C_leadingCoeff_mul_prod_multiset_X_sub_C
code: /-- A polynomial `p` that has as many roots as its degree
can be written `p = p.leadingCoeff * ∏(X - a)`, for `a` in `p.roots`. -/
theorem C_leadingCoeff_mul_prod_multiset_X_sub_C (hroots : Multiset.card p.roots = p.natDegree) :
    C p.leadingCoeff * (p.roots.map fun a => X - C a).prod = p 
goal: Polynomial.C p.leadingCoeff * (Multiset.map (fun a => Polynomial.X - Polynomial.C a) p.roots).prod = p

full_name: Polynomial.prod_multiset_X_sub_C_of_monic_of_roots_card_eq
code: /-- A monic polynomial `p` that has as many roots as its degree
can be written `p = ∏(X - a)`, for `a` in `p.roots`. -/
theorem prod_multiset_X_sub_C_of_monic_of_roots_card_eq (hp : p.Monic)
    (hroots : Multiset.card p.roots = p.natDegree) : (p.roots.map fun a => X - C a).prod = p 
goal: (Multiset.map (fun a => Polynomial.X - Polynomial.C a) p.roots).prod = p

full_name: Polynomial.Monic.isUnit_leadingCoeff_of_dvd
code: theorem Monic.isUnit_leadingCoeff_of_dvd {a p : R[X]} (hp : Monic p) (hap : a ∣ p) :
    IsUnit a.leadingCoeff 
goal: IsUnit a.leadingCoeff

full_name: Polynomial.Monic.irreducible_iff_degree_lt
code: /-- To check a monic polynomial is irreducible, it suffices to check only for
divisors that have smaller degree.

See also: `Polynomial.Monic.irreducible_iff_natDegree`.
-/
theorem Monic.irreducible_iff_degree_lt {p : R[X]} (p_monic : Monic p) (p_1 : p ≠ 1) :
    Irreducible p ↔ ∀ q, degree q ≤ ↑(p.natDegree / 2) → q ∣ p → IsUnit q 
goal: Irreducible p ↔ ∀ (q : Polynomial R), q.degree ≤ ↑(p.natDegree / 2) → q ∣ p → IsUnit q

full_name: Polynomial.le_rootMultiplicity_map
code: theorem le_rootMultiplicity_map {p : A[X]} {f : A →+* B} (hmap : map f p ≠ 0) (a : A) :
    rootMultiplicity a p ≤ rootMultiplicity (f a) (p.map f) 
goal: Polynomial.rootMultiplicity a p ≤ Polynomial.rootMultiplicity (f a) (Polynomial.map f p)

full_name: Polynomial.eq_rootMultiplicity_map
code: theorem eq_rootMultiplicity_map {p : A[X]} {f : A →+* B} (hf : Function.Injective f) (a : A) :
    rootMultiplicity a p = rootMultiplicity (f a) (p.map f) 
goal: Polynomial.rootMultiplicity a p = Polynomial.rootMultiplicity (f a) (Polynomial.map f p)

full_name: Polynomial.count_map_roots
code: theorem count_map_roots [IsDomain A] [DecidableEq B] {p : A[X]} {f : A →+* B} (hmap : map f p ≠ 0)
    (b : B) :
    (p.roots.map f).count b ≤ rootMultiplicity b (p.map f) 
goal: Multiset.count b (Multiset.map (⇑f) p.roots) ≤ Polynomial.rootMultiplicity b (Polynomial.map f p)

full_name: Polynomial.count_map_roots_of_injective
code: theorem count_map_roots_of_injective [IsDomain A] [DecidableEq B] (p : A[X]) {f : A →+* B}
    (hf : Function.Injective f) (b : B) :
    (p.roots.map f).count b ≤ rootMultiplicity b (p.map f) 
goal: Multiset.count b (Multiset.map (⇑f) p.roots) ≤ Polynomial.rootMultiplicity b (Polynomial.map f p)

full_name: Polynomial.map_roots_le
code: theorem map_roots_le [IsDomain A] [IsDomain B] {p : A[X]} {f : A →+* B} (h : p.map f ≠ 0) :
    p.roots.map f ≤ (p.map f).roots 
goal: Multiset.map (⇑f) p.roots ≤ (Polynomial.map f p).roots

full_name: Polynomial.map_roots_le_of_injective
code: theorem map_roots_le_of_injective [IsDomain A] [IsDomain B] (p : A[X]) {f : A →+* B}
    (hf : Function.Injective f) : p.roots.map f ≤ (p.map f).roots 
goal: Multiset.map (⇑f) p.roots ≤ (Polynomial.map f p).roots

full_name: Polynomial.card_roots_le_map
code: theorem card_roots_le_map [IsDomain A] [IsDomain B] {p : A[X]} {f : A →+* B} (h : p.map f ≠ 0) :
    Multiset.card p.roots ≤ Multiset.card (p.map f).roots 
goal: Multiset.card p.roots ≤ Multiset.card (Polynomial.map f p).roots

full_name: Polynomial.card_roots_le_map_of_injective
code: theorem card_roots_le_map_of_injective [IsDomain A] [IsDomain B] {p : A[X]} {f : A →+* B}
    (hf : Function.Injective f) : Multiset.card p.roots ≤ Multiset.card (p.map f).roots 
goal: Multiset.card p.roots ≤ Multiset.card (Polynomial.map f p).roots

full_name: Polynomial.roots_map_of_injective_of_card_eq_natDegree
code: theorem roots_map_of_injective_of_card_eq_natDegree [IsDomain A] [IsDomain B] {p : A[X]}
    {f : A →+* B} (hf : Function.Injective f) (hroots : Multiset.card p.roots = p.natDegree) :
    p.roots.map f = (p.map f).roots 
goal: Multiset.map (⇑f) p.roots = (Polynomial.map f p).roots