Reasoned Schemer (62) fresh, conde
fresh
(define-syntax fresh
(syntax-rules ()
((fresh () g ...) (conj g ...))
((fresh (x0 x ...) g ...)
(call/fresh 'x0
(lambda (x0)
(fresh (x ...) g ...))))))
やってみる
(fresh (x y) (== 'split x) (== 'pea y))
= (call/fresh 'x (lambda (x) (fresh (y) (== 'split x) (== 'pea y))))
= (call/fresh 'x (lambda (x) (call/fresh 'y (lambda (y) (fresh () (== 'split x) (== 'pea y))))))
= (call/fresh 'x (lambda (x) (call/fresh 'y (lambda (y) (conj (== 'split x) (== 'pea y))))))
これはとくに問題ないだろう
マクロに'x0
って書いてあるときもx0
が置き換えられるんだな
conde
(define-syntax conde
(syntax-rules ()
((conde (g ...) ...)
(disj (conj g ...) ...))))
節をひとつずつ再帰・・・じゃないなこれは
んーとどうなるんだ
(g ...) ...
っていうのは(g ...)
のあとに何かが続いてる、
じゃなくて(g ...)
が繰り返し出てくるよ、ってことか
(conj g ...) ...
も(conj g ...)
を繰り返すってことね
むしろ簡単だった
(conde ((== 'split x) (== 'pea y)) ((== 'red x) (== 'bean y)))
= (disj (conj (== 'split x) (== 'pea y)) (conj (== 'red x) (== 'bean y)))