Objective
Specify exact sign determination and comparison of real algebraic numbers
thoroughly: every executable strategy, the theorem tying each to the
reference semantics, the input-computable termination bound of each, and the
Phase-4 evidence that decides which strategy runs where. The text lands in
SPEC/Libraries/hex-real-algebraic.md (the consumer) with the new primitives
specified in the SPECs of the libraries that own them (hex-real-roots for
Tarski queries, hex-number-field for lazy and fixed-field comparison).
Current state
AlgebraicNumber.realCompare (HexNumberField/Nearest.lean) already
rejects on disjoint stored intervals, then refines both operands on a
geometric schedule capped at separationPrec (a.p * b.p) + 1, and only
then falls back to realCompareExact, which approximates both numbers at
the Mahler-bound precision of the product polynomial. realCompare_eq and
realCompareExact_eq prove both return the real order. The SPEC documents
this as the existing reference path rather than designing it again.
- Nothing compares two factorization-lazy
AlgebraicRoots without
exactifying both, which costs two Berlekamp–Zassenhaus factorizations.
- Nothing determines the sign of a fixed-field element
f(α) : QAdjoin a
without approximation, and nothing orders real elements of a
NumberTower.
- hex-rcf builds and kernel-replays literal Sturm chains, but
SturmReplay.check requires the second entry to be a positive multiple of
the derivative, strictly descending degrees, and a terminal nonzero
constant; its common-root packages replay the gcd's own derivative chain.
It does not cover sturm(p, f·p') for arbitrary f, a zero f, or a
nonconstant gcd. Its step 5 decides the position of a root relative to a
dyadic endpoint by one Sturm count plus exact evaluation. Neither is
exposed as a comparison primitive.
- Isolation precision separates the roots of a polynomial from each other,
not from zero when zero is not a root. ofEliminant? isolates at
separationDepth p, which is 12 for every linear polynomial whatever its
height, so the lazy difference (±2⁻ᵏ) − 0 for k ≥ 13 is a nonzero root
whose stored real centre is 0. The sign of the isolation centre therefore
does not decide the order, and the previous text of this directive was
wrong to say it did.
- No benchmark measures comparison at all.
Required design
- Reference semantics:
realCompare remains the definition. Every fast path
below is specified with a theorem that it returns the same Ordering.
- Stored-isolation fast path:
realCompare as it exists, with its theorem
and its structural fuel (the geometric schedule to the product-polynomial
separation precision) stated in the SPEC; equality is decided structurally
with no refinement. Any change to the schedule must preserve
realCompare_eq.
- Comparison against a rational or dyadic point: the exact sign of the
minimal polynomial at the point plus one Sturm count on the split interval
(hex-rcf's endpoint test), no refinement, no factorization.
- Lazy comparison:
AlgebraicRoot.compare as the sign of the difference,
using the eliminant sub? already builds, then isZero, then a
certified sign for the nonzero difference d with stored polynomial
p (squarefree, primitive, positive leading coefficient):
- degree one: the sign of
−p.coeff 0;
- degree at least two with
p.coeff 0 ≠ 0: the stored centre has the
exact sign, because separationDepth p ≥ ceilLog2 H + 12 for
H = coeffAbsMax p while every nonzero root has
|α| ≥ 1/(1 + H) ≥ 2^(−(ceilLog2 H + 1)) (reciprocal Cauchy) and the
stored disc radius is below 2^(1 − prec);
- degree at least two with
p.coeff 0 = 0: zero is another root of p,
so the root-separation guarantee of the isolation already excludes zero
from the disc and the centre sign is exact.
The companion proves this bound explicitly; it is not a remark. The SPEC
states the invariant every lazy root relies on, that its stored precision
is at least separationDepth of its stored polynomial, and either shows
every AlgebraicRoot constructor maintains it or has compare refine to
that depth first. If the SPEC prefers a uniform rule to the degree split,
the alternative is one bounded refinement pass to the reciprocal-Cauchy
depth of the difference eliminant (after removing its maximal X power)
whenever the stored real interval meets zero, with that cost stated next to
the resultant and the isolation. Say when either beats exactifying.
- Sign in a fixed field: for real
α and f : QAdjoin a, (i) the Tarski
query TaQ(f, p; I) from the Sturm chain of (p, f·p') evaluated at the
dyadic endpoints of the isolating interval, exact integer arithmetic with
no refinement, added to hex-real-roots as tarskiQuery and reusing
hex-rcf's replay shape; (ii) approximation at the a priori precision from
Disambiguation.evalMajorant and the reciprocal Cauchy bound. Specify
both; the default per degree and height regime is left to Phase 4.
- Tower elements: the sign of a real
NumberTower.Elem by fixed-embedding
evaluation with the same majorant bound, and comparison inside a real
tower.
- Sorting,
min, max and Ord on arrays of real algebraic numbers, reusing
the algebraicRoots order where the numbers share a polynomial.
- Certificates: state which comparisons are kernel-checkable (a Tarski query
against dyadic endpoints is, since hex-rcf already replays Sturm chains in
the kernel) and whether a decide-style comparison proof is worth
exposing now or deferred.
- Phase-4 evidence per SPEC/benchmarking.md: families for well-separated
pairs (degree sweep), close real pairs from Mignotte x^n − (a·x − 1)²
(sweep in a), equal numbers from different lazy polynomials,
rational-point comparisons, and fixed-field sign at growing coefficient
height. Comparators: python-flint qqbar and Z3's RCF Python bindings,
both informational; Sage AA is not an oracle. Required-check ceilings
follow the existing mode rules.
- Conformance: python-flint supplies expected orderings; cypari2 cannot.
Do not implement in this issue.
Verification
- Each strategy has a stated equality theorem against
realCompare and a
stated input-computable termination bound.
- Confirm that hex-rcf's generalized replay covers
sturm(p, f·p') for
arbitrary f, or state the extension needed.
- Sanity-check every strategy on equal numbers, on numbers closer than the
stored isolation width, on the sign of zero in a fixed field, on a
rational point that is exactly a root, and on the lazy differences
(±2⁻ᵏ) − 0 for k ∈ {20, 50, 100} and (a ± 2⁻ᵏ) − a for a
quadratic irrational a, which must return the strict order.
- The lazy-comparison sign rule is stated with the theorem that justifies
it; no strategy relies on the sign of an isolation centre without a stated
lower bound on the value it approximates.
- All relative links resolve;
git diff --check passes.
Dependencies
depends-on: #10141
Objective
Specify exact sign determination and comparison of real algebraic numbers
thoroughly: every executable strategy, the theorem tying each to the
reference semantics, the input-computable termination bound of each, and the
Phase-4 evidence that decides which strategy runs where. The text lands in
SPEC/Libraries/hex-real-algebraic.md(the consumer) with the new primitivesspecified in the SPECs of the libraries that own them (hex-real-roots for
Tarski queries, hex-number-field for lazy and fixed-field comparison).
Current state
AlgebraicNumber.realCompare(HexNumberField/Nearest.lean) alreadyrejects on disjoint stored intervals, then refines both operands on a
geometric schedule capped at
separationPrec (a.p * b.p) + 1, and onlythen falls back to
realCompareExact, which approximates both numbers atthe Mahler-bound precision of the product polynomial.
realCompare_eqandrealCompareExact_eqprove both return the real order. The SPEC documentsthis as the existing reference path rather than designing it again.
AlgebraicRoots withoutexactifying both, which costs two Berlekamp–Zassenhaus factorizations.
f(α) : QAdjoin awithout approximation, and nothing orders real elements of a
NumberTower.SturmReplay.checkrequires the second entry to be a positive multiple ofthe derivative, strictly descending degrees, and a terminal nonzero
constant; its common-root packages replay the gcd's own derivative chain.
It does not cover
sturm(p, f·p')for arbitraryf, a zerof, or anonconstant gcd. Its step 5 decides the position of a root relative to a
dyadic endpoint by one Sturm count plus exact evaluation. Neither is
exposed as a comparison primitive.
not from zero when zero is not a root.
ofEliminant?isolates atseparationDepth p, which is12for every linear polynomial whatever itsheight, so the lazy difference
(±2⁻ᵏ) − 0fork ≥ 13is a nonzero rootwhose stored real centre is
0. The sign of the isolation centre thereforedoes not decide the order, and the previous text of this directive was
wrong to say it did.
Required design
realCompareremains the definition. Every fast pathbelow is specified with a theorem that it returns the same
Ordering.realCompareas it exists, with its theoremand its structural fuel (the geometric schedule to the product-polynomial
separation precision) stated in the SPEC; equality is decided structurally
with no refinement. Any change to the schedule must preserve
realCompare_eq.minimal polynomial at the point plus one Sturm count on the split interval
(hex-rcf's endpoint test), no refinement, no factorization.
AlgebraicRoot.compareas the sign of the difference,using the eliminant
sub?already builds, thenisZero, then acertified sign for the nonzero difference
dwith stored polynomialp(squarefree, primitive, positive leading coefficient):−p.coeff 0;p.coeff 0 ≠ 0: the stored centre has theexact sign, because
separationDepth p ≥ ceilLog2 H + 12forH = coeffAbsMax pwhile every nonzero root has|α| ≥ 1/(1 + H) ≥ 2^(−(ceilLog2 H + 1))(reciprocal Cauchy) and thestored disc radius is below
2^(1 − prec);p.coeff 0 = 0: zero is another root ofp,so the root-separation guarantee of the isolation already excludes zero
from the disc and the centre sign is exact.
The companion proves this bound explicitly; it is not a remark. The SPEC
states the invariant every lazy root relies on, that its stored precision
is at least
separationDepthof its stored polynomial, and either showsevery
AlgebraicRootconstructor maintains it or hascomparerefine tothat depth first. If the SPEC prefers a uniform rule to the degree split,
the alternative is one bounded refinement pass to the reciprocal-Cauchy
depth of the difference eliminant (after removing its maximal
Xpower)whenever the stored real interval meets zero, with that cost stated next to
the resultant and the isolation. Say when either beats exactifying.
αandf : QAdjoin a, (i) the Tarskiquery
TaQ(f, p; I)from the Sturm chain of(p, f·p')evaluated at thedyadic endpoints of the isolating interval, exact integer arithmetic with
no refinement, added to hex-real-roots as
tarskiQueryand reusinghex-rcf's replay shape; (ii) approximation at the a priori precision from
Disambiguation.evalMajorantand the reciprocal Cauchy bound. Specifyboth; the default per degree and height regime is left to Phase 4.
NumberTower.Elemby fixed-embeddingevaluation with the same majorant bound, and comparison inside a real
tower.
min,maxandOrdon arrays of real algebraic numbers, reusingthe
algebraicRootsorder where the numbers share a polynomial.against dyadic endpoints is, since hex-rcf already replays Sturm chains in
the kernel) and whether a
decide-style comparison proof is worthexposing now or deferred.
pairs (degree sweep), close real pairs from Mignotte
x^n − (a·x − 1)²(sweep in
a), equal numbers from different lazy polynomials,rational-point comparisons, and fixed-field sign at growing coefficient
height. Comparators: python-flint
qqbarand Z3'sRCFPython bindings,both informational; Sage
AAis not an oracle. Required-check ceilingsfollow the existing mode rules.
Do not implement in this issue.
Verification
realCompareand astated input-computable termination bound.
sturm(p, f·p')forarbitrary
f, or state the extension needed.stored isolation width, on the sign of zero in a fixed field, on a
rational point that is exactly a root, and on the lazy differences
(±2⁻ᵏ) − 0fork ∈ {20, 50, 100}and(a ± 2⁻ᵏ) − afor aquadratic irrational
a, which must return the strict order.it; no strategy relies on the sign of an isolation centre without a stated
lower bound on the value it approximates.
git diff --checkpasses.Dependencies
depends-on: #10141