Five new guest-language plans mirroring the js-on-sx / hs-loop pattern, each with a phased roadmap (Progress log + Blockers), a self-contained agent briefing for respawning a long-lived loop, and a shared restore-all.sh that snapshots state across all seven language loops. Briefings bake in the lessons from today's stall debugging: never call sx_build (600s watchdog), only touch lib/<lang>/** + own plan file, commit every feature, update Progress log on each commit, route shared-file issues to Blockers rather than fixing them. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.8 KiB
4.8 KiB
Prolog-on-SX: mini-Prolog interpreter on delimited continuations
Horn clauses + unification + cut + arithmetic, implemented as an interpreter (clauses live as SX data, a SX-implemented solver walks them). Backtracking is powered by the delimited-continuations machinery in lib/callcc.sx + spec/evaluator.sx Step 5 — this is the reason Prolog fits SX well.
End-state goal: 200+ tests passing (classic programs + Hirst's ISO conformance subset + Hyperscript integration suite). Long-lived background agent driving the scoreboard up.
Ground rules
- Scope: only touch
lib/prolog/**andplans/prolog-on-sx.md. Do not editspec/,hosts/,shared/,lib/js/**,lib/hyperscript/**,lib/lua/**,lib/stdlib.sx, or anything inlib/root. Prolog primitives go inlib/prolog/runtime.sx. - Shared-file issues go under "Blockers" below with a minimal repro; do not fix from this loop.
- SX files: use
sx-treeMCP tools only. - Architecture: Prolog source → term AST → clause DB. Solver is SX code walking the DB; backtracking via delimited continuations, not a separate trail machine.
- Commits: one feature per commit. Keep
## Progress logupdated and tick boxes.
Architecture sketch
Prolog source text
│
▼
lib/prolog/tokenizer.sx — atoms, vars, numbers, punct, comments
│
▼
lib/prolog/parser.sx — term AST; phase 1: f(a,b) syntax only, no operator table
│
▼
lib/prolog/runtime.sx — clause DB, unify!, trail, solver (DFS + delimited-cont backtracking)
│ built-ins: =/2, \=/2, !/0, is/2, call/1, findall/3, …
▼
solutions / side-effects
Representation choices (finalise in phase 1, document here):
- Term: nested SX list. Compound
(functor arg1 arg2). Atom = symbol. Number = number. Variable ={:var "X" :binding <ref>}with mutable binding slot. - List: cons-cell compound
(. H T)or similar.[1,2,3]sugar desugared at parse. - Clause:
{:head <term> :body <term>}where body is the conjunction goal. - Clause DB: dict
"functor/arity" → list of clauses.
Roadmap
Phase 1 — tokenizer + term parser (no operator table)
- Tokenizer: atoms (lowercase/quoted), variables (uppercase/
_), numbers, strings, punct( ) , . [ ] | ! :-, comments (%,/* */) - Parser: clauses
head :- body.and factshead.; termsatom | Var | number | compound(args) | [list,sugar] - Skip for phase 1: operator table.
X is Y + 1must be writtenis(X, '+'(Y, 1));=written=(X, Y). Operators land in phase 4. - Unit tests in
lib/prolog/tests/parse.sx
Phase 2 — unification + trail
make-var,walk(follow binding chain),prolog-unify!(terms + trail → bool),trail-undo-to!- Occurs-check off by default, exposed as flag
- 30+ unification tests in
lib/prolog/tests/unify.sx: atoms, vars, compounds, lists, cyclic (no-occurs-check), mutual occurs
Phase 3 — clause DB + DFS solver + cut + first classic programs
- Clause DB:
"functor/arity" → list-of-clauses, loader inserts - Solver: DFS with choice points backed by delimited continuations (
lib/callcc.sx). On goal entry, capture; per matching clause, unify head + recurse body; on failure, undo trail, try next - Cut (
!): cut barrier at current choice-point frame; collapse all up to barrier - Built-ins:
=/2,\\=/2,true/0,fail/0,!/0,,/2,;/2,->/2inside;,call/1,write/1,nl/0 - Arithmetic
is/2with+ - * / mod abs - Classic programs in
lib/prolog/tests/programs/:append.pl— list append (with backtracking)reverse.pl— naive reversemember.pl— generate all solutions via backtrackingnqueens.pl— 8-queensfamily.pl— facts + rules (parent/ancestor)
lib/prolog/conformance.sh+ runner,scoreboard.json+scoreboard.md- Target: all 5 classic programs passing
Phase 4 — operator table + more built-ins (next run)
- Operator table parsing (prefix/infix/postfix, precedence, assoc)
assert/1,asserta/1,assertz/1,retract/1findall/3,bagof/3,setof/3copy_term/2,functor/3,arg/3,=../2- String/atom predicates
Phase 5 — Hyperscript integration
prolog-queryprimitive callable from SX/Hyperscript- Hyperscript DSL:
when allowed(user, :edit) then … - Integration suite
Phase 6 — ISO conformance
- Vendor Hirst's conformance tests
- Drive scoreboard to 200+
Phase 7 — compiler (later, optional)
- Compile clauses to SX continuations for speed
- Keep interpreter as the reference
Progress log
Newest first. Agent appends on every commit.
- (awaiting phase 1)
Blockers
Shared-file issues that need someone else to fix. Minimal repro only.
- (none yet)