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 a
is the polynomiala X^n
. Note thatmonomial n
is defined as anR
-linear map.C a
is the constant polynomiala
. Note thatC
is defined as a ring homomorphism.X
is the polynomialX
, i.e.,monomial 1 1
.p.sum f
is∑ 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 n
is the polynomialp
in which one removes thec X^n
term.
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_index
states that(p + q).sum f = p.sum f + q.sum f
;sum_add
states 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))}