请解释Bubblesort Prolog计划中的剪辑?

时间:2013-11-19 18:57:44

标签: prolog bubble-sort prolog-cut

我目前正在通过Bratko Prolog的书工作,我正在研究泡沫排序计划。我似乎无法弄清楚为什么切割(!)是必要的。说削减不存在,Prolog会回溯,怎么可能找到错误的答案?因为如果我从中删除它,Prolog首先给我正确的答案,但随后也给出了其他不好的答案。

正如我所看到的,如何交换返回非排序列表?如何将非排序列表击中目标bubblesort(Sorted, Sorted)

当然除非第一个名单也被改变了......不能理解它。

Prolog BubbleSort计划:

gt(X,Y) :- X > Y.

bubblesort(List, Sorted) :-
  swap(List, List1), !,           % A useful swap in List?
  bubblesort(List1, Sorted).
bubblesort(Sorted, Sorted).       % Otherwise list is already sorted

swap([X,Y|Rest], [Y,X|Rest]) :-   % Swap first two elements
  gt(X,Y).
swap([Z|Rest], [Z|Rest1]) :-      % Swap elements in tail
  swap(Rest, Rest1).

离开时,它给了我:

?- bubblesort([5,7,3,6,8,9,2,6], Sorted).

Sorted = [2, 3, 5, 6, 6, 7, 8, 9] ;

Sorted = [2, 3, 5, 6, 7, 6, 8, 9] ;

Sorted = [2, 3, 5, 6, 7, 8, 6, 9] ;

Sorted = [2, 3, 5, 6, 7, 8, 9, 6] ;

我认为我得到了它,但我不确定。可能是在某个时刻,它会回溯swap(List, List1)进入第二个冒泡排序谓词并达到目标,这意味着两个列表Sorted相等?

在英语中,这是否意味着冒泡排序需要继续进行掉期,直到无法进行掉期,但是需要终止?或者这是否意味着每次成功完成交换,对成功进行回溯都没有用?

2 个答案:

答案 0 :(得分:5)

有几种可能性使目标swap(List, List1)失败。 List是长度为0或1的列表;或者它不包含两个紧接着的元素,其中第二个元素小于第一个元素。

切割的方式是切割swap/2bubblesort/2的替代方式。

这是一个很好的例子,其中“深切”(切入swap/2)仍然可以很好地运作。但是,这种情况非常罕见。大多数时候,削减太多了。如果已经提出第二个论点,那么最大多数此类程序使用起来非常脆弱,更是如此。他们往往不是坚定

啊,我几乎错过了它:即使在这个程序中,我们有bubblesort(nonlist,L)成功,或bubblesort([1|nonlist],L)这可能不是故意的,并导致细微的编程错误。

此程序没有提供理想的逻辑编程风格还有另一个原因:bubblesort/2的第二条规则单独阅读时说: Everything是一个排序列表`。要理解这一点,我们必须同时阅读这两条规则并将其缩小到除了......之外的所有内容。

  

在英语中,这是否意味着冒泡排序需要继续进行掉期,直到无法进行掉期,但是需要终止?或者这是否意味着每次成功完成交换,对成功进行回溯都没有用?

这是第一个适用于此的程序性意义。当然,将成功回溯到bubblesort/2的第二个条款将是一个错误。

另一个非常不直观的细节不是特定于剪辑,除了数字之外,该程序还可以成功使用像bubblesort([1,1+1],L)这样的表达式,这可能会导致细微的差异。

答案 1 :(得分:2)

我只想添加 if-then-else 是一个比!/0更合适的语言结构来表达意图(我知道你没有选择!/0你自己在这里):

bubblesort(List0, List) :-
        (   swap(List0, List1) ->
            bubblesort(List1, List)
        ;   List0 = List
        ).

您可以将->更改为*->以查看swap/2的替代解决方案,例如,如果您将其更改为:

bubblesort(List0, List) :-
        (   swap(List0, List1) *->
            bubblesort(List1, List)
        ;   List0 = List
        ).

然后你得到例如:

?- bubblesort([5,7,3,6,8,9,2,6], Ascending).
Ascending = [2, 3, 5, 6, 6, 7, 8, 9] ;
Ascending = [2, 3, 5, 6, 6, 7, 8, 9] ;
Ascending = [2, 3, 5, 6, 6, 7, 8, 9] .

如您所见,正如您所料,所有这些列表都没有减少。