datalog: org-chart + transitive headcount demo (219/219)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 27s

Adds dl-demo-org-rules: (subordinate Mgr Emp) over a (manager
EMP MGR) graph, and (headcount Mgr N) using count aggregation
grouped by manager. Demonstrates real-world hierarchy queries
(e.g. "everyone reporting up to the CEO") + per-manager rollup.

3 new demo tests: transitive subordinates of CEO (5 entries),
CEO headcount, and direct manager headcount.
This commit is contained in:
2026-05-08 10:24:10 +00:00
parent de734b27b8
commit e0c7de1a1c
4 changed files with 62 additions and 7 deletions

View File

@@ -6,7 +6,7 @@
;; below show the shape of queries we want, and the test suite runs
;; them against synthetic in-memory tuples loaded via dl-program-data.
;;
;; Six thematic demos:
;; Seven thematic demos:
;;
;; 1. Federation — follow graph, transitive reach, mutuals, FOAF.
;; 2. Content — posts, tags, likes, popularity, "for you" feed.
@@ -15,6 +15,7 @@
;; follow (transitively)" multi-domain query.
;; 5. Tag co-occurrence — distinct (T1, T2) pairs with counts.
;; 6. Shortest path — weighted-DAG path enumeration + min agg.
;; 7. Org chart — transitive subordinate + headcount per mgr.
;; ── Demo 1: federation follow graph ─────────────────────────────
;; EDB: (follows ACTOR-A ACTOR-B) — A follows B.
@@ -132,6 +133,24 @@
(is W (+ W1 W2)))
(shortest X Y W <- (path X Y _) (min W C (path X Y C))))))
;; ── Demo 7: org chart + transitive headcount ───────────────────
;; Manager graph: each employee has a single manager. Compute the
;; transitive subordinate set and headcount per manager.
;;
;; EDB:
;; (manager EMP MGR) — EMP reports directly to MGR
;; IDB:
;; (subordinate MGR EMP) — EMP is in MGR's subtree
;; (headcount MGR N) — number of subordinates under MGR
(define
dl-demo-org-rules
(quote
((subordinate Mgr Emp <- (manager Emp Mgr))
(subordinate Mgr Emp
<- (manager Mid Mgr) (subordinate Mid Emp))
(headcount Mgr N
<- (subordinate Mgr Anyone) (count N E (subordinate Mgr E))))))
;; ── 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": 216,
"total_passed": 219,
"total_failed": 0,
"total": 216,
"total": 219,
"suites": [
{"name":"tokenize","passed":26,"failed":0,"total":26},
{"name":"parse","passed":18,"failed":0,"total":18},
@@ -14,7 +14,7 @@
{"name":"aggregates","passed":19,"failed":0,"total":19},
{"name":"api","passed":20,"failed":0,"total":20},
{"name":"magic","passed":22,"failed":0,"total":22},
{"name":"demo","passed":18,"failed":0,"total":18}
{"name":"demo","passed":21,"failed":0,"total":21}
],
"generated": "2026-05-08T10:21:54+00:00"
"generated": "2026-05-08T10:23:54+00:00"
}

View File

@@ -1,6 +1,6 @@
# datalog scoreboard
**216 / 216 passing** (0 failure(s)).
**219 / 219 passing** (0 failure(s)).
| Suite | Passed | Total | Status |
|-------|--------|-------|--------|
@@ -14,4 +14,4 @@
| aggregates | 19 | 19 | ok |
| api | 20 | 20 | ok |
| magic | 22 | 22 | ok |
| demo | 18 | 18 | ok |
| demo | 21 | 21 | ok |

View File

@@ -262,6 +262,42 @@
(quote (shortest a d W)))
(list))
;; ── Org chart + headcount ─────────────────────────────
(dl-demo-test-set! "ceo subordinate transitive"
(dl-query
(dl-demo-make
(quote
((manager ic1 mgr1) (manager ic2 mgr1)
(manager mgr1 vp1) (manager ic3 vp1)
(manager vp1 ceo)))
dl-demo-org-rules)
(quote (subordinate ceo X)))
(list
{:X (quote vp1)} {:X (quote mgr1)} {:X (quote ic1)}
{:X (quote ic2)} {:X (quote ic3)}))
(dl-demo-test-set! "ceo headcount = 5"
(dl-query
(dl-demo-make
(quote
((manager ic1 mgr1) (manager ic2 mgr1)
(manager mgr1 vp1) (manager ic3 vp1)
(manager vp1 ceo)))
dl-demo-org-rules)
(quote (headcount ceo N)))
(list {:N 5}))
(dl-demo-test-set! "mgr1 headcount = 2"
(dl-query
(dl-demo-make
(quote
((manager ic1 mgr1) (manager ic2 mgr1)
(manager mgr1 vp1) (manager ic3 vp1)
(manager vp1 ceo)))
dl-demo-org-rules)
(quote (headcount mgr1 N)))
(list {:N 2}))
(dl-demo-test-set! "no access without grant"
(dl-query
(dl-demo-make