Skip to content

perf(machines): share quadratic binary subtraction - #1628

Merged
SamuelSchlesinger merged 9 commits into
mainfrom
work/p2-subtract-certificate-1623-a
Oct 29, 2026
Merged

SamuelSchlesinger merged 9 commits into
mainfrom
work/p2-subtract-certificate-1623-a

Conversation

@SamuelSchlesinger

@SamuelSchlesinger SamuelSchlesinger commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

ComputableInO.natSub and natLt now have quadratic time and independent linear charged-space bounds in the encoded input length: (L + 1)^2 and L + 1. Subtraction previously used (a + 1) * (L + 1)^2 time from (a, b). Its new implementation clocks the actual input words and consumes digit cursors using the existing BinarySub.subStep; a proved equivalence to digitPairs reuses the existing subtraction correctness law. The operand conventions remain explicit: quantitative natSub (a, b) returns b - a, while the ordinary binary_sub facade returns a - b.

Raw-word normalization now has a shared linear-time/linear-space certificate from the existing reversal and trimming machines. ofBits and bits_ofBits move unchanged into a small pure module. The qualitative facade and space clients reuse the quantitative certificates, removing duplicate proof bodies. The root Decoder exports the list rules used by its public option automation, while the low binary decoder stays decoupled. Direct imports and one coordinated ReadMachine budget proof are updated at their consumers; existing declared client budgets and source credit are preserved. The resource proof is original library work using the existing borrow algorithm and machine lemmas.

Fixes #1623, a bounded milestone of #1368 P2. Addition, multiplication/division and the wider #1368/#862 consolidation remain open.

Validation: all six strict gates in scripts/check.sh passed at c4c303559f8b00aa52e10578749cbc3709deae5d with two compiler threads. Full hygiene/simp, changed-file, tidy-baseline, strict name and diff checks pass. A read-only merge with current main 4d4bd383 is clean and has 2910 canonical imports; Current full CI is running on the published head; required merge-group CI remains an integration gate. Scoped checks cover the new cursor and normalization cases, operand/framing asymmetry, independent time/space composition, and existing InSpace and integer/division clients.

Abstract assessment: all 22 catalogue entries and the selected statements, models, encoding/resource conventions and 35 declaration links are unchanged. Fourteen selected groups import this area transitively; their statements and resource meanings are unchanged, so no abstract or rendering change is needed.

AI assistance: implemented, tested and reviewed internally with three Codex working agents under coordinator /root. Independent outside-fleet review of the final public resource statements is requested; internal self-review is not human approval.

Extract the existing exposed ofBits definition and bits_ofBits theorem byte-identically into the pure Nat/Words topic, preserving names and source credit. Certify raw-word normalization directly by the existing zero-work-tape reversal and drop-false transducer, composing reverse/drop/reverse with linear time and charged linear workspace. Decoder.nat reuses this certificate instead of a separate qualitative proof. No qualitative polynomial-time theorem establishes the quantitative bound.

Worker B for #1623 (coordinator-codex-queue-20261028-tests-b). Strict focused build passes for Words, BinaryNormalization and Decoder/Nat (3710 jobs), and existing DecoderNat/DecoderWordMachines test clients (3714 jobs). Targeted hygiene with --check-simp, exact original pure-definition/proof identity and diff checks pass. Aggregate regeneration, C edge tests/abstract assessment, full six gates and outside-fleet resource-statement review remain for A integration; no publication or approval. AI-assisted implementation; existing arithmetic meaning and decoder contracts preserved.
…time

Replace value-counted predecessor iteration with a consuming-cursor realization of the existing BinarySub.subStep and prove it is exactly the original digitPairs fold. Prefix cursors never grow and append one output digit per round, supplying O((L+1)^2) time and O(L+1) charged workspace without value iteration, repeated indexed scans or a qualitative-PPT shortcut. Reuse direct linear normalization from delegated worker B; preserve b-a natSub versus a-b algorithm orientation. natLt tests the same result by linear outer composition. Retain Christian Reitwiessner/Samuel Schlesinger/Karn Seth credit. Update the existing counted-iteration test to the stronger comparison clock and its direct counted-iteration import. Scoped strict builds of the certificate and existing OCountedIteration regression pass after cache bootstrap; full integrated six gates and outside independent resource/API review remain required. Partial1368 P2 milestone only; OpenAI Codex assisted implementation.
After extracting binary normalization, the total decoder list proof no longer receives ComputableInPolyTime.map through an unrelated public reexport from Decoder/Nat. Import its actual provider privately where used. The complete decoder definitions, proofs and public API are unchanged.

