Skip to content

feat(primality): add certificate search and the bounded decision API - #9402

Merged
kim-em merged 45 commits into
mainfrom
primality-decide
Aug 24, 2026
Merged

feat(primality): add certificate search and the bounded decision API#9402
kim-em merged 45 commits into
mainfrom
primality-decide

Conversation

@kim-em

@kim-em kim-em commented Aug 22, 2026

Copy link
Copy Markdown
Owner

This PR completes the search half of milestone 3 in HexPrimality/SPEC/hex-primality.md. primeCertGo/assembleGo are a mutual recursion on (fuel, worklist length) — runtime dispatch that appears in no proof term, so well-founded recursion is fine here — with verdict tiers first (size, table completeness, a Miller-Rabin base scan) and then partialFactor (n - 1), one certified child and one searched witness per claimed prime-power entry. A child-certification failure is reported as exhaustion, never as compositeness of the parent: a composite child only means the untrusted factorization guessed wrong.

primeCert? builds the indexed CheckedPrimeCert through runtime dependent checks (zero proof plumbing), so a certificate for one number can never answer a request about another. primeCert?_composite is proved by path analysis: the only .composite exits are the three justified verdicts, and assembleGo_error_stop shows search failures cannot masquerade as verdicts. On top sit isPrime? (table below primeTableBound, exact trial below a placeholder threshold the bench will measure, then certificate search) with isPrime?_spec, the total isPrime whose trial fallback makes isPrime_iff unconditional, and nextPrime? with the leastness invariant carried through the scan.

Guards cover all three decision tiers; 2^31 - 1 exercises the certificate tier deterministically since its n - 1 factors entirely over the committed table.

Stacked on #9401.

🤖 Prepared with Claude Code

Kim Morrison and others added 9 commits August 22, 2026 03:43
…visor lemmas

powModNat gains the p = 0 guard so it agrees with powMod at every
input, its recursion (powModNatGo, bitLength) is @[expose]d, its
correctness theorem is exported, and an unconditional @[csimp] names
powModNat the kernel-facing specification with powMod the runtime
twin. instDecidablePrime re-routes decide through isPrimeTrial,
exists_trial_divisor is exported, and exists_prime_dvd plus
exists_prime_le_sqrt are the composite-witness lemmas the hex-primality
Pocklington argument finishes with. SPEC amendments record the landed
state (hex-arith SPEC modular-exponentiation and primality sections;
hex-primality SPEC stale claims corrected).

Progress: progress/20260822T034253Z_primality-m0.md

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133rJ7x9mYiiXpJceCnc1A9
… at 10^4

Adds the HexPrimality library (deps HexArith, HexBasic) with its
umbrella, libraries.yml entry, CI lib target, and the SPEC co-located
at HexPrimality/SPEC/hex-primality.md. Table.lean commits the
1229-entry primeTable below primeTableBound = 10000 with sortedness,
binary-search membership (isTablePrime_iff), soundness via one
kernel-replayed isPrimeTrial sweep, completeness via five balanced
kernel-replayed coverOk chunks, and primesIn with its membership
theorem. Statements are sieve-agnostic so the planned kernel-reducible
sieve swaps proof internals only.

Progress: progress/20260822T040440Z_primality-table.md

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133rJ7x9mYiiXpJceCnc1A9
Order.lean defines orderOf as a bounded least-search with junk value 0
off the coprime domain and proves the SPEC's order stack Mathlib-free:
coprimality from a unit power, coprime cancellation, multiplicative
Fermat, order positivity via pigeonhole through the ListShim, order
divisibility both ways, orderOf_dvd_pred, prime-power extraction into
the order, and the two square roots of 1 modulo a prime.

Progress: progress/20260822T041921Z_primality-order.md

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133rJ7x9mYiiXpJceCnc1A9
…tion

MillerRabin.lean adds oddSplit with its spec, the squaring loop, and
millerRabin with the SPEC's exact branch table, plus defaultBases and
isProbablePrime. Soundness is the contrapositive
millerRabin_eq_true_of_prime by forward induction along the loop with
sq_roots_of_one; not_prime_of_millerRabin_false is the public theorem,
and no completeness is claimed. Guards cover Carmichael numbers,
strong pseudoprimes, and agreement with isPrimeTrial below 512.

Progress: progress/20260822T042306Z_primality-millerrabin.md

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133rJ7x9mYiiXpJceCnc1A9
Implements the hex-finite-field SPEC's Randomness section at its
specified site in hex-basic: Rand with next, RandError carrying the
advanced state on exhaustion, Rand.nat by rejection sampling that
rejects the incomplete top interval, Rand.ofSeed, and the range
theorem Rand.nat_lt. Known-answer guards pin the canonical splitmix64
seed-0 vector and deterministic replay.

