diff --git a/lib/datalog/demo.sx b/lib/datalog/demo.sx index f15dd645..657c64c1 100644 --- a/lib/datalog/demo.sx +++ b/lib/datalog/demo.sx @@ -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/...). diff --git a/lib/datalog/scoreboard.json b/lib/datalog/scoreboard.json index 82d72289..28545113 100644 --- a/lib/datalog/scoreboard.json +++ b/lib/datalog/scoreboard.json @@ -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" } diff --git a/lib/datalog/scoreboard.md b/lib/datalog/scoreboard.md index 9da23bc9..590c3c02 100644 --- a/lib/datalog/scoreboard.md +++ b/lib/datalog/scoreboard.md @@ -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 | diff --git a/lib/datalog/tests/demo.sx b/lib/datalog/tests/demo.sx index 1559f800..c893ade3 100644 --- a/lib/datalog/tests/demo.sx +++ b/lib/datalog/tests/demo.sx @@ -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