質問
familytree.plファイルに以下のコードがあるとします。
male(tom).
male(bob).
female(lisa).
female(emily).
parent(tom, bob).
parent(lisa, bob).
morethanfriends(emily, bob).
father(X,Y) :- male(X), parent(X,Y).
mother(X,Y) :- female(X), parent(X,Y).
girlfriend(X,Y) :- female(X), (morethanfriends(X,Y); morethanfriends(Y,X)).
boyfriend(X,Y) :- male(X), (morethanfriends(X,Y); morethanfriends(Y,X)).
今、私は次のような質問に対する答えを取得したいと思います:
What is the relationship between Tom and Bob ?
What is the relationship between Lisa and Emily ?
上記の質問をプロログに尋ねるにはどうすればよいですか?
私が思いつくことができる唯一の解決策は、既知の関係タイプ(トム、ボブ)または(リサ、エミリー)をparemeterとして繰り返して、どちらが真であるかを確認することでした。だが;この解決策は、既知の関係タイプの数が少数である場合、および/または与えられた2人の間に連鎖関係がある場合(つまり、リサとエミリー:リサはエミリーのボーイフレンドの母親)。
解決
私はこのソリューションを思いつきました(徹底的にチェックしていませんが、大丈夫のようです):
relations(What, Name1, Name2):-
relation_facts(Facts, Name1, _),
relations1(Facts, [], Name2, What1),
atomic_list_concat(What1, What).
relations1(Facts, Forbidden, Name2, What):-
member(Relation, Facts),
call(Relation),
relations2(Relation, Forbidden, Name2, What).
relations2(Relation, Forbidden, Right, [Left, ' ', is, ' ', Right, '''s ', Name]):-
Relation =.. [Name, Left, Right],
Forbidden \= Right.
relations2(Relation, Forbidden, Name2, [Left, ' ', is, ' '| What]):-
Relation =.. [Name, Left, Right],
relation_facts(Facts, Right, _),
Forbidden\=Right,
relations1(Facts, Left, Name2, [_,_,_,_, NRight|What1]),
append([NRight|What1], ['''s ', Name], What).
% Here goes the relations you want to check for:
relation_facts([father(X,Y), mother(X,Y), girlfriend(X,Y), boyfriend(X,Y)], X, Y).
テストケース:
?- relations(Relation,lisa,emily).
Relation = 'lisa is emily\'s boyfriend\'s mother' ;
?- relations(Relation,lisa,bob).
Relation = 'lisa is bob\'s mother' ;
?- relations(Relation,_,_).
Relation = 'tom is bob\'s father' ;
Relation = 'tom is emily\'s boyfriend\'s father' ;
Relation = 'lisa is bob\'s mother' ;
Relation = 'lisa is emily\'s boyfriend\'s mother' ;
Relation = 'emily is bob\'s girlfriend' ;
Relation = 'bob is emily\'s boyfriend' ;
他のヒント
上記のプログラムの簡素化されたバージョンであるこのプログラムは、データベースに直接関係のために機能します。
クエリ:qus(y、how、is、a1、related、to、b3)。
事実
/*facts*/
father(a1,a2).
father(a1,a3).
father(a1,b3).
father(a1,b3).
father(a3,a4).
father(a2,b4).
father(a5,b8).
father(a8,b7).
father(a6,a7).
mother(b1,a2).
mother(b1,a3).
mother(b1,b2).
mother(b1,b3).
mother(b2,a5).
mother(b3,b5).
mother(b4,a6).
mother(b6,a7).
mother(b8,b7).
male(a1).
male(a2).
male(a3).
male(a4).
male(a5).
male(a6).
male(a7).
male(a8).
female(b1).
female(b3).
female(b3).
female(b4).
female(b5).
female(b6).
female(b7).
female(b8).
ルール
/*rules*/
parent(X, Y) :-
father(X,Y); mother(X,Y).
child(X, Y) :-
parent(Y, X).
sister(X, Y) :-
female(X),
parent(Z, X), parent(Z,Y),
X \= Y.
brother(X, Y) :-
parent(Z, X), parent(Z, Y),
male(X),
X \= Y.
partner(X, Y) :-
father(X,Z),mother(Y,Z);
father(Y,Z),mother(X,Z).
sibling(X, Y):-
parent(Z, X), parent(Z,Y).
chacha(X, Y) :-
brother(X, Z),
father(Z, Y).
mama(X, Y) :-
brother(X, Z),
mother(Z, Y).
bua(X, Y) :-
sister(X, Z),
father(Z, Y).
mosi(X, Y) :-
sister(X, Z),
mother(Z, Y).
nani(X, Y) :-
mother(X, Z),
mother(Z, Y).
nana(X, Y) :-
father(X, Z),
mother(Z, Y).
dadi(X, Y) :-
mother(X, Z),
father(Z, Y).
dada(X, Y) :-
father(X, Z),
father(Z, Y).
cousin(X, Y) :-
parent(Z, X),
parent(W, Y),
sibling(W, Z),
\+sibling(X, Y),
X \= Y.
secondcousin(X, Y) :-
parent(A, B),
parent(B, X),
parent(C, D),
parent(D, Y),
sibling(C, A),
\+sibling(X, Y),
X \= Y.
プログラム
qus(Y,how,is,Person1,related,to,Person2):-
database_relations(Relations, Person1, Person2),
find_relation(Relations, Person2, X),
atomic_list_concat(X, Y).
qus(Y,who,is,Person1,of,Person2):-
database_relations(Relations, Person1, Person2),
find_relation(Relations, Person2, X),
atomic_list_concat(X, Y).
find_relation(Relations, Person2, X):-
member(Query, Relations),
call(Query),
write_answer(Query, Person2, X).
write_answer(Relation_in_list, Person2, [Person1, ' ', is, ' ', the, ' ',RelationalAnswer,' ', of, ' ', Person2]):-
Relation_in_list =.. [RelationalAnswer, Person1, Person2].
database_relations([chacha(X,Y),mama(X,Y),bua(X,Y),mosi(X,Y),nani(X,Y),nana(X,Y),dadi(X,Y),dada(X,Y),father(X,Y), mother(X,Y),brother(X,Y),sister(X,Y),parent(X,Y),partner(X,Y),cousin(X,Y),secondcousin(X,Y)], X, Y).
所属していません StackOverflow