Repository navigation
P4+P2: import_closure worklist BFS + parser token index - #6241
Conversation
… by position. Prebuild normalized adjacency once per ModuleGraphFactsLive (O(V+E) per entry instead of O(D·R·E) fixpoint). Mirror the same BFS shape in module_graph.dag. Switch v1 parser token_stream_first/peek from skip|>first to O(1) get() with a matching interpreter builtin. Co-authored-by: Cursor <cursoragent@cursor.com>
fba7b47 to
e13ba06
Compare
|
Re: Confirmed intentional — duplicate module names from distinct declaring files are unrepresentable in the fact rows this lens consumes.
So the BFS adjacency does not silently drop a competing authority; that state is refused before facts reach — sent from smart-lynx-289 |
|
Re: composer-2.5 review (no findings) Verified — no code changes requested. Scope matches the two roadmap items only; — sent from smart-lynx-289 |
Measure-first: floor witness roster (519 entries × 2 closure calls) — fixpoint 29.8s vs BFS 14.6ms (~2040× on this microbench; does not move the ~72min emit-dominated compile-clean gate). Consolidate list-index get into list_get_at_or_null shared by method + free-function paths. Co-authored-by: Cursor <cursoragent@cursor.com>
b3f776a to
c9e55ae
Compare
There was a problem hiding this comment.
Approving on adversarial review + landed discipline. Correctness verified (P4 worklist BFS is behavior-preserving vs the fixpoint — dedup adjacency, finite reached-set, order normalized via sort with BTreeSet consumers; P2 get builtin matches the pre-existing method-form get, no OOB). rust_tests green; purity oracle (set-identity vs independent reference over the whole floor) + RED control present; measure-first receipt landed (~2040x on discovery-side resolve) with an HONEST note that it does not move the emit-dominated compile-clean gate. section-2 dup consolidated. The ci-floor timeout failure is the by-design dark-CI cap, not a blocker.
…mpile) (#6255) #6241 landed get(xs:, index:) calls in 02_parse.dag (token_stream_first / token_stream_peek). The name was already the single surface for this builtin in the interpreter ("get" -> list_get_at_or_null, both call forms, v1_interpreter.rs) and the Rust emitter (emit_typed_call special-case), but builtin_function_registry (04_method.dag) had no row, so the self-compile / regen path could not resolve it: regen_stage0 failed with two "function 'get' not found in scope" diagnostics on any tree, blocking regen for every lane. Registering get (returns element?, mirroring map_get's optional-cardinality row) completes the same builtin across all three stages — no second name minted (DESIGN.md section 3). Two layers: the .dag registry row (authority) + the same row hand-synced into the seed's v1_compiler_infer_method.rs (regen needs the seed to resolve the corpus before it can regenerate itself). Witness: dag/test/claim/builtin_get_resolver_test.dag (in/out-of-bounds/negative). Verified by execution: regen_stage0 --emit-fresh exits 0 on this branch (fails with the two get diagnostics on origin/main). Co-authored-by: Brian Searls <briansearls1@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…ed data rows, dedup dag_collect registry (GENERATED -> HAND-only) (#6262) #6242 added // comments to dag_collect.dag / dag_collect_support.dag — .dag has no comment syntax since #5579, so the corpus stopped parsing (Slash diagnostic + 64 cascade errors: modules unresolved, json_quote/dag_node_key/is_module_shell_node not in scope) — and left v1_compiler_dag_collect{,_support}.rs in BOTH regen registries, which assert_registry_is_partitioned correctly fail-closes on. Both breaks were invisible: CI floor dark (10-min interim) and regen was already red from #6235/#6241 when #6242 merged. - comments -> typed data rows (dag-no-comment convention), content preserved verbatim including both Dissolve-on markers - registry dedup: dag_collect pair GENERATED->HAND-only (matches #6242's intent comment: hand-edited seed carries the Rc::as_ptr memo until grounded) - .dag roster mirror (gunbc.stage0_emit_model) deduped to match; witness pin 92->90 Receipts (local; CI dark): regen self-compile 0 hard diagnostics (was 2-layer red: registry assert, then 65 diagnostics); --verify now reaches byte-compare and reds only on the PRE-EXISTING latent emitter drift (the 1667-error cutover backlog, tracked on the 5-regen-cutover carrier). Co-authored-by: Brian Searls <briansearls1@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Summary
import_closure_from_factswhole-corpus fixpoint with worklist BFS over prebuilt normalized adjacency onModuleGraphFactsLive. Mirror inv2.lens.module_graph.token_stream_first/peekfromskip|>firstto indexedget(xs, index); add matchinggetlist-index builtin (consolidated vialist_get_at_or_null).Measure-first receipt (P4)
Command:
cargo test -p v1-compiler --lib import_closure_bfs_vs_fixpoint_perf_receipt -- --ignored --nocaptureFixture: floor witness
*_test.dagroster (519 entries), 2 closure calls/entry (resolve-path shape).origin/main)Honest CI gate assessment: This is a resolve/discovery-side speedup. The load-bearing
cicompile-clean gate is emit-dominated (~72 min whole-tree--target dag, ~85–90% emit per survey). This PR does not materially move that number. It still pays off on every discovery/claim resolve that callsimport_closure_live(hook-gate runs, shard resolve, precompute) — denominated accurately, not as a compile-clean unblocker.P2 (
getvsskip|>first) removes O(M²) per-module parse in the interpreted v1 parser path; native Rust seed already used.get(). Parse floor impact is separate from the emit gate.Test plan
cargo test -p v1-compiler --lib import_closure_live_matches— 5/5 greencargo test -p v1-compiler --lib import_closure_bfs_vs_fixpoint_perf_receipt -- --ignored— BFS < fixpoint on floor rostercargo clippy -p v1-compiler -- -D warnings— clean (prior run)cargo fmt --all --check— clean