0

I'm trying to best understand everything about this code. This is how I currently perceive what's happening:

So I can see if X > Y we swap the elements, if not we recurse down the sublist until we find an X that X > Y, if we do not, then the list is sorted. Problems I'm having is I don't really understand the base case, bubblesort(Sorted, Sorted). I thought you would need a base case for an empty list? I would really appreciate if someone could describe a sort of step by step description of this program.

bubblesort(List,Sorted) :-
   swap(List,List1),
   !,
   bubblesort(List1,Sorted).
bubblesort(Sorted,Sorted).

swap([X,Y|Rest],[Y,X|Rest]) :-   % swaps X with Y if gt(X,Y) is true.
   gt(X,Y).
swap([Z|Rest],[Z|Rest1]) :-      % calls swap on sublists excluding the heads.
   swap(Rest,Rest1).

gt(X,Y) :-                       % true if X is greater than Y.
   X > Y.
Rahn
  • 4,787
  • 4
  • 31
  • 57
user2069328
  • 71
  • 1
  • 7
  • 1
    possible duplicate of [Please explain the cut in the Bubblesort Prolog program?](http://stackoverflow.com/questions/20079763/please-explain-the-cut-in-the-bubblesort-prolog-program) – false Mar 10 '14 at 17:36
  • The base case doesn't use an empty list because the arguments don't reduce to an empty list in the recursion. The list is always the same length when it's passed recursively. A base case isn't always an empty list case or a zero case. Also, in the `bubblesort` predicate, the base case only occurs if `swap` in the first clause fails, meaning the sort is done and your solution is the `List` itself, thus `bubblesort(Sorted, Sorted).` The link that @false provided gives a more detailed analysis of the predicate. – lurker Mar 10 '14 at 17:41
  • So if the first swap clause fails then it skips the bubblesort(List1, Sorted). line and goes to bubblesort(Sorted,Sorted)? – user2069328 Mar 10 '14 at 17:49
  • Yes, exactly. That's called "backtracking" in Prolog. Multiple occurrences ("clauses") of the predicate are a bit like a logical "OR". If one fails, then Prolog moves to try the next one (since there was nothing left to try inside the first one, the `swap` being the first expression in the first clause). – lurker Mar 10 '14 at 21:11
  • swap([Z | Rest], [Z | Rest1]) :- swap(Rest, Rest1). Does this line fail if the length of the list is 0 or 1 because you can't split that up into a head and tail? – user2069328 Mar 10 '14 at 22:00
  • The arguments won't unify with the empty list, but a list of length one such as `[x]` can be expressed as `[x|[]]` so `Rest` would unify with `[]`. But the `swap(List, List1)` query will fail if `List` is just one element since you don't have a base case for `swap` that handles empty lists. – lurker Mar 11 '14 at 01:08

0 Answers0