The denominators of a polynomial of odd degree #
For a polynomial of odd degree the denominator of every point is a squarefree divisor of the
leading coefficient c_d times a square, and a square when |c_d| = 1: a prime p ∤ c_d divides
it an even number of times, since the term c_d a ^ d b of F(a, b) alone has the least valuation.
The divisor set-up (Ratpoints.Setup.setupUs1) factors |c_d| over 2 and the primes of the
table, the cofactor below the square of the next prime of the table being a prime since the table
holds every odd prime below 1022 in increasing order (Ratpoints.Setup.factorLcf), lists the
squarefree divisors of c_d up to the largest denominator by the doubling loop
(Ratpoints.Setup.squarefreeDivisors), and computes the slopes of the valuation test
(Ratpoints.Setup.slope), whose entries exclude no denominator of a point. The products x p that
the C code computes as longs stay at most the largest denominator, and the square p * p of a
prime of the table, an int, below 2 ^ 31. The factorization finds the primes in increasing
order, so that the divisors come in the order of binary counting over the primes, and while a prime
of the table is still to come its cofactor is the part of |c_d| at the primes from it on
(Nat.IsRoughPart), so that it is complete exactly when the specification of the order says so
(Ratpoints.FactorsByTrialDivision): the divisor set-up succeeds exactly when the factorization is
complete and the doubling loop, which lists a prefix of all the products when it stops, finds fewer
than Ratpoints.maxDivisors divisors.
Main definitions #
Ratpoints.Setup.IsFactorization: a list of primes in increasing order with their valuations that holds every prime factor of a number.Ratpoints.Setup.extendDivisors: one pass of the doubling loop of the squarefree divisors.Ratpoints.Setup.DenInfo.excludes: whether an entry of the valuation test of the divisor shape excludes a denominator.
Main statements #
Ratpoints.isSquare_of_sq_eq_binaryForm_of_odd: for odd degree and|c_d| = 1, the denominator of every point is a square.Ratpoints.exists_eq_mul_mul_of_sq_eq_binaryForm_of_odd: for odd degree, the denominator of every point iss k ^ 2withssquarefree ands ∣ c_d.Ratpoints.even_add_of_sq_eq_binaryForm_of_odd: the valuation test of the slopes.Ratpoints.factorsByTrialDivision_of_isRoughPart_one,Ratpoints.factorsByTrialDivision_of_isRoughPart_of_lt,Ratpoints.eq_one_iff_factorsByTrialDivision_of_isRoughPart: whetherratpointsfactors a number completely, read off its parts at the primes from a bound on.Ratpoints.Setup.factorLcf_spec,Ratpoints.Setup.squarefreeDivisors_spec,Ratpoints.Setup.slope_spec,Ratpoints.Setup.setupUs1_spec: the contracts of the divisor set-up; the factorization leaves the cofactor1exactly whenratpointsfactors the number completely, and then it lists the primes in increasing order, each with its valuation; the set-up succeeds exactly when the cofactor is1and the doubling loop gives fewer thanRatpoints.maxDivisorsdivisors.Ratpoints.Setup.foldl_extendDivisors_eq_filter: the doubling loop lists the products of the sublists of the primes in the order of binary counting, up to the bound.Ratpoints.Setup.map_snd_run_setupUs1: the divisor set-up succeeds exactly whenratpointsfactors|c_d|completely and finds fewer thanRatpoints.maxDivisorsdivisors, and its divisors are then those ofRatpoints.binaryDivisors.Ratpoints.mem_binaryDivisors_iff,Ratpoints.nodup_binaryDivisors: the divisors ofRatpoints.binaryDivisorsare the squarefree divisors up to the bound, each once.Ratpoints.Setup.mem_iff_of_setupUs1_eq_some,Ratpoints.Setup.nodup_of_setupUs1_eq_some: so the divisors of the divisor set-up are the squarefree divisors of|c_d|up to the largest denominator, each once.Ratpoints.Setup.DenInfo.excludes_eq_false_of_sq_eq: no entry of the valuation test, a prime ofc_dwith its valuation and its slope, excludes the denominator of a point.Ratpoints.Setup.fitsLong_mul_of_le_div: the productsx pof the C code arelongs;Ratpoints.Setup.mul_self_lt_of_mem_primeTable,Ratpoints.Setup.fitsLong_of_lt_mul_self: the squarep * pof a prime of the table is anint, and a cofactor below it along.
Implementation notes #
The contracts are proved with vcgen, the program logic of Lean core, with loop invariants that are
named definitions, in a file with Mathlib, since they speak of primes and their valuations. That
the macro CEIL of the C code rounds up is a private lemma of this file, which only the slopes use:
its if is that of the macro, and Mathlib has no ceiling division of integers to state it with.
Ratpoints.Setup.fitsLong_mul_of_le_div discharges a range obligation that a Deviation paragraph of
the model states, and no proof consumes it.
The denominators of the points #
For odd degree, a point (a, y, b) whose term c_d a ^ d b of F(a, b) is p ^ V u with
p ∤ u, while p ^ (V + 1) divides every other term, has an even V
(Int.even_and_exists_isSquare_add_of_sq_eq_sum).
The valuation test of the slopes (odd degree): for a prime p with v_p(c_d) = val and a
denominator b of a point with m = v_p(b) ≥ 1 and (d - k) m ≥ 1 + val - v_p(c_k) for every
k < d with c_k ≠ 0, the term c_d a ^ d b of F(a, b) alone has the least valuation
val + m, which is then even.
For odd degree, a prime p ∤ c_d divides the denominator b of every point an even number of
times: for v_p(b) ≥ 1 the term c_d a ^ d b of F(a, b) alone has the least valuation v_p(b)
(Ratpoints.even_add_of_sq_eq_binaryForm_of_odd with v_p(c_d) = 0).
For odd degree and a leading coefficient ±1, the denominator b of every point is a square:
its valuation v_p(b) at every prime p is even (Ratpoints.even_of_sq_eq_binaryForm_of_odd),
since for v_p(b) ≥ 1 the term c_d a ^ d b of F(a, b) alone has the least valuation.
For odd degree, the denominator of every point is s k ^ 2 with s squarefree and dividing the
leading coefficient: a prime that divides b an odd number of times divides c_d
(Ratpoints.even_of_sq_eq_binaryForm_of_odd).
Factoring by trial division #
A number whose part at the primes from q ≤ 1022 on is 1 has no prime factor above 1021,
so that ratpoints factors it completely.
A number whose part at the primes from q ≤ 1021 on is below q ^ 2 has its part at the
primes from 1021 on below 1021 ^ 2, so that ratpoints factors it completely.
When the part w of n ≠ 0 at the primes from 1021 on is at least 1021 ^ 2, ratpoints
factors n completely exactly when its part m at the primes from 1022 on is 1.
The squarefree divisors in the order of binary counting #
The products of the sublists of the distinct prime factors of n ≠ 0 are its squarefree
divisors; for n = 0 there is only the empty product 1.
Distinct sublists of the distinct prime factors of n have distinct products.
The factorization of the leading coefficient #
The list fac of pairs (p, v) is the factorization of w: its primes p ascend, each with
its valuation v = v_p(w) ≥ 1, and every prime factor of w is among them.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The square p * p of a prime of the table, which setup_us1 computes as an int
(find_points.c:800), is below 2 ^ 31.
A cofactor below the square of a prime of the table is a long, so that the test of
Ratpoints.Setup.factorLcf before it takes the cofactor as a prime always passes
(find_points.c:808).
The part of the invariant of Ratpoints.Setup.factorLcf for its cofactor w, with the factors
fac found and the primes suff of the table still to come: while a prime cur is still to come,
the primes found lie below it and every prime factor of w is at least cur; at the end, w = 1
exactly when ratpoints factors w0 completely.
Equations
Instances For
The invariant of the loop of Ratpoints.Setup.factorLcf over the primes of the table, for the
number w0 ≥ 1 to factor, with the primes suff still to come: w0 is the cofactor w times the
powers of the factors found, ascending primes p with their valuations v_p(w0) ≥ 1 that do not
divide w, and the cofactor satisfies Ratpoints.Setup.CofactorInvariant: while a prime cur of
the table is still to come, w is the part of w0 at the primes from cur on
(Ratpoints.Setup.FactorLcfInvariant.isRoughPart).
w0is the cofactor times the powers of the factors found.The primes found ascend.
- prime_valuation (x : ℕ × ℕ) : x ∈ fac.toList → Nat.Prime x.1 ∧ x.2 = padicValNat x.1 w0 ∧ 0 < x.2 ∧ ¬x.1 ∣ w
Each factor found is a prime with its valuation in
w0, at least1, that does not divide the cofactor. - cofactor : CofactorInvariant w0 fac.toList suff w
The cofactor satisfies
Ratpoints.Setup.CofactorInvariant.
Instances For
While the prime cur of the table is still to come, the cofactor is the part of w0 at the
primes from cur on: the product of the powers of the primes found, all below cur, is
cur-smooth.
A new prime factor p of the cofactor w = p ^ v m, p ∤ m, above the primes found, taken
with its exponent v ≥ 1, leaves the cofactor m.
After the power 2 ^ v2 ≠ 1 of w0, found: the odd part of w0, every prime factor of which
is at least 3, the first prime of the table.
For odd w0: the cofactor w0, every prime factor of which is at least 3, the first prime of
the table, and no prime found.
The cofactor m after the prime cur of the table, whose part w ≥ cur ^ 2 of w0 at the
primes from cur on it has divided by the power of cur, with the primes found at most cur:
while a prime is still to come, the primes found lie below it and m is the part of w0 at the
primes from it on; after the last prime, 1021, m = 1 exactly when ratpoints factors w0
completely.
The prime cur of the table divided off w with its valuation v ≥ 1.
The prime cur of the table, which does not divide w, passed.
A cofactor w ≠ 1 below cur ^ 2, with no prime factor below cur, is a prime
(Nat.prime_of_lt_mul_self), taken with the valuation 1, which leaves the cofactor 1.
The cofactor 1: the loop ends, every prime factor of w0 found.
A cofactor below cur ^ 2 is a long, so the loop never ends with it unfactored.
At the end of the loop, the cofactor is 1 exactly when ratpoints factors w0 completely,
and then the factors found are the factorization of w0.
The factorization of w ≥ 1 over 2 and the primes of the table leaves the cofactor 1
exactly when ratpoints factors w completely, and then it is the factorization of w, the primes
in increasing order, each with its valuation.
Ratpoints.Setup.factorLcf_spec as a plain statement, for the cofactor.
The squarefree divisors #
One pass of the doubling loop of Ratpoints.Setup.squarefreeDivisors with the prime p: the
divisors ds found so far, then x p for each x of them with x ≤ ⌊bHigh / p⌋, in their
order.
Equations
Instances For
The invariant of the loop of Ratpoints.Setup.squarefreeDivisors over the primes, after the
primes pref with the primes suff still to come: the list is that of the passes over pref
(Ratpoints.Setup.extendDivisors), or the loop has stopped at the end with
Ratpoints.maxDivisors entries or more, a prefix of that list.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The invariant of the pass of Ratpoints.Setup.squarefreeDivisors with the prime p over the
divisors divs0, after the positions pref with the positions suff still to come: the list is
divs0 followed by the products x p of the entries x ≤ ⌊bHigh / p⌋ among the first |pref|
ones, or the pass has stopped at the end with Ratpoints.maxDivisors entries or more, a prefix of
that list.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The pass over all positions of divs0 ends with Ratpoints.Setup.extendDivisors of divs0,
or with a prefix of it with Ratpoints.maxDivisors entries or more.
The doubling loop gives the list of all passes (Ratpoints.Setup.extendDivisors), or, when it
stops at Ratpoints.maxDivisors entries, a prefix of it with that many entries or more.
Ratpoints.Setup.squarefreeDivisors_spec as a plain statement.
The divisors in the order of binary counting #
The doubling loop over positive numbers ps lists the products of the sublists of ps that
are at most bHigh ≥ 1, in the order of List.sublists: binary counting, the first entry of ps
the lowest bit.
The distinct primes of a factorization of n ≠ 0, in increasing order, are those of
Nat.primeFactorsList n.
The slopes #
The invariant of the loop of Ratpoints.Setup.slope after the positions pref: the slope n
so far is at least 1, and for the coefficient c_k, k = d - 1 - j, of each position j done,
(d - k) n ≥ 1 + val - v_p(c_k), with the valuation of Ratpoints.Setup.valuation.
Equations
Instances For
The slope of the valuation test of the divisor shape is at least 1 and satisfies
(d - k) n ≥ 1 + val - v_p(c_k) for every k < d, the valuation by Ratpoints.Setup.valuation
(Ratpoints.veryBig for c_k = 0), since the macro CEIL rounds up.
The divisor set-up #
The divisor set-up succeeds exactly when the factorization of |c_d| leaves the cofactor 1
(Ratpoints.Setup.factorLcf) and the doubling loop over its primes
(Ratpoints.Setup.squarefreeDivisors) gives fewer than Ratpoints.maxDivisors entries; it then
gives the primes with their valuations and slopes (Ratpoints.Setup.slope) and that list.
Ratpoints.Setup.setupUs1_spec as a plain statement, which the proofs use without the program
logic.
The divisor set-up, when it succeeds for c_d ≠ 0, is made of the factorization of |c_d|
(Ratpoints.Setup.factorLcf, with the cofactor 1) and its primes with their valuations and
slopes (Ratpoints.Setup.slope).
For a factorization of n ≥ 1 with the cofactor 1, the doubling loop over its primes lists
the squarefree divisors of n up to bHigh ≥ 1 in the order of Ratpoints.binaryDivisors.
The divisor set-up of c_d ≠ 0 succeeds exactly when ratpoints factors |c_d| completely
and |c_d| has fewer than Ratpoints.maxDivisors squarefree divisors up to bHigh ≥ 1; its
divisors are then those of Ratpoints.binaryDivisors, in that order.
When the divisor set-up of c_d ≠ 0 succeeds, its divisors are those of
Ratpoints.binaryDivisors up to bHigh ≥ 1.
When the divisor set-up succeeds, its divisors are exactly the squarefree divisors of |c_d| up
to the largest denominator bHigh ≥ 1.
Whether the entry e of the valuation test of the divisor shape (Ratpoints.Sieve.denInfoTest)
excludes the denominator b: v_p(b) ≥ e.slope with v_p(b) + e.val odd, for the valuation
v_p(b) of Ratpoints.Setup.valuation.
Equations
Instances For
An entry of the valuation test, a prime p with the valuation val = v_p(c_d) and its slope
(Ratpoints.Setup.slope_spec), does not exclude the denominator b ≥ 1 of a point: for
v_p(b) ≥ slope, v_p(b) + val is even (Ratpoints.even_add_of_sq_eq_binaryForm_of_odd).