Prolog:查询中的'cut'与规则/事实

时间:2018-01-05 15:13:48

标签: prolog prolog-cut

learnprolognow上进行练习10.4,有人可以向我解释或帮助我想象我们获得?- p(X),p(Y)的原因:
X=1,Y=1; X=1,Y=2; X=2, Y=1; X=2, Y=1. 而不只是 X=1, Y=1; X=1, Y=2.

我认为我误解了切割是如何发生的,当它在规则集而不是查询中时 - 因为我认为我可以将它可视化为?- p(X),!,p(Y).,它实际上就像我认为的那样。 ..

编辑:来自网站

% database
p(1).
p(2):-!.
p(3).

% Queries
p(X). % returns: X=1; X=2.
p(X),p(Y). % returns: X=1,Y=1; X=1, Y=1; X=2, Y=2. (?)
p(X),!,p(Y). % returns X=1, Y=1; X=1, Y=2.

1 个答案:

答案 0 :(得分:1)

要理解这个问题,您可以想象一个树X作为第一级,Y作为第二级(prolog使用可以用树很好地描述的sld分辨率)。考虑一下这个问题:

p(1).
p(2):-!.
p(3).

sol(X,Y):-
    p(X),
    p(Y).

我已添加谓词solve/2以使其更清晰。运行查询:

?- solve(X,Y).

首先,您必须选择X的值。 Prolog从左到右使用从顶部到底部的深度优先搜索。因此,它评估p(x)p(1)成功(因为是第一个子句,如果您在p(2)之上写p(1)p(2)将成功),所以{{1 }}。然后评估X = 1p(Y)成功,这样您就有了第一个解决方案:

p(1)

如果你点击更多,那么prolog会做一个回溯(你可以把它想象成树上面的一步)并为X = Y, Y = 1. 尝试另一个值。在这种情况下p(Y)成功,谓词为真,你得到:

p(2)

现在,如果你点击更多,由于X = 1, Y = 2. 正文中有一个剪切(!)(prolog中的一般规则有p(2)形式) ,prolog不会更深入,head :- body被忽略。因此p(3)没有更多解决方案。所以还有另一个回溯,这一次,p(Y)p(X)成功,p(2)X = 2p(Y)成功,你得到:

p(1)

如果你点击更多,你会得到:

X = 2, Y = 1.

现在,由于X = Y, Y = 2. 之后出现了削减,因此p(2)X都没有更多可用的解决方案(Y会削减!以下的所有内容1}})。

如果你删除剪切,你会得到所有可能的解决方案:

p(2)

请记住,条款的顺序很重要。如果你写

X = Y, Y = 1
X = 1,
Y = 2
X = 1,
Y = 3
X = 2,
Y = 1
X = Y, Y = 2
X = 2,
Y = 3
X = 3,
Y = 1
X = 3,
Y = 2
X = Y, Y = 3

你得到了

p(2).
p(1):-!.
p(3).

您可以使用跟踪器检查此行为。在SWI或SWISH中,您可以写X = Y, Y = 2 X = 2, Y = 1 X = 1, Y = 2 X = Y, Y = 1

如果您遇到这样的情况:

?-
 trace, solve(X,Y).

prolog将测试p(1). p(2). p(3). sol(X,Y):- p(X), !, p(Y). 的所有可能值以及Y的仅一个值,因为剪切会停止对树的探索(理想情况下,您有X的3个分支(1, 2,3 {和3为X(1,2,3),Y!切割2和3),你得到:

X

很抱歉这篇长篇文章,希望明白。