我有典型的关系示例。
m(thomas).
m(leon).
w(nina).
born(thomas, nina, leon).
born(Father, Mother, Child) :- born(Mother, Father, Child).
father(Father, Child) :- born(Father, Mother, Child), m(Father).
mother(Mother, Child) :- born(Father, Mother, Child), w(Mother).
parent(Parent, Child) :- (father(Parent, Child); mother(Parent, Child)).
当我问父母之后,只会列出父亲:
?- parent(X, leon).
X = thomas ;
X = thomas ;
.....
我想要父母双方:
?- parent(X, leon).
X = thomas ;
X = nina ;
我该怎么办?
编辑:问题:
我的问题不是or
,因为它normally
会回复两个陈述。
问题是上面代码中的born/3
是一个循环。
我试图让母亲和父亲互相交换。
修改:修复:
我从ChristianF和CapelliC得到了两个答案。他们都帮助我理解我的陈述有什么问题。
我自己的解决方案:
m(thomas).
m(leon).
w(nina).
b(thomas, nina, leon).
born(Father, Mother, Child)
:- (m(Father), w(Mother), b(Father, Mother, Child)); b(Mother, Father, Child).
father(Father, Child) :- born(Father,_, Child), m(Father).
mother(Mother, Child) :- born(_, Mother, Child), w(Mother).
parent(Parent, Child) :- (father(Parent, Child); mother(Parent, Child)).
答案 0 :(得分:2)
你的规则中有'循环'。删除born / 3规则,你会得到
?- parent(P,leon).
P = thomas ;
P = nina.
编辑,因为您需要父母可以留在第一或第二“位置”而不论性别,我建议
father(Father, Child) :-
m(Father), (born(Father, _, Child) ; born(_, Father, Child)).
我在出生/ 3查询之前移动了性别测试,似乎更有效避免重复查询......
答案 1 :(得分:1)
问题是,由于存在无限递归,因此父亲显示born
的方式有很多种。
m(thomas).
m(leon).
w(nina).
born(thomas, nina, leon).
born_sym(Father, Mother, Child) :- born(Father, Mother, Child).
born_sym(Father, Mother, Child) :- born(Mother, Father, Child).
father(Father, Child) :- born_sym(Father, Mother, Child), m(Father).
mother(Mother, Child) :- born_sym(Father, Mother, Child), w(Mother).
parent(Parent, Child) :- (father(Parent, Child); mother(Parent, Child)).
答案 2 :(得分:0)
另一个修复实际上是使用cut
来避免无限递归:
m(thomas).
m(leon).
w(nina).
born(thomas, nina, leon) :- !.
born(Father, Mother, Child) :- born(Mother, Father, Child).
father(Father, Child) :- born(Father, Mother, Child), m(Father).
mother(Mother, Child) :- born(Father, Mother, Child), w(Mother).
parent(Parent, Child) :- father(Parent, Child); mother(Parent, Child).
另一种修复无限递归的方式,也许不是一种好的风格:)