Reasoned Schemer (69) 勘違い修正
いろいろ考え直さないとか?
↓みたいなのやっていくときはq
をq
のままにしないで書き替えてったほうがいいのかなー
(run* q (== q 'pea))
= (run #f q (== q 'pea))
= (let ((q (var 'q))) (map (reify q) (run-goal #f (conj (== q 'pea)))))
= ...
こんな風に
(run* q (== q 'pea))
= (run #f q (== q 'pea))
= (let ((q (var 'q))) (map (reify q) (run-goal #f (conj (== q 'pea)))))
= (let ((q '#(q))) (map (reify q) (run-goal #f (conj (== q 'pea)))))
= (map (reify '#(q)) (run-goal #f (conj (== '#(q) 'pea))))
でもこれだと実行してみたとき最後の式で評価の結果が合わなくなってしまうんだよな
> (run* q (== q 'pea))
'(pea)
> (let ((q '#(q))) (map (reify q) (run-goal #f (conj (== q 'pea)))))
'(pea)
> (map (reify '#(q)) (run-goal #f (conj (== '#(q) 'pea))))
'(_0)
reify
の'#(q)
とconj
の'#(q)
が別物なのが原因
(eqv? '#(q) '#(q))
は#f
なのでwalk
のassv
が(#(q) . pea)
を見つけてくれなくなる
脳内でやる分には問題ないんだけど
うまい書き方はないかなあ
assv
をassoc
にするとどうかな
> (map (reify '#(q)) (run-goal #f (conj (== '#(q) 'pea))))
'(pea)
うまくいった
でも変なところで影響が出そうでこわい
occurs?
やunify
のeqv?
もequal?
にしないとおかしいかな
いやここはequal?
ではおかしい
なにかあったら思い出すことにしてこのままで進んでみる
(思い出せるかどうかは知らない)
> (run* q (fresh (x) (== `(,x) q)))
'((_0))
今や当然
でもこの(run* q ...)
っていうのがq
を変数に思わせる罠という気がしないでもない
マクロ使ってるときにかかりやすい罠?
いやわかってないだけかな