I have that previous question about this quicksort here.The 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).
[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).
The array for example is [3,2,4,1,5]. This is the first part of the trace route:
?- 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
At the line 2, prolog apply the rule [2] of split and we have Call: (8) split(3, [2, 4, 1, 5], _G4269, _G4270)
and we have _G4269
is [2|Small]
and _G4270
is Big
.
It then compare 3 and 2, gt(3,2)
return true and it does not execute the cut. Continue with split(X,Tail,Small,Big)
which is Call: (9) split(3, [4, 1, 5], _G4261, _G4273)
If the gt(X,Y)
return false, prolog will execute the cut and then apply the rule [3] of the split (line 11-12).
Am I doing right and why the last variable has become a new one (_G4237
instead of _G4270
)? Because in the code I thought it is the same.
Anyone could help me clear things out? Many thanks!
To be precise: your question concerns this part of the trace:
which corresponds to the call to:
and you are right there is no VISIBLE reason to obtain different variables since the same variable
Big
is used. I admit it is confusing. And, you could obtain the same variable. This can be shown calling directlysplit(3, [2, 4, 1, 5], S, B)
the trace is then (with swi v6.6.6):And the same variable is used (
_G4538
).However, the interpreter can have INVISIBLE reason to unify a variable
X
with a brand new oneY
and useY
instead ofX
in subsequent computations. It is what occurs in your example. You can use the commandg
(goals) when debugging to obtain a backtrace, which will show the current stack trace with current variable bindings. Returning to your example, when you reachtype
g
to have a backtrace and you obtain something like:And now you can see that
_G4273
is the same variable in depth [8] and [9].