正直言ってここらへんの問題はつまらない...
delay演算を陽に使用しない場合とする場合での違いが一番わかるのは,質問が無限ループになるとき.
つまり,P.276のような場合に振る舞いがおかしくなる.
"無限ループ"なのでもともと正しいものではない
(assert! (married Minnie Mickery)) (assert! (rule (married ?x ?y) (married ?y ?x))) (married Mickery ?who)
simple-queryにdelayを使用する場合
;;; Query results: (married Mickery Minnie) (married Mickery Minnie) (married Mickery Minnie) (married Mickery Minnie) : :
一応結果が表示される.
simple-queryにdelayを使用しない場合
;;; Query input:
何も表示されない.
なぜかというと,delayを使用しない場合,
(define (simple-query query-pattern frame-stream) (stream-flatmap (lambda (frame) (stream-append (find-assertions query-pattern frame) (apply-rules query-pattern frame))) :<- frame-stream))
<-のところの評価が遅延されないために,そこから帰ってこられなくなるから.
apply-rulesでは, apply-a-ruleを呼び出し,apply-a-ruleでは,qevalを呼び出す.
そのqevalで同じquery, frameに対して,simple-queryを呼び出し, 同じループに陥る.
つまり,qeval->simple-query->apply-rules->apply-a-rule->qeval->simple-query->apply-rules->apply-a-rule->....となってしまう.
delayを陽に使わないと,driver-loopのdisplay-streamに帰れないため,何も表示されないまま,ループし続ける.