Files
rose-ash/lib/minikanren/tests/run.sx
giles 57a84b372d
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 57s
Merge loops/minikanren into architecture: full miniKanren-on-SX library
Squash merge of 76 commits from loops/minikanren. Adds lib/minikanren/
— a complete miniKanren-on-SX implementation built on top of
lib/guest/match.sx, validating the lib-guest unify-and-match kit as
intended.

Modules (20 .sx files, ~1700 LOC):
  unify, stream, goals, fresh, conde, condu, conda, run, relations,
  peano, intarith, project, nafc, matche, fd, queens, defrel, clpfd,
  tabling

Phases 1–5 fully done (core miniKanren API, all classic relations,
matche, conda, project, nafc).

Phase 6 — native CLP(FD): domain primitives, fd-in / fd-eq / fd-neq /
fd-lt / fd-lte / fd-plus / fd-times / fd-distinct / fd-label, with
constraint reactivation iterating to fixed point. N-queens via FD:
4-queens 2 solutions, 5-queens 10 solutions (vs naive timeout past N=4).

Phase 7 — naive ground-arg tabling: table-1 / table-2 / table-3.
Fibonacci canary: tab-fib(25) = 75025 in seconds, naive fib(25) times
out at 60s. Ackermann via table-3: A(3,3) = 61.

71 test files, 644+ tests passing across the suite. Producer/consumer
SLG (cyclic patho, mutual recursion) deferred — research-grade work.

The lib-guest validation experiment is conclusive: lib/minikanren/
unify.sx adds ~50 lines of local logic (custom cfg, deep walk*, fresh
counter) over lib/guest/match.sx's ~100-line kit. The kit earns its
keep ~3× by line count.
2026-05-08 23:01:54 +00:00

115 lines
2.3 KiB
Plaintext

;; lib/minikanren/tests/run.sx — Phase 3 tests for run* / run / reify.
;; --- canonical TRS one-liners ---
(mk-test "run*-eq-one" (run* q (== q 1)) (list 1))
(mk-test "run*-eq-string" (run* q (== q "hello")) (list "hello"))
(mk-test "run*-eq-symbol" (run* q (== q (quote sym))) (list (quote sym)))
(mk-test "run*-fail-empty" (run* q (== 1 2)) (list))
;; --- run with a count ---
(mk-test
"run-3-of-many"
(run
3
q
(conde
((== q 1))
((== q 2))
((== q 3))
((== q 4))
((== q 5))))
(list 1 2 3))
(mk-test "run-zero-empty" (run 0 q (== q 1)) (list))
(mk-test
"run-1-takes-one"
(run 1 q (conde ((== q "a")) ((== q "b"))))
(list "a"))
;; --- reification: unbound vars get _.N left-to-right ---
(mk-test
"reify-single-unbound"
(run* q (fresh (x) (== q x)))
(list (make-symbol "_.0")))
(mk-test
"reify-pair-unbound"
(run* q (fresh (x y) (== q (list x y))))
(list (list (make-symbol "_.0") (make-symbol "_.1"))))
(mk-test
"reify-mixed-bound-unbound"
(run* q (fresh (x y) (== q (list 1 x 2 y))))
(list
(list 1 (make-symbol "_.0") 2 (make-symbol "_.1"))))
(mk-test
"reify-shared-unbound-same-name"
(run* q (fresh (x) (== q (list x x))))
(list (list (make-symbol "_.0") (make-symbol "_.0"))))
(mk-test
"reify-distinct-unbound-distinct-names"
(run* q (fresh (x y) (== q (list x y x y))))
(list
(list
(make-symbol "_.0")
(make-symbol "_.1")
(make-symbol "_.0")
(make-symbol "_.1"))))
;; --- conde + run* ---
(mk-test
"run*-conde-three"
(run*
q
(conde ((== q 1)) ((== q 2)) ((== q 3))))
(list 1 2 3))
(mk-test
"run*-conde-fresh-mix"
(run*
q
(conde ((fresh (x) (== q (list 1 x)))) ((== q "ground"))))
(list (list 1 (make-symbol "_.0")) "ground"))
;; --- run* + conjunction ---
(mk-test
"run*-conj-binds-q"
(run* q (fresh (x) (== x 5) (== q (list x x))))
(list (list 5 5)))
;; --- run* + condu ---
(mk-test
"run*-condu-first-wins"
(run* q (condu ((== q 1)) ((== q 2))))
(list 1))
(mk-test
"run*-onceo-trim"
(run* q (onceo (conde ((== q "a")) ((== q "b")))))
(list "a"))
;; --- multi-goal run ---
(mk-test
"run*-three-goals"
(run*
q
(fresh
(x y z)
(== x 1)
(== y 2)
(== z 3)
(== q (list x y z))))
(list (list 1 2 3)))
(mk-tests-run!)