問題4.60 – SICP(計算機プログラムの構造と解釈)その233

問題4.60

元の lives-near では重複する対が出てくるために結果の組み合わせ数が2倍になる。

(assert! (rule (lives-near ?person-1 ?person-2)
               (and (address ?person-1 (?town . ?rest-1))
                    (address ?person-2 (?town . ?rest-2))
                    (not (same ?person-1 ?person-2)))))

実行結果

;;; Query input:
(lives-near ?person-1 ?person-2)

;;; Query results:
(lives-near (Aull DeWitt) (Reasoner Louis))
(lives-near (Aull DeWitt) (Bitdiddle Ben))
(lives-near (Reasoner Louis) (Aull DeWitt))
(lives-near (Reasoner Louis) (Bitdiddle Ben))
(lives-near (Hacker Alyssa P) (Fect Cy D))
(lives-near (Fect Cy D) (Hacker Alyssa P))
(lives-near (Bitdiddle Ben) (Aull DeWitt))
(lives-near (Bitdiddle Ben) (Reasoner Louis))

この問題を解決するために、各人に id を割り当てて、2つの名前の間に優先順位を付ける。

(assert! (id (Warbucks Oliver) 0))
(assert! (id (Bitdiddle Ben) 1))
(assert! (id (Hacker Alyssa P) 2))
(assert! (id (Fect Cy D) 3))
(assert! (id (Tweakit Lem E) 4))
(assert! (id (Reasoner Louis) 5))
(assert! (id (Scrooge Eben) 6))
(assert! (id (Cratchet Robert) 7))
(assert! (id (Aull DeWitt) 7))

id の数値の大きさで優先順位を付ける。

(assert! (rule (lives-near ?person-1 ?person-2)
               (and (address ?person-1 (?town . ?rest-1))
                    (address ?person-2 (?town . ?rest-2))
                    (id ?person-1 ?id-1)
                    (id ?person-2 ?id-2)
                    (lisp-value > ?id-1 ?id-2)
                    (not (same ?person-1 ?person-2)))))

実行結果
元の lives-near に比べて重複がなくなり、半分の組み合わせ数になっている。

;;; Query input:
(lives-near ?person-1 ?person-2)

;;; Query results:
(lives-near (Aull DeWitt) (Reasoner Louis))
(lives-near (Aull DeWitt) (Bitdiddle Ben))
(lives-near (Reasoner Louis) (Bitdiddle Ben))
(lives-near (Fect Cy D) (Hacker Alyssa P))
計算機プログラムの構造と解釈
ジェラルド・ジェイ サスマン ジュリー サスマン ハロルド エイブルソン
ピアソンエデュケーション
売り上げランキング: 6542
«
»