扩展Prolog谓词

时间:2017-10-08 07:39:47

标签: prolog

我有prolog谓词male, female, parent,如下所示:

parent(bob, rick).
parent(jane, rick).
parent(rick, alice).
parent(betsy, alice).
male(rick).
female(jane).

现在,推断不完整性别信息的一种方法是看一个父母是男性,然后另一个必须是女性,反之亦然,所以我试图扩展女性:

female(X) :- parent(X, Y), parent(Z, Y), male(Z).

因此,我的最终female谓词是:

female(jane).
female(X) :- parent(X, Y), parent(Z, Y), male(Z).

然而,当我尝试:

?- female(jane).
true ;
false.

?- female(betsy).
true ;
false.

为什么那里出现了错误?当我尝试为male做类似的事情时会出现更多问题,因为这会导致无限递归。

2 个答案:

答案 0 :(得分:3)

让我们来看看如果你查询female / 1会发生什么:

?- female(jane).

Prolog试图通过尝试你为其编写的所有事实和规则来证明谓词。首先,female(jane).成功匹配,Prolog告诉您:

?- female(jane).
true 

点击;后,Prolog会寻找更多解决方案:

?- female(jane).
true ;

对于女性/ 1而言,没有更多的事实,但是规则,因此Prolog试图通过按照您编写的顺序证明其目标来证明该规则。规则头部的Xjane统一。 parent(jane,Y)的第一个目标Y=rick成功。然后Prolog试图证明parent(Z,rick)成功Z=bob。现在Prolog试图证明male(bob),但由于你的事实不包括male(bob)而失败了。因此,Prolog回溯到上一个目标parent(Z,rick)并找到第二个解决方案Z=jane(在您的所有规则未指定XZ必须不同之后)。但是,目标male(jane)失败了。 Prolog正在回溯到之前的目标,但没有找到parent(Z,rick)的更多解决方案,因此它进一步回溯到第一个目标parent(jane,Y)。  因为没有更多的解决方案,Prolog告诉你:

?- female(jane).
true ;
false

为了进一步说明这是如何工作的,我建议你添加一个事实:

male(bob).

现在查询产生:

?- female(jane).
true ;
true ;
false.

现在按照上述原因进行操作:第一个true是因为female(jane)。您获得的第二个true因为规则成功,因为Prolog现在可以证明male(bob)。你得到false,因为没有更多的解决方案。

您的第二个查询的答案可以用相同的方式解释:您得到答案true,因为male(rick)可以在规则中得到证明。 false告诉您没有更多解决方案。

答案 1 :(得分:0)

如果这有助于任何人,我想在这种情况下进一步添加,如果我也想同样地扩展male,它会导致无限递归,因为male引用{{1} }和female引用female

为避免这种情况,最好将事实和规则分开,如下所示:

male

(这只适用于此处,因为进一步的递归级别不会产生任何额外的信息,这在其他情况下可能不正确。)