feat: isolation semantics and driver completeness#8748
Merged
Conversation
Add HexRealRootsMathlib/Isolations.lean and HexRealRootsMathlib/Drivers.lean, proving isolation soundness and driver completeness for the executable real-root isolation library. `RealRootIsolation.exists_unique_root` and `RealRootIsolations.isolates` establish that a certified isolation names exactly one real root and that a complete run names every real root once; `refine1_isolates_same` shows one bisection preserves the root and halves the width; `isolateSturm?_isSome` and `isolate?_isSome` show the Sturm engine and the top-level driver succeed on positive-degree squarefree input. The `±rootBound`-versus-`±∞` question is resolved: `sturmVar_neg_pos_sub` proves the variation gap between `-rootBound p` and `rootBound p` equals `rootCount p`, a statement about `p`'s roots only, so chain-element zeros beyond the bound never disturb the count. One structural lemma (`sturmVisit_spec`, the worklist-drain induction) remains a `sorry` with its full invariant and proof plan documented; everything downstream (`isolateSturm?_isSome`, `isolate?_isSome`, the `assemble?` discharge) is complete modulo it. Two SPEC theorems (`RealRootIsolations.isolates`, `isolateSturm?_isSome`) gain an explicit `1 ≤ (p.degree?).getD 0` hypothesis: the SquareFreeRat-only forms are unsound because `SquareFreeRat 0` holds while the statements fail at `p = 0`. `exists_unique_root` keeps the SquareFreeRat-only form by deriving positive degree from its `count_one` certificate. Progress file: progress/2026-07-11T18-17-37Z-isolations-drivers.md Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NUB5EStJpJ8CPqMkNw7Qjz
Discharge the worklist-drain induction `sturmVisit_spec`, the last remaining sorry in the driver-completeness tranche: structural induction on the depth budget with truthful memoised counts, using `sturmCount_le_one` (an interval no wider than 2^(-sepPrec p) holds at most one root, by `sepPrec_separates'` on real pairs) to refute the count-≥-2-at-depth-0 branch, exact dyadic midpoint halving for the bisection step, and the containment invariants to keep the left ++ right emission ordered. `isolateSturm?_isSome` and `isolate?_isSome` are now fully proven. Progress file: progress/2026-07-11T18-37-39Z-drivers-sorry-free.md Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NUB5EStJpJ8CPqMkNw7Qjz
Weaken the hypothesis of `isolateSturm?_isSome`, `isolate?_isSome`, and `RealRootIsolations.isolates` from `1 ≤ (p.degree?).getD 0` to `p ≠ 0`: the driver's nonzero-constant branch genuinely succeeds (the empty Sturm chain certifies `rootCount = 0` through `assemble?`), and hex-rcf will call isolation on constants after `squareFreeCore`, so the degree form would force artificial downstream case splits. The positive-degree proofs stay as private helpers; the public theorems case-split on `degree?` (`none` refuted by the new `degree?_ne_none`, `some 0` via the empty-chain certification or vacuity, `some (n+1)` the existing content). Progress file: progress/2026-07-11T18-46-00Z-drivers-ne-zero-shape.md Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NUB5EStJpJ8CPqMkNw7Qjz
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR add
HexRealRootsMathlib/Isolations.leanandHexRealRootsMathlib/Drivers.lean, the isolation-semantics and driver-completeness theorems of the hex-real-roots companion, all sorry-free.RealRootIsolation.exists_unique_rootshows a certified isolation names exactly one real root oftoPolyℝ pin its half-open interval;RealRootIsolations.isolatesshows a complete run names every real root exactly once (injective root map plus therootCountcardinality);refine1_isolates_sameshows one bisection refinement preserves the isolated root and halves the width exactly, with the fallback branch unreachable;isolateSturm?_isSomeandisolate?_isSomeshow the Sturm engine and the top-level driver succeed on nonzero squarefree input, via the worklist-drain inductionsturmVisit_spec(an interval no wider than2^(-sepPrec p)holds at most one root bysepPrec_separates', so the depth budget always suffices).Three SPEC statements gain an explicit
p ≠ 0hypothesis (RealRootIsolations.isolates,isolateSturm?_isSome,isolate?_isSome): theSquareFreeRat p-only forms are unsound becauseSquareFreeRat 0holds while all three fail atp = 0(every real is a root of the zero polynomial, butcompleteforces zero isolations and the engine returnsnone). Same precedent as #8738/#8741/#8745. The nonzero-constant case is genuinely covered: the driver'sdegree? = some 0branch certifies through the empty chain (rootCount = 0), andisolatesis vacuous there, so downstream consumers (hex-rcf calling isolation onsquareFreeCoreoutput) need no degree case split.exists_unique_rootkeeps the SPEC signature verbatim by deriving positive degree from itscount_onecertificate (a Sturm count of1forces a nonempty chain).One correctness question got resolved along the way: the engine's completeness check compares the
sturmVisittotals seeded at±rootBound pagainstrootCount pcomputed from±∞leading-coefficient variations, and one might worry a chain element (a remainder of(p, p'), whose rootsrootBound pdoes not bound) could break the match. There is no gap:sturmVar_neg_pos_subproves the±rootBoundvariation difference equalsrootCount poutright, becausesturmCount_eq_card_rootsis a statement aboutp's roots only — the chain elements' own zeros are already absorbed by Sturm's theorem, and Cauchy's bound puts all ofp's roots inside(-R, R].🤖 Prepared with Claude Code