Prime powers and products as moduli #
The sieve entry of a modulus m that the choice of the moduli makes (Ratpoints.primeEntry for a
prime, Ratpoints.makeModulus for a composite modulus) holds its factors: a prime with its table,
and a prime power p ^ e with the tables of examine_power (Ratpoints.Sieve.examinePower): the
bit arrays of Ratpoints.modWords words of the residues at which f, and of the multiples of p
at which the reversed polynomial, take square values, read from the bit array of the squares
(Ratpoints.Sieve.setSquareBits_spec), and the inverses of the units, from the extended Euclidean
algorithm (Ratpoints.Sieve.modinv) in a loop over the residues
(Ratpoints.Sieve.unitInverses_spec), all in Ratpoints.Sieve.examinePower_spec, for either value
of the flag pinf, which only the density reads. The tables of a prime power within the words of
its bit arrays compute what they claim, and its rows let every point through
(Ratpoints.Sieve.admits_run_examinePower_of_sq_eq): for p ∤ b, since f(a / b) is a square
modulo p ^ e, and for p ∣ b, since then p ∤ a and the reversed polynomial takes a square value
at b / a, both from the lemmas of Ratpoints.Proof.Tables for any commutative ring, here
ZMod (p ^ e); the prime powers below Ratpoints.maxPrimeEven fit the words
(Ratpoints.maxPrimeEven_le_sixty_four_mul_modWords). The values of examine_power stay in the
range of their C types for the prime powers below Ratpoints.maxPrimeEven: the cofactors of the
extended Euclidean algorithm (Ratpoints.Sieve.ModinvInvariant.natAbs_add_mul_le), the steps of
Horner's rule and the squares (Ratpoints.mul_add_lt_two_pow_64_of_lt_maxPrimeEven,
Ratpoints.mul_self_lt_two_pow_63_of_lt_maxPrimeEven), and the inverses
(Ratpoints.Sieve.getElem!_inv_run_examinePower_lt_two_pow_16); these lemmas discharge the range
obligations that the Deviation paragraphs of the model state, and no proof consumes them. A factor
that divides m reads the residues modulo m as those of the numbers
(Ratpoints.Sieve.Entry.admits_mod_of_dvd, Ratpoints.Sieve.Power.admits_mod_of_dvd, in
Ratpoints.Proof.Words) and lets every point through (Ratpoints.Sieve.isSound_prime_examinePrime,
Ratpoints.Sieve.isSound_power_run_examinePower); no Chinese remainder theorem is needed. The
tables of inverses of its factors serve the scaling of the rows by a unit modulo m
(Ratpoints.Sieve.Factor.HasInverses). An entry of an odd modulus whose factors are sound and
multiply to m, with the bias of m and an inverse of Ratpoints.rbaLength modulo m, read from
the table of a prime as examine_prime reads it (Ratpoints.inverses_mulMod_rbaLength_of_isSound)
or computed with Ratpoints.Sieve.modinv, has what the packing of the numerators reads
(Ratpoints.Sieve.SieveEntry.Packable), and with the reference to its table of rows and the kind of
its builder that Ratpoints.Sieve.SieveEntry.refInit gives at its position it fits the rows of the
references of the run (Ratpoints.IsModulusEntry.rowsFit_runRows).
Main definitions #
Ratpoints.Sieve.ModinvState,Ratpoints.Sieve.ModinvInvariant,Ratpoints.Sieve.SquareBitsInvariant,Ratpoints.Sieve.UnitInversesInvariant,Ratpoints.Sieve.FsqInvariant,Ratpoints.Sieve.GsqInvariant: the state of the loop ofRatpoints.Sieve.modinvand its invariant, and the invariants of the loops over the residues ofRatpoints.Sieve.setSquareBitsandRatpoints.Sieve.unitInverses, and of the loops ofRatpoints.Sieve.examinePowerandRatpoints.Sieve.setRevBitsthat set the bits offsqandgsq.Ratpoints.Sieve.Factor.IsSound: a factor whose rows admit every point modulom, whose tables of inverses serve the scaling, whose builder has what it needs and whose tables are those thatRatpoints.Sieve.examinePrimeandRatpoints.Sieve.examinePowercompute.Ratpoints.IsModulusEntry: what the soundness of the run needs of the sieve entry of a modulus: the modulus, sound factors whose moduli multiply to it, and the fields of the packing.
Main statements #
Ratpoints.Sieve.modinv_spec: forxprime tom > 1,Ratpoints.Sieve.modinvgives the inverse ofxmodulom, belowm;Ratpoints.Sieve.ModinvInvariant.natAbs_add_mul_le: its cofactors stay between-mandm.Ratpoints.Sieve.setSquareBits_spec,Ratpoints.Sieve.unitInverses_spec: the bits of the squares and the inverses of the units of a prime power.Ratpoints.Sieve.examinePower_spec, with its plain formsRatpoints.Sieve.getElem!_inv_run_examinePower_ltandRatpoints.Sieve.mul_getElem!_inv_run_examinePower_mod: the inverses of a prime power are below it and hold the inverses of the units;Ratpoints.Sieve.bitAt_fsq_run_examinePower_of_isSquare,Ratpoints.Sieve.bitAt_gsq_run_examinePower_of_isSquare: its tables mark the residues at whichf, or the reversed polynomial at a multiple ofp, takes a square value.Ratpoints.Sieve.getElem!_inv_run_examinePower_lt_two_pow_16: the inverses of a prime power belowRatpoints.maxPrimeEvenare below2 ^ 16, the range of their C type.Ratpoints.Sieve.admits_run_examinePower_of_sq_eq: the rows of a prime power let every point through.Ratpoints.Sieve.isSound_prime_examinePrime,Ratpoints.Sieve.isSound_power_run_examinePower: a prime of the table, or a power of one, that dividesmis a sound factor form.Ratpoints.isModulusEntry_of_forall_isSound: an entry of an odd modulus with sound factors that multiply to it, its reciprocal, bias and an inverse ofRatpoints.rbaLengthisRatpoints.IsModulusEntry;Ratpoints.inverses_mulMod_rbaLength_of_isSound: the inverse that a prime reads from its table.Ratpoints.IsModulusEntry.admits_of_sq_eq,Ratpoints.IsModulusEntry.rowsFit_runRows: such an entry admits every point and fits the rows of the references of the run (Ratpoints.Sieve.runRows).Ratpoints.coprime_rbaLength_of_mod_two_eq_one: an odd modulus is prime toRatpoints.rbaLength.
Implementation notes #
The contracts of Ratpoints.Sieve.modinv, Ratpoints.Sieve.setSquareBits,
Ratpoints.Sieve.unitInverses and Ratpoints.Sieve.examinePower are proved with vcgen, the
program logic of Lean core, with loop invariants that are named definitions, in a file with
Mathlib, next to the soundness of the rows that they serve; the density of a prime power
(Ratpoints.Sieve.powerDensity) is read through a private specification
⦃True⦄ x ⦃fun r ↦ r = Id.run x⦄, since no contract reads its value.
The inverse modulo m by the extended Euclidean algorithm #
The state of the loop of Ratpoints.Sieve.modinv for x modulo m, on the remainders
r₀, r₁ and the cofactors s₀, s₁, with the flag of the exit: rᵢ ≡ sᵢ x (mod m),
gcd(r₀, r₁) = gcd(m, x), r₀ > 0, the cofactors are of opposite signs or one of them is 0,
|s₀| r₁ + |s₁| r₀ = m, |s₀| ≤ m, and r₁ = 0 at the exit.
r₀ ≡ s₀ x (mod m).r₁ ≡ s₁ x (mod m).gcd(r₀, r₁) = gcd(m, x).r₀ > 0.The cofactors are of opposite signs, or one of them is
0.|s₀| r₁ + |s₁| r₀ = m.|s₀| ≤ m.r₁ = 0at the exit.
Instances For
The invariant of the loop of Ratpoints.Sieve.modinv for x modulo m
(Ratpoints.Sieve.ModinvState).
Equations
Instances For
The step of the loop of Ratpoints.Sieve.modinv, with the measure r₁.
The range obligation of the cofactors of modinv (find_points.c:2246-2249): in each step of
the loop, the product q s₁ and the new cofactor s₀ - q s₁, q = ⌊r₀ / r₁⌋, lie between -m and
m, as s₀ and s₁ do, so that the longs do not overflow for m < 2 ^ 63.
The exit of the loop of Ratpoints.Sieve.modinv for x prime to m > 1: r₀ = gcd(m, x) = 1,
so that s₀ x ≡ 1 (mod m), and |s₀| ≤ m.
The contract of Ratpoints.Sieve.modinv: for x prime to m > 1, the extended Euclidean
algorithm gives the inverse of x modulo m, below m. The loop ends, since r₁ drops; the
cofactors stay between -m and m (Ratpoints.Sieve.ModinvInvariant.natAbs_add_mul_le).
The tables of a prime power #
The invariant of the loop of Ratpoints.Sieve.setSquareBits after the residues pref, on the
bit array: Ratpoints.modWords words, the bits of the squares x ^ 2 mod m of the residues x of
pref set.
Equations
- Ratpoints.Sieve.SquareBitsInvariant m pref sq = (sq.size = Ratpoints.modWords ∧ ∀ x ∈ pref, Ratpoints.Sieve.bitAt sq (x * x % m) = true)
Instances For
The step of the loop of Ratpoints.Sieve.setSquareBits at the residue cur < m, within the
words of the bit array.
The contract of Ratpoints.Sieve.setSquareBits on a bit array of Ratpoints.modWords words
with room for m bits: the bits of the squares modulo m are set.
The path through longs, with the helper mod of the C code, and the path through GMP
integers give the same tables of a prime power.
The invariant of the loop of Ratpoints.Sieve.unitInverses over the residues 1, …, k modulo
m, on the inverses inv: k + 1 entries, each below m, that of a residue not divisible by p
its inverse modulo m.
Equations
Instances For
The step of the loop of Ratpoints.Sieve.unitInverses at a residue divisible by p, whose
entry is 0.
The step of the loop of Ratpoints.Sieve.unitInverses at a residue whose entry r is its
inverse modulo m, as Ratpoints.Sieve.modinv gives it for a residue not divisible by p.
At the end of the loop of Ratpoints.Sieve.unitInverses, for m > 0: every entry of the
inverses is below m, and that of a residue not divisible by p is its inverse modulo m.
The contract of Ratpoints.Sieve.unitInverses for a prime p and e ≥ 1: the inverses of the
prime power p ^ e are below p ^ e, and that of a unit is its inverse modulo p ^ e, by the
extended Euclidean algorithm (Ratpoints.Sieve.modinv_spec).
The invariant of the loop of Ratpoints.Sieve.examinePower over the residues that sets the bits
of fsq, after the residues pref, on the bit array: Ratpoints.modWords words, the bit of each
residue x of pref at which f takes a square value modulo m set.
Equations
- Ratpoints.Sieve.FsqInvariant c d m pref fsq = (fsq.size = Ratpoints.modWords ∧ ∀ x ∈ pref, IsSquare (∑ k ∈ Finset.range (d + 1), ↑(c.getD k 0) * ↑x ^ k) → Ratpoints.Sieve.bitAt fsq x = true)
Instances For
The invariant of the loop of Ratpoints.Sieve.examinePower over the multiples t of p that
sets the bits of gsq, on the bit array and the multiple: Ratpoints.modWords words, t a
multiple of p, the bit of each multiple of p below t at which the reversed polynomial of the
even degree D = d + d % 2 takes a square value modulo m set, and t ≥ m at the exit.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The step of the loop that sets the bits of fsq at the residue cur, its bit set when f(cur)
is a square modulo m, read from the bits of the squares.
The step of the loop that sets the bits of gsq at the multiple t < m of p, its bit set
when the reversed polynomial takes a square value modulo m at t, read from the bits of the
squares, with the measure m - t.
The precondition of Ratpoints.Sieve.setSquareBits in Ratpoints.Sieve.examinePower.
The end of Ratpoints.Sieve.examinePower: the inverses of the units, and the bits of fsq and
gsq of the residues and the multiples of p at which the polynomial and the reversed polynomial
take square values modulo m.
The contract of Ratpoints.Sieve.examinePower for a prime p, e ≥ 1 and p ^ e within the
words of its bit arrays: the inverses of the prime power p ^ e are below p ^ e, and that of a
unit is its inverse modulo p ^ e (Ratpoints.Sieve.unitInverses_spec); bit x of fsq is set
when f(x) is a square modulo p ^ e, and bit t of gsq, for p ∣ t, when the reversed
polynomial of the even degree D = d + d % 2 takes a square value at t, read from the bits of the
squares (Ratpoints.Sieve.setSquareBits_spec).
The range obligation of the inverses of examine_power (find_points.c:2303), which it casts
to the unsigned short entries of inv (rp-private.h:533): for a prime power
p ^ e < maxPrimeEven, they are below p ^ e (Ratpoints.Sieve.getElem!_inv_run_examinePower_lt),
so below 2 ^ 10 (Ratpoints.maxPrimeEven_le_two_pow_10) and below 2 ^ 16: the cast keeps
them.
Bit x of the table Ratpoints.Sieve.Power.fsq of m = p ^ e
(Ratpoints.Sieve.examinePower), for m within the words of its bit arrays, is set when f(x) is
a square modulo m.
Bit t of the table Ratpoints.Sieve.Power.gsq of m = p ^ e
(Ratpoints.Sieve.examinePower), for m within the words of its bit arrays and p ∣ t, is set
when the reversed polynomial ∑ cₖ t ^ (D - k) of the even degree D = d + d % 2 takes a square
value modulo m at t.
The rows of a prime power let every point through #
The row of the denominator b for the prime power p ^ e, e ≥ 1, within the words of its
bit arrays, admits the numerator a of every point (a, y, b) with gcd(a, b) = 1: for p ∤ b,
since f(a / b) is a square modulo p ^ e, and for p ∣ b, since p ∤ a and the reversed
polynomial takes a square value at b / a
(Ratpoints.isSquare_sum_mul_pow_sub_of_sq_eq_binaryForm).
The sieve entry of a modulus #
A factor that the choice of the moduli makes for the modulus m of the curve y ^ 2 = F(x, z)
with the coefficient list c (Ratpoints.makeModulus, Ratpoints.primeEntry): it admits every
point (a, y, b) with gcd(a, b) = 1 at the residues of b and a modulo m, its tables of
inverses serve the scaling of the rows by a unit modulo m (Ratpoints.Sieve.Factor.HasInverses),
its builder has what it needs (Ratpoints.Sieve.Factor.Buildable), and its table or tables are
those that Ratpoints.Sieve.examinePrime computes for a prime and Ratpoints.Sieve.examinePower on
the path of GMP integers for a prime power, which both paths give
(Ratpoints.Sieve.examinePower_eq_examinePower_false), with either value of the flag pinf, which
only the density reads.
- admits_of_sq_eq ⦃a y : ℤ⦄ ⦃b : ℕ⦄ (hab : a.gcd ↑b = 1) (hy : y ^ 2 = binaryForm c a ↑b) : f.admits (b % m) (a % ↑m) = true
The factor admits every point at the residues modulo
m. - hasInverses : f.HasInverses m
The tables of inverses serve the scaling of the rows by a unit modulo
m. - buildable : f.Buildable
The builder of the rows has what it needs.
A prime has the table that
Ratpoints.Sieve.examinePrimecomputes.- power_eq (pw : Power) (h : f = power pw) : ∃ (pinf : Bool), pw = (examinePower c (degree c) pw.p pw.e false pinf).run
A prime power has the tables that
Ratpoints.Sieve.examinePowercomputes.
Instances For
A prime factor has the inverses that Ratpoints.Sieve.inversesMod computes.
The factor of a prime p = primeTable[pn] of the table that divides m, with its table.
The factor of a prime power primeTable[pn] ^ e, e ≥ 1, of the table that divides a modulus
0 < m < maxPrimeEven, with its tables, for either path of the reduction and either value of the
flag pinf.
What the choice of the moduli makes of the sieve entry s of the modulus m for the curve with
the coefficient list c (Ratpoints.makeModulus, Ratpoints.primeEntry): its modulus is m, its
factors are sound for m (Ratpoints.Sieve.Factor.IsSound) and their moduli multiply to m, and
it has the fields that the packing reads (Ratpoints.Sieve.SieveEntry.Packable); so it admits every
point (Ratpoints.IsModulusEntry.admits_of_sq_eq) and fits the rows of the references of the run
(Ratpoints.IsModulusEntry.rowsFit_runRows).
The modulus is
m.- isSound_of_mem (f : Sieve.Factor) : f ∈ s.factors → Sieve.Factor.IsSound c m f
The factors are sound for
m. - packable : s.Packable
The entry has the fields that the packing reads.
The moduli of the factors multiply to
m.
Instances For
The sieve entry of m as the choice makes it admits every point (a, y, b) with
gcd(a, b) = 1, since its factors admit it at the residues modulo m.
The sieve entry of an odd modulus 1 < m < maxPrimeEven with factors that are sound for m
and whose moduli multiply to m, the reciprocal and the bias of m, an inverse x < m of
Ratpoints.rbaLength modulo m and any reference, kind of builder, density and count of factors
is an entry of m as the choice makes it.
Ratpoints.rbaLength, a power of 2 (Ratpoints.rbaLength_eq_two_pow_rbaShift), is prime to
every odd modulus.
The product of Ratpoints.rbaLength < 2 ^ 32 (Ratpoints.rbaShift_lt_thirty_two) and a
modulus m ≤ 2 ^ 32 is below 2 ^ 64, so that the remainder of Ratpoints.rbaLength by the
reciprocal of m is exact.
The inverse of Ratpoints.rbaLength modulo an odd prime modulus 1 < m < maxPrimeEven, read
from its table, sound for m, with the remainder of rbaLength by the reciprocal of m, as
examine_prime reads it.
The precondition of Ratpoints.Sieve.modinv for the inverse of Ratpoints.rbaLength modulo an
odd modulus m > 1.
The inverse of Ratpoints.rbaLength that Ratpoints.Sieve.modinv gives, in the form of
Ratpoints.Sieve.SieveEntry.Packable.
The factors of the sieve entry of m as the choice makes it are not empty, since their moduli
multiply to m > 1.
A sieve entry with one factor as the choice makes it has the modulus of its factor.
The sieve entry of m that the choice makes at the position n of the entries es of a run
fits the rows of the references of the run (Ratpoints.Sieve.runRows): its reference and kind of
builder are those of Ratpoints.Sieve.SieveEntry.refInit, its factors have what their builders
need and the tables that Ratpoints.Sieve.examinePrime and Ratpoints.Sieve.examinePower
compute.