datalog: dl-eval source + query convenience (181/181)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 23s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 23s
Single-call entry: dl-eval source-string query-string parses both, builds a db via dl-program, saturates implicitly, runs the query (extracted from the parsed `?- ...` clause), and returns the substitution list. Most user-friendly path: (dl-eval "parent(a, b). ..." "?- ancestor(a, X).") 2 new api tests cover ancestor and multi-goal usage.
This commit is contained in:
@@ -149,6 +149,26 @@
|
|||||||
(dl-saturate! db)
|
(dl-saturate! db)
|
||||||
db))))
|
db))))
|
||||||
|
|
||||||
|
;; ── Convenience: single-call source + query ───────────────────
|
||||||
|
;; (dl-eval source query-source) parses both, builds a db, saturates,
|
||||||
|
;; runs the query, returns the substitution list. The query source
|
||||||
|
;; should be `?- goal[, goal ...].` — the parser produces a clause
|
||||||
|
;; with :query containing a list of literals which is fed straight
|
||||||
|
;; to dl-query.
|
||||||
|
(define
|
||||||
|
dl-eval
|
||||||
|
(fn
|
||||||
|
(source query-source)
|
||||||
|
(let
|
||||||
|
((db (dl-program source))
|
||||||
|
(queries (dl-parse query-source)))
|
||||||
|
(cond
|
||||||
|
((= (len queries) 0) (error "dl-eval: query string is empty"))
|
||||||
|
((not (has-key? (first queries) :query))
|
||||||
|
(error "dl-eval: second arg must be a `?- ...` query clause"))
|
||||||
|
(else
|
||||||
|
(dl-query db (get (first queries) :query)))))))
|
||||||
|
|
||||||
(define
|
(define
|
||||||
dl-rule-head-rels
|
dl-rule-head-rels
|
||||||
(fn
|
(fn
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"lang": "datalog",
|
"lang": "datalog",
|
||||||
"total_passed": 179,
|
"total_passed": 181,
|
||||||
"total_failed": 0,
|
"total_failed": 0,
|
||||||
"total": 179,
|
"total": 181,
|
||||||
"suites": [
|
"suites": [
|
||||||
{"name":"tokenize","passed":26,"failed":0,"total":26},
|
{"name":"tokenize","passed":26,"failed":0,"total":26},
|
||||||
{"name":"parse","passed":18,"failed":0,"total":18},
|
{"name":"parse","passed":18,"failed":0,"total":18},
|
||||||
@@ -12,8 +12,8 @@
|
|||||||
{"name":"semi_naive","passed":8,"failed":0,"total":8},
|
{"name":"semi_naive","passed":8,"failed":0,"total":8},
|
||||||
{"name":"negation","passed":10,"failed":0,"total":10},
|
{"name":"negation","passed":10,"failed":0,"total":10},
|
||||||
{"name":"aggregates","passed":16,"failed":0,"total":16},
|
{"name":"aggregates","passed":16,"failed":0,"total":16},
|
||||||
{"name":"api","passed":11,"failed":0,"total":11},
|
{"name":"api","passed":13,"failed":0,"total":13},
|
||||||
{"name":"demo","passed":18,"failed":0,"total":18}
|
{"name":"demo","passed":18,"failed":0,"total":18}
|
||||||
],
|
],
|
||||||
"generated": "2026-05-08T09:38:47+00:00"
|
"generated": "2026-05-08T09:40:51+00:00"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# datalog scoreboard
|
# datalog scoreboard
|
||||||
|
|
||||||
**179 / 179 passing** (0 failure(s)).
|
**181 / 181 passing** (0 failure(s)).
|
||||||
|
|
||||||
| Suite | Passed | Total | Status |
|
| Suite | Passed | Total | Status |
|
||||||
|-------|--------|-------|--------|
|
|-------|--------|-------|--------|
|
||||||
@@ -12,5 +12,5 @@
|
|||||||
| semi_naive | 8 | 8 | ok |
|
| semi_naive | 8 | 8 | ok |
|
||||||
| negation | 10 | 10 | ok |
|
| negation | 10 | 10 | ok |
|
||||||
| aggregates | 16 | 16 | ok |
|
| aggregates | 16 | 16 | ok |
|
||||||
| api | 11 | 11 | ok |
|
| api | 13 | 13 | ok |
|
||||||
| demo | 18 | 18 | ok |
|
| demo | 18 | 18 | ok |
|
||||||
|
|||||||
@@ -198,6 +198,21 @@
|
|||||||
(list (quote (n X)) (list (string->symbol ">") (quote X) 2)))
|
(list (quote (n X)) (list (string->symbol ">") (quote X) 2)))
|
||||||
(list {:X 3} {:X 4} {:X 5}))
|
(list {:X 3} {:X 4} {:X 5}))
|
||||||
|
|
||||||
|
;; dl-eval: single-call source + query.
|
||||||
|
(dl-api-test-set! "dl-eval ancestor"
|
||||||
|
(dl-eval
|
||||||
|
"parent(a, b). parent(b, c).
|
||||||
|
ancestor(X, Y) :- parent(X, Y).
|
||||||
|
ancestor(X, Z) :- parent(X, Y), ancestor(Y, Z)."
|
||||||
|
"?- ancestor(a, X).")
|
||||||
|
(list {:X (quote b)} {:X (quote c)}))
|
||||||
|
|
||||||
|
(dl-api-test-set! "dl-eval multi-goal"
|
||||||
|
(dl-eval
|
||||||
|
"p(1). p(2). p(3). q(2). q(3)."
|
||||||
|
"?- p(X), q(X).")
|
||||||
|
(list {:X 2} {:X 3}))
|
||||||
|
|
||||||
;; dl-rule-from-list with no arrow → fact-style.
|
;; dl-rule-from-list with no arrow → fact-style.
|
||||||
(dl-api-test-set! "no arrow → fact-like rule"
|
(dl-api-test-set! "no arrow → fact-like rule"
|
||||||
(let
|
(let
|
||||||
|
|||||||
@@ -284,6 +284,11 @@ large graphs.
|
|||||||
|
|
||||||
_Newest first._
|
_Newest first._
|
||||||
|
|
||||||
|
- 2026-05-08 — Convenience: `dl-eval source query-source`. Parses
|
||||||
|
both strings, builds a db, saturates, runs the query, returns
|
||||||
|
the substitution list. Single-call user-friendly entry. 2 new
|
||||||
|
api tests cover ancestor and multi-goal queries.
|
||||||
|
|
||||||
- 2026-05-08 — Phase 6 stub: `dl-set-strategy! db strategy` and
|
- 2026-05-08 — Phase 6 stub: `dl-set-strategy! db strategy` and
|
||||||
`dl-get-strategy db` user-facing hooks. Default `:semi-naive`;
|
`dl-get-strategy db` user-facing hooks. Default `:semi-naive`;
|
||||||
`:magic` is accepted but the actual transformation is deferred,
|
`:magic` is accepted but the actual transformation is deferred,
|
||||||
|
|||||||
Reference in New Issue
Block a user