家谱中的相互参照Prolog规则

时间:2017-06-04 04:03:10

标签: prolog

我已经在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 

有没有办法可以让它在给我一整套结果后停止?

更一般地说,这种定义是否是一个奇怪的事情(因为相互递归)?我希望能够得到父母或孩子的事实,如报道的那样,但也要推断出相反的情况。这些关系。

谢谢!

1 个答案:

答案 0 :(得分:2)

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

重命名规则,一切正常。此外,规则中的基本子句应该添加一个与事实匹配的条件,如下所示:

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

另外,不要在你的情况下使用补充规则,这是不必要的,并且会避免你的递归