hex

35.8. HexPolyZGcd: checked integer-polynomial gcds🔗

35.8.1. Introduction🔗

HexPolyZGcd computes greatest common divisors in ℤ[x] together with exact cofactors and replayable coprimality evidence. Its fast routes use modular images, heuristic reconstruction, and subresultant chains. Every route passes through the same small checker before its answer becomes public.

The executable library is Mathlib-free. It builds on HexPolyZ, HexModular, and HexResultant, and it supplies the square-free decomposition used by integer-polynomial factorization.

35.8.2. Certificates and exact division🔗

🔗inductive type

Evidence that the two cofactors have no common nonunit factor.

Hex.ZPoly.CoprimeWitness.modular (p : Hex.ZMod64.Prime)
  (alpha beta : Hex.FpPoly p.m) : Hex.ZPoly.CoprimeWitness

A degree-preserving reduction and a Bezout identity over a prime field.

Hex.ZPoly.CoprimeWitness.constant (u v : Hex.ZPoly)
  (k : ) : Hex.ZPoly.CoprimeWitness

An integral polynomial combination equal to a nonzero constant.

🔗structure

A gcd candidate, its two exact cofactors, and checked coprimality data.

Hex.ZPoly.GcdCert.mk
gcd : Hex.ZPoly

The proposed normalized greatest common divisor.

cofL : Hex.ZPoly

The exact cofactor of the left input.

cofR : Hex.ZPoly

The exact cofactor of the right input.

coprime : Hex.ZPoly.CoprimeWitness

Replayable evidence that the two cofactors have no common nonunit.

🔗def

Check a gcd certificate. Every producer, including deterministic fallbacks, must pass through this function before its candidate is exposed.

🔗theorem
Hex.ZPoly.checkGcd_sound {f h : Hex.ZPoly} {c : Hex.ZPoly.GcdCert} (hc : f.checkGcd h c = true) : f = c.gcd * c.cofL h = c.gcd * c.cofR (d : Hex.ZPoly), d c.cofL d c.cofR d.IsUnit
Hex.ZPoly.checkGcd_sound {f h : Hex.ZPoly} {c : Hex.ZPoly.GcdCert} (hc : f.checkGcd h c = true) : f = c.gcd * c.cofL h = c.gcd * c.cofR (d : Hex.ZPoly), d c.cofL d c.cofR d.IsUnit

A successful checker establishes both exact cofactor identities and coprimality of the cofactors.

The checker verifies two exact product identities, the normalization convention, coprime cofactor contents, and one modular or integral Bezout witness. Candidate production is separate from certificate replay.

🔗def

The exact quotient f / g, or none when g = 0 or the executable integer-polynomial division does not reconstruct f exactly.

🔗theorem
Hex.ZPoly.divExact?_product {f g q : Hex.ZPoly} (h : f.divExact? g = some q) : q * g = f
Hex.ZPoly.divExact?_product {f g q : Hex.ZPoly} (h : f.divExact? g = some q) : q * g = f

A successful exact division carries the checked multiplication witness.

35.8.3. Gcd operations🔗

🔗def

Produce a checked gcd certificate. Mandatory zero and constant certificates run before content or x extraction. Remaining route-0 reduction runs next; rejected fast candidates and failed restoration fall through to total, data-only extended-subresultant route 4.

🔗def

Canonically normalized gcd of two integer polynomials. Exposure is limited to the projection equation gcd_eq_cert; gcdCert and its route search remain opaque to kernel replay.

🔗def

Exact cofactors belonging to the checked gcd.

🔗def

Fold gcd over a list; the empty-list convention is zero.

🔗def

Canonically normalized least common multiple.

The usual divisibility laws hold for the checked result, including the greatestness direction that downstream factorization algorithms need.

🔗theorem

The canonical gcd divides the left input.

🔗theorem

The canonical gcd divides the right input.

🔗theorem
Hex.ZPoly.dvd_gcd (d f h : Hex.ZPoly) (hf : d f) (hh : d h) : d f.gcd h
Hex.ZPoly.dvd_gcd (d f h : Hex.ZPoly) (hf : d f) (hh : d h) : d f.gcd h

Every common divisor divides the canonical gcd.

35.8.3.1. Worked example🔗

open Hex namespace HexPolyZGcdChapter def x1 : ZPoly := DensePoly.ofList [1, 1] def x2 : ZPoly := DensePoly.ofList [2, 1] def left : ZPoly := x1 * x1 * x2 def right : ZPoly := x1 * x2 * x2 #guard ZPoly.gcd left right == x1 * x2 end HexPolyZGcdChapter

35.8.4. Fast square-free decomposition🔗

🔗def
Hex.ZPoly.sqfDecomp (f : Hex.ZPoly) : Hex.ZPoly.PrimitiveSquareFreeDecomposition
Hex.ZPoly.sqfDecomp (f : Hex.ZPoly) : Hex.ZPoly.PrimitiveSquareFreeDecomposition

Integer-gcd replacement for primitiveSquareFreeDecomposition's rational Euclidean bottleneck. The return type and normalization convention are shared with the existing reference implementation.

🔗theorem
Hex.ZPoly.sqfDecomp_reassembly_signed (f : Hex.ZPoly) : have d := f.sqfDecomp; ε, (ε = 1 ε = -1) Hex.DensePoly.scale ε (d.squareFreeCore * d.repeatedPart) = d.primitive
Hex.ZPoly.sqfDecomp_reassembly_signed (f : Hex.ZPoly) : have d := f.sqfDecomp; ε, (ε = 1 ε = -1) Hex.DensePoly.scale ε (d.squareFreeCore * d.repeatedPart) = d.primitive

The fast square-free core and repeated part reassemble the primitive input up to the normalization sign.

🔗theorem
Hex.ZPoly.sqfDecomp_squareFreeCore (f : Hex.ZPoly) (hcore : f.sqfDecomp.squareFreeCore 0) : f.sqfDecomp.squareFreeCore.SquareFreeRat
Hex.ZPoly.sqfDecomp_squareFreeCore (f : Hex.ZPoly) (hcore : f.sqfDecomp.squareFreeCore 0) : f.sqfDecomp.squareFreeCore.SquareFreeRat

Every nonzero fast square-free core is square-free over Rat[x].

The implementation uses the checked integer gcd of a primitive polynomial and its derivative. Its proof compares the repeated factor with the rational reference decomposition, then cancels that factor from their signed reassembly laws.

35.8.5. The Mathlib correspondence🔗

HexPolyZGcdMathlib transports the divisibility and maximality results through the ring equivalence from ZPoly to Mathlib's Polynomial ℤ.

🔗theorem

Checked exact division succeeds precisely for a nonzero divisor that divides after transport to Mathlib polynomials.

The exact-division correspondence records a nonzero-divisor condition. This distinguishes the executable operation, which rejects division by zero, from the proposition 0 ∣ 0, which is true.