Repository navigation
Engine: convert each party's position to clauses once per table - #192
Merged
Merged
Conversation
A certified defeat cell converted both parties' positions to clauses, so a party in a row and a column of cells was converted once for every cell. `prepare_clauses` converts each party's position once, writes the clauses out, and has the kernel check, once per party, that they are what the conversion gives; every cell reads them. `Horn.defeatsWith?` decides a cell from given clauses, `Horn.defeatsBy?` is it with the clauses converted, and `Horn.defeats_iff_of_prepared` takes each party's proof. Every whole-dispute defeat table is ported: eleven in the arguments, two in the grits example, and the library's fixture. Five interleaved rounds, certified against prepared: the Septuagint's table 1.52 s to 0.93 s (-39%, p = 0.008), half of sola fide's 6.31 s to 5.53 s (-12%, p = 0.016); preparing sola fide's parties costs 0.35 s, once. Ledger round 10, with the measurement that set component pruning after a faster checker; the citation checks' pins move by the new definitions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BC49XsbtehCbmJMavF1K5Q
# Conflicts: # arguments/TestimonyArguments/Checks.lean # docs/src/performance.md
… off the pages `Horn.defeatChecks` and `Horn.defeatsWith?` no longer take the attacking package, which a cell with given clauses never reads; `horn_certify` finds a prepared cell's hints from the clauses themselves (`Horn.hintsWith`). The argument pages skip a declaration with no place in the source: it was generated by a command, `prepare_clauses`, as machinery for the kernel, not written for a reader, and every generated page stays as it was. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BC49XsbtehCbmJMavF1K5Q
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BC49XsbtehCbmJMavF1K5Q
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BC49XsbtehCbmJMavF1K5Q
# Conflicts: # Testimony/Logic/Certificate.lean # arguments/TestimonyArguments/Checks.lean # arguments/bench/Engine.lean # docs/src/performance.md
# Conflicts: # CLAUDE.md # arguments/bench/Engine.lean # docs/src/performance.md
deanberris
marked this pull request as ready for review
November 3, 2026 15:34
deanberris
pushed a commit
that referenced
this pull request
Nov 3, 2026
`clausesSatisfiableBy?` recursed through a pruned hint's inner one, which made it structural recursion over hints: the kernel unfolded it through `brecOn` on every question, pruned or not, and CI's benchmark gate found the prepared Septuagint table 10% slower (p = 0.032). A pruned hint is only meaningful to `askPruned`, which interprets it itself; asked of a whole position it now answers `none`, which proves nothing, and the check is a plain case split. Seven interleaved rounds against #192's head: the prepared Septuagint table +1.0% (p = 0.90) and the certified one -3.5% (p = 0.26), where the first version measured +4.7% and +8.2%. Recorded in ledger round 11. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BC49XsbtehCbmJMavF1K5Q
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.
Step 1 of the plan agreed after the relevance-pruning prototype: make each party's position a per-party artifact, rather than something every cell recomputes.
Why
A certified defeat cell converted both parties' positions to clauses. A party appears in a row and a column of its table, so a 12-party table converted each position 24 times. Measured in the kernel, conversion was about 14 ms of a sola fide cell.
What changes
Horn.defeatsWith?decides a cell from given clauses.Horn.defeatsBy?is it with the clauses converted inside, so every existing theorem stands unchanged.Horn.defeats_iff_of_preparedproves a cell from each party's proof that its clauses are what conversion gives.prepare_clauses d for D(Testimony.Logic.Certificate) converts each party's position once, at elaboration time, and writes the clauses out. It also provesd.spec : ∀ i, clausesOf (D.node i).held = d i, which the kernel checks once per party: 0.35 s for sola fide's twelve.horn_certifyfinds a prepared cell's hints from the clauses themselves (Horn.hintsWith).defeatChecksanddefeatsWith?no longer take the attacking package, which they never read.main's.Measured
scripts/bench-ab.sh origin/main --filter table, five interleaved rounds, on the final code. The prepared benchmarks exist only on this side, so they are compared with the certified ones, as in rounds 3 and 8:Every benchmark shared with
mainmatched it ("NO CHANGE"). An earlier run, before hints were searched from the clauses, measured −39% and −12% (p = 0.016).What this round also found
Ledger round 10 records two negative results, so nobody tries them again.
Pruning gave only 15% at this size. Each question was pruned to the components of a position it touches, found by union-find over the claims each clause mentions. That cut the clauses the kernel read to a third (6,671 of 19,800), but the time by only 15%.
A
List.recchecker gained nothing in the tables. Cold micro-benchmarks suggested the kernel spends most of a model check in core'sbrecOnlist functions and inClaim.ctorIdx: 7.6 ms against about 3 ms rewritten. So the checker was rewritten onList.rec, each function proved equal to core's, and the result was checked against this PR's head:List.recoverNat.recmade refutations exponential in the kernel: over 150 s for 32 synthetic formulas.Within a cell the kernel shares the work the cold measurement repeated. The rewrite was dropped, and clauses over constructor indices with it, since they rested on the same measurement.
Pins
The citation checks' definition counts move by exactly the new definitions:
#190 and #191 each also move the first arguments pin and add a ledger row. Whichever merges later meets a trivial conflict in both.
Gates
All run locally and all pass:
lake build,lake build TestimonyTools,lake lint,lake exe axiom-audit,scripts/kernel-replay.sh;bibgen/argtex/statusgen/argdoc --check;exampletex --check;testimony_lint.pyandmdbook build.The last commit changes only the ledger's prose;
testimony_lint.pyandmdbook buildpass on it.🤖 Generated with Claude Code
https://claude.ai/code/session_01BC49XsbtehCbmJMavF1K5Q