kb84tkhrのブログ

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

Reasoned Schemer (66) (run* q fail)とか(run* q (== q 'pea)とか

さて読み返してみるとは言ったもののどうやっていくか
せっかく実行できるようになったんだから式を実行してみるのはもちろんだけど
デバッガーで追いかけたりしてみるかな
DrRacketのデバッガー、いまひとつどう動いてるかよくわからなかったりする

とりあえず実行してみよう

> (run* q fail)
'()

ちょっとこれだけだと味気ない
追ってみよう

  (run* q fail)
= (run #f q fail)
= (let ((q (var 'q))) (map (reify q) (run-goal #f (conj fail))))
= (map (reify (var 'q)) (run-goal #f fail))
= (map (reify (var 'q)) (take-inf #f (fail empty-s)))
= (map (reify (var 'q)) (take-inf #f '()))
= (map (reify (var 'q)) '())
= '()

reifyって何するんだっけかと思っているうちに終わってしまった
ほかの例でやろう

> (run* q (== 'pea 'pod))
'()
> (run* q (== q 'pea)) 
'(pea)
> (run* q (== 'pea q))
'(pea)

こんどはreifyが活躍しそう

  (run* q (== q 'pea))
= (run #f q (== q 'pea))
= (let ((q (var 'q))) (map (reify q) (run-goal #f (conj (== q 'pea)))))

; ここから (define q (var q)) されているものと考える

= (map (reify q) (run-goal #f (== q 'pea)))
= (map (reify q) (take-inf #f ((== q 'pea) empty-s)))

==も追っかける

  ((== q 'pea) empty-s)
= ((lambda (s) (let ((s (unify q 'pea s))) (if s `(,s) '()))) empty-s)
= (let ((s (unify q 'pea empty-s))) (if s `(,s) '()))
= (let ((s `((,q . pea)))) (if s `(,s) '()))
= (if `((,q . pea)) `( ((,q . pea))) '())
= `(((,q . pea)))

元に戻って

= (map (reify q) (take-inf #f ((== q 'pea) empty-s)))
= (map (reify q) `(((,q . pea))))
= (cons ((reify q) `((,q . pea))) '())

reifyも追いかける

  ((reify q) `((,q . pea)))
= ((lambda (s) (let ((v (walk* q s))) (let ((r (reify-s v empty-s))) (walk* v r)))) `((,q . pea)))
= (let ((v (walk* q `((,q . pea))))) (let ((r (reify-s v empty-s))) (walk* v r)))
= (let ((v 'pea)) (let ((r (reify-s v empty-s))) (walk* v r)))
= (let ((r (reify-s 'pea empty-s))) (walk* 'pea r))
= (let ((r '())) (walk* 'pea r))
= (walk* 'pea '())
= 'pea

これで終わり

  (cons ((reify q) `((,q . pea))) '())
= (cons 'pea '())
= '(pea)

うーん
まだ理解が足りてないなあ

ひとつひとつの関数のお仕事をひとことで言えて
関数の呼び出し関係がイメージできるくらいになりたい
もう一回勉強しなおすか