SICP 問題4.63と4.69

 問題4.69を読んだときは、”はたしてこんなことができるんだろうか?”と思ったものでしたが、結局できました。

 ただ、かなり難しかったし、ハマりもありました。(プログラムでハマったのはずいぶん久しぶり)

 そのハマりの一つは先日組み込んだループ検出器。実はこれが無限ループしないものまでループと判定し、推論を止めてしまってました。
 なんとか修正を試みましたがうまくいかず、ループ検出器の組み込みが予想以上に難しいことを悟りました。

 ただ、出来上がったときは感動です。デバッグを繰り返しているうちに”(?relationship Adam Mehujael)”の答えが出たときはビックリしました。

 この質問システムは未だ「自分で組んでおきながら思わぬ振る舞いをする」プログラムです。このプログラムの振る舞いが「本当に」分かるようになったら、プログラマとして一段上にあがれるような気がします。

 また、これの途中でGAE版にもバグがあることが見つかりました。今は”(?relationship Adam Mehujael)”を処理できません。近々修正しようと思います。

 では、最後に問題4.69の答えを載せます。日本語サイトにはあまりないみたい。

 ここに書かれてあるのと大体同じ*1なのであってるでしょう。

;;; Ex.4.63
(rule (grandson ?g ?s)
      (and (son ?g ?f) 
	   (son ?f ?s)))

(rule (son ?f ?s) 
      (and (wife ?f ?w) 
	   (son ?w ?s)))


;;; Ex. 4.69
(rule (end-grandson? (grandson)))

(rule (end-grandson? (?x . ?y)) 
      (and (not (same ?y ())) 
           (end-grandson? ?y)))
      
(rule ((grandson) ?g ?ggs) 
      (grandson ?g ?ggs))

(rule ((great . ?rel) ?x ?y) 
      (and (son ?x ?s) 
           (?rel ?s ?y) 
           (end-grandson? ?rel)))

*1:append-to-formを使う手は思いつかなかった。やられた!