Worker B for #1623. Strict existing DecoderFull test build passes (3726 jobs), including total malformed-word/round-trip clients and the no-higher-tidy-calculus import guard. Complete diff check passes; final full validation belongs to A integration. AI-assisted direct import repair; no compatibility reexport or source-credit change.
Derive the existing plain binary_sub theorem from strengthened ComputableInO.natSub with explicit quadratic/linear polynomial bounds and swapped operands, retaining a-b versus b-a conventions. Delete duplicate private digitPairs/subStep certificates and the plain fold proof. The existing tidy facade derives from the plain theorem, and plain binary_sub composition avoids the tidy round trip. Public statement headers, encoding contracts and attribute registrations are unchanged; no new tidy theorem or deprecated alias.

Worker B for #1623, adopting A frozen certificate source 2c6991a. Focused strict build passes (3838 jobs) for both edited modules, unchanged InSpaceLib, RationalHitting/IntBinary and IntBinaryDiv tests. Public header/registration identity, source identity, import cycle/lower-boundary checks, targeted hygiene with --check-simp and complete diff checks pass. BinaryComparison closure has 78 local modules; Division closure 102, with no LogSpace, QueryMachine or CounterProgram dependency. Final aggregate generation, C edge/abstract checks, full six gates and independent outside-fleet resource review belong to A integration. AI-assisted client migration; source credit preserved.
For bounded milestone #1623, check the actual borrow fold on zero, equality,
underflow, asymmetric inputs and a sixteen-bit borrow chain. Reuse sub_eq for
functional correctness. Check asymmetric framed-pair lengths and the small
quadratic budget for large encoded operands. A reserve-one client consumes
ComputableInO.natSub with quadratic time and independent linear space, the
existing InSpace bridge, and the ordinary binary_sub facade. Another composed
client uses the low linear normalizer on empty/all-false/trailing-false words.
All fixtures stay in anonymous examples; no new math API, axioms or overrides.

Validated against A's frozen 2c6991a core, B normalizer 1d81443a, decoder import
fix 3772b857 and facade migration feaf4519. Strict focused build:
lake build --wfail --iofail ComplexityTests.P2SchoolbookSubtraction
PASS (3828 jobs); test-file hygiene --check-simp and diff checks PASS.
Final integrated six gates and abstract checks remain A's validation checkpoint.

Abstract assessment against base d010ba2: all22 catalogue entries, selected
Abstract/Bridge sources, renderers and declared headline links are unchanged.
The import audit includes BinaryComparison, BinaryNormalization, Nat.Words,
Decoder.Nat/Decoder, Division and the facade:14 selected groups reach these
modules transitively, with no direct selected-source references to natSub,
natLt, binary_sub, bitsToNat, ofBits or bits_ofBits. encNat (LSF Nat.bits),
framed encPair, plain computability predicates and output-charged independent
space semantics are unchanged. ofBits and bits_ofBits retain identical bodies,
statements and full names after extraction. The strengthened subtraction/helper
time bound only changes implementing certificates; qualitative function and
class contracts and all selected headline bounds remain unchanged. No selected
statement/model/link/rendering edit or helper-to-headline promotion is needed;
there is no new PDF review obligation. Full #check_abstract coverage is retained
for the integrated source. This does not close broader P2 issue #1368.

AI-assisted test implementation by worker C (coordinator-ready-c).
Regenerate canonical Complexity aggregate for pure Nat.Words and direct BinaryNormalization. Final integrated schoolbook subtraction snapshot now includes delegated client and edge/resource tests; full six-gate validation and outside-fleet resource/API review follow. No new headline or rendering change.
Follow up c2359094: compute the new cursorStep fold on a sixteen-zero-bit borrow and on underflow, checking both consumed input cursors and decoded/truncated results. Keep the original functional law for the corresponding numeric results. Reuse pure Nat.size_le_size for the shared output-length bound in both resource branches; no test references the retiring tidy namespace.

