【发布时间】:2014-10-31 16:41:00
【问题描述】:
我有关于这个快速排序here的先前问题。快速排序的序言代码:
gt(X,Y):- X @>Y.
conc([],List, List).
conc([Head|Tail], List1, [Head|List2]):- conc(Tail, List1, List2).
quicksort([],[]).
quicksort([X|Tail],Sorted):-
split(X,Tail,Small,Big),
quicksort(Small,SortedSmall),
quicksort(Big,SortedBig),
conc(SortedSmall,[X|SortedBig],Sorted).
[1]split(X,[],[],[]).
[2]split(X,[Y|Tail],[Y|Small],Big):-
gt(X,Y),!,
split(X,Tail,Small,Big).
[3]split(X,[Y|Tail],Small,[Y|Big]):-
split(X,Tail,Small,Big).
例如数组是[3,2,4,1,5]。这是跟踪路由的第一部分:
?- trace, quicksort([3,2,4,1,5], Sorted).
1 Call: (7) quicksort([3, 2, 4, 1, 5], _G4136) ? creep
2 Call: (8) split(3, [2, 4, 1, 5], _G4269, _G4270) ? creep
3 Call: (9) gt(3, 2) ? creep
4 Call: (10) 3@>2 ? creep
5 Exit: (10) 3@>2 ? creep
6 Exit: (9) gt(3, 2) ? creep
7 Call: (9) split(3, [4, 1, 5], _G4261, _G4273) ? creep
8 Call: (10) gt(3, 4) ? creep
9 Call: (11) 3@>4 ? creep
10 Fail: (11) 3@>4 ? creep
11 Fail: (10) gt(3, 4) ? creep
12 Redo: (9) split(3, [4, 1, 5], _G4261, _G4273) ? creep
13 Call: (10) split(3, [1, 5], _G4261, _G4264) ? creep
在第 2 行,prolog 应用拆分规则 [2],我们有 Call: (8) split(3, [2, 4, 1, 5], _G4269, _G4270),我们有 _G4269 是 [2|Small] 和 _G4270 是 Big。
然后比较 3 和 2,gt(3,2) 返回 true 并且不执行剪切。继续split(X,Tail,Small,Big),即Call: (9) split(3, [4, 1, 5], _G4261, _G4273)
如果gt(X,Y) 返回 false,prolog 将执行剪切,然后应用拆分规则 [3](第 11-12 行)。
我做得对吗?为什么最后一个变量变成了一个新变量(_G4237 而不是_G4270)?因为在代码中我认为是一样的。
谁能帮我把事情弄清楚? 非常感谢!
【问题讨论】:
-
对谓词的每次调用都有自己的变量。您的跟踪显示
_G4270在 (8) 层深,_G4273在 (9) 层深。所以它们是不同的。 -
你可以信任变量名,特别是当由算法生成时!
标签: prolog stack-trace quicksort