Documentation

CompPoly.Univariate.Basic

Computable Univariate Polynomials #

This file defines CPolynomial R, the type of canonical univariate polynomials. Canonicality is tracked semantically by requiring the last stored coefficient, when present, to be nonzero.

This provides a unique representation for each polynomial, enabling stronger extensionality properties compared to the raw CPolynomial.Raw type.

def CompPoly.CPolynomial (R : Type u_2) [Zero R] :
Type u_2

Computable univariate polynomials are represented canonically with no trailing zeros.

A polynomial p : CPolynomial.Raw R is canonical if its last stored coefficient is nonzero whenever the underlying array is nonempty. This gives an instance-stable carrier while keeping the raw normalization algorithms available separately.

Raw.mul defers trimming to the end of its convolution fold (it accumulates with the untrimmed Raw.mulRaw and trims once). Raw.powBySq likewise routes through an untrimmed powBySqUntrimmed and trims once at the top of the repeated-squaring recursion. CPolynomial.divX skips trimming entirely: the input is canonical and extract 1 size only strips from the front, so the leading coefficient (when present) is preserved and the result is already canonical. The division wrappers (divByMonic, modByMonic, modByMonicRemainderOnly, modByMonicByReversal, div, mod) likewise skip the redundant post-trim: each underlying Raw algorithm bottoms out in operations (Raw.add, Raw.sub, subScaledShift) that already trim. CLagrange.basis folds the s.erase i factors with the untrimmed Raw.mulRaw via Quotient.liftOn on the underlying multiset and trims once at the end, and CLagrange.interpolate does the analogous deferred-trim sum via Raw.addRaw/Raw.mulRaw. Remaining opportunities to trim only at the end of an iterative computation: the Array.foldl accumulator in Bivariate/ToPoly.lean (toPoly_foldl_zipIdx_eq_sum), and the two ExtTreeMap.foldl monomial accumulators in Multivariate/Operations.lean. The NTT butterflyStage in Univariate/NTT/Transform.lean is not on this list: it operates on a scalar coefficient Array R and never calls trim.

