問題4-57〜60

「規則」を作れば、質問を抽象化することができるそうです。
問題4-57。person-1とperson-2が同じ担当か、person-1がperson-2の仕事もできる(can-do-job)の場合を洗い出し、これだけだと、person-1とperson-2が同じ人になってしまう可能性があるため、not条件を加えてやります。

(rule (replace ?person-1 ?person-2)
      (and (or (and (job ?person-1 ?x)
                    (job ?person-2 ?x))
               (and (job ?person-1 ?job-1)
                    (job ?person-2 ?job-2)
                    (can-do-job ?job-1 ?job-2)))
           (not (same ?person-1 ?person-2))))

Cyの代わりに仕事ができる人を探す場合は、

(replace ?x (Fect Cy D))

というqueryを投げればよさそうです。また、代わりに仕事ができ、しかもその人よりも給料が低い人を探す場合は、

(and (replace ?x ?y)
     (salary ?x ?x-amount)
     (salary ?y ?y-amount)
     (lisp-value < ?x-amount ?y-amount))

と問いかけてやります。
問題4-58。queryに渡した人が黒幕かどうかをチェックする質問は、以下のように定義しました。

(rule (bigshot ?person)
      (and (job ?person (?department . ?person-type))
           (supervisor ?person ?boss)
           (not (job ?boss (?department . ?boss-type)))))

渡した人の担当部門と上司を抽出して、その上司が渡した人の担当部門に属していないという条件を付け加えてやります。
問題4-59。meeting情報を管理できるようにします。金曜日の会合を抽出するためには、

(meeting ?department (Fridy ?time))

と問いかければ良さそうです。Alyssaの要望を実装すると、

(rule (meeting-time ?person ?day-and-time)
      (or (meeting whole-company ?company-time)
          (and (job ?person (?department . ?type))
               (meeting ?department ?department-time))))

となり、ある人に関係のある会合(全社会合と自部門会合)をピックアップすることができます。使い方は、

(meeting-time (Hacker Alyssa P) (Wednesday ?time))

となります。
問題4-60。lives-nearを使う時に、誰かを指定してやれば上手くいきますが、Alyssaのように使ってしまうと、同じ組み合わせが二度登場してしまいます。person-1を一件ずつ調べていったら、そうなってしまうだろうなということは想像することができます。これを防ぐためには、結果の組み合わせが既に構成されていないかどうかを再帰的にチェックすればよさそうです。しかし、実装方法までは考えることができませんでした。いずれにしても、おそろしく非効率な処理になってしまうような気がします。