终止条件序言

时间:2015-01-14 12:42:19

标签: prolog termination failure-slice

我的老师为我们提供了一些关于Prolog的幻灯片,我发现了一些有点奇怪的东西。

reverse([],[]).
reverse([X|Xs],Zs) :- reverse(Xs,Ys), append(Ys, [X], Zs).

据他说,当第一个参数reverse([],..)是完整列表时,程序终止。 此外,如果您将谓词中的目标切换为reverse([X|Xs],Zs) :- append(Ys, [X], Zs), reverse(Xs,Ys).,则当第二个参数是完整列表reverse(..,[]).时,程序应该终止

这与我迄今为止学到的东西有点不同。我认为这两个论点都影响了节目的终止条件,显然它们并不符合我老师的例子。 任何人都可以给我一些意见吗?

1 个答案:

答案 0 :(得分:4)

由于Prolog相对复杂的控制流程,Prolog程序的终止属性有点难以理解。有很多方法可以降低复杂性。一个是通过在程序中插入其他目标 false 来仅考虑部分计划。你可以把它们放在任何地方。无论你把它们放在哪里,下面都有:如果这个名为failure-slice的新程序没有终止,那么你的原始程序也不会终止。注意“如果”。这是你的计划:

reverse([],[]) :- false.
reverse([X|Xs],Zs) :-
   reverse(Xs,Ys), false,
   append(Ys, [X], Zs).

此故障切片对于理解您的关系所描述的完全没用。它永远不会成功。但是,它有助于我们更好地理解 终止将如何做。

请注意,事实已完全消除。事实上,无论事实如何,它都无法改善reverse/2这个失败切片的终止。 (但它可能会使终止恶化)。

另请注意第二个参数Zs:没有进一步提及此Zs。因此:reverse/2的第二个参数可以是它想要的任何东西。它将再次无法改善终止。

要使reverse/2终止,必须实例化第一个参数,以便此片段终止。因此,[][X|[]]将终止,即使[X|nonlist]也会终止。但部分列表(例如Xs[a|Xs]等不会终止。

如果你想改善终止,比如reverse(Xs,[])你需要改变可见的剩余部分。一种方法是交换目标。现在,Zs可能会导致终止。但是-alas-第一个论点现在不再具有它曾经拥有的影响力。考虑reverse([a], Zs)和:

reverse([],[]) :- false.
reverse([X|Xs],Zs) :-
   append(Ys, [X], Zs), false,
   reverse(Xs,Ys).

append([], Zs, Zs) :- false.
append([X|Xs], Ys, [X|Zs]) :-
   append(Xs, Ys, Zs), false.

因此,虽然这个片段仍然坚持第一个参数是[_|_],但它并没有考虑剩余的术语。因此,目标不会终止。

如果您想了解更多信息,请查看。同样,请考虑using cTI。为了培养良好的直觉,你需要自己尝试一下。