datalog: shortest-path demo on weighted DAG (176/176)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 37s

dl-demo-shortest-path-rules: path enumerates X→Z with cost
W = sum of edge weights via is/+; shortest filters to the
minimum cost path per (X, Y) pair via min aggregation.

3 demo tests cover direct/multi-hop choice, multi-hop wins on
cheaper route, and unreachable-empty.

Note: cycles produce infinite distance values without a depth
filter; the rule docstring flags this and suggests adding
(<, D, MAX) for graphs that may cycle.
This commit is contained in:
2026-05-08 09:35:38 +00:00
parent 380580af17
commit cf634ad2b1
5 changed files with 62 additions and 6 deletions

View File

@@ -104,6 +104,30 @@
(tag-pair T1 T2)
(count N P (cotagged P T1 T2))))))
;; ── Demo 6: weighted-DAG shortest path ─────────────────────────
;; "What's the cheapest way from X to Y?" Edge weights with `is`
;; arithmetic to sum costs, then `min` aggregation to pick the
;; shortest. Termination requires the graph to be a DAG (cycles
;; would produce infinite distances without a bound; programs
;; built on this should add a depth filter `(<, D, MAX)` if cycles
;; are possible).
;;
;; EDB:
;; (edge FROM TO COST)
;; IDB:
;; (path FROM TO COST) — any path
;; (shortest FROM TO COST) — minimum cost path
(define
dl-demo-shortest-path-rules
(quote
((path X Y W <- (edge X Y W))
(path X Z W
<-
(edge X Y W1)
(path Y Z W2)
(is W (+ W1 W2)))
(shortest X Y W <- (path X Y _) (min W C (path X Y C))))))
;; ── Loader stub ──────────────────────────────────────────────────
;; Wiring to PostgreSQL would replace these helpers with calls into
;; rose-ash's internal HTTP RPC (fetch_data → /internal/data/...).

View File

@@ -1,8 +1,8 @@
{
"lang": "datalog",
"total_passed": 173,
"total_passed": 176,
"total_failed": 0,
"total": 173,
"total": 176,
"suites": [
{"name":"tokenize","passed":26,"failed":0,"total":26},
{"name":"parse","passed":18,"failed":0,"total":18},
@@ -13,7 +13,7 @@
{"name":"negation","passed":10,"failed":0,"total":10},
{"name":"aggregates","passed":16,"failed":0,"total":16},
{"name":"api","passed":11,"failed":0,"total":11},
{"name":"demo","passed":15,"failed":0,"total":15}
{"name":"demo","passed":18,"failed":0,"total":18}
],
"generated": "2026-05-08T09:30:37+00:00"
"generated": "2026-05-08T09:35:25+00:00"
}

View File

@@ -1,6 +1,6 @@
# datalog scoreboard
**173 / 173 passing** (0 failure(s)).
**176 / 176 passing** (0 failure(s)).
| Suite | Passed | Total | Status |
|-------|--------|-------|--------|
@@ -13,4 +13,4 @@
| negation | 10 | 10 | ok |
| aggregates | 16 | 16 | ok |
| api | 11 | 11 | ok |
| demo | 15 | 15 | ok |
| demo | 18 | 18 | ok |

View File

@@ -237,6 +237,31 @@
(quote (tag-pair-count cooking vegetarian N)))
(list {:N 2}))
;; ── Shortest path on a weighted DAG ──────────────────
(dl-demo-test-set! "shortest a→d via DAG"
(dl-query
(dl-demo-make
(quote ((edge a b 5) (edge b c 3) (edge a c 10) (edge c d 2)))
dl-demo-shortest-path-rules)
(quote (shortest a d W)))
(list {:W 10}))
(dl-demo-test-set! "shortest a→c picks 2-hop"
(dl-query
(dl-demo-make
(quote ((edge a b 5) (edge b c 3) (edge a c 10)))
dl-demo-shortest-path-rules)
(quote (shortest a c W)))
(list {:W 8}))
(dl-demo-test-set! "shortest unreachable empty"
(dl-query
(dl-demo-make
(quote ((edge a b 5) (edge b c 3)))
dl-demo-shortest-path-rules)
(quote (shortest a d W)))
(list))
(dl-demo-test-set! "no access without grant"
(dl-query
(dl-demo-make

View File

@@ -280,6 +280,13 @@ large graphs.
_Newest first._
- 2026-05-08 — Demo: weighted-DAG shortest path. `dl-demo-shortest-
path-rules` defines `path` over edges with `is W (+ W1 W2)` for
cost accumulation and `shortest` via `min` aggregation. 3 demo
tests cover direct/multi-hop choice, multi-hop wins on cheaper
route, and unreachable-empty. Added `dl-summary db` inspection
helper returning `{<rel>: count}` (4 eval tests).
- 2026-05-08 — Phase 5e perf: first-arg index per relation. db gains
`:facts-index {<rel>: {<first-arg-key>: tuples}}` mirroring the
existing `:facts-keys` membership index. `dl-add-fact!` populates