The fixed word-sized prime carrying the divisibility obstruction.
Any prime below 2 ^ 31 satisfies ZMod64.Bounds; 2 ^ 26 - 5 is large enough
that an accidental zero remainder costs at most one exact division that would
have been performed anyway, and small enough that its trial-division primality
proof is cheap to check in the kernel.
Equations
- Hex.obstructionPrime = 67108859
Instances For
obstructionPrime fits the word-arithmetic bounds of ZMod64.
obstructionPrime is prime, by kernel-checked trial division.
ZMod64 arithmetic modulo obstructionPrime is arithmetic in a prime
field, by obstructionPrime_prime.
The image of an integer polynomial in 𝔽_q[X].
Equations
Instances For
The recombination target's image in 𝔽_q[X], computed once for a whole
subset-cardinality level rather than once per candidate.
The subtype proof pins the stored array to the reference reduction, so a traversal reading this is interchangeable with one reducing the target at every leaf.
Equations
- Hex.TargetImage target = { image : Hex.FpPoly Hex.obstructionPrime // image = Hex.obstructionImage target }
Instances For
Reduce a recombination target once.
Equations
- Hex.targetImage target = ⟨Hex.obstructionImage target, ⋯⟩
Instances For
Reference form of the obstruction: the 𝔽_q[X] remainder of the reduced
target by the reduced candidate.
Equations
- Hex.obstructionRemainder target candidate = Hex.DensePoly.mod (Hex.obstructionImage target) (Hex.obstructionImage candidate)
Instances For
The divisibility obstruction: true exactly when the reduced candidate
leaves a nonzero remainder in the reduced target, which certifies that the
candidate does not divide the target over ℤ.
The divisor's leading-coefficient inverse is computed once for the whole
long-division pass, which is the only difference from obstructionRemainder.
Equations
- Hex.obstructs cached candidate = !Hex.DensePoly.isZero (cached.val.modCached (Hex.obstructionImage candidate))
Instances For
The optimized obstruction computes the reference remainder.
Reduction modulo q carries integer divisibility into 𝔽_q[X], where
division by the image leaves no remainder. This is the whole content of the
obstruction: it fires only on candidates that cannot divide.
No false rejection: a genuine divisor is never obstructed.
An obstructed candidate does not divide the target.
An obstructed candidate would have failed exact division, so skipping the exact division changes nothing. This is the equation the traversal's leaf rewrites through.
Exact division, guarded by the obstruction.
This is the single production entry point for "reject over 𝔽_q, otherwise
divide exactly": both recombination traversals reach exact division only
through it, so obstructedQuotient?_eq is the one equation that has to hold
for either of them to be unchanged.
Equations
- Hex.obstructedQuotient? cached candidate = if Hex.obstructs cached candidate = true then none else Hex.exactQuotient? target candidate
Instances For
Guarding exact division by the obstruction does not change its value.