序言:一个人是他自己的兄弟姐妹吗?

我在理解为什么我的序言中的代码为什么会根据我放置规则的顺序执行某些操作时遇到麻烦。


这是我的数据库:


parent(tom, bob).

parent(tom, liz).

parent(mary, bob).

parent(mary, liz).


male(tom).

male(bob).

female(mary).

female(liz).

以下是规则:


%difference(X, Y) ==> Predicate to check if two people X and Y are not the same person.

difference(X, Y) :- \==(X, Y).

father(X, Y) :- male(X), parent(X, Y), difference(X, Y).

mother(X, Y) :- female(X), parent(X, Y), difference(X, Y).

sibling(X, Y) :-

    difference(X, Y),

    mother(M, X), mother(M, Y),

    father(F, X), father(F, Y).

问题是当我这样做时


?- sibling(bob, X).

我懂了


X = bob ;

X = liz ;

false.

但是当我更改顺序时(我在最后部分放了差(X,Y))


sibling(X, Y) :-

    mother(M, X), mother(M, Y),

    father(F, X), father(F, Y),

    difference(X, Y).

我打电话


?- sibling(bob, X).

我懂了


X = liz;

false.

这就是我想要的。


到目前为止,我只看到规则的顺序在进行递归时很重要。所以我不明白鲍勃仍然只是他自己的兄弟姐妹,因为我把差异检查放在首位。


谢谢你的帮助!


慕勒3428872
浏览 473回答 3
3回答

至尊宝的传说

这是因为统一的工作方式。如果先放差异,则X和Y的值尚未统一为任何值。考虑一下跟踪: goal list: [sibling(bob, Z)] goal: sibling(bob, Z). X-> bob, Y -> Z goal list: [difference(bob, Y), mother(M, bob), mother(M, Y), father(F, bob), father(F, Y).] goal: difference(bob, Y) --SUCCESS goal list: [mother(M, bob), mother(M, Y), father(F, bob), father(F, Y).] goal: mother(M, bob) ...当您将差异调用放在最后时,X和Y都已统一,并且如果它们的值相同,则差异将失败。然后将发生回溯。使用序言环境的跟踪功能可以查看执行过程中逐步发生的情况。

慕桂英4014372

Wrt:“如果将其放在规则的“末尾”,则很有可能最终会出现在“数据记录”中,并且无论如何都可以直接使用(\ ==)/ 2。这是一个误解:当单独使用(\ ==)/ 2时,不能保证结果将是正确的。但是iso_dif/2只要没有错误,它们就是正确的。
打开App,查看更多内容
随时随地看视频慕课网APP