diff --git a/lib/datalog/magic.sx b/lib/datalog/magic.sx index 4a2953f0..97168a4e 100644 --- a/lib/datalog/magic.sx +++ b/lib/datalog/magic.sx @@ -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)) diff --git a/lib/datalog/scoreboard.json b/lib/datalog/scoreboard.json index 9692afe3..a566115b 100644 --- a/lib/datalog/scoreboard.json +++ b/lib/datalog/scoreboard.json @@ -1,8 +1,8 @@ { "lang": "datalog", - "total_passed": 224, + "total_passed": 225, "total_failed": 0, - "total": 224, + "total": 225, "suites": [ {"name":"tokenize","passed":26,"failed":0,"total":26}, {"name":"parse","passed":18,"failed":0,"total":18}, @@ -13,8 +13,8 @@ {"name":"negation","passed":10,"failed":0,"total":10}, {"name":"aggregates","passed":19,"failed":0,"total":19}, {"name":"api","passed":20,"failed":0,"total":20}, - {"name":"magic","passed":24,"failed":0,"total":24}, + {"name":"magic","passed":25,"failed":0,"total":25}, {"name":"demo","passed":21,"failed":0,"total":21} ], - "generated": "2026-05-08T10:36:02+00:00" + "generated": "2026-05-08T10:40:13+00:00" } diff --git a/lib/datalog/scoreboard.md b/lib/datalog/scoreboard.md index 7810f66a..a6d1976d 100644 --- a/lib/datalog/scoreboard.md +++ b/lib/datalog/scoreboard.md @@ -1,6 +1,6 @@ # datalog scoreboard -**224 / 224 passing** (0 failure(s)). +**225 / 225 passing** (0 failure(s)). | Suite | Passed | Total | Status | |-------|--------|-------|--------| @@ -13,5 +13,5 @@ | negation | 10 | 10 | ok | | aggregates | 19 | 19 | ok | | api | 20 | 20 | ok | -| magic | 24 | 24 | ok | +| magic | 25 | 25 | ok | | demo | 21 | 21 | ok | diff --git a/lib/datalog/tests/magic.sx b/lib/datalog/tests/magic.sx index e9ebefb3..90855cd2 100644 --- a/lib/datalog/tests/magic.sx +++ b/lib/datalog/tests/magic.sx @@ -197,6 +197,19 @@ 6) ;; dl-magic-query: end-to-end driver, doesn't mutate caller's db. + ;; Mixed EDB + IDB: a relation can be both EDB-seeded and + ;; rule-derived. dl-magic-query must include the EDB portion + ;; even though the relation has rules. + (dl-mt-test! "magic mixed EDB+IDB" + (len + (dl-magic-query + (dl-program + "link(a, b). link(c, d). link(e, c). + via(a, e). + link(X, Y) :- via(X, M), link(M, Y).") + (list (quote link) (quote a) (quote X)))) + 2) + ;; dl-magic-query falls back to dl-query for built-in, ;; aggregate, and negation goals (the magic seed would ;; otherwise be non-ground).