Progress: progress/20260822T042502Z_hexbasic-rand.md

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133rJ7x9mYiiXpJceCnc1A9
…e checker

Cert.lean defines PrimeCert (with the pock3 constructor carrying the
integer-square-root witness the SPEC amendment records, its arithmetic
stubbed false until milestone 4), the structurally recursive
checkPrime/checkChildren pair with all workers @[expose]d against the
kernel-facing powModNat, and checker soundness prime_of_checkPrime by
strong induction on the subject value, through the pocklington core
theorem, the fused coprime-prime-power combination, and the
gcd-to-noncongruence transport. CheckedPrimeCert and the
single-Bool-slot prime_of_checkPrimeAt serve the coming search and
tactic layers. Guards cover accepted multi-level certificates and one
rejected certificate of each kind.

Progress: progress/20260822T043327Z_primality-cert.md

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133rJ7x9mYiiXpJceCnc1A9
Search.lean adds RhoStop/RhoFailure with the resumable-failure
convention, rhoFactor? as Brent cycle search with restart draws from
Hex.Rand and dynamic validation at every success exit (making
rhoFactor?_spec a fuel induction over guards), and the internal
partialFactor: table trial division, then a rho worklist whose every
path preserves the product exactly, giving the unconditional
partialFactor_prod invariant.

Progress: progress/20260822T044003Z_primality-rho.md

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133rJ7x9mYiiXpJceCnc1A9
Search.lean gains the resumable failure types, the mutual
fuel-and-worklist certificate search primeCertGo/assembleGo (runtime
only, so well-founded recursion is fine), the indexed primeCert? whose
runtime dependent checks build CheckedPrimeCert with zero proof
plumbing, the verdict theorem primeCert?_composite by path analysis,
isPrime? across the table/trial/certificate tiers with its exactness
spec, the total isPrime with unconditional isPrime_iff, and nextPrime?
with its leastness spec.

Progress: progress/20260822T044458Z_primality-decide.md

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133rJ7x9mYiiXpJceCnc1A9
Kim Morrison and others added 20 commits August 24, 2026 02:27
The stack changes factor-sweep-relevant sources with no effect on the
factorization service: the powModNat kernel-facing amendments and the
Decidable (Prime p) reroute in hex-arith, the primality conformance
emitters, the hotPathCandidates proof-carrying view with pinned values,
and per-milestone lakefile registrations. Each transition gets an exact
blob-pair exemption with its reason, and the file is unioned with
main's current entries so the stack also inherits the HexBasic/Rand
attestation that merged separately.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133rJ7x9mYiiXpJceCnc1A9
# Conflicts:
#	scripts/bench/proof_only_runtime_exemptions.json
# Conflicts:
#	scripts/bench/proof_only_runtime_exemptions.json
# Conflicts:
#	.github/workflows/ci.yml
#	SPEC/future-work.md
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133rJ7x9mYiiXpJceCnc1A9
rhoInnerFuel scaled as 16 * (n^(1/4) + 2) with no ceiling, so one
Brent restart at 256+ bits had an effectively unbounded budget and a
search whose smallest factor was out of reach hung inside the first
restart instead of returning a clean exhausted. Capping at 2^22 binds
only past n ~ 2^72 and still covers factors to about 2^44, beyond
rho's documented ~10^12 remit; a semiprime with two ~2^35 factors
still splits in 182 ms while one with two ~2^60 factors now exhausts
cleanly at seconds per restart. The spec proofs are fuel-agnostic and
unchanged, and the emitted conformance fixtures are byte-identical.

Progress: progress/20260824T004117Z_primality-rho-cap.md

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133rJ7x9mYiiXpJceCnc1A9
(cherry picked from commit 7fb9f77)
Codex review of the decision core noted the counter reads as a global
total; it counts only the failing search's restarts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133rJ7x9mYiiXpJceCnc1A9
Codex review of the decision core noted the counters read as global
totals; each counts only its own failing subsearch, and the next-prime
counter excludes the unresolved candidate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133rJ7x9mYiiXpJceCnc1A9
Tail-appended exemption entries conflict textually with every
concurrent append on main; placing the stack's entries after the first
entry keeps future main-side appends automatically mergeable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0133rJ7x9mYiiXpJceCnc1A9
# Conflicts:
#	.github/workflows/ci.yml
#	scripts/bench/proof_only_runtime_exemptions.json
@kim-em
kim-em changed the base branch from primality-search to main August 24, 2026 15:49
@kim-em
kim-em merged commit 0922748 into main Aug 24, 2026
1 check passed
@kim-em
kim-em deleted the primality-decide branch August 24, 2026 16:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant