datalog: first-arg index per relation (Phase 5e perf, 169/169)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 33s

db gains :facts-index {<rel>: {<first-arg-key>: tuples}} mirroring
the membership :facts-keys index. dl-add-fact! populates the index;
dl-match-positive walks the body literal's first arg under the
current subst — when it's bound to a non-var, look up by (str arg)
instead of scanning the full relation.

For chain-style recursive rules (parent X Y), (ancestor Y Z) the
inner Y has at most one parent, so the inner lookup returns 0–1
tuples instead of N. chain-25 saturation drops from ~33s to ~18s
real (~2x). chain-50 still long but tractable; next bottleneck is
subst dict copies during unification.

dl-retract! refreshed to keep the new index consistent: kept-index
rebuilt during EDB filter, IDB wipes clear all three slots.

Differential semi-naive test bumped to chain-12, semi-only count
test to chain-25.
This commit is contained in:
2026-05-08 09:27:44 +00:00
parent c7315f5877
commit cc64ec5cf2
6 changed files with 105 additions and 23 deletions

View File

@@ -120,18 +120,20 @@
(dl-sn-counts-agree?
(dl-sn-counts "p(a). p(b). q(X) :- p(X), =(X, a)."))
true)
;; Chain length 10 exercises multiple semi-naive iterations
;; against the recursive ancestor rule.
;; Chain length 12 — multiple semi-naive iterations against
;; the recursive ancestor rule (differential vs naive).
(dl-sn-test!
"chain-10 ancestor counts match"
(dl-sn-counts-agree? (dl-sn-counts (dl-sn-chain-source 10)))
"chain-12 ancestor counts match"
(dl-sn-counts-agree? (dl-sn-counts (dl-sn-chain-source 12)))
true)
;; Chain length 25 — semi-naive only — first-arg index makes
;; this tractable in conformance budget.
(dl-sn-test!
"chain-15 ancestor count value (semi only)"
"chain-25 ancestor count value (semi only)"
(let
((db (dl-program (dl-sn-chain-source 15))))
((db (dl-program (dl-sn-chain-source 25))))
(do (dl-saturate! db) (len (dl-relation db "ancestor"))))
120)
325)
(dl-sn-test!
"query through semi saturate"
(let