2016/01/21

SICP 問題 4.71

;; 本文中のsimple-query
(define (simple-query query-pattern frame-stream)
  (stream-flatmap
   (lambda (frame)
     (stream-append-delayed
      (find-assertions query-pattern frame)
      (delay (apply-rules query-pattern frame))))
   frame-stream))

;; 本文中のdisjoin
(define (disjoin disjuncts frame-stream)
  (if (empty-disjunction? disjuncts)
      the-empty-stream
      (interleave-delayed
       (qeval (first-disjunct disjuncts) frame-stream)
       (delay (disjoin (rest-disjuncts disjuncts)
                       frame-stream)))))

;; Louis Reasonerが提案したsimple-query
(define (simple-query query-pattern frame-stream)
  (stream-flatmap
   (lambda (frame)
     (stream-append-delayed
      (find-assertions query-pattern frame)
      (apply-rules query-pattern frame)))
   frame-stream))

;; Louis Reasonerが提案したdisjoin
(define (disjoin disjuncts frame-stream)
  (if (empty-disjunction? disjuncts)
      the-empty-stream
      (interleave-delayed
       (qeval (first-disjunct disjuncts) frame-stream)
       (disjoin (rest-disjuncts disjuncts)
                frame-stream))))

;; Louis Readonerの提案したものだとinterleaveの二つ目のストリームが遅延されていないので
;; 評価が終わるまで印字されない.
;; 仮にruleのほうで無限ループに陥った時に,delayする場合は一つ一つの評価結果を印字しながらループし
;; delayがない場合は何も印字せずに無限ループする.
;; 本文でも出てきたmarriedを使って試してみる.

(assert! (married Minnie Mickey))

(assert! (rule (married ?x ?y)
               (married ?y ?x)))
;; delayありの場合
;;; Query input:
(assert! (married Minnie Mickey))

Assertion added to data base.

;;; Query input:
(assert! (rule (married ?x ?y)
               (married ?y ?x)))

Assertion added to data base.

;;; Query input:
(married Mickey ?x)

;;; Query result:
(married Mickey Minnie)
(married Mickey Minnie)
(married Mickey Minnie)
(married Mickey Minnie)
(married Mickey Minnie)
(married Mickey Minnie)
(married Mickey Minnie)
(married Mickey Minnie)
(married Mickey Minnie)
(married Mickey Minnie)
(married Mickey Minnie)
...
;; delayなしの場合
;;; Query input:
(assert! (married Minnie Mickey))

Assertion added to data base.

;;; Query input:
(assert! (rule (married ?x ?y)
               (married ?y ?x)))

Assertion added to data base.

;;; Query input:
(married Mickey ?x)


;;; Query result: の表示も出てこない


© 2022 wat-aro