在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.
答案 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 = 1
:p(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 = 2
,p(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
很抱歉这篇长篇文章,希望明白。