The Jacobi test by tables #
The test by tables (Ratpoints.Sieve.jacobiSetup, Ratpoints.Sieve.jacobiTest) computes the symbol
of the binary algorithm, (lcf / b*) for 1 ≤ b ≤ bHigh, where b* is the largest divisor of b
prime to 2 lcf: it takes 2 and the odd primes of lcf out of b and reads the symbol off the
sign of b* mod 8 and the tables of the non-squares modulo the primes of lcf with an odd
exponent, by quadratic reciprocity. The proof has two layers: the contracts describe the loops, the
tables of the non-squares giving the Legendre symbol, the set-up the tables of lcf
(Ratpoints.Sieve.IsJacobiInfo) and the test the exclusive or of the sign and the entries over the
part of b free of 2 and of the primes of the tables; and
Ratpoints.Sieve.jacobiSym_eq_ite_foldl reads the Jacobi symbol off the tables. So the test lets
the denominator of every point of a curve of even degree through. The set-up gives tables only for
bHigh ≤ Ratpoints.mulModLimit, so that the denominators of the test stay below 2 ^ 32, where
RP_MULDIV with the reciprocals that the tables hold, those of their primes, is exact
(Ratpoints.Sieve.run_jacobiTest).
Main definitions #
Ratpoints.Sieve.IsJacobiInfo: what the tables of the test by tables say of the leading coefficient.
Main statements #
Ratpoints.Sieve.nonSquares_spec,Ratpoints.Sieve.legendreSym_eq_ite_getElem!_nonSquares: the tables of the non-squares give the Legendre symbol;Ratpoints.Sieve.ite_getElem!_jacobiSigns: the signs.Ratpoints.Sieve.jacobiSetup_spec,Ratpoints.Sieve.jacobiTest_spec: the contracts of the set-up, whose tables hold primes ofRatpoints.primeTablewith their reciprocals, and of the test by tables.Ratpoints.Sieve.jacobiSym_eq_ite_foldl: the Jacobi symbol read off the tables.Ratpoints.Sieve.run_jacobiTest: the test by tables decides whether(lcf / b*) = 1.Ratpoints.Sieve.run_jacobiTest_of_sq_eq: the test by tables passes the denominator of every point of a curve of even degree.
Implementation notes #
The contracts are proved with vcgen, with loop invariants that are named definitions, in a file
with Mathlib, since they speak of primes, their valuations and the Legendre symbol. A contract that
needs the exact value of a component that its loop calls takes a specification
⦃True⦄ x ⦃fun r ↦ r = Id.run x⦄ of it (Ratpoints.Setup.valuation_value for the valuation, a
private one for the table of the non-squares), since the registered contract would give only what it
says of the value. The test reduces by the reciprocals that the tables hold, which the set-up makes
those of their primes, and the reductions are exact (Ratpoints.Sieve.mulDiv_magic), since these
are primes of Ratpoints.primeTable, below 1022, and the denominators are at most
Ratpoints.mulModLimit < 2 ^ 32 (Ratpoints.mul_lt_two_pow_64_of_le_mulModLimit). The proofs use
only that Ratpoints.mulModLimit is below 2 ^ 64 and 2 ^ 32 (Ratpoints.mulModLimit_lt_size,
Ratpoints.mulModLimit_lt_two_pow_32, which decide checks next to the constant), never the values
of Ratpoints.mulModLimit, Ratpoints.jacobiPrimes and Ratpoints.jacobiTable.
The tables of the non-squares and the signs #
The invariant of the loop of Ratpoints.Sieve.nonSquares on q after the steps x ≤ k, k
the length of pref: the table has q entries, s = (k + 1) ^ 2 mod q, and an entry r < q is
false exactly when r = x ^ 2 mod q for some 1 ≤ x ≤ k.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The step x of Ratpoints.Sieve.nonSquares clears the entry of s = x ^ 2 mod q and moves on
to (x + 1) ^ 2 mod q = s + 2 x + 1, less q at most once, since 2 x + 1 ≤ q for odd q.
The table of the non-squares modulo an odd q > 1 has q entries, an entry r < q being false
exactly when r is the square modulo q of one of 1, …, q / 2.
The table of Ratpoints.Sieve.nonSquares gives the Legendre symbol of a residue r ≠ 0 modulo
an odd prime q: its entry is true exactly where the symbol is -1.
The signs of Ratpoints.Sieve.jacobiSigns for odd b: the entry of b mod 8, read as -1 for
true, is χ₄(b) ^ (n₃ + neg) χ₈(b) ^ v, the product of the signs of (-1 / b) ^ neg, of the
reciprocity of the n₃ primes ≡ 3 (mod 4) and of (2 / b) ^ v.
The set-up of the tables #
What the tables ji of the Jacobi test say of the leading coefficient lcf
(Ratpoints.Sieve.jacobiSetup): its primes are odd primes of lcf, each with the table of the
non-squares modulo it (Ratpoints.Sieve.nonSquares) exactly when its exponent in lcf is odd;
|lcf| is 2 ^ v₂(lcf) times the powers of these primes with their exponents in lcf; and the
signs are those of Ratpoints.Sieve.jacobiSigns for the number of these primes with an odd
exponent that are 3 (mod 4), the sign of lcf and v₂(lcf).
Equations
- One or more equations did not get rendered due to their size.
Instances For
The invariant of the loop of Ratpoints.Sieve.jacobiSetup on lcf with the exponent v of 2
in it, on the cofactor w and the entries qs: for lcf = 0, w = 0; otherwise |lcf| is
2 ^ v w times the powers of the primes of qs with their exponents in lcf, w is odd, and the
entries are odd primes of lcf from Ratpoints.primeTable that do not divide w, each with the
table of the non-squares exactly when its exponent in lcf is odd.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The invariant of the loop of Ratpoints.Sieve.jacobiSetup over the primes of the table, with
the primes suff still to come, on the result of an early return, the cofactor, the entries, the
reciprocals, the number n3 and the space taken by the tables: without a result,
Ratpoints.Sieve.JacobiSetupInvariant of the cofactor and the entries, with the reciprocals those
of the primes of the entries in their order (Ratpoints.Sieve.magic) and n3 the number of the
entries with a table whose prime is 3 (mod 4); and a result, which is none, only at the end.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Before the last prime, the loop of Ratpoints.Sieve.jacobiSetup has not returned, and its state
passes on unchanged to any primes to come.
The exponent e of a prime q of the cofactor w = q ^ e m, q ∤ m, is v_q(lcf), since q
is neither 2 nor one of the primes taken out before.
An entry (q, ns) for a prime q of the cofactor w = q ^ e m, q ∤ m, with its exponent
e = v_q(lcf) and the table of the non-squares exactly for odd e, leaves the cofactor m.
An entry for the prime cur of the table that divides the cofactor w, with the table of the
non-squares exactly for an odd exponent e, and the count n3 of the entries with a table whose
prime is 3 (mod 4); the space u' taken by the tables is free.
At the end of the loop of Ratpoints.Sieve.jacobiSetup with the cofactor 1, lcf ≠ 0, the
tables are those of lcf, their primes are from Ratpoints.primeTable, and they hold the
reciprocals of their primes.
The set-up of the test by tables gives tables only for bHigh ≤ Ratpoints.mulModLimit and
lcf ≠ 0, and then the tables of lcf (Ratpoints.Sieve.IsJacobiInfo), whose primes are from
Ratpoints.primeTable and which hold their reciprocals, so that the reductions of the test by them
are exact.
The test by tables #
The precondition of Ratpoints.Sieve.jacobiTest on the tables ji and the denominator b,
under which the reductions by the reciprocals that the tables hold are exact.
The denominator is positive.
The denominator is below
2 ^ 64.The entries are primes
qwithb q < 2 ^ 64.The tables hold the reciprocals of their primes.
Instances For
The invariant of the first loop of Ratpoints.Sieve.jacobiTest on the tables ji and the
denominator b, after the entries pref: the current b' is odd and positive, has the part of b
free of 2 and of the primes of ji, is prime to the primes of pref, and is at most b, so that
the reductions by the reciprocals of the primes stay exact (Ratpoints.Sieve.mulDiv_magic).
Equations
- One or more equations did not get rendered due to their size.
Instances For
The invariant of the loop of Ratpoints.Sieve.jacobiTest that divides b' by the prime q as
often as it divides: that of the first loop, and q ∤ b' at the exit.
Equations
- Ratpoints.Sieve.JacobiDivideInvariant ji b pref q = Std.WP.WhileInvariant.mk fun (exit : Bool) (b' : ℕ) => Ratpoints.Sieve.JacobiTestInvariant ji b pref b' ∧ (exit = true → ¬q ∣ b')
Instances For
The quotient by the prime q of the entry at the position i of the tables ji, by the
reciprocal that the tables hold there, is exact for the current b' ≤ b, since b q < 2 ^ 64.
The remainder by the prime q of the entry at the position i of the tables ji, by the
reciprocal that the tables hold there, is exact for the current b' ≤ b, since b q < 2 ^ 64.
At the end of the first loop of Ratpoints.Sieve.jacobiTest, b' is the part of b free of
2 and of the primes of the tables.
The invariant of the second loop of Ratpoints.Sieve.jacobiTest on the tables ji and the
odd part b' free of their primes, after the entries pref: the sign s is the exclusive or of
the sign of b' mod 8 and the entries of b' mod q in the tables of the primes q of pref.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dividing b' by a prime q of the tables keeps the part of b' free of 2 and of the primes
of the tables.
The test by tables on 0 < b < 2 ^ 64, for tables whose entries are primes q with
b q < 2 ^ 64 and which hold the reciprocals of their primes, so that the reductions by them are
exact: the exclusive or of the sign of b* mod 8 and the entries of b* mod q in the tables of the
primes q, negated, for b* the part of b free of 2 and of the primes of the tables.
The Jacobi symbol by the tables #
The factor J(q | b) ^ e of an odd prime q ∤ b of the leading coefficient with its exponent
e, for odd b: 1 for even e, and for odd e, with the table ns of the non-squares modulo
q, the entry of b mod q read as a sign, times χ₄(b) when q ≡ 3 (mod 4).
The Jacobi symbol by the tables. The symbol (lcf / b) of an odd b prime to the primes of
the tables ji of lcf is read off the tables, by quadratic reciprocity: the exclusive or of the
sign of b mod 8 and the entries of b mod q in the tables of the primes q with an odd exponent,
read as -1 for true.
For the tables of lcf, the primes prime to 2 lcf are those other than 2 and the primes of
the tables, which are all the odd primes of lcf.
The test by tables. It decides whether (lcf / b*) = 1, b* the largest divisor of b
prime to 2 lcf, for 1 ≤ b ≤ bHigh when the set-up gives tables. The C code refuses the tables
for a b_high above Ratpoints.mulModLimit, RP_MULMOD_LIMIT (find_points.c:688), so that
jacobi_test divides only numbers below 2 ^ 32, where its multiplication by the reciprocal
RP_MULDIV is exact (rp-private.h:389-393).
The Jacobi test by the tables of the leading coefficient, when they apply, passes the
denominator b ≤ bHigh of every point of a curve of even degree: it computes whether the Jacobi
symbol (c_d / b*) is 1.