Reasoned Schemer (96) *o 続き
本物のbound-*o
(*o n m p)
でn
>p
だったりm
>p
だったりしたら失敗するようにする
んだけどそのかわりにn
やm
をリストとみてn
やm
がp
より長かったら失敗するようにするらしい
(defrel (bound-*o q p n m)
(conde
((=='() q) (poso p))
((fresh (a0 a1 a2 a3 x y z)
(== `(,a0 . ,x) q)
(== `(,a1 . ,y) p)
(conde
((== '() n)
(== `(,a2 . ,z) m)
(bound-*o x y z '()))
((== `(,a3 . ,z) n)
(bound-*o x y z m)))))))
訂正
bound-*o
自体はp
が0でない限り失敗しない
q
がfreshだから((=='() q) (poso p))
はp
が0じゃない限りbound-*o
は成功する
失敗するのはbound-*o
とその続きのgoalとの連係プレーだな
しかしq
ってなんなんだいまひとつイメージがつかめん
適当に動かしてみるか
n
、m
が1より大きい奇数のときに通るんだからたとえばこう
> (run* q (bound-*o q '(1 0 0 1) '(1 1) '(1 1)))
'(() (_0) (_0 _1) (_0 _1 _2))
bound-*o
が呼ばれるたびにq
が()
になってそこにa0
がくっついていくから
ひとつずつ長くなっていくリストができるのか
q
を中心としてみると
q
はp
かn
+m
の短いほうよりも短いリストすべて、を表現してるってわけか
その範囲で(*o x m q)
になるようにx
やm
を探してみるけど
なかったらodd-*o
が失敗すると
了解です
了解なんだけどこんなことまで気にしながらプログラミングするのって大変じゃないですか
うっかり考え忘れると突然無限ループして帰ってこないとかこわい