家谱树中的互指Prolog规则

家谱树中的互指Prolog规则,prolog,Prolog,我已经在Prolog中看到了各种家谱树的实现,但是我还没有找到一个可以实现我想做的事情,即通过相互引用来定义子和父。 我想这样做是因为有时候我有一个事实,某个人是某个人的孩子,有时候我有一个事实,某个人是某个人的父母。从这两种事实中,我想问谁是父母,谁是孩子 我尝试将其编码为:- parent(mary, fred). child(john, peter). child(paul, peter). parent(P, C). parent(P, C) :- child(C, P). child

我已经在Prolog中看到了各种家谱树的实现,但是我还没有找到一个可以实现我想做的事情,即通过相互引用来定义子和父。 我想这样做是因为有时候我有一个事实,某个人是某个人的孩子,有时候我有一个事实,某个人是某个人的父母。从这两种事实中,我想问谁是父母,谁是孩子

我尝试将其编码为:-

parent(mary, fred).
child(john, peter).
child(paul, peter).

parent(P, C).
parent(P, C) :- child(C, P).
child (C, P).
child(C, P) :- parent(P, C).
这似乎工作正常,除了它将继续给我相同的结果重复了一遍又一遍。例如:-

[3]  ?- parent(peter, X).
true ;
X = john ;
X = paul ;
true ;
X = john ;
X = paul ;
true 
有没有一种方法可以让它在给我一次完整的结果后停止

更一般地说,这种定义是一件奇怪的事情吗(因为相互递归)?我希望能够得到父母或孩子的事实,正如报道的那样,但也能从中推断出“相反”的关系


谢谢

程序的问题是您正在合并谓词。 父级/2和子级/2是事实,您不应将规则命名为程序中已定义的事实

重命名规则,所有规则都将起作用。此外,规则中的base子句应添加一个与事实相匹配的条件,如下所示:

parent(mary, fred).
child(john, peter).
child(paul, peter).

isparent(P, C):- parent(P, C).
isparent(P, C):- child(C, P).

ischild(C, P):- child(C, P).
ischild(C, P) :- parent(P, C).
现在查询:

?- isparent(peter, X).
X = john
X = paul
另外,不要在您的条件中使用补码规则,这不是必需的,并且会避免递归