kb84tkhrのブログ

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

Reasoned Schemer (75) fresh、run*

こういう式を短く書く話

(run* r (fresh (x) (fresh (y) (conj2 (== 'split x) (conj2 (== 'pea y) (== `(,x ,y) r))))))

(fresh (x) (fresh (y) g ...)(fresh (x y) g ...)と書ける

(run* r (fresh (x y) (conj2 (== 'split x) (conj2 (== 'pea y) (== `(,x ,y) r)))))

これはfreshマクロの力

このへんがやってくれる

    ((fresh (x0 x ...) g ...)
     (call/fresh 'x0
       (lambda (x0)
         (fresh (x ...) g ...))))

結果を作るために使っていたrを使わないように書くこともできる

(run* (x y) (conj2 (== 'split x) (== 'pea y)))

これはrunマクロがやってくれる

    ((run n (x0 x ...) g ...)
     (run n q (fresh (x0 x ...) (== `(,x0 ,x ...) q) g ...)))

run*freshconj2を含む

(run* r (fresh (x y) (== 'split x) (== 'pea y) (== `(,x ,y) r)))
(run* (x y) (== 'split x) (== 'pea y))

これは

    ((fresh () g ...) (conj g ...))

とか

    ((run n q g ...)
     (let ((q (var 'q)))
       (map (reify q) (run-goal n (conj g ...)))))))

とかが面倒を見ている
あとconjマクロ

(define-syntax conj
  (syntax-rules ()
    ((conj) succeed)
    ((conj g) g)
    ((conj g0 g ...) (conj2 g0 (conj g ...)))))