要理解这个问题,您可以想象一棵树,其中X
in 作为第一级和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 :- 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
(!
删减下面的所有内容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
对不起,很长的帖子,希望清楚。