Prolog实施Mergersort不会停止

时间:2018-06-11 02:45:23

标签: prolog infinite-loop mergesort failure-slice

我是一名新的Prolog开发人员,我正在尝试让合并排序工作。查询

mergesort([2,1],T).

将生产

T=[1,2];
T=[1,2];
T=[1,2];
...

所以虽然它似乎正确"排序它不会停止的序列

另一方面,如果我有一个查询,如

mergesort([2,1],[2,1])

进入无限循环。我想知道为什么会这样?

append([H|T],LISTB,[H|LISTC]):-
    append(T,LISTB,LISTC).

split(LIST,L1,L2):-
    length(LIST,LENGTH),
    M is div(LENGTH,2),
    append(L1,L2,LIST),
    length(L1,L1LENGTH),
    (L1LENGTH =:= M).

merge(A,[],A).
merge([],B,B).
merge([A|TA],[B|TB],[A|MERGED]) :-
    A =< B,
    merge(TA,[B|TB],MERGED).
merge([A|TA],[B|TB],[B|MERGED]) :-
    B < A,
    merge([A|TA],TB,MERGED).

mergesort([],[]).
mergesort([X],[X]).
mergesort(LIST,OLIST):-
    split(LIST,L1,L2),
    mergesort(L1,OLIST1),
    mergesort(L2,OLIST2),
    merge(OLIST1,OLIST2,OLIST).

2 个答案:

答案 0 :(得分:6)

append([], L, L).缺失)

首先,减小输入的大小!使用[2,1]甚至[2]已经可以发现[]带来的问题!

?- mergesort([],T).
   T = []
;  T = []
;  T = []
;  T = []
...

所以问题似乎是程序没有终止。或者也许它在十个答案后停止?有一种方法可以更好地测试这个:

?- mergesort([], T), false.
*LOOPS*

如果我参与其中,我会在你的程序中添加更多目标,以便生成的程序仍然循环:

append([], L, L).
append([H|T],LISTB,[H|LISTC]):- false,
    append(T,LISTB,LISTC).

split(LIST,L1,L2):- LIST = [],
    length(LIST,LENGTH),
    M is div(LENGTH,2),
    append(L1,L2,LIST),
    length(L1,L1LENGTH),
    (L1LENGTH =:= M).

mergesort([],[]) :- false.
mergesort([X],[X]) :- false.
mergesort(LIST,OLIST):- LIST = [],
    split(LIST,L1,L2), L1 = [], L2 = [],
    mergesort(L1,OLIST1), false,
    mergesort(L2,OLIST2),
    merge(OLIST1,OLIST2,OLIST).

我添加了目标 false L = [] 这些目标都会终止,因此会改善终止或将其保留为< / b>。这个程序的结果片段称为

因为这个程序循环,你的原始程序也会循环。因此,可见部分的某处必定存在错误。 mergesort/2的递归规则是否适用于空列表真的有意义吗?

((除此之外,分裂是非常低效的。))

答案 1 :(得分:0)

我确定这是hacky解决方案,但它是 A 解决方案

<svg xmlns="http://www.w3.org/2000/svg" version="1.1"  width="1000"     height="140"  viewBox="0 0 1000 140">
<text x="260" y="70" font-size="60" fill=" #888888" style="text-anchor: right">Multimediale Kunst</text>
<defs>
  <linearGradient id="linearGradient" x1="0%" y1="0%" x2="0%" y2="100%">
    <stop offset="0%" stop-color="#000000" />
    <stop offset="10%" stop-color="#666666" />
  </linearGradient>
</defs> 
<text rotate="180"  x="310"  y="80" font-size="60" fill="url(#linearGradient)" style="text-anchor: right">Multimediale Kunst</text>
</svg>