datalog: magic-sets building blocks (199/199)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 22s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 22s
Adds the primitives a future magic-sets rewriter will compose: dl-magic-rel-name rel adornment → "magic_<rel>^<adornment>" dl-magic-lit rel adn bound-args → magic literal as SX list dl-bound-args lit adornment → bound-position arg values Rewriter algorithm (worklist over (rel, adornment) pairs, generating seed, propagation, and adorned-rule outputs) is still TODO — these helpers are inspection-only for now. 4 new magic tests cover naming, lit construction, and bound-args extraction (mixed/free).
This commit is contained in:
@@ -158,3 +158,45 @@
|
||||
(dl-vars-bound-by-lit lit bound)))))))
|
||||
(get rule :body))
|
||||
out))))
|
||||
|
||||
;; ── Magic predicate naming + bound-args extraction ─────────────
|
||||
;; These are building blocks for the magic-sets *transformation*
|
||||
;; itself. The transformation (which generates rewritten rules
|
||||
;; with magic_<rel>^<adornment> filters) is future work — for now
|
||||
;; these helpers can be used to inspect what such a transformation
|
||||
;; would produce.
|
||||
|
||||
;; "magic_p^bf" given relation "p" and adornment "bf".
|
||||
(define
|
||||
dl-magic-rel-name
|
||||
(fn (rel adornment) (str "magic_" rel "^" adornment)))
|
||||
|
||||
;; A magic predicate literal:
|
||||
;; (magic_<rel>^<adornment> arg1 arg2 ...)
|
||||
(define
|
||||
dl-magic-lit
|
||||
(fn
|
||||
(rel adornment bound-args)
|
||||
(cons (string->symbol (dl-magic-rel-name rel adornment)) bound-args)))
|
||||
|
||||
;; Extract bound args (those at "b" positions in `adornment`) from a
|
||||
;; literal `(rel arg1 arg2 ... argN)`. Returns the list of arg values.
|
||||
(define
|
||||
dl-bound-args
|
||||
(fn
|
||||
(lit adornment)
|
||||
(let ((args (rest lit)) (out (list)))
|
||||
(do
|
||||
(define
|
||||
dl-ba-loop
|
||||
(fn
|
||||
(i)
|
||||
(when
|
||||
(< i (len args))
|
||||
(do
|
||||
(when
|
||||
(= (slice adornment i (+ i 1)) "b")
|
||||
(append! out (nth args i)))
|
||||
(dl-ba-loop (+ i 1))))))
|
||||
(dl-ba-loop 0)
|
||||
out))))
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"lang": "datalog",
|
||||
"total_passed": 194,
|
||||
"total_passed": 199,
|
||||
"total_failed": 0,
|
||||
"total": 194,
|
||||
"total": 199,
|
||||
"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":10,"failed":0,"total":10},
|
||||
{"name":"magic","passed":15,"failed":0,"total":15},
|
||||
{"name":"demo","passed":18,"failed":0,"total":18}
|
||||
],
|
||||
"generated": "2026-05-08T09:50:50+00:00"
|
||||
"generated": "2026-05-08T09:53:23+00:00"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# datalog scoreboard
|
||||
|
||||
**194 / 194 passing** (0 failure(s)).
|
||||
**199 / 199 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 | 10 | 10 | ok |
|
||||
| magic | 15 | 15 | ok |
|
||||
| demo | 18 | 18 | ok |
|
||||
|
||||
@@ -124,7 +124,30 @@
|
||||
{:lit (list (quote p) (quote X)) :adornment "f"}
|
||||
{:lit (list (quote is) (quote Y)
|
||||
(list (string->symbol "+") (quote X) 1))
|
||||
:adornment "fb"})))))
|
||||
:adornment "fb"}))
|
||||
|
||||
;; Magic predicate naming.
|
||||
(dl-mt-test! "magic-rel-name"
|
||||
(dl-magic-rel-name "ancestor" "bf")
|
||||
"magic_ancestor^bf")
|
||||
|
||||
;; Bound-args extraction.
|
||||
(dl-mt-test! "bound-args bf"
|
||||
(dl-bound-args (list (quote ancestor) (quote tom) (quote X)) "bf")
|
||||
(list (quote tom)))
|
||||
|
||||
(dl-mt-test! "bound-args mixed"
|
||||
(dl-bound-args (list (quote p) 1 (quote Y) 3) "bfb")
|
||||
(list 1 3))
|
||||
|
||||
(dl-mt-test! "bound-args all-free"
|
||||
(dl-bound-args (list (quote p) (quote X) (quote Y)) "ff")
|
||||
(list))
|
||||
|
||||
;; Magic literal construction.
|
||||
(dl-mt-test! "magic-lit"
|
||||
(dl-magic-lit "ancestor" "bf" (list (quote tom)))
|
||||
(list (string->symbol "magic_ancestor^bf") (quote tom))))))
|
||||
|
||||
(define
|
||||
dl-magic-tests-run!
|
||||
|
||||
@@ -156,6 +156,8 @@ large graphs.
|
||||
is a constant or a variable already in the bound set.
|
||||
- [ ] Magic transformation: for each adorned predicate, generate a
|
||||
`magic_<pred>` relation and rewrite rule bodies to filter through it.
|
||||
*Building blocks present in `magic.sx`: `dl-magic-rel-name`,
|
||||
`dl-magic-lit`, `dl-bound-args`. Full rewriter still TODO.*
|
||||
- [x] Sideways information passing strategy (SIPS): left-to-right
|
||||
`dl-rule-sips rule head-adornment` walks body literals tracking
|
||||
the bound set, returning `({:lit :adornment} ...)`. Recognises
|
||||
@@ -289,6 +291,12 @@ large graphs.
|
||||
|
||||
_Newest first._
|
||||
|
||||
- 2026-05-08 — Phase 6 building blocks for the magic-sets
|
||||
transformation: `dl-magic-rel-name`, `dl-magic-lit`,
|
||||
`dl-bound-args`. The rewriter that generates magic seed and
|
||||
propagation rules is still future work; with these primitives
|
||||
in place it's a straightforward worklist algorithm. 4 new tests.
|
||||
|
||||
- 2026-05-08 — Phase 6 adornments + SIPS in
|
||||
`lib/datalog/magic.sx`. Inspection helpers — `dl-adorn-goal` and
|
||||
`dl-adorn-lit` compute per-arg `b`/`f` patterns under a bound
|
||||
|
||||
Reference in New Issue
Block a user