首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Prolog家族树中两个人关系的查询

Prolog家族树中两个人关系的查询
EN

Stack Overflow用户
提问于 2010-12-23 10:49:28
回答 2查看 3.3K关注 0票数 5

假设我的familyTree.pl文件中有以下代码:

代码语言:javascript
运行
复制
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)).

现在,我想得到以下问题的答案:

代码语言:javascript
运行
复制
What is the relationship between Tom and Bob ?

What is the relationship between Lisa and Emily ?

如何向prolog提出上述问题?

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-12-23 15:53:57

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

代码语言:javascript
运行
复制
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).

测试用例:

代码语言:javascript
运行
复制
?- 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' ;
票数 4
EN

Stack Overflow用户

发布于 2018-05-17 21:07:44

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

查询: qus(Y,how,is,a1,related,to,b3)。

事实

代码语言:javascript
运行
复制
/*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).

规则

代码语言:javascript
运行
复制
/*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.

程序

代码语言:javascript
运行
复制
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).
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4518040

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档