Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 57s
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.
57 lines
1.8 KiB
Plaintext
57 lines
1.8 KiB
Plaintext
;; lib/minikanren/run.sx — Phase 3: drive a goal + reify the query var.
|
|
;;
|
|
;; reify-name N — make the canonical "_.N" reified symbol.
|
|
;; reify-s term rs — walk term in rs, add a mapping from each fresh
|
|
;; unbound var to its _.N name (left-to-right order).
|
|
;; reify q s — walk* q in s, build reify-s, walk* again to
|
|
;; substitute reified names in.
|
|
;; run-n n q-name g... — defmacro: bind q-name to a fresh var, conj goals,
|
|
;; take ≤ n answers from the stream, reify each
|
|
;; through q-name. n = -1 takes all (used by run*).
|
|
;; run* — defmacro: (run* q g...) ≡ (run-n -1 q g...)
|
|
;; run — defmacro: (run n q g...) ≡ (run-n n q g...)
|
|
;; The two-segment form is the standard TRS API.
|
|
|
|
(define reify-name (fn (n) (make-symbol (str "_." n))))
|
|
|
|
(define
|
|
reify-s
|
|
(fn
|
|
(term rs)
|
|
(let
|
|
((w (mk-walk term rs)))
|
|
(cond
|
|
((is-var? w) (extend (var-name w) (reify-name (len rs)) rs))
|
|
((mk-list-pair? w) (reduce (fn (acc a) (reify-s a acc)) rs w))
|
|
(:else rs)))))
|
|
|
|
(define
|
|
reify
|
|
(fn
|
|
(term s)
|
|
(let
|
|
((w (mk-walk* term s)))
|
|
(let ((rs (reify-s w (empty-subst)))) (mk-walk* w rs)))))
|
|
|
|
(defmacro
|
|
run-n
|
|
(n q-name &rest goals)
|
|
(quasiquote
|
|
(let
|
|
(((unquote q-name) (make-var)))
|
|
(map
|
|
(fn (s) (reify (unquote q-name) s))
|
|
(stream-take
|
|
(unquote n)
|
|
((mk-conj (splice-unquote goals)) empty-s))))))
|
|
|
|
(defmacro
|
|
run*
|
|
(q-name &rest goals)
|
|
(quasiquote (run-n -1 (unquote q-name) (splice-unquote goals))))
|
|
|
|
(defmacro
|
|
run
|
|
(n q-name &rest goals)
|
|
(quasiquote (run-n (unquote n) (unquote q-name) (splice-unquote goals))))
|