understand the running trace of quicksort in prolog

荒凉一梦 提交于 2019-12-24 03:52:24

问题


I have the following prolog code for quicksort:

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).

split(X,[],[],[]).
split(X,[Y|Tail],[Y|Small],Big):-
    gt(X,Y),
    !,
    split(X,Tail,Small, Big).

split(X,[Y|Tail],Small,[Y|Big]):-
    split(X,Tail,Small,Big).

The array for example is [3,2,4,1,5]. quicksort([3,2,4,1,5], Sorted). I need to understand the running trace of the program. I almost do but there is one point that I don't: (this is just a part of the trace):

Redo: (11) split(3, [5], _G3785, _G3782) ? creep
Call: (12) split(3, [], _G3785, _G3788) ? creep
Exit: (12) split(3, [], [], []) ? creep
Exit: (11) split(3, [5], [], [5]) ? creep
Exit: (10) split(3, [1, 5], [1], [5]) ? creep
Exit: (9) split(3, [4, 1, 5], [1], [4, 5]) ? creep
Exit: (8) split(3, [2, 4, 1, 5], [2, 1], [4, 5]) ? creep

Why do we have Exit: (11) split(3, [5], [], [5]) ? creep at the line 11, where does 5 come from? Someone could help me please!! I'd really appreciate that.


回答1:


There should be a cut after comparing at the rule number 2 of function split:

split(X,[Y|Tail],[Y|Small],Big):-
gt(X,Y), 
!,
split(X,Tail,Small, Big).



回答2:


We'll use this for reference:

[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).

And we'll follow your trace fragment.

Redo: (11) split(3, [5], _G3785, _G3782) ? creep

This redo is due to the failure of clause [2] in the original query (not shown, prior in the trace) since gt(3,5) is false. Redo would then result in the query of clause [3]. We'll substitute the known instantiated variables and see what that 3rd clause query looks like:

[A] split(3, [5|[]], Small, [5|Big]) :- split(3, [], Small, Big)

This leads to the next trace line, where _G3785 is Small, and _G3788 is Big:

Call: (12) split(3, [], _G3785, _G3788) ? creep

This will succeed on the first clause [1] and yield this part of the trace:

Exit: (12) split(3, [], [], []) ? creep

Since this was in the midst of executing clause [3] above (as shown with [A]), it yields the following since now Small has been instantiated with [] and Big with [].

split(3, [5|[]], [], [5|[]])

In other words, execution of the third clause shown in [A] results in:

split(3, [5], [], [5])

Which is what your next trace line shows:

Exit: (11) split(3, [5], [], [5]) ? creep


来源:https://stackoverflow.com/questions/26648556/understand-the-running-trace-of-quicksort-in-prolog

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!