扩展Prolog谓词

扩展Prolog谓词,prolog,Prolog,我有prolog谓词男、女、父,如下所示: 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). 因此,我的最后一个女性谓词是:

我有prolog谓词
男、女、父
,如下所示:

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(jane).
female(X) :- parent(X, Y), parent(Z, Y), male(Z).
但是,当我尝试时:

?- female(jane).
true ;
false.

?- female(betsy).
true ;
false.

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

让我们看看如果查询女性/1会发生什么:

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

?- female(jane).
true 
?- female(jane).
true ;
false
点击
-关键序言寻找进一步的解决方案:

?- female(jane).
true ;
对于female/1来说,没有更多的事实,只有一条规则,因此Prolog试图通过按照您编写的顺序证明其目标来证明该规则。规则头部的
X
jane
统一。第一个目标是父母(jane,Y)
成功的
Y=rick
。然后,Prolog试图证明
父(Z,rick)
Z=bob
成功。现在,Prolog试图证明
male(bob)
,但失败了,因为您的事实不包括
male(bob)
。因此,Prolog返回到上一个目标
parent(Z,rick)
,并找到第二个解决方案
Z=jane
(毕竟您的规则没有指定
X
Z
必须不同)。但是,目标
male(jane)
失败。Prolog正在回溯到上一个目标,但没有找到任何更多的父级(Z,rick)
解决方案,因此它进一步回溯到第一个目标
父级(jane,Y)
。 由于没有更多的解决方案,Prolog告诉您:

?- female(jane).
true 
?- female(jane).
true ;
false
为了进一步说明其工作原理,我建议您添加一个事实:

male(bob).
现在,查询将生成:

?- female(jane).
true ;
true ;
false.
现在按照上面描述的推理:第一个
true
是因为
女性(jane)
这个事实。第二个
true
是因为规则成功了,因为Prolog现在可以证明
male(bob)
。因为没有更多的解决方案,所以得到的
false


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

如果这对任何人都有帮助,我想进一步补充一点,在这种情况下,如果我也想扩展
male
类似地,它会导致无限递归,因为
male
引用
male
male
引用
male

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

male(rick).
is_male(X) :- male(X).
is_male(X) :- parent(X, Y), parent(Z, Y), X \== Z, female(Z).

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

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

谢谢,明白了。我很困惑,因为
是真的;false
似乎在说,
jane
是一个逻辑上的女性,而不是另一个逻辑上的女性,这是不应该的。现在我明白了,这意味着没有更多的解决方案。关于我忘记
X\==Z
条件的好消息。使用内置\==2时要小心。考虑下面的查询:<代码> -x=y,x\= y.< /代码>收益>代码>“否”/代码>预期,但<代码> -x==y,x=y/<代码>与<代码> x= y成功,因为\==/ 2对变量没有任何影响,因此它们可以随后统一。如果你在Prolog系统中可用的话,可以考虑使用DIF 2。这样,上述查询都会失败:
?-X=Y,dif(X,Y)。
产生
no
?-dif(X,Y),X=Y。
也产生
no