Files
rose-ash/plans/prolog-on-sx.md
giles 0f67021aa3 plans: briefings + roadmaps for lua, prolog, forth, erlang, haskell
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>
2026-04-24 15:16:45 +00:00

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/** and plans/prolog-on-sx.md. Do not edit spec/, hosts/, shared/, lib/js/**, lib/hyperscript/**, lib/lua/**, lib/stdlib.sx, or anything in lib/ root. Prolog primitives go in lib/prolog/runtime.sx.
  • Shared-file issues go under "Blockers" below with a minimal repro; do not fix from this loop.
  • SX files: use sx-tree MCP 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 log updated 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 facts head.; terms atom | Var | number | compound(args) | [list,sugar]
  • Skip for phase 1: operator table. X is Y + 1 must be written is(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, ->/2 inside ;, call/1, write/1, nl/0
  • Arithmetic is/2 with + - * / mod abs
  • Classic programs in lib/prolog/tests/programs/:
    • append.pl — list append (with backtracking)
    • reverse.pl — naive reverse
    • member.pl — generate all solutions via backtracking
    • nqueens.pl — 8-queens
    • family.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/1
  • findall/3, bagof/3, setof/3
  • copy_term/2, functor/3, arg/3, =../2
  • String/atom predicates

Phase 5 — Hyperscript integration

  • prolog-query primitive 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)