kb84tkhrのブログ

何を書こうか考え中です あ、あと組織とは関係ないってやつです 個人的なやつ

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))))
condedisjの連続に
freshcall/freshの連続に
freshの内部はconj2の連続になってる

このへんはあとでマクロを定義するらしい
マクロ作成前のイメージづくりみたいなもんかな

で、これは動かせる・・・?
nulloconsoがないと動かないか

見よう見まねで作っておく

(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っていう言葉が出てきたということは大詰めが近いってことだよな

近いっていうか、大事なところは終わってたんだな
もうちっとだけ続くんじゃ

でもまだ、動いちゃったというレベルでまだ全体像がイメージできる理解できてない