查询Prolog族树中两个人之间的关系

时间:2010-12-23 10:49:29

标签: prolog family-tree

假设我在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 ?

如何才能提出上述问题进行序言?

我能想出的唯一解决方案是迭代已知的关系类型(Tom,Bob)或(Lisa,Emily)作为paremeter并检查哪一个返回true。但;这个解决方案似乎是浪费时间,当已知关系类型的数量超过几个和/或给定两个人之间存在链式关系时(即:Lisa和Emily:Lisa是Emily的男朋友的母亲)。 / p>

2 个答案:

答案 0 :(得分:4)

我已经提出了这个解决方案(没有彻底检查,但似乎没问题):

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' ;

答案 1 :(得分:0)

该程序是上述程序的简化版本,适用于数据库中存在的直接关系。

查询: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).