次の話は、N. Wirth の (1976) Algorithms + Datastructures = Programs からのものです。
私は成人した娘(彼女を D と呼ぶ)を持つ未亡人(彼女を W としましょう)と結婚しました。よく訪ねてくれた父(F)は、継娘に恋をして結婚しました。したがって、父が義理の息子になり、義理の娘が母になりました。数か月後、妻は息子(S1)を出産し、父の義理の兄弟であり、叔父でもありました。この父の妻、つまり義理の娘にも息子がいました(S2)。
プロローグでこれらの関係をモデル化しようとしているので、最終的には次のように入力できるようになります。
| ?- grandfather(i,i).
そして、私が自分のおじいちゃんかどうかについて「はい」または「いいえ」が与えられます。
これまでに書いたコード (grandpa.pl) は次のとおりです。
aunt(X,Y):-
sibling(X,Z),
parent(Z,Y),
female(X).
brother(X,Y):-
sibling(X,Y),
male(X).
brother_in_law(X,Y):-
child(X,Z),
married(Z,W),
parent(W,Y),
not(sibling(X,Y)),
male(X).
brother_in_law(s1,f).
child(X,Y):-
parent(Y,X).
daughter(X,Y):-
parent(Y,X),
child(X,Y),
female(X).
daughter(d,w).
father(X,Y):-
parent(X,Y),
male(X).
father(f,i).
father_in_law(X,Y):-
child(X,Z),
married(Y,Z),
not(child(X,Y)),
male(X).
grandparent(X,Y):-
parent(X,Z),
parent(Z,Y).
grandmother(X,Y):-
grandparent(X,Y),
female(X).
grandfather(X,Y):-
grandparent(X,Y),
male(X).
grandchild(X,Y):-
child(X,Z),
child(Z,Y).
married(X,Y):-
wife(X,Y),
female(X).
married(X,Y):-
husband(X,Y),
male(X).
married(i,w).
married(f,d).
mother(X,Y):-
parent(X,Y),
female(X).
parent(X,Y):-
child(Y,X).
sibling(X,Y):-
parent(Z,X),
parent(Z,Y).
sister(X,Y):-
sibling(X,Y),
female(X).
son(X,Y):-
parent(Y,X),
male(X).
son(s1,w).
son(s2,d).
son_in_law(X,Y):-
child(X,Z),
not(child(X,Y)),
married(Z,Y),
male(X).
son_in_law(f,i).
step_daughter(X,Y):-
child(X,Z),
married(Z,Y),
not(child(X,Y)),
female(X).
step_daughter(d,i).
step_parent(X,Y):-
married(X,Z),
parent(Z,Y),
not(parent(X,Y)).
step_father(X,Y):-
step_parent(X,Y),
male(X).
step_mother(X,Y):-
step_parent(X,Y),
female(X).
step_mother(d,i).
uncle(X,Y):-
sibling(X,Z),
parent(Z,Y),
male(X).
uncle(s1,i).
現在、循環定義で多くの問題を抱えているため、クエリを実行すると無限ループに陥ります:祖父(i、i)。
たとえば、私は持っています:
(1 ミリ秒) はい {トレース} | ?- 祖父(i,i)。1 1 コール: おじいさん(i,i) ?
2 2 呼び出し: 祖父母(i,i) ?
3 3 呼び出し: 親(i,_103) ?
4 4 コール: child(_127,i) ?
5 5 呼び出し: 親(i,_151) ?
6 6 コール: child(_175,i) ?
7 7 呼び出し: 親(i,_199) ?
8 8 コール: child(_223,i) ?
9 9 呼び出し: 親(i,_247) ?
10 10 コール: child(_271,i) ?
11 11 呼び出し: 親(i,_295) ?
12 12 コール: child(_319,i) ?
13 13 呼び出し: 親(i,_343) ?
14 14 コール: child(_367,i) ?
15 15 呼び出し: 親(i,_391) ?
...
これは、子が親を持っていると定義し、親が子を持っていると定義しているためです (私が投稿した上記の述語でわかるように)。
私が自分のおじいちゃんかどうかを判断できるように、これらの関係の述語を再定義するのを手伝ってくれる人はいますか?