Запросите связь между двумя людьми в Семейном древе Пролога - PullRequest
4 голосов
/ 23 декабря 2010

Предположим, у меня есть код ниже в моем файле 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 ?

Как я могу задать эти вопросы прологу?

Единственное решение, которое я мог придумать, - это перебирать известные типы отношений, задавая (Том, ​​Боб) или (Лиза, Эмили) как параметр и проверять, какой из них возвращает true. Но; это решение кажется пустой тратой времени, когда число известных типов отношений превышает несколько и / или существует цепная связь между данными двумя людьми (то есть: Лиза и Эмили: Лиза - мать парня Эмили).

Ответы [ 2 ]

4 голосов
/ 23 декабря 2010

Я придумала это решение (не проверено тщательно, но, кажется, все в порядке):

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' ;
0 голосов
/ 18 мая 2018

Эта программа, упрощенная версия вышеуказанной программы, будет работать для прямых связей, присутствующих в базе данных.

Запрос: qus (Y, как, a1, относится к, 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).
...