Theory of univariate polynomials #
THIS FILE IS SYNCHRONIZED WITH MATHLIB4. Any changes to this file require a corresponding PR to mathlib4.
This file defines polynomial R, the type of univariate polynomials over the semiring R, builds
a semiring structure on it, and gives basic definitions that are expanded in other files in this
directory.
Main definitions #
monomial n ais the polynomiala X^n. Note thatmonomial nis defined as anR-linear map.C ais the constant polynomiala. Note thatCis defined as a ring homomorphism.Xis the polynomialX, i.e.,monomial 1 1.p.sum fis∑ n in p.support, f n (p.coeff n), i.e., one sums the values of functions applied to coefficients of the polynomialp.p.erase nis the polynomialpin which one removes thec X^nterm.
There are often two natural variants of lemmas involving sums, depending on whether one acts on the
polynomials, or on the function. The naming convention is that one adds index when acting on
the polynomials. For instance,
sum_add_indexstates that(p + q).sum f = p.sum f + q.sum f;sum_addstates thatp.sum (λ n x, f n x + g n x) = p.sum f + p.sum g.- Notation to refer to
polynomial R, asR[X]orR[t].
Implementation #
Polynomials are defined using add_monoid_algebra R ℕ, where R is a semiring.
The variable X commutes with every polynomial p: lemma X_mul proves the identity
X * p = p * X. The relationship to add_monoid_algebra R ℕ is through a structure
to make polynomials irreducible from the point of view of the kernel. Most operations
are irreducible since Lean can not compute anyway with add_monoid_algebra. There are two
exceptions that we make semireducible:
- The zero polynomial, so that its coefficients are definitionally equal to
0. - The scalar action, to permit typeclass search to unfold it to resolve potential instance diamonds.
The raw implementation of the equivalence between R[X] and add_monoid_algebra R ℕ is
done through of_finsupp and to_finsupp (or, equivalently, rcases p when p is a polynomial
gives an element q of add_monoid_algebra R ℕ, and conversely ⟨q⟩ gives back p). The
equivalence is also registered as a ring equiv in polynomial.to_finsupp_iso. These should
in general not be used once the basic API for polynomials is constructed.
- to_finsupp : add_monoid_algebra R ℕ
polynomial R is the type of univariate polynomials over R.
Polynomials should be seen as (semi-)rings with the additional constructor X.
The embedding from R is called C.
Instances for polynomial
- polynomial.has_pow
- polynomial.normalized_gcd_monoid
- polynomial.wf_dvd_monoid
- polynomial.unique_factorization_monoid
- polynomial.has_sizeof_inst
- polynomial.has_zero
- polynomial.has_one
- polynomial.has_add
- polynomial.has_neg
- polynomial.has_sub
- polynomial.has_mul
- polynomial.smul_zero_class
- polynomial.inhabited
- polynomial.has_nat_cast
- polynomial.semiring
- polynomial.distrib_smul
- polynomial.distrib_mul_action
- polynomial.has_faithful_smul
- polynomial.module
- polynomial.smul_comm_class
- polynomial.is_scalar_tower
- polynomial.is_scalar_tower_right
- polynomial.is_central_scalar
- polynomial.unique
- polynomial.comm_semiring
- polynomial.has_int_cast
- polynomial.ring
- polynomial.comm_ring
- polynomial.nontrivial
- polynomial.has_repr
- polynomial.infinite
- polynomial.char_zero
- polynomial.has_well_founded
- polynomial.algebra_of_algebra
- polynomial.no_zero_divisors
- polynomial.is_domain
- polynomial.normalization_monoid
- polynomial.has_div
- polynomial.has_mod
- polynomial.euclidean_domain
- polynomial.char_p
- polynomial.is_noetherian_ring
Conversions to and from add_monoid_algebra #
Since R[X] is not defeq to add_monoid_algebra R ℕ, but instead is a structure wrapping
it, we have to copy across all the arithmetic operators manually, along with the lemmas about how
they unfold around polynomial.of_finsupp and polynomial.to_finsupp.
Equations
- polynomial.has_zero = {zero := {to_finsupp := 0}}
Equations
- polynomial.has_one = {one := {to_finsupp := 1}}
Equations
- polynomial.has_add = {add := add _inst_1}
Equations
- polynomial.has_neg = {neg := neg _inst_2}
Equations
- polynomial.has_sub = {sub := λ (a b : polynomial R), a + -b}
Equations
- polynomial.has_mul = {mul := mul _inst_1}
Equations
- polynomial.smul_zero_class = {to_has_smul := {smul := λ (r : S) (p : polynomial R), {to_finsupp := r • p.to_finsupp}}, smul_zero := _}
Equations
- polynomial.has_pow = {pow := λ (p : polynomial R) (n : ℕ), npow_rec n p}
A more convenient spelling of polynomial.of_finsupp.inj_eq in terms of iff.
Equations
- polynomial.inhabited = {default := 0}
Equations
- polynomial.has_nat_cast = {nat_cast := λ (n : ℕ), {to_finsupp := ↑n}}
Equations
- polynomial.semiring = function.injective.semiring polynomial.to_finsupp polynomial.to_finsupp_injective polynomial.to_finsupp_zero polynomial.to_finsupp_one polynomial.to_finsupp_add polynomial.to_finsupp_mul polynomial.semiring._proof_1 polynomial.to_finsupp_pow polynomial.semiring._proof_2
Equations
- polynomial.distrib_smul = function.injective.distrib_smul {to_fun := polynomial.to_finsupp _inst_1, map_zero' := _, map_add' := _} polynomial.to_finsupp_injective polynomial.distrib_smul._proof_1
Equations
- polynomial.distrib_mul_action = function.injective.distrib_mul_action {to_fun := polynomial.to_finsupp _inst_1, map_zero' := _, map_add' := _} polynomial.to_finsupp_injective polynomial.distrib_mul_action._proof_1
Equations
- polynomial.module = function.injective.module S {to_fun := polynomial.to_finsupp _inst_1, map_zero' := _, map_add' := _} polynomial.to_finsupp_injective polynomial.module._proof_1
Equations
- polynomial.unique = {to_inhabited := {default := inhabited.default polynomial.inhabited}, uniq := _}
Ring isomorphism between R[X] and add_monoid_algebra R ℕ. This is just an
implementation detail, but it can be useful to transfer results from finsupp to polynomials.
Equations
- polynomial.to_finsupp_iso R = {to_fun := polynomial.to_finsupp _inst_1, inv_fun := polynomial.of_finsupp _inst_1, left_inv := _, right_inv := _, map_mul' := _, map_add' := _}
The set of all n such that X^n has a non-zero coefficient.
Equations
- {to_finsupp := p}.support = p.support
monomial s a is the monomial a * X^s
Equations
- polynomial.monomial n = {to_fun := λ (t : R), {to_finsupp := finsupp.single n t}, map_add' := _, map_smul' := _}
C a is the constant polynomial a.
C is provided as a ring homomorphism.
Equations
- polynomial.C = {to_fun := (polynomial.monomial 0).to_fun, map_one' := _, map_mul' := _, map_zero' := _, map_add' := _}
X is the polynomial variable (aka indeterminate).
Equations
X commutes with everything, even when the coefficients are noncommutative.
Prefer putting constants to the left of X.
This lemma is the loop-avoiding simp version of polynomial.X_mul.
Prefer putting constants to the left of X ^ n.
This lemma is the loop-avoiding simp version of X_pow_mul.
Prefer putting constants to the left of X ^ n.
This lemma is the loop-avoiding simp version of X_pow_mul_assoc.
coeff p n (often denoted p.coeff n) is the coefficient of X^n in p.
Equations
- {to_finsupp := p}.coeff = ⇑p
Monomials generate the additive monoid of polynomials.
erase p n is the polynomial p in which the X^n term has been erased.
Equations
- polynomial.erase n {to_finsupp := p} = {to_finsupp := finsupp.erase n p}
Replace the coefficient of a p : R[X] at a given degree n : ℕ
by a given value a : R. If a = 0, this is equal to p.erase n
If p.nat_degree < n and a ≠ 0, this increases the degree to n.
Equations
- p.update n a = {to_finsupp := finsupp.update p.to_finsupp n a}
Equations
- polynomial.comm_semiring = function.injective.comm_semiring polynomial.to_finsupp polynomial.comm_semiring._proof_1 polynomial.comm_semiring._proof_2 polynomial.comm_semiring._proof_3 polynomial.comm_semiring._proof_4 polynomial.comm_semiring._proof_5 polynomial.comm_semiring._proof_6 polynomial.comm_semiring._proof_7 polynomial.comm_semiring._proof_8
Equations
- polynomial.has_int_cast = {int_cast := λ (n : ℤ), {to_finsupp := ↑n}}
Equations
- polynomial.ring = function.injective.ring polynomial.to_finsupp polynomial.ring._proof_1 polynomial.ring._proof_2 polynomial.ring._proof_3 polynomial.ring._proof_4 polynomial.ring._proof_5 polynomial.to_finsupp_neg polynomial.to_finsupp_sub polynomial.ring._proof_6 polynomial.ring._proof_7 polynomial.ring._proof_8 polynomial.ring._proof_9 polynomial.ring._proof_10
Equations
- polynomial.comm_ring = function.injective.comm_ring polynomial.to_finsupp polynomial.comm_ring._proof_1 polynomial.comm_ring._proof_2 polynomial.comm_ring._proof_3 polynomial.comm_ring._proof_4 polynomial.comm_ring._proof_5 polynomial.comm_ring._proof_6 polynomial.comm_ring._proof_7 polynomial.comm_ring._proof_8 polynomial.comm_ring._proof_9 polynomial.comm_ring._proof_10 polynomial.comm_ring._proof_11 polynomial.comm_ring._proof_12
Equations
- polynomial.has_repr = {repr := λ (p : polynomial R), ite (p = 0) "0" (list.foldr (λ (n : ℕ) (a : string), a ++ ite (a = "") "" " + " ++ ite (n = 0) ("C (" ++ repr (p.coeff n) ++ ")") (ite (n = 1) (ite (p.coeff n = 1) "X" ("C (" ++ repr (p.coeff n) ++ ") * X")) (ite (p.coeff n = 1) ("X ^ " ++ repr n) ("C (" ++ repr (p.coeff n) ++ ") * X ^ " ++ repr n)))) "" (finset.sort has_le.le p.support))}