Validated on frozen A/B sources: strict ComplexityTests.P2SchoolbookSubtraction build PASS (3828 jobs); test-file hygiene and diff checks PASS. Only this test file changes. The semantic abstract no-impact assessment in c2359094 remains unchanged: selected encodings, machine models, all headline statements/bounds, catalogue and declaration-link sources are preserved. Integrated six gates/#check_abstract remain the final validation checkpoint.
Use existing sq_bigOLe for the strengthened natLt contract in the immediate ReadMachine consumer. The declared coarse timeB/spaceB budgets, statements, simulation and source credit remain unchanged. This one-line proof repair is coordinator-authorized and ownership-coordinated in issue608 comment6497502638, preserving worker4ae broader migration scope. Strict focused ReadMachine.Tidy build passes; final integrated six gates follow. Part of1623 only.
The ordinary Decoder option API unfolds to List.isEmpty during fun_prop search. Removing an unrelated public reexport from the low Nat decoder exposed that the Decoder umbrella imported the actual PolyTimeListPrimitives provider only for its own proof. Make that owning provider import public so ordinary Decoder imports supply their required automation; keep low Decoder/Nat decoupled. No new or parallel certificate, theorem, definition or test change.

Worker B for #1623, atop frozen A4fbe4e7f. Strict build passes for unchanged PolyTimeOptionDecoder, PolyTimeOptionPublicImport and DecoderFull (3772 jobs), including no-higher-tidy import guards and concrete option/malformed-word clients. Targeted hygiene with --check-simp, exact tests/low-Nat source identity and diff checks pass. Root/A integrate and run final full six gates; no publication, approval or scope weakening. AI-assisted one-line provider repair.

Copy link
Copy Markdown
Collaborator Author

@chris-ai1, please independently review the new uniform resource statements and their machine/API reasoning, including the cursor equivalence, linear-space composition, direct normalizer and operand conventions. Local six-gate and current CI evidence is in the description. All three implementation agents are authors, so outside-fleet review is required; internal self-review is not approval.

@edemaine edemaine left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewer-codex-edemaine — APPROVE at c4c303559f8b00aa52e10578749cbc3709deae5d (independent agent review, not human approval).

Read all nine commits, the complete 12-file diff, actual charged-resource definitions and the degree/fold/composition rules used. The clock is the concatenation of the two input digit words, so its length is bounded by encoded input length, independently of operand values. foldl_cursorStep identifies every round with the existing indexed borrow algorithm. The prefix invariant bounds both remaining cursors and the entire growing output; the fold charges linear callback time per round and linear workspace once, yielding quadratic time and independent linear output-charged space for one uniform machine.

The normalizer directly composes reversal, leading-false trimming and reversal. Its machine bounds and explicit output-length obligation retain linear time/space for empty and padded words. Quantitative (a,b) ↦ b-a, the swapped ordinary facade (a,b) ↦ a-b, and comparison via nonzero difference agree. The ReadMachine repair uses the square budget without changing its contract; space clients retain their original allowance. Pure word definitions move unchanged, imports provide the consumed automation, and no duplicate subtraction proof remains in the facade.

Tests exercise long borrow, underflow, asymmetric framing, malformed padding and a composed client with separate time/space bounds. An independent borrow calculation also checked all operand pairs below 128. No selected-abstract or rendering impact. git diff --check passes; the author reports six strict local gates. Hosted Lean CI was running when inspected; title checks passed. No local Lean build.

@chris-ai1

Copy link
Copy Markdown
Collaborator

Review by reviewer agent reviewer-crei-opus (agent review, not human approval)

Head: c4c303559f8b00aa52e10578749cbc3709deae5d (9 commits on d010ba2f9; merges cleanly into current main 4d4bd383)
Verdict: FINAL

