parent(fune,wakame).
parent(masuo,tara).
parent(umi,namihei).
male(namihei). .....list 1
female(fune).
female(sazae).
male(katuo).
female(wakame).
male(masuo).
male(tara).
female(umi).
最初にparent関係について定義したときはparent(namihei,sazae).のように引数が2つありました。今度のmale/female関係は1つです。これらは定義の仕方次第で、2つでも3つでも構いません。その時々で一番判りやすいように定義すればいいでしょう。male/female関係も次のように引数2つで定義することができます。
sex(namihei,male). .....list 2
sex(fune,female).
sex(sazae,female).
........
ここでは、male/female関係(list 1)で実習を進めましょう。上のmale/female関係の定義をプログラムに追加してください。
child(sazae,namihei).
というように、定義していけばいいです。でも、これはちょっと面倒です。プログラムの中にparent関係は全部でいくつありますか。それと同じだけ、全く逆のchild関係を記述しなければなりません。parent関係の定義が既にあるのですから、これを利用してもっと楽にchild関係を定義しようではありませんか。
難しい言い方になりますが、child関係は
child(Y,X):-parent(X,Y).
これは、また、
parent(sazae,tara).
という定義があった場合、
?- parent(sazae,tara).
という質問は、常に無条件に目標を充足します。内容の同じ節がプログラム中にあるのですから。一方、ルールは常に真とは限りません。
child(Y,X):-parent(X,Y).
というルールは、変数X,Yに何らかの値が設定されて、そのX,Yに対応するparent関係がプログラム中に定義されていて、はじめて真となるのです。つまり、ルールの:-の右辺はルールが充足されるための条件となっているのです。このことから、ルールの左辺を結論部、右辺を条件部と言います。また、その形式から左辺を頭部、右辺を本体とも言います。

図2.1 ルールの形式
?- child(wakame,fune).
プログラム中にはchild(wakame,fune).という節はないので、Prologは次のルールを考えます。
child(Y,X):-parent(X,Y).
ここでPrologは、このルールでX=fune,Y=wakameと考えればいいかな、と思うわけです。そうすると、
?- child(wakame,fune).
を解決するためには、
child(wakame,fune):-parent(fune,wakame).
について考えればいいということになります。即ち、ルールの条件部(本体)であるparent(fune,wakame).について考えればいいわけで、結局
?- parent(fune,wakame).
という質問があった場合と同じと言えます。ここで、
?- child(wakame,fune).
という目標が
?- parent(fune,wakame).
という目標に置き換えられたことになります。このような場合の新しい目標を副目標と言います。この新しい目標は、プログラム中に同じ内容の節がありますから真です。したがって、Prologは質問に対してyesと答えます。
mother(X,Y):-parent(X,Y),female(X).
となります。本体部の2つの目標の間のカンマはandを表し、両方の目標が充足されなくてはなりません。
sister(X,Y):-
parent(Z,X),
parent(Z,Y),
female(X).
となります。
?- sister(wakame,sazae).
ができるようになりました。(ぱちぱち)上のような質問をするとPrologは期待通り、yesと答えるでしょう。(答えなければ見直すこと)「完璧!!」と思うのは早計です。次のような質問をしてみましょう。「ワカメの姉は誰か」、即ち、
?- sister(X,wakame).
です。Prologは複数の答えを見つけます。
X=sazae;
X=wakame
現在の我々のプログラムが姉と妹の区別が付かないのは仕方がないとして、ワカメの姉(妹)がワカメとは何事だ、ということです。一体全体どうなっているのでしょう。
sister(X,Y):-
parent(Z,X),
parent(Z,Y),
female(X).
でした。X=wakame,Y=wakame,Z=namihei(Z=funeでもよい)とすると、ワカメはワカメの姉(妹)です。今後のためにも、XとYとが同一ではない、という関係differentを定義しておきましょう。
different(X,Y):-X / == Y.
/ ==は等しくない、という意味です。このようにdifferent関係を定義しておけば、これを利用してsister関係を簡単に修正することができます。
sister(X,Y):-
parent(Z,X),
parent(Z,Y),
female(X),
different(X,Y).
本章の要点をまとめておきましょう。