Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 53s
(fresh (x y z) g1 g2 ...) expands to a let that calls (make-var) for each named var, then mk-conjs the goals. call-fresh is the function-shaped alternative for programmatic goal building. 9 new tests: empty-vars, single var, multi-var multi-goal, fresh under disj, nested fresh, call-fresh equivalents. 91/91 cumulative.
24 lines
841 B
Plaintext
24 lines
841 B
Plaintext
;; lib/minikanren/fresh.sx — Phase 2 piece B: `fresh` for introducing
|
|
;; logic variables inside a goal body.
|
|
;;
|
|
;; (fresh (x y z) goal1 goal2 ...)
|
|
;; ≡ (let ((x (make-var)) (y (make-var)) (z (make-var)))
|
|
;; (mk-conj goal1 goal2 ...))
|
|
;;
|
|
;; A macro rather than a function so user-named vars are real lexical
|
|
;; bindings — which is also what miniKanren convention expects.
|
|
;; The empty-vars form (fresh () goal ...) is just a goal grouping.
|
|
|
|
(defmacro
|
|
fresh
|
|
(vars &rest goals)
|
|
(quasiquote
|
|
(let
|
|
(unquote (map (fn (v) (list v (list (quote make-var)))) vars))
|
|
(mk-conj (splice-unquote goals)))))
|
|
|
|
;; call-fresh — functional alternative for code that builds goals
|
|
;; programmatically:
|
|
;; ((call-fresh (fn (x) (== x 7))) empty-s) → ({:_.N 7})
|
|
(define call-fresh (fn (f) (fn (s) ((f (make-var)) s))))
|