Reasoned Schemer (57) 10章 appendoふたたび
Let’s put the pieces together!
piecesをtogetherすると完成?
appendo
をこの章で定義した関数だけで書く
(define (appendo l t out)
(lambda (s)
(lambda ()
((disj2
(conj2 (nullo l) (== t out))
(call/fresh 'a
(lambda (a)
(call/fresh 'd
(lambda (d)
(call/fresh 'res
(lambda (res)
(conj2
(conso a d l)
(conj2
(conso a res out)
(appendo d t res))))))))))
s))))
もとはこれ
(defrel (appendo l t out)
(conde
((nullo l) (== t out))
((fresh (a d res)
(conso a d l)
(appendo d t res))
(conso a res out))))))
対応付けはわかる
defrel
が(define ... (lambda (s) (lambda () (<goal> s))))
に
conde
がdisj
の連続に
fresh
がcall/fresh
の連続に
fresh
の内部はconj2
の連続になってる
このへんはあとでマクロを定義するらしい
マクロ作成前のイメージづくりみたいなもんかな
で、これは動かせる・・・?
nullo
とconso
がないと動かないか
見よう見まねで作っておく
(define (nullo x)
(lambda (s)
(lambda ()
((== '() x) s))))
(define (conso a d p)
(lambda (s)
(lambda ()
((== `(,a . ,d) p) s))))
そして
> (let ((q (var 'q)))
(map (reify q)
(run-goal
#f
(call/fresh 'x
(lambda (x)
(call/fresh 'y
(lambda (y)
(conj2 (== `(,x ,y) q)
(appendo x y '(cake & ice d t))))))))))
((() (cake & ice d t))
((cake) (& ice d t))
((cake &) (ice d t))
((cake & ice) (d t))
((cake & ice d) (t))
((cake & ice d t) ()))
おー
これは(run* (x y) (appendo x y '(cake & ice d t)))
相当
run
っていう言葉が出てきたということは大詰めが近いってことだよな
近いっていうか、大事なところは終わってたんだな
もうちっとだけ続くんじゃ
でもまだ、動いちゃったというレベルでまだ全体像がイメージできる理解できてない