Documentation

HexPolyZ.IntegerPolynomial

@[reducible, inline]
abbrev Hex.ZPoly :

Integer polynomials represented by the dense normalized coefficient type from HexPoly.

Equations
Instances For
    instance Hex.instAssociativeZPolyHMul :
    Std.Associative fun (x1 x2 : ZPoly) => x1 * x2

    ZPoly is a multiplicative monoid for Std, so the shared List.foldl_mul_* algebra and the standard List.foldl_assoc apply to fold-products of integer polynomials.

    def Hex.ZPoly.congr (f g : ZPoly) (m : Nat) :

    Coefficientwise congruence modulo m.

    Equations
    Instances For
      def Hex.ZPoly.coprimeModP (f g : ZPoly) (p : Nat) :

      Two integer polynomials are coprime mod p when they admit a Bezout combination congruent to 1 modulo p.

      Equations
      Instances For

        The nonnegative gcd of the coefficients of f.

        Equations
        Instances For

          Divide every coefficient by the content to obtain a primitive polynomial.

          Equations
          Instances For
            def Hex.ZPoly.dilate (c : Int) (p : ZPoly) :

            Substitute the variable X ↦ c * X: the i-th coefficient is multiplied by c ^ i.

            On a monic transform c^(d-1) · core(X / c), this is the inverse of the integer-scaling substitution: it maps a monic factor g of the transform to g(c · X), an integer multiple of the corresponding factor of core. Composing with Hex.ZPoly.primitivePart recovers the primitive integer factor of core. This is not the same as Hex.DensePoly.scale, which multiplies the whole polynomial by a constant.

            Equations
            Instances For
              theorem Hex.ZPoly.coeff_dilate (c : Int) (p : ZPoly) (n : Nat) :

              The n-th coefficient of dilate c p is c ^ n times the n-th coefficient of p.

              Reflection in the origin preserves the stored coefficient count.

              @[simp]

              Reflection in the origin is an involution on integer polynomials.

              theorem Hex.ZPoly.dilate_neg_one_ne_zero {p : ZPoly} (hp : p 0) :
              dilate (-1) p 0

              Reflection in the origin preserves nonzeroness.

              @[simp]

              Reflection in the origin preserves integer content.

              @[simp]

              Reflection in the origin preserves the optional degree.

              The reflected leading coefficient differs only by the degree-parity sign.

              @[simp]
              theorem Hex.ZPoly.dilate_one (p : ZPoly) :
              dilate 1 p = p

              Dilation by 1 is the identity: dilate 1 p = p. The simp normal form for the trivial dilation.

              A Hex.ZPoly is primitive when its content is 1.

              Equations
              Instances For

                Reflection in the origin preserves primitivity.

                A Hex.ZPoly is a unit iff it is the constant polynomial 1 or -1.

                Equations
                Instances For
                  @[instance_reducible]

                  Hex.ZPoly.IsUnit is decidable: it reduces to equality with the constant polynomials C 1 or C (-1), both of which are decidable.

                  Equations

                  The Hex.ZPoly.IsUnit predicate is exactly equality with the constant polynomial 1 or the constant polynomial -1.

                  @[simp]

                  The polynomial 1 is a unit, since (1 : ZPoly) is the constant polynomial C 1.

                  @[simp]

                  The constant polynomial C 1 is a unit.

                  @[simp]

                  The constant polynomial C (-1) is a unit.

                  theorem Hex.ZPoly.isUnit_of_eq_one {f : ZPoly} (h : f = 1) :

                  Equality to 1 is the common constructor form for IsUnit.

                  theorem Hex.ZPoly.isUnit_of_eq_neg_one {f : ZPoly} (h : f = -1) :

                  Equality to -1 is the common constructor form for IsUnit.

                  @[simp]

                  The polynomial -1 is a unit.

                  View an integer polynomial as a rational polynomial.

                  Equations
                  Instances For
                    @[simp]

                    Coefficients of toRatPoly f are the rational casts of the coefficients of f.

                    @[simp]

                    Rational conversion sends the zero integer polynomial to the zero rational polynomial. The simp normal form for the zero case.

                    @[simp]

                    Rational conversion sends the constant integer polynomial C c to the constant rational polynomial C (c : Rat). The simp normal form for the constant case.

                    @[simp]

                    Rational conversion sends the unit integer polynomial 1 to the rational polynomial 1, since (1 : ZPoly) is the constant polynomial C 1. The simp normal form for the one case.

                    Rational conversion commutes with scaling an integer polynomial by an integer.

                    Rational conversion preserves the dense size of an integer polynomial.

                    A nonzero integer polynomial remains nonzero after coefficientwise rational casting.

                    Rational conversion preserves multiplication of integer polynomials.

                    Negate f when its leading coefficient is negative, normalizing a primitive part to have nonnegative leading sign.

                    Equations
                    Instances For

                      Clear denominators in a rational polynomial and return the primitive integer representative of the resulting rational associate.

                      Equations
                      Instances For

                        A rational polynomial is a rational scalar multiple of the rationalization of its integer primitive part.

                        Executable primitive square-free decomposition data for integer-polynomial normalization.

                        primitive is the content-free input. squareFreeCore is computed over Rat[x] as primitive / gcd(primitive, primitive'), then converted back to a primitive integer representative. repeatedPart records the same rational gcd, also converted to a primitive integer representative. The proof layer relates these representatives back to the primitive input up to a rational unit.

                        • primitive : ZPoly

                          The input divided by its content and normalized to positive leading coefficient.

                        • squareFreeCore : ZPoly

                          A primitive representative of the product of the distinct irreducible factors.

                        • repeatedPart : ZPoly

                          A primitive representative of the gcd of the primitive polynomial and its derivative.

                        Instances For

                          Square-free over Rat[x], up to the executable rational gcd's unit factor.

                          Equations
                          Instances For
                            @[instance_reducible]

                            SquareFreeRat is by definition a Nat size inequality on the executable rational gcd, so Nat.decLe decides it. Drivers branch on this instance for their square-freeness precondition.

                            Equations

                            Compute the primitive square-free normalization data needed by the integer factorization computation.

                            Equations
                            • One or more equations did not get rendered due to their size.
                            Instances For
                              theorem Hex.ZPoly.congr_refl (f : ZPoly) (m : Nat) :
                              f.congr f m

                              Coefficientwise congruence modulo m is reflexive.

                              theorem Hex.ZPoly.congr_symm (f g : ZPoly) (m : Nat) (hfg : f.congr g m) :
                              g.congr f m

                              Coefficientwise congruence modulo m is symmetric.

                              theorem Hex.ZPoly.congr_trans (f g h : ZPoly) (m : Nat) (hfg : f.congr g m) (hgh : g.congr h m) :
                              f.congr h m

                              Coefficientwise congruence modulo m is transitive.

                              theorem Hex.ZPoly.congr_add (f g f' g' : ZPoly) (m : Nat) (hf : f.congr f' m) (hg : g.congr g' m) :
                              (f + g).congr (f' + g') m

                              Addition preserves coefficientwise congruence modulo m in both inputs.

                              theorem Hex.ZPoly.congr_mul (f g f' g' : ZPoly) (m : Nat) (hf : f.congr f' m) (hg : g.congr g' m) :
                              (f * g).congr (f' * g') m

                              Multiplication preserves coefficientwise congruence modulo m in both inputs.

                              Scaling the primitive part by the content reconstructs the original integer polynomial.

                              The content of an integer polynomial divides every coefficient.

                              theorem Hex.ZPoly.dvd_content_of_nat_dvd_coeff (f : ZPoly) (d : Nat) (h : ∀ (n : Nat), d DensePoly.coeff f n) :
                              d f.content

                              If a natural number divides every coefficient, then its integer cast divides the content.

                              theorem Hex.ZPoly.natCast_dvd_content_of_dvd_coeff (f : ZPoly) (d : Nat) (h : ∀ (n : Nat), d DensePoly.coeff f n) :
                              d f.content

                              Alias for dvd_content_of_nat_dvd_coeff with the divisibility conclusion written for the natural number cast to Int.

                              If the content of f is nonzero, then the primitive part of f is primitive.

                              A primitive integer polynomial is equal to its primitive part.

                              theorem Hex.ZPoly.primitive_mul (p q : ZPoly) (hp : p.Primitive) (hq : q.Primitive) :
                              (p * q).Primitive

                              The product of primitive integer polynomials is primitive.

                              theorem Hex.ZPoly.content_mul (p q : ZPoly) :

                              Hex.ZPoly-level wrapper for Hex.DensePoly.content_mul: the content of a product of integer polynomials is the product of their contents.

                              Hex.ZPoly-level wrapper for Hex.DensePoly.primitivePart_mul (Gauss's lemma): the primitive part of a product of integer polynomials is the product of their primitive parts.

                              The top coefficient of a product of nonzero integer polynomials is the product of their top coefficients.

                              The size of a product of nonzero integer polynomials is one less than the sum of their sizes.

                              A nonzero integer polynomial has positive dense size.

                              The leading coefficient of a product of nonzero integer polynomials is the product of their leading coefficients.

                              A product of integer polynomials with positive leading coefficients has positive leading coefficient.

                              Multiplication by an integer constant agrees with coefficient scaling.

                              Nonzero integer scalar multiplication preserves the stored size.

                              Leading coefficient after nonzero integer scalar multiplication.

                              Shifting a nonzero polynomial by x^k preserves its leading coefficient.

                              theorem Hex.ZPoly.mul_ne_zero_of_ne_zero (p q : ZPoly) (hp : p 0) (hq : q 0) :
                              p * q 0

                              Integer dense polynomials have no zero divisors.

                              theorem Hex.ZPoly.mul_right_cancel_of_ne_zero {p q r : ZPoly} (hr : r 0) (h : p * r = q * r) :
                              p = q

                              Right cancellation for multiplication by a nonzero integer polynomial.

                              theorem Hex.ZPoly.size_le_of_dvd_nonzero {d r : ZPoly} (hd : d 0) (hr : r 0) :

                              A nonzero divisor of a nonzero integer polynomial has no larger dense size.

                              theorem Hex.ZPoly.divMod_reconstruction_of_monic (target candidate : ZPoly) (hmonic : DensePoly.Monic candidate) :
                              (DensePoly.divMod target candidate).fst * candidate + (DensePoly.divMod target candidate).snd = target

                              Euclidean reconstruction for a monic integer divisor: the executable dense-polynomial division recomposes the dividend, quot * candidate + rem = target, for any dividend. This is the monic specialization over Int of DensePoly.divMod_reconstruction; the leading-coefficient cancellation invariant it requires holds because a monic divisor has leading coefficient 1. Unlike divMod_eq_of_monic_mul_eq, no exact-multiple hypothesis is needed, so the remainder may be nonzero.

                              theorem Hex.ZPoly.divMod_remainder_eq_zero_of_monic_mul_eq (target candidate quotient : ZPoly) (hmonic : DensePoly.Monic candidate) (hdegree : 0 < DensePoly.natDegree candidate) (hmul : quotient * candidate = target) :
                              (DensePoly.divMod target candidate).snd = 0

                              If a monic positive-degree integer divisor has an exact product witness, the executable dense-polynomial division returns zero remainder.

                              theorem Hex.ZPoly.divMod_eq_of_monic_mul_eq (target candidate quotient : ZPoly) (hmonic : DensePoly.Monic candidate) (hdegree : 0 < DensePoly.natDegree candidate) (hmul : quotient * candidate = target) :
                              DensePoly.divMod target candidate = (quotient, 0)

                              If a monic positive-degree integer divisor has an exact product witness, the executable dense-polynomial division returns the witnessed quotient and zero remainder.

                              theorem Hex.ZPoly.divMod_eq_mul (target candidate quotient : ZPoly) (hpos_lc : 0 < DensePoly.leadingCoeff candidate) (hmul : quotient * candidate = target) :
                              DensePoly.divMod target candidate = (quotient, 0)

                              Non-monic exact-multiple divMod identity: if the divisor candidate has positive leading coefficient and the dividend factors as quotient * candidate, the executable dense-polynomial division returns the witnessed quotient and zero remainder. Sits one level above divMod_eq_of_monic_mul_eq, dropping the monic requirement at the cost of needing 0 < candidate.leadingCoeff to discharge the integer-division exactness side-conditions.