datalog: magic-vs-semi work-shape test on chain-12 (209/209)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 24s

Demonstrates the practical effect of goal-directed evaluation:
chain of 12 nodes, semi-naive derives the full ancestor closure
(78 = 12·13/2 tuples), while a magic-rooted query at node 0
returns only its 12 descendants. Concrete check that magic
limits derivation to the query's transitive cone.
This commit is contained in:
2026-05-08 10:13:13 +00:00
parent 4a643a5c52
commit 43fa31375d
3 changed files with 35 additions and 6 deletions

View File

@@ -1,8 +1,8 @@
{
"lang": "datalog",
"total_passed": 208,
"total_passed": 209,
"total_failed": 0,
"total": 208,
"total": 209,
"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":17,"failed":0,"total":17},
{"name":"magic","passed":21,"failed":0,"total":21},
{"name":"magic","passed":22,"failed":0,"total":22},
{"name":"demo","passed":18,"failed":0,"total":18}
],
"generated": "2026-05-08T10:06:36+00:00"
"generated": "2026-05-08T10:13:00+00:00"
}

View File

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

View File

@@ -227,6 +227,35 @@
;; 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.
;; Magic-vs-semi work shape: chain of 12. Semi-naive
;; derives the full closure (78 = 12·13/2). A magic query
;; rooted at node 0 returns the 12 descendants only —
;; demonstrating that magic limits derivation to the
;; query's transitive cone.
(dl-mt-test! "magic vs semi work-shape on chain-12"
(let
((source (str
"parent(0, 1). parent(1, 2). parent(2, 3). "
"parent(3, 4). parent(4, 5). parent(5, 6). "
"parent(6, 7). parent(7, 8). parent(8, 9). "
"parent(9, 10). parent(10, 11). parent(11, 12). "
"ancestor(X, Y) :- parent(X, Y). "
"ancestor(X, Z) :- parent(X, Y), ancestor(Y, Z).")))
(let
((db1 (dl-make-db)) (db2 (dl-make-db)))
(do
(dl-load-program! db1 source)
(dl-saturate! db1)
(dl-load-program! db2 source)
(let
((semi-count (len (dl-relation db1 "ancestor")))
(magic-count
(len (dl-magic-query
db2 (list (quote ancestor) 0 (quote X))))))
;; Magic returns only descendants of 0 (12 of them).
(and (= semi-count 78) (= magic-count 12))))))
true)
(dl-mt-test! "magic skips irrelevant clusters"
(let
;; Two disjoint chains. Query is rooted in cluster 1.