Repository navigation
Conversation
EagerGraphNilMmap32Jets answers arboretum's Nat.mul and Nat.add natively when both operands are naturals without trailing △s; anything else is left to the rules. `mul a` is △U (△△a) by S and K alone, so mul's key is one compare. `add a` holds a closure per cell of a, so add's key is a compare and a walk down a, about as long as reading a; its pieces are read off trees/addPartial.dag, which addPartial_check shows is add [△, △△]. Otherwise not proven yet: implementation/lean/Cpp/README.md has the plan. Measured back to back against main. Each test alone (base -> mul only -> add + mul, steps and median runner seconds): Music.Melody.36 139.0M 10.8 s -> 96.8M 7.8 s -> 79.1M 5.9 s; Audio.Wav.33 73.1M 5.0 s -> 50.3M 3.6 s -> 43.6M 3.1 s. Whole bundles in one runner dump the same bytes in fewer steps: arboretum 2,126.2M -> 2,058.6M, forest (no collection) 2,212.4M -> 2,031.3M. Builds from empty caches (n=1): arboretum 65.8 s -> 61.6 s, forest 140.4 s -> 134.1 s. RUNNER_JETS=0 reduces step for step as main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018ffv5AybPTpV56D5vuayQr
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.
Draft: these jets are not proven.
skip_linehasruntimeJets_sound;addandmulhave no theorem yet. Here is the proof plan, also written inimplementation/lean/Cpp/README.md:a.mulisS (K (△U)) K, somul a=△U (△△a).explorecan decide this withaas the uninspectedvar 0.add a=△ (△ (△C Z(a))) K, withZ([]) = NandZ(h:t) = △ L(h) (△ (△ (h:t) △) (△△ Z(t))). This needs list induction overa, because_zip_rest ais unrolled one layer per cell.addPartial_check, which shows thataddPartial(the treeC,K,N,L(△)andL(△△)are read off) isadd [△, △△]. It ischeckRununderdecide +kerneland takes under a second.Nat(core Lean, no Mathlib).add: ripple-carry induction through_zip_rest,_addand_carry/succ.explorehas to be extended to handle pending frames and several opaque variables.mul: induction overa's bits throughList.foldr(s ↦ 2s + h·b), usingadd's lemma and one fordouble.reduce P b k → dispatch r kand use them asJs ofruntime_sound, asDropJet's are used.What changes
eager-graph-nil-mmap-32.hpp. In the S-rule branch, after the memo lookup, there are two compares:an.u == Uleads tomul(). It readsaunder theK, decodesaandbinto 64-bit limbs, multiplies them schoolbook-style, and builds the result withlist().y == K && un.u.u == Cleads toadd(). It readsaoff the first layer ofZ(a), decodesaandb, walksZ(a)downacomparing every layer (5 loads per bit, no allocation), and adds the limbs.△s.answered(),limbs()andnatural()are eager: Nat.divmod__fastest as a jet #62's, verbatim.trees/add.dag,trees/mul.dagcome from arboretum e3df589. They are identical in forest 452c3f0's bundle.trees/addPartial.dagisadd [△, △△].embed.mjsturns all three intojets.hppandJets/Trees.lean.test-jets.cpp:add(up to 140 bits) andmul(up to 70 bits). Inputs include trailing△, cells that hold no bit, and lists that end in a stem (the last two not asmul'sb, where the rules take up to 48M steps).clear().Ls) makes a test fail.Does
add's O(|a|) key pay? YesEach test below runs alone in a fresh runner. Times are runner seconds, the median of 3, with the configurations alternated. "mul only" is this PR with
add's compare removed.Music.Melody.36Audio.Wav.33Audio.Wav.31Random.Test.3addremoves is worth about an average step (68–105 ns, against 62–80 ns/step overall), so the walk costs about nothing.add anatively, which would skip the O(|a|) rules for the partial too. It changed arboretum's replay by +0.4M steps and the times above by noise, because the partials are mostly memo hits. It is not included.Measured
All runs are on the same machine, back to back. Base is
b873b56(main)../build.sh, empty cache, wall (n=1)./build/full.sh, wall (n=1)Jets fired per replay: 197,275 (arboretum) and 248,605 (forest). In a count over the arboretum replay (an earlier build of the same jets),
muldeclined none of its 90,691 candidates, andadddeclined 816 of the 105,990 whose key matched.Review rerun: the step counts, dump hashes and cachegrind counts on this page reproduce exactly. arboretum
./build.shfrom empty caches, base and head alternated: 67.1 s, 64.6 s → 58.6 s, 60.1 s.What a key costs where it never fires
Certify.Size.Test.50runs noaddormul. Instructions under cachegrind:mul's compare: 437.0M (+2.2%).In time, the median of 5 for heavier certify tests sits within noise:
Certify.Size.Test.43: 1.86 s base, 1.83 s with both jets.Certify.Size.Test.47(94 jets fire): 8.82 s base, 8.99 s with both jets (+2.0%), and +0.7% over the same layout without the compares. Review rerun, median of 3 alternated: 8.51 s → 8.43 s.One thing I learned on the way: reducing
add [△, △△]at intern time made GCC cloneapply(), which cost 4% more instructions onCertify.Size.Test.50(456.5M against 438.4M). That is why the pieces now come from the committedaddPartialtree.Validation
implementation/cpp/dag-machine/test.shpasses underLC_ALL=Cand underLC_ALL=C.UTF-8.lake build --wfailpasses, includingaddPartial_check.dumps are byte-identical between base, mul only, and add + mul, for both bundles. WithRUNNER_JETS=0, the arboretum replay takes 2,124,623,037 steps, step for step equal to main's../build.shfrom empty caches with this runtime:src/is unchanged.submodules/lambadashows the build's exports, identical to base's../build/full.sh:git diff --exit-code --ignore-submodulesis clean, andsubmodules/arboretumshows only the tree-calculus checkout.add/mulpairs at 0–4,097 bits (limb edges, all-ones carries), with and without collections, all equal and all answered by the jet;addof 70,000-bit operands, whose sumlist()lays as a run, equal too.Caveats
add's andmul's trees without any compare moves forest's replay by −26.2M steps and arboretum's by −4.8M.add.add,mulor anything they use turns them off silently, and the fallback is still correct. That covers_zip_rest,_add,_carry,succ,_add_3bits_k,Pair,Bool.match,List.foldr,doubleandfix. A CI canary that checks jets > 0 would catch it.divmod): the S-branch ofapply,intern_jets,collect's mark line,test-jets.cpp, and the generatedjets.hpp/Trees.lean.answered,limbs,naturaland the test helperstree,kidsandbitsare eager: Nat.divmod__fastest as a jet #62's code, verbatim (onlykids's comment differs). Whichever PR lands second keeps one copy and rerunsembed.mjs. arboretum and forest only benefit once their tree-calculus pin is bumped, which is not part of this PR.🤖 Generated with Claude Code
https://claude.ai/code/session_018ffv5AybPTpV56D5vuayQr