Interroger la relation entre deux personnes dans un arbre de la famille Prolog
-
12-10-2019 - |
Question
Supposons que je le dessous du code dans mon fichier 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)).
Maintenant, je veux obtenir la réponse aux questions telles que:
What is the relationship between Tom and Bob ?
What is the relationship between Lisa and Emily ?
Comment puis-je poser les questions ci-dessus Prolog?
La seule solution que je pouvais venir avec était itérer sur les types de relation connue donnant (Tom, Bob) ou (Lisa, Emily) comme paremeter et cocher un renvoie true. Mais; cette solution semble être une perte de temps, lorsque le nombre de types de relations connues sont plus que quelques-uns et / ou il y a une relation de chaîne entre les données deux personnes (c.-à-: Lisa et Emily: Lisa est la mère de petit ami d'Emily) <. / p>
La solution
Je suis venu avec cette solution (non vérifié à fond, mais il semble être ok):
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).
cas de test:
?- 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' ;
Autres conseils
Ce programme, une version simplifiée du programme ci-dessus, travaillera pour présenter des relations directes dans la base de données.
Requête:. QUS (Y, comment, est, a1, lié à, b3)
Faits
/*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).
Règles
/*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.
Programme
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).