datalog: dl-magic-query handles mixed EDB+IDB relations (225/225)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 51s

Bug: dl-magic-query was skipping EDB facts for relations that had
rules ("rule-headed"). When a single relation has both EDB facts
and rules deriving more (mixed EDB+IDB), the rewritten run would
miss the EDB portion entirely, producing too few or zero results.

Fix: copy ALL existing facts to the internal mdb regardless of
whether the relation has rules. EDB-only relations bring their
tuples; mixed relations bring both EDB and any pre-saturated IDB
(which the rewritten rules would re-derive anyway).

1 new test: link relation seeded with 3 EDB tuples plus a
recursive rule via via/2. dl-magic-query rooted at `a` returns
2 results (a→b direct, a→c via via(a,e), link(e,c)).
This commit is contained in:
2026-05-08 10:41:36 +00:00
parent 254052a43b
commit 96f66d3596
4 changed files with 28 additions and 12 deletions

View File

@@ -397,15 +397,18 @@
(mdb (dl-make-db))
(rule-heads (dl-magic-rule-heads rules)))
(do
;; Copy EDB facts (relations not headed by any caller rule).
;; Copy ALL existing facts. EDB-only relations bring their
;; tuples; mixed EDB+IDB relations bring both their EDB
;; portion and any pre-saturated IDB tuples (which the
;; rewritten rules would re-derive anyway). Skipping facts
;; for rule-headed relations would leave the magic run
;; without the EDB portion of mixed relations.
(for-each
(fn
(rel)
(when
(not (dl-member-string? rel rule-heads))
(for-each
(fn (t) (dl-add-fact! mdb t))
(dl-rel-tuples db rel))))
(for-each
(fn (t) (dl-add-fact! mdb t))
(dl-rel-tuples db rel)))
(keys (get db :facts)))
;; Seed + rewritten rules.
(dl-add-fact! mdb (get rewritten :seed))