さかもとのブログ

つらつらと

SICP演習問題4.64, 4.65, 4.66, 4.68

4.67, 4.69はパスします。

exercise 4.64
;; exercise 4.64
(assert! (rule (outranked-by2 ?staff-person ?boss)
               (or (supervisor ?staff-person ?boss)
                   (and (outranked-by2 ?middle-manager ?boss)
                        (supervisor ?staff-person ?middle-manager)))))

(outranked-by2 (Bitdiddle Ben) ?who)

;; 無限ループ
;; (outranked-by ?middle-manager ?boss)
;; がどちらも未束縛のまま再びoutranked-by規則を呼び出している
;; 停止条件である, (supervisor ?staff-person ?boss)にいつまでも一致しない
exercise 4.65
;; exercise 4.65, exercise 4.66
(assert! (rule (wheel ?person)
               (and (supervisor ?middle-manager ?person)
                    (supervisor ?x ?middle-manager))))

(wheel ?who)
;;; Query results:
(wheel (Warbucks Oliver))
(wheel (Warbucks Oliver))
(wheel (Bitdiddle Ben))
(wheel (Warbucks Oliver))
(wheel (Warbucks Oliver))

;; 当てはまるデータが4つあるから
;; データベースに当てはまるものがあればとりあえず表示されてしまう
;; 同じ内容かどうかを確認しないため

;; exercise 4.66
;; 同じ内容かどうかを確認しないため,複数回足されてしまう可能性がある
exercise4.68
;; exercise 4.68
(define (my-reverse lis)
  (if (null? lis)
      '()
      (append (my-reverse (cdr lis)) (list (car lis)))))

;; rule1: 任意のリストについて, (cons x ())なら, リストxを返す
;; rule2: 任意のx, y, zについて, yのreverseがwであり, かつ,
;;        wと(x)をappendして, zになるなら,zは(cons x y)のreverseである
;; 手続きと対応させると,
;; x -> (car lis)
;; y -> (cdr lis)
;; w -> (my-reverse (cdr lis))
;; z -> (append (my-reverse (cdr lis)) (car lis))

(load "./evaluator-with-query.scm")
(query-driver-loop)

(assert! (rule (append-to-form () ?y ?y)))
(assert! (rule (append-to-form (?u . ?v) ?y (?u . ?z))
               (append-to-form ?v ?y ?z)))

(append-to-form (1 2 3) (1 2 3) ?x)
(append-to-form ?x (1 2) (3 1 2))

(assert! (rule (reverse (?x) (?x))))
(assert! (rule (reverse (?x . ?y) ?z)
               (and (reverse ?y ?w)
                    (append-to-form ?w (?x) ?z))))
; andの中を逆にすると, append-to-formから帰ってこられなくなる
; (append-to-form ?x (1 2) ?y)のようにxとyが未定義の場合
; (append-to-form (?u . ?v) ?y (?u . ?z))が探索不可能

;;; Query input:
(reverse (1) ?x)
;;; Query results:
(reverse (1) (1))

;;; Query input:
(reverse (1 2 3) ?x)
;;; Query results:
(reverse (1 2 3) (3 2 1))

;; Query input:
(reverse ?x (1 2 3))
;; 無限ループ
;; (reverse (?x . ?y) ?z)の部分で, xが分割できない