%%   知識情報処理実習 r1練習問題 解答例

(1)
parent(tom,bob).
parent(tom,liz).
parent(pam,bob).
parent(bob,pat).
parent(pat,jim).

male(tom).
male(bob).
male(jim).
female(pam).
female(liz).
female(pat).

% 以下はテスト用述語なので定義する必要はない
test1_1_1(X) :- parent(bob,X).  
test1_1_2(X) :- parent(X,bob).
test1_1_3(X,Y) :- parent(X,Y).
test1_1_4 :- male(bob).
test1_1_5 :- female(bob).


/* Prolog を立ち上げ、
  ?- parent(tom,X).  
と入力すると、
  X=bob
という解答が得られる。
ここで  を押すと単解のみが求まって終了。(注:は Enter-keyの意味)
別解を求めるには
  X=bob;
のように、セミコロン(;)を入力するとよい。
別解があればこれを繰り返すとすべての解が得られる。

プログラムの中に以下のようにテスト用の述語を定義しておくと
実行環境では
  ?- test1_1_1(X)
と入力するだけでよい。述語名や引数が複雑になった場合タイプミスを防ぐために有効。
*/      

% (2)
father(X,Y) :- parent(X,Y), male(X).

test1_2_1(X) :- father(bob,X).
test1_2_2(X) :- father(X,bob).

% (3)
ok :- father(tom,bob), father(tom,liz).

test1_3 :- ok.

% (4)
grandfather(X,Y) :- father(X,Z), parent(Z,Y).

test1_4_1 :- grandfather(bob,jim).
test1_4_2(X) :- grandfather(X,jim).

% (5)
ancestor(X,Y) :- parent(X,Y).
ancestor(X,Y) :- parent(X,Z), ancestor(Z,Y).

test1_5(X) :- ancestor(X,jim).

% (6)
論理的意味
 X が Y の親で,かつ,X が男性ならば,X は Y の父である.
動作
 :- father(X,Y).  を実行すると,まず,parent(X,Y) を実行する.
 このゴールと parent の定義の一番上にある parent(tom,bob) と
 単一化が成功し,X=tom, Y=bob を得る.
 続いて male(tom) を実行すると,male(tom) がデータベースに書かれているので
 この単一化も成功し(変数がないので代入することなく一致) male(tom) というゴールも成功する.
 したがってすべてのボディゴールが成功するので,father(X,Y) が成功し,
 X=tom, Y=bob を最初の解として得る.
 ( ; をタイプすると,バックトラックして別解を探しにいく.)