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