我有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
做类似的事情时会出现更多问题,因为这会导致无限递归。
答案 0 :(得分:3)
让我们来看看如果你查询female / 1会发生什么:
?- female(jane).
Prolog试图通过尝试你为其编写的所有事实和规则来证明谓词。首先,female(jane).
成功匹配,Prolog告诉您:
?- female(jane).
true
点击;
后,Prolog会寻找更多解决方案:
?- female(jane).
true ;
对于女性/ 1而言,没有更多的事实,但是规则,因此Prolog试图通过按照您编写的顺序证明其目标来证明该规则。规则头部的X
与jane
统一。 parent(jane,Y)
的第一个目标Y=rick
成功。然后Prolog试图证明parent(Z,rick)
成功Z=bob
。现在Prolog试图证明male(bob)
,但由于你的事实不包括male(bob)
而失败了。因此,Prolog回溯到上一个目标parent(Z,rick)
并找到第二个解决方案Z=jane
(在您的所有规则未指定X
和Z
必须不同之后)。但是,目标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
(这只适用于此处,因为进一步的递归级别不会产生任何额外的信息,这在其他情况下可能不正确。)