datalog: parser + 18 tests + conformance harness (Phase 1 done, 44/44)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 45s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 45s
Tokens → list of {:head :body} / {:query} clauses. SX symbols for
constants and variables (case-distinguished). not(literal) in body
desugars to {:neg literal}. Nested compounds permitted in arg
position for arithmetic; safety analysis (Phase 3) will gate them.
Conformance harness wraps lib/guest/conformance.sh; produces
lib/datalog/scoreboard.{json,md}.
This commit is contained in:
@@ -58,16 +58,21 @@ Key differences from Prolog:
|
||||
## Roadmap
|
||||
|
||||
### Phase 1 — tokenizer + parser
|
||||
- [ ] Tokenizer: atoms (lowercase/quoted), variables (uppercase/`_`), numbers, strings,
|
||||
operators (`:- `, `?-`, `,`, `.`), comments (`%`, `/* */`)
|
||||
Note: no function symbol syntax (no nested `f(...)` in arg position).
|
||||
- [ ] Parser:
|
||||
- [x] Tokenizer: atoms (lowercase/quoted), variables (uppercase/`_`), numbers, strings,
|
||||
punct (`( )`, `,`, `.`), operators (`:-`, `?-`, `<=`, `>=`, `!=`, `<`, `>`, `=`,
|
||||
`+`, `-`, `*`, `/`), comments (`%`, `/* */`)
|
||||
Note: no function symbol syntax (no nested `f(...)` in arg position) — but the
|
||||
parser permits nested compounds for arithmetic; safety analysis (Phase 3) rejects
|
||||
non-arithmetic nesting.
|
||||
- [x] Parser:
|
||||
- Facts: `parent(tom, bob).` → `{:head (parent tom bob) :body ()}`
|
||||
- Rules: `ancestor(X,Z) :- parent(X,Y), ancestor(Y,Z).`
|
||||
→ `{:head (ancestor X Z) :body ((parent X Y) (ancestor Y Z))}`
|
||||
- Queries: `?- ancestor(tom, X).` → `{:query (ancestor tom X)}`
|
||||
- Queries: `?- ancestor(tom, X).` → `{:query ((ancestor tom X))}`
|
||||
(`:query` value is always a list of literals; `?- p, q.` → `{:query ((p) (q))}`)
|
||||
- Negation: `not(parent(X,Y))` in body position → `{:neg (parent X Y)}`
|
||||
- [ ] Tests in `lib/datalog/tests/parse.sx`
|
||||
- [x] Tests in `lib/datalog/tests/parse.sx` (18) and `lib/datalog/tests/tokenize.sx` (26).
|
||||
Conformance harness: `bash lib/datalog/conformance.sh` → 44 / 44 passing.
|
||||
|
||||
### Phase 2 — unification + substitution
|
||||
- [ ] Share or port unification from `lib/prolog/` — term walk, occurs check off by default
|
||||
@@ -142,4 +147,12 @@ _(none yet)_
|
||||
|
||||
_Newest first._
|
||||
|
||||
_(awaiting phase 1)_
|
||||
- 2026-05-07 — Phase 1 done. `lib/datalog/tokenizer.sx` (~190 LOC) emits
|
||||
`{:type :value :pos}` tokens; `lib/datalog/parser.sx` (~150 LOC) produces
|
||||
`{:head … :body …}` / `{:query …}` clauses, with nested compounds
|
||||
permitted for arithmetic and `not(...)` desugared to `{:neg …}`. 44 / 44
|
||||
via `bash lib/datalog/conformance.sh` (26 tokenize + 18 parse). Local
|
||||
helpers namespace-prefixed (`dl-emit!`, `dl-peek`) after a host-primitive
|
||||
shadow clash. Test harness uses a custom `dl-deep-equal?` that handles
|
||||
out-of-order dict keys and number repr (`equal?` fails on dict key order
|
||||
and on `30` vs `30.0`).
|
||||
|
||||
Reference in New Issue
Block a user