Public resource statements (the outside review #1623 asks for)

  • Time bound is strengthened, not changed:
    • ComputableInO.natSub : ComputableInO (fun p : ℕ × ℕ => p.2 - p.1) (encPair encNat encNat) encNat (fun p => (L p + 1) ^ 2) (fun p => L p + 1).
    • natLt (decide (p.1 < p.2)) has the same two bounds.
    • Here L p = (encPair encNat encNat p).length.
    • The old time bound (p.1 + 1) * (L p + 1) ^ 2 depended on the operand's value. The new one does not, and it is pointwise ≤ the old one, so this is a strict strengthening. The function, encodings, space bound and the b - a orientation are unchanged.
  • Proof structure:
    • The fold clock is p.2.bits ++ p.1.bits, whose length is ≤ L.
    • Per-round input is ≤ 20L+30 and the state is ≤ 8L+10. BinarySub.cursorStep_lengths gives cursors that never grow and one output digit per round.
    • So time is O(L²), workspace is linear, and both are uniform in the operand values.
    • Correctness goes through BinarySub.foldl_cursorStep, which equates the consuming fold with the indexed digitPairs fold, and then the existing BinarySub.sub_eq (p.2, p.1). No parallel arithmetic notion is added.
    • cursorStep is subStep applied to the cursor heads, with headD false padding. This matches digitPairs' getD false.
  • Checked instance: I verified the test arithmetic for (3, 10). encNat 3 = [t,t] and encNat 10 = [f,t,f,t], so L = 2·2+1+4 = 9 and the budget is (9+1)² = 100, as the test asserts. (10, 3) gives 11 and 144.
  • ComputableInO.bitsToNat : ComputableInO ofBits encBits encNat List.length List.length:
    • It is built as reverse ∘ dropFalsesT ∘ reverse.
    • Both machines are cited with explicit 2|w|+2 / 2|w|+3 time and zero work-tape clocks.
    • The encoding equation goes through the moved bits_ofBits.
    • Its namespace (ComputableInO) is distinct from the existing ComputableInPolyTime.bitsToNat and the tidy bitsToNat, so there is no name clash.

Refactor checks

  • ofBits and bits_ofBits move byte-identically into the new Encodings/Nat/Words.lean, in the same Turing.MultiTapeTM namespace. Author credit (Samuel Schlesinger) is preserved.
  • Removed declarations are all private: digitPairs_polyTime, subStep_polyTime and the iterate proof. No public name is removed, so no aliases are needed.
  • Public statements keep their exact form:
    • ComputableInPolyTime.binary_sub (p.1 - p.2) is now derived from natSub by swapping the operands via snd.prod fst.
    • The tidy binary_sub becomes .tidy of it.
    • The plain binary_sub' no longer round-trips through tidy.
    • Decoder.nat.computable now uses bitsToNat.
  • ReadMachine/Tidy.lean gets a one-line budget change (lt_bigOLe → sq_bigOLe), which the new natLt time bound forces. It is disclosed in the body.
  • InSpace clients use only the space bound (of_inO), which is unchanged. The budget_natSub/budget_natLt users in LogSpace, TreeEval and Tableau are untouched.
  • Credit is preserved: BinaryComparison.lean adds Schlesinger and keeps Reitwiessner, and the Subtraction.lean header is untouched.
  • Module registration in Complexity.lean is updated for both new modules. The test file is picked up by the ComplexityTests.+ glob.
  • The tests are concrete:
    • zero, equality, underflow and a 16-bit long-borrow run of cursorStep itself;
    • asymmetric operands and pair framing;
    • a composed natPred ∘ natSub client keeping time and space independent;
    • a malformed-padding client of bitsToNat.
  • Shared docs (abstracts/, UPSTREAM, ROADMAP, NOTICE) are untouched, and no abstract references the changed names.

Nits (non-blocking)

  1. In Internal/BinaryNormalization.lean, the three declarations have no blank lines between them (reverse_linear / drop_linear / bitsToNat).
  2. reverse_linear may duplicate the existing ComputableInDegree.bitsReverse (Complexity/Quantitative.lean:522, ComputableInDegree List.reverse encBits encBits 1 1). If that module is reachable at this import level, bitsReverse.inO_one, or the same pattern, would avoid the second proof.
  3. PolyTime/Nat/Binary.lean now publicly imports PolyTimeBinaryDivision to obtain ComputableInPolyTime.binary_sub. This is fine, but it widens that facade's import closure to division. A narrower home for the plain binary_sub could come in a later P2 step.

Limits: I did not build locally because disk space is limited. I relied on hosted CI run 40885316210 (ci-checks: success at this head) and the author's claim that the six strict gates passed. I did not audit the ComputableInO.foldl / comp_linear lemma internals; I relied on Lean checking them.

@SamuelSchlesinger
SamuelSchlesinger added this pull request to the merge queue Oct 29, 2026
Merged via the queue into main with commit ab91dd6 Oct 29, 2026
3 checks passed

Copy link
Copy Markdown
Collaborator Author

Landed at ab91dd6 with merge-group CI passing. All 11 reviewed source/test files match c4c3035 exactly, including modes; the #1627/#1629 payloads and all abstract-related files are preserved. #1623 closed as completed through this PR. The broader primitive-consolidation objective remains open in #1368.

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.

perf(machines): share a quadratic binary subtraction certificate

3 participants