要理解这个问题,您可以想象一棵树,其中Xin 作为第一级和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)将成功)等等X = 1。然后评估p(Y):p(1)成功,所以你有第一个解决方案:
X = Y, Y = 1.
如果单击 more,则 prolog 会进行回溯(您可以将其想象为树上的一个步骤)并尝试为p(Y). 在这种情况下p(2)成功,谓词为真,你得到:
X = 1, Y = 2.
现在,如果您单击更多,由于在(prolog 中的一般规则具有形式)!的主体中有一个切口(),prolog 不会更深入并被忽略。所以没有更多的解决方案。所以还有另一个回溯,这一次, for ,成功 和,成功,你得到:p(2)head :- bodyp(3)p(Y)p(X)p(2)X = 2p(Y)p(1)
X = 2, Y = 1.
如果您点击更多,您将获得:
X = Y, Y = 2.
现在,由于在 之后有一个删减p(2),因此没有更多的解决方案适用于X和Y(!删减下面的所有内容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).
你得到
X = Y, Y = 2
X = 2,
Y = 1
X = 1,
Y = 2
X = Y, Y = 1
您可以使用跟踪器检查此行为。在 SWI 或 SWISH 你可以写?-
trace, solve(X,Y).
如果你有这样的情况:
p(1).
p(2).
p(3).
sol(X,Y):-
p(X),
!,
p(Y).
prolog 将测试所有可能的值,Y并且只有一个值,X因为切割停止了对树的探索(理想情况下,(1,2,3) 有 3 个分支,X(1,2,3)有 3 个分支Y,!切割 2 和3 从X) 你得到:
X = Y, Y = 1
X = 1,
Y = 2
X = 1,
Y = 3
对不起,很长的帖子,希望清楚。