From d20df7aa8c95af5efa1f894c633f766aeea48083 Mon Sep 17 00:00:00 2001 From: giles Date: Fri, 8 May 2026 12:28:52 +0000 Subject: [PATCH] datalog: magic over rule with aggregate body literal (226/226) --- lib/datalog/scoreboard.json | 8 ++++---- lib/datalog/scoreboard.md | 4 ++-- lib/datalog/tests/magic.sx | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/lib/datalog/scoreboard.json b/lib/datalog/scoreboard.json index a566115b..c89da138 100644 --- a/lib/datalog/scoreboard.json +++ b/lib/datalog/scoreboard.json @@ -1,8 +1,8 @@ { "lang": "datalog", - "total_passed": 225, + "total_passed": 226, "total_failed": 0, - "total": 225, + "total": 226, "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":19,"failed":0,"total":19}, {"name":"api","passed":20,"failed":0,"total":20}, - {"name":"magic","passed":25,"failed":0,"total":25}, + {"name":"magic","passed":26,"failed":0,"total":26}, {"name":"demo","passed":21,"failed":0,"total":21} ], - "generated": "2026-05-08T10:40:13+00:00" + "generated": "2026-05-08T12:28:42+00:00" } diff --git a/lib/datalog/scoreboard.md b/lib/datalog/scoreboard.md index a6d1976d..b0593332 100644 --- a/lib/datalog/scoreboard.md +++ b/lib/datalog/scoreboard.md @@ -1,6 +1,6 @@ # datalog scoreboard -**225 / 225 passing** (0 failure(s)). +**226 / 226 passing** (0 failure(s)). | Suite | Passed | Total | Status | |-------|--------|-------|--------| @@ -13,5 +13,5 @@ | negation | 10 | 10 | ok | | aggregates | 19 | 19 | ok | | api | 20 | 20 | ok | -| magic | 25 | 25 | ok | +| magic | 26 | 26 | ok | | demo | 21 | 21 | ok | diff --git a/lib/datalog/tests/magic.sx b/lib/datalog/tests/magic.sx index 90855cd2..96b9f81e 100644 --- a/lib/datalog/tests/magic.sx +++ b/lib/datalog/tests/magic.sx @@ -197,6 +197,24 @@ 6) ;; dl-magic-query: end-to-end driver, doesn't mutate caller's db. + ;; Magic over a rule whose body contains an aggregate. + ;; The rewriter passes aggregate body lits through unchanged + ;; (no propagation generated for them), so semi-naive's count + ;; logic still fires correctly under the rewritten program. + (dl-mt-test! "magic over rule with aggregate body" + (let + ((db (dl-program + "post(p1). post(p2). post(p3). + liked(u1, p1). liked(u2, p1). liked(u3, p1). + liked(u1, p2). + rich(P) :- post(P), count(N, U, liked(U, P)), + >=(N, 2)."))) + (let + ((semi (dl-query db (list (quote rich) (quote P)))) + (magic (dl-magic-query db (list (quote rich) (quote P))))) + (= (len semi) (len magic)))) + true) + ;; Mixed EDB + IDB: a relation can be both EDB-seeded and ;; rule-derived. dl-magic-query must include the EDB portion ;; even though the relation has rules.