datalog: magic-sets benefit test on disjoint-cluster graph (205/205)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 24s

Two disjoint chains, query rooted in cluster 1. Semi-naive
derives the full closure over both clusters (6 ancestor tuples).
Magic-sets only seeds magic_ancestor^bf for cluster 1, so only
2 query-relevant tuples are returned (a→b, a→c). The test
asserts both numbers, demonstrating the actual perf-shape
benefit of goal-directed evaluation.
This commit is contained in:
2026-05-08 10:03:04 +00:00
parent a53e47b415
commit 57a1dbb232
3 changed files with 29 additions and 6 deletions

View File

@@ -1,8 +1,8 @@
{
"lang": "datalog",
"total_passed": 204,
"total_passed": 205,
"total_failed": 0,
"total": 204,
"total": 205,
"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":18,"failed":0,"total":18},
{"name":"api","passed":14,"failed":0,"total":14},
{"name":"magic","passed":20,"failed":0,"total":20},
{"name":"magic","passed":21,"failed":0,"total":21},
{"name":"demo","passed":18,"failed":0,"total":18}
],
"generated": "2026-05-08T10:00:29+00:00"
"generated": "2026-05-08T10:02:51+00:00"
}

View File

@@ -1,6 +1,6 @@
# datalog scoreboard
**204 / 204 passing** (0 failure(s)).
**205 / 205 passing** (0 failure(s)).
| Suite | Passed | Total | Status |
|-------|--------|-------|--------|
@@ -13,5 +13,5 @@
| negation | 10 | 10 | ok |
| aggregates | 18 | 18 | ok |
| api | 14 | 14 | ok |
| magic | 20 | 20 | ok |
| magic | 21 | 21 | ok |
| demo | 18 | 18 | ok |

View File

@@ -224,6 +224,29 @@
(= rules-before (len (dl-rules db))))))
true)
;; Magic-sets benefit: query touches only one cluster of a
;; multi-component graph. Semi-naive derives the full closure
;; over both clusters; magic only the seeded one.
(dl-mt-test! "magic skips irrelevant clusters"
(let
;; Two disjoint chains. Query is rooted in cluster 1.
((db (dl-program
"parent(a, b). parent(b, c).
parent(x, y). parent(y, z).
ancestor(X, Y) :- parent(X, Y).
ancestor(X, Z) :- parent(X, Y), ancestor(Y, Z).")))
(do
(dl-saturate! db)
(let
((semi-count (len (dl-relation db "ancestor")))
(magic-results
(dl-magic-query
db (list (quote ancestor) (quote a) (quote X)))))
;; Semi-naive derives 6 (3 in each cluster). Magic
;; gives 3 query results (a's reachable: b, c).
(and (= semi-count 6) (= (len magic-results) 2)))))
true)
(dl-mt-test! "magic-rewritten finds same answers"
(let
((rules