Instances For
    theorem CompPoly.CPolynomial.ext {R : Type u_1} [Zero R] {p q : CPolynomial R} (h : p = q) :
    p = q

    Extensionality for canonical polynomials.

    theorem CompPoly.CPolynomial.ext_iff {R : Type u_1} [Zero R] {p q : CPolynomial R} :
    p = q p = q
    @[implicit_reducible]

    Canonical polynomials coerce to raw polynomials.

    @[implicit_reducible]

    The zero polynomial is canonical without any normalization assumptions.

    @[implicit_reducible]

    The zero polynomial provides the inhabited instance.

    @[implicit_reducible]
    instance CompPoly.CPolynomial.instBEq (R : Type u_2) [Zero R] [BEq R] :

    CPolynomial R has BEq when R does, comparing the underlying coefficient arrays.

    CPolynomial R has LawfulBEq when R does: p == q iff p = q.

    @[implicit_reducible]

    CPolynomial R has DecidableEq when R does, via the underlying Array R representation.

    @[simp]
    theorem CompPoly.CPolynomial.trim_eq {R : Type u_1} [Zero R] [BEq R] [LawfulBEq R] (p : CPolynomial R) :
    (↑p).trim = p

    Canonical computable polynomials are trim-stable.

    @[implicit_reducible]

    Addition of canonical polynomials (result is canonical).

    theorem CompPoly.CPolynomial.add_comm {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (p q : CPolynomial R) :
    p + q = q + p
    theorem CompPoly.CPolynomial.add_assoc {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (p q r : CPolynomial R) :
    p + q + r = p + (q + r)
    theorem CompPoly.CPolynomial.zero_add {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (p : CPolynomial R) :
    0 + p = p
    theorem CompPoly.CPolynomial.add_zero {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (p : CPolynomial R) :
    p + 0 = p
    def CompPoly.CPolynomial.nsmul {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (n : ) (p : CPolynomial R) :

    Scalar multiplication by a natural number (result is canonical).

    Instances For
      theorem CompPoly.CPolynomial.nsmul_zero {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (p : CPolynomial R) :
      nsmul 0 p = 0
      theorem CompPoly.CPolynomial.nsmul_succ {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (n : ) (p : CPolynomial R) :
      nsmul (n + 1) p = nsmul n p + p
      @[implicit_reducible]

      Multiplication of canonical polynomials.

      The product of two canonical polynomials is canonical because multiplication preserves the "no trailing zeros" property.

      @[implicit_reducible]

      The constant polynomial 1 is canonical, and is the Unit for multiplication.

      This is #[1], which has no trailing zeros.

      This proof does not work without the assumption that R is non-trivial.

      @[reducible]
      def CompPoly.CPolynomial.coeff {R : Type u_1} [Zero R] (p : CPolynomial R) (i : ) :
      R

      The coefficient of X^i in the polynomial. Returns 0 if i is out of bounds.

      Instances For
        def CompPoly.CPolynomial.ofArray {R : Type u_1} [Zero R] [BEq R] [LawfulBEq R] (coeffs : Array R) :

        Build a canonical polynomial from a dense coefficient array.

        Instances For
          theorem CompPoly.CPolynomial.coeff_ofArray {R : Type u_1} [Zero R] [BEq R] [LawfulBEq R] (coeffs : Array R) (i : ) :
          (ofArray coeffs).coeff i = coeffs.getD i 0

          Coefficients of ofArray are exactly the source array entries, with zero default.

          def CompPoly.CPolynomial.C {R : Type u_1} [Zero R] [BEq R] [LawfulBEq R] (r : R) :

          The constant polynomial C r.

          Instances For

            The variable X.

            Instances For

              The monic linear factor X - C x.

              Instances For
                def CompPoly.CPolynomial.monomial {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] [DecidableEq R] (n : ) (c : R) :

                Construct a canonical monomial c * X^n as a CPolynomial R.

                The result is canonical (no trailing zeros) when c ≠ 0. For example, monomial 2 3 represents 3 * X^2.

                Note: If c = 0, this returns 0 (the zero polynomial).

                Instances For

                  Return the degree of a CPolynomial.

                  Instances For

                    Natural number degree of a canonical polynomial.

                    Returns the degree as a natural number. For the zero polynomial, returns 0. This matches Mathlib's Polynomial.natDegree API.

                    Instances For

                      Return the leading coefficient of a CPolynomial as the last coefficient of the trimmed array, or 0 if the trimmed array is empty.

                      Instances For
                        def CompPoly.CPolynomial.eval {R : Type u_1} [Semiring R] (x : R) (p : CPolynomial R) :
                        R

                        Evaluate a polynomial at a point.

                        Instances For
                          def CompPoly.CPolynomial.eval₂ {R : Type u_1} {S : Type u_2} [Semiring R] [Semiring S] (f : R →+* S) (x : S) (p : CPolynomial R) :
                          S

                          Evaluate at x : S via a ring hom f : R →+* S; eval₂ f x p = f(a₀) + f(a₁)*x + f(a₂)*x² + ....

                          Instances For
                            @[inline, specialize #[]]
                            def CompPoly.CPolynomial.eval₂Horner {R : Type u_1} {S : Type u_2} [Semiring R] [Semiring S] (f : R →+* S) (x : S) (p : CPolynomial R) :
                            S

                            Evaluate at x : S via a ring hom using Horner's method.

                            Instances For
                              @[inline, specialize #[]]
                              def CompPoly.CPolynomial.evalHorner {R : Type u_1} [Semiring R] (x : R) (p : CPolynomial R) :
                              R

                              Evaluate a polynomial at a point using Horner's method.

                              Instances For
                                theorem CompPoly.CPolynomial.eval₂_horner_eq_eval₂ {R : Type u_1} {S : Type u_2} [Semiring R] [Semiring S] (f : R →+* S) (x : S) (p : CPolynomial R) :
                                eval₂Horner f x p = eval₂ f x p

                                Horner evaluation agrees with the sum-of-powers evaluation.

                                theorem CompPoly.CPolynomial.eval_horner_eq_eval {R : Type u_1} [Semiring R] (x : R) (p : CPolynomial R) :
                                evalHorner x p = eval x p

                                Horner evaluation agrees with the sum-of-powers evaluation.

                                The support of a polynomial: indices with nonzero coefficients.

                                Instances For

                                  Number of coefficients (length of the underlying array).

                                  Instances For

                                    Upper bound on degree: size - 1 if non-empty, if empty.

                                    Instances For

                                      Convert degreeBound to a natural number by sending to 0.

                                      Instances For
                                        def CompPoly.CPolynomial.monic {R : Type u_1} [Zero R] [One R] [BEq R] (p : CPolynomial R) :

                                        Check if a CPolynomial is monic, i.e. its leading coefficient is 1.

                                        Instances For

                                          The polynomial with the constant term removed; coeff (divX p) i = coeff p (i + 1).

                                          No post-extract trim is needed: since p is canonical, its last entry is nonzero, and extract 1 p.val.size strips only from the front, so the result is already canonical (vacuously when p.val.size ≤ 1).

                                          Instances For
                                            theorem CompPoly.CPolynomial.coeff_C {R : Type u_1} [Zero R] [BEq R] [LawfulBEq R] (r : R) (i : ) :
                                            (C r).coeff i = if i = 0 then r else 0

                                            Coefficient of the constant polynomial C r.

                                            theorem CompPoly.CPolynomial.coeff_X {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] [Nontrivial R] (i : ) :
                                            X.coeff i = if i = 1 then 1 else 0

                                            Coefficient of the variable X.

                                            @[simp]
                                            theorem CompPoly.CPolynomial.coeff_zero {R : Type u_1} [Zero R] (i : ) :
                                            coeff 0 i = 0

                                            Coefficient of the zero polynomial.

                                            theorem CompPoly.CPolynomial.coeff_one {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] [Nontrivial R] (i : ) :
                                            coeff 1 i = if i = 0 then 1 else 0

                                            Coefficient of the constant polynomial 1.

                                            theorem CompPoly.CPolynomial.coeff_add {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (p q : CPolynomial R) (i : ) :
                                            (p + q).coeff i = p.coeff i + q.coeff i

                                            Coefficient of a sum.

                                            theorem CompPoly.CPolynomial.coeff_monomial {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] [DecidableEq R] (n i : ) (c : R) :
                                            (monomial n c).coeff i = if i = n then c else 0

                                            Coefficient of a monomial.

                                            theorem CompPoly.CPolynomial.coeff_mul {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (p q : CPolynomial R) (k : ) :
                                            (p * q).coeff k = iFinset.range (k + 1), p.coeff i * q.coeff (k - i)

                                            Coefficient of a product (convolution sum).

                                            theorem CompPoly.CPolynomial.eq_iff_coeff {R : Type u_1} [Zero R] [BEq R] [LawfulBEq R] {p q : CPolynomial R} :
                                            p = q ∀ (i : ), p.coeff i = q.coeff i

                                            Two polynomials are equal iff they have the same coefficients.

                                            theorem CompPoly.CPolynomial.monomial_add {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] [DecidableEq R] (n : ) (a b : R) :
                                            monomial n (a + b) = monomial n a + monomial n b

                                            Monomials are additive in their coefficient.

                                            theorem CompPoly.CPolynomial.eq_zero_iff_coeff_zero {R : Type u_1} [Zero R] [BEq R] [LawfulBEq R] {p : CPolynomial R} :
                                            p = 0 ∀ (i : ), p.coeff i = 0

                                            Zero characterization: p = 0 iff all coefficients are zero.

                                            theorem CompPoly.CPolynomial.mem_support_iff {R : Type u_1} [Zero R] [BEq R] [LawfulBEq R] (p : CPolynomial R) (i : ) :
                                            i p.support p.coeff i 0

                                            An index is in the support iff the coefficient there is nonzero.

                                            The support is empty iff the polynomial is zero.

                                            @[simp]
                                            theorem CompPoly.CPolynomial.C_zero {R : Type u_1} [Zero R] [BEq R] [LawfulBEq R] :
                                            C 0 = 0

                                            The constant polynomial C 0 is zero.

                                            theorem CompPoly.CPolynomial.natDegree_C {R : Type u_1} [Zero R] [BEq R] [LawfulBEq R] (r : R) :
                                            (C r).natDegree = 0

                                            The natDegree of a constant polynomial C r is zero.

                                            theorem CompPoly.CPolynomial.support_C {R : Type u_1} [Zero R] [BEq R] [LawfulBEq R] {r : R} (hr : r 0) :
                                            (C r).support = {0}

                                            The support of a constant polynomial C r is {0}.

                                            theorem CompPoly.CPolynomial.support_monomial {R : Type u_1} [Semiring R] [DecidableEq R] [BEq R] [LawfulBEq R] {n : } {c : R} (hc : c 0) :

                                            The support of a nonzero monomial c * X^n is {n}.

                                            theorem CompPoly.CPolynomial.natDegree_monomial {R : Type u_1} [Semiring R] [DecidableEq R] [BEq R] [LawfulBEq R] {n : } {c : R} (hc : c 0) :

                                            The natDegree of a nonzero monomial c * X^n is n.

                                            The support of the sum of two polynomials is a subset of the union of their supports.

                                            theorem CompPoly.CPolynomial.eval_eq_sum_support {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (p : CPolynomial R) (x : R) :
                                            eval x p = ip.support, p.coeff i * x ^ i

                                            Evaluation equals the sum over support of coefficients times powers.

                                            theorem CompPoly.CPolynomial.eval₂_eq_sum_support {R : Type u_1} {S : Type u_2} [Semiring R] [BEq R] [LawfulBEq R] [Semiring S] (f : R →+* S) (p : CPolynomial R) (x : S) :
                                            eval₂ f x p = ip.support, f (p.coeff i) * x ^ i

                                            Evaluation via a ring hom equals the sum over support of mapped coefficients times powers.

                                            theorem CompPoly.CPolynomial.coeff_C_mul {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] [Nontrivial R] (p : CPolynomial R) (c : R) (i : ) :
                                            (C c * p).coeff i = c * p.coeff i
                                            theorem CompPoly.CPolynomial.coeff_X_mul_succ {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] [Nontrivial R] (p : CPolynomial R) (n : ) :
                                            (X * p).coeff (n + 1) = p.coeff n

                                            Lemmas on coefficients and multiplication by X.

                                            theorem CompPoly.CPolynomial.coeff_mul_X_succ {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] [Nontrivial R] (p : CPolynomial R) (n : ) :
                                            (p * X).coeff (n + 1) = p.coeff n
                                            theorem CompPoly.CPolynomial.coeff_extract_succ {R : Type u_1} [Zero R] (a : Raw R) (i : ) :
                                            Raw.coeff (Array.extract a 1) i = a.coeff (i + 1)
                                            theorem CompPoly.CPolynomial.coeff_divX {R : Type u_1} [Zero R] (p : CPolynomial R) (i : ) :
                                            p.divX.coeff i = p.coeff (i + 1)
                                            theorem CompPoly.CPolynomial.divX_size_lt {R : Type u_1} [Zero R] (p : CPolynomial R) (hp : Array.size p > 0) :
                                            theorem CompPoly.CPolynomial.induction_on {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] [Nontrivial R] {P : CPolynomial RProp} (p : CPolynomial R) (h0 : P 0) (hC : ∀ (a : R), P (C a)) (hadd : ∀ (p q : CPolynomial R), P pP qP (p + q)) (hX : ∀ (p : CPolynomial R), P pP (X * p)) :
                                            P p

                                            Induction principle for polynomials (mirrors mathlib's Polynomial.induction_on).

                                            theorem CompPoly.CPolynomial.degree_eq_support_max_aux_degree {R : Type u_1} [Zero R] [BEq R] [LawfulBEq R] (p : CPolynomial R) {k : Fin (Array.size p)} (hk : (↑p).lastNonzero = some k) :
                                            p.degree = k

                                            Lemma for degree_eq_support_max: degree in terms of lastNonzero.

                                            theorem CompPoly.CPolynomial.degree_eq_support_max_aux_lastNonzero {R : Type u_1} [Zero R] [BEq R] [LawfulBEq R] (p : CPolynomial R) (hp : p 0) :
                                            ∃ (k : Fin (Array.size p)), (↑p).lastNonzero = some k
                                            theorem CompPoly.CPolynomial.degree_eq_support_max {R : Type u_1} [Zero R] [BEq R] [LawfulBEq R] (p : CPolynomial R) (hp : p 0) :
                                            np.support, p.degree = n

                                            Degree equals the maximum of the support when the polynomial is non-zero. Here p.degree = some n where n is the maximum index in p.support.

                                            theorem CompPoly.CPolynomial.degree_eq_natDegree {R : Type u_1} [Zero R] (p : CPolynomial R) (hp : p 0) :

                                            When p ≠ 0, degree p equals natDegree p (as WithBot).

                                            Lemma for computing the degree of 0 in proofs.

                                            theorem CompPoly.CPolynomial.natDegree_eq_support_sup {R : Type u_1} [Zero R] [BEq R] [LawfulBEq R] (p : CPolynomial R) :
                                            p.natDegree = p.support.sup fun (n : ) => n

                                            The natural degree is the maximum element of the support.

                                            theorem CompPoly.CPolynomial.le_natDegree_of_ne_zero {R : Type u_1} [Zero R] [BEq R] [LawfulBEq R] {p : CPolynomial R} {i : } (h : p.coeff i 0) :

                                            If coeff p i ≠ 0 then i ≤ p.natDegree.

                                            The natDegree of a sum is at most the max of the natDegrees.

                                            theorem CompPoly.CPolynomial.leadingCoeff_ne_zero {R : Type u_1} [Zero R] [BEq R] [LawfulBEq R] {p : CPolynomial R} (h : p 0) :

                                            The leading coefficient of a nonzero polynomial is nonzero.

                                            Quotient of p by a monic polynomial q. Matches Mathlib's Polynomial.divByMonic.

                                            Instances For

                                              Remainder of p modulo a monic polynomial q. Matches Mathlib's Polynomial.modByMonic.

                                              Instances For

                                                Remainder of p modulo a monic polynomial q, using a remainder-only implementation.

                                                Instances For

                                                  Remainder of p modulo a monic polynomial q, using reversal and low products.

                                                  Instances For

                                                    The remainder-only monic remainder agrees with the canonical monic remainder.

                                                    def CompPoly.CPolynomial.div {R : Type u_1} [Field R] [BEq R] [LawfulBEq R] (p q : CPolynomial R) :

                                                    Quotient of p by q (when R is a field).

                                                    Instances For
                                                      @[simp]
                                                      theorem CompPoly.CPolynomial.div_zero {R : Type u_1} [Field R] [BEq R] [LawfulBEq R] (p : CPolynomial R) :
                                                      p.div 0 = 0

                                                      Any CPolynomial divided by the zero polynomial gives the zero polynomial.

                                                      def CompPoly.CPolynomial.mod {R : Type u_1} [Field R] [BEq R] [LawfulBEq R] (p q : CPolynomial R) :

                                                      Remainder of p modulo q (when R is a field).

                                                      Instances For
                                                        @[simp]
                                                        theorem CompPoly.CPolynomial.mod_zero {R : Type u_1} [Field R] [BEq R] [LawfulBEq R] (p : CPolynomial R) :
                                                        p.mod 0 = 0

                                                        Any CPolynomial modulo the zero polynomial gives the zero polynomial.

                                                        @[implicit_reducible]
                                                        @[implicit_reducible]

                                                        Normalize a nonzero polynomial to monic form. The zero polynomial stays zero.

                                                        Instances For

                                                          Euclidean gcd with explicit fuel, normalized to a monic result.

                                                          Instances For

                                                            Monic Euclidean gcd for canonical univariate polynomials.

                                                            Instances For
                                                              theorem CompPoly.CPolynomial.one_mul {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] [Nontrivial R] (p : CPolynomial R) :
                                                              1 * p = p
                                                              theorem CompPoly.CPolynomial.mul_one {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] [Nontrivial R] (p : CPolynomial R) :
                                                              p * 1 = p
                                                              theorem CompPoly.CPolynomial.mul_assoc {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (p q r : CPolynomial R) :
                                                              p * q * r = p * (q * r)
                                                              theorem CompPoly.CPolynomial.zero_mul {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (p : CPolynomial R) :
                                                              0 * p = 0
                                                              theorem CompPoly.CPolynomial.mul_zero {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (p : CPolynomial R) :
                                                              p * 0 = 0
                                                              theorem CompPoly.CPolynomial.mul_add {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (p q r : CPolynomial R) :
                                                              p * (q + r) = p * q + p * r
                                                              theorem CompPoly.CPolynomial.add_mul {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (p q r : CPolynomial R) :
                                                              (p + q) * r = p * r + q * r
                                                              theorem CompPoly.CPolynomial.pow_is_trimmed {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] [Nontrivial R] (p : Raw R) (n : ) :
                                                              (p ^ n).trim = p ^ n
                                                              theorem CompPoly.CPolynomial.pow_succ_right {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] [Nontrivial R] (p : Raw R) (n : ) :
                                                              p ^ (n + 1) = p ^ n * p
                                                              @[implicit_reducible]

                                                              CPolynomial R forms a commutative monoid when R is a semiring.

                                                              @[implicit_reducible]

                                                              CPolynomial R forms a semiring when R is a semiring.

                                                              The semiring structure extends the AddCommGroup structure with multiplication. All operations preserve the canonical property (no trailing zeros).

                                                              @[simp]
                                                              theorem CompPoly.CPolynomial.natCast_eq_C {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] [Nontrivial R] (n : ) :
                                                              n = C n
                                                              theorem CompPoly.CPolynomial.val_pow {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] [Nontrivial R] (p : CPolynomial R) (n : ) :
                                                              ↑(p ^ n) = p ^ n

                                                              The underlying Raw value of p ^ n equals p.val ^ n (using the Raw Pow instance). This bridges the optimized powBySq used in the Semiring instance with the spec pow.

                                                              theorem CompPoly.CPolynomial.C_mul_X_pow_eq_monomial {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] [DecidableEq R] [Nontrivial R] (r : R) (n : ) :
                                                              C r * X ^ n = monomial n r

                                                              C r * X^n = monomial n r as canonical polynomials.

                                                              theorem CompPoly.CPolynomial.coeff_finset_sum {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] {ι : Type u_2} [DecidableEq ι] (s : Finset ι) (f : ιCPolynomial R) (n : ) :
                                                              (s.sum f).coeff n = is, (f i).coeff n

                                                              Distribute CPolynomial.coeff over a Finset.sum.

                                                              theorem CompPoly.CPolynomial.mul_comm {R : Type u_1} [CommSemiring R] [BEq R] [LawfulBEq R] (p q : CPolynomial R) :
                                                              p * q = q * p
                                                              @[implicit_reducible]

                                                              CPolynomial R forms a commutative semiring when R is a commutative semiring.

                                                              Commutativity follows from the commutativity of multiplication in the base ring.

                                                              @[implicit_reducible]
                                                              @[implicit_reducible]
                                                              def CompPoly.CPolynomial.erase {R : Type u_1} [Zero R] [BEq R] [LawfulBEq R] (n : ) (p : CPolynomial R) :

                                                              Erase the coefficient at index n (same as p except coeff n = 0, then trimmed).

                                                              Uses an in-place Array.setIfInBounds and avoids allocating a length-n monomial array plus the padding/zip passes of sub.

                                                              Instances For
                                                                theorem CompPoly.CPolynomial.coeff_erase {R : Type u_1} [Zero R] [BEq R] [LawfulBEq R] (n i : ) (p : CPolynomial R) :
                                                                (erase n p).coeff i = if i = n then 0 else p.coeff i

                                                                Coefficient of erase n p: zero at n, otherwise coeff p i.

                                                                Leading coefficient equals the coefficient at natDegree.

                                                                A polynomial equals its leading monomial plus the rest (erase at natDegree).

                                                                theorem CompPoly.CPolynomial.coeff_neg {R : Type u_1} [Ring R] [BEq R] [LawfulBEq R] (p : CPolynomial R) (i : ) :
                                                                (-p).coeff i = -p.coeff i
                                                                theorem CompPoly.CPolynomial.coeff_sub {R : Type u_1} [Ring R] [BEq R] [LawfulBEq R] (p q : CPolynomial R) (i : ) :
                                                                (p - q).coeff i = p.coeff i - q.coeff i
                                                                theorem CompPoly.CPolynomial.erase_correct {R : Type u_1} [Ring R] [BEq R] [LawfulBEq R] [DecidableEq R] (n : ) (p : CPolynomial R) :
                                                                erase n p = p - monomial n (p.coeff n)

                                                                The in-place erase agrees with the subtraction-based characterization: erase n p equals p - monomial n (p.coeff n).

                                                                theorem CompPoly.CPolynomial.neg_add_cancel {R : Type u_1} [Ring R] [BEq R] [LawfulBEq R] (p : CPolynomial R) :
                                                                -p + p = 0
                                                                @[implicit_reducible]

                                                                CPolynomial R forms a ring when R is a ring.

                                                                The ring structure extends the semiring structure with negation and subtraction. Most of the structure is already provided by the Semiring instance.

                                                                @[implicit_reducible]

                                                                CPolynomial R forms a commutative ring when R is a commutative ring.

                                                                This combines the CommSemiring and Ring structures.

                                                                @[implicit_reducible]
                                                                instance CompPoly.CPolynomial.smul {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] :

                                                                Scalar multiplication for canonical polynomials: multiply each coefficient by r, then trim to restore canonicity.

                                                                theorem CompPoly.CPolynomial.coeff_smul {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (r : R) (p : CPolynomial R) (i : ) :
                                                                (r p).coeff i = r * p.coeff i

                                                                Coefficient of a scalar multiple.

                                                                theorem CompPoly.CPolynomial.smul_zero {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (r : R) :
                                                                r 0 = 0

                                                                Scalar multiplication on 0 gives 0.

                                                                theorem CompPoly.CPolynomial.smul_eq_of_coeff_eq {R : Type u_1} [Zero R] [BEq R] [LawfulBEq R] {p q : CPolynomial R} (h : Raw.Trim.equiv p q) :
                                                                p = q

                                                                Helper lemma: Two CPolynomials are equal if the underlying Raw CPolynomials are trim equivalent.

                                                                theorem CompPoly.CPolynomial.smul_add {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (r : R) (p q : CPolynomial R) :
                                                                r (p + q) = r p + r q

                                                                Scalar multiplication distributes.

                                                                theorem CompPoly.CPolynomial.add_smul {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (r s : R) (p : CPolynomial R) :
                                                                (r + s) p = r p + s p

                                                                Scalar multiplication distributes across scalar addition.

                                                                theorem CompPoly.CPolynomial.zero_smul {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (p : CPolynomial R) :
                                                                0 p = 0

                                                                Scalar multiplication by 0 gives 0.

                                                                theorem CompPoly.CPolynomial.one_smul {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (p : CPolynomial R) :
                                                                1 p = p

                                                                Scalar multiplication on p by 1 gives p.

                                                                theorem CompPoly.CPolynomial.mul_smul {R : Type u_1} [Semiring R] [BEq R] [LawfulBEq R] (r s : R) (p : CPolynomial R) :
                                                                (r * s) p = r s p

                                                                Scalar multiplication is associative.

                                                                @[implicit_reducible]

                                                                CPolynomial forms a module when R is a semiring.