Search code examples
sortingprologcounting-sort

Prolog counting sort


So i created counting sort(https://en.wikipedia.org/wiki/Counting_sort) program in Prolog using ECLiPSe 6.1. It sorts fine, but it can only write sorted list in console instead of returning it as second variable. So how to make it return sorted list as variable?
For example:

mysort([1,1,6,7,4,1.5,11,6,7],Z) 

is writing ([7, 7, 6, 6, 4, 1, 1]) in console, which is correct answer (it sorts numbers from 0 to 10).But variable Z is Z=Z, instead of Z=([7, 7, 6, 6, 4, 1, 1])

      build(_,0,[]).  %create list with ARG1 value , ARG2 size, and write to ARG3
      build(X,N1,[X|L]) :- N1 > 0, N is N1 - 1, build(X,N,L). 
      build(X,N1,[X]):- N1>0, N1 is N - 1, build(X,N,[]).  

      build_list(X,N):-build(0,N,X).%create list with ARG1 value , ARG2 size, and write to ARG3

      sum_list([], 0).% ARG1 list sum, write to ARG2
      sum_list([H|T], Sum) :-
         sum_list(T, Rest),
         Sum is H + Rest.

      replace([_|T], 0, X, [X|T]).%replace in ARG1 list,  ARG2 index with           ARG3 value,return as ARG4
      replace([H|T], I, X, [H|R]):- I > -1, NI is I-1, replace(T, NI, X, R), !.
      replace(L, _, _, L).

      increment_nth_in_list( [] , [],_ ) .%Increment element in ARG1, return as ARG2, increment element on ARG3 position
      increment_nth_in_list( [X|Xs] , [Y|Ys],N) :-
        (N=0->Y is X+1,N1 is N-1;
        N1 is N-1,Y is X),
        increment_nth_in_list(Xs,Ys,N1).    

      decrement_nth_in_list( [] , [],_ ) .%Decrement element in ARG1, return as ARG2, Decrement element on ARG3 position
      decrement_nth_in_list( [X|Xs] , [Y|Ys],N) :- 
        (N=0->Y is X-1,N1 is N-1;
         N1 is N-1,Y is X),
        decrement_nth_in_list(Xs,Ys,N1).    

      mysort([],[]).
      mysort([_],[]).
      mysort(Sorting,Sorted):-%Starting sort
      build_list(Amounts_of,10),%create list from 0 to 10 (MAX)
      count_numbers(Sorting,Amounts_of).%starting to count numbers

      count_numbers([Sortinghead|Sortingtail],Amount_of):-%counting numbers from ARG1 and writing to ARG2
      increment_nth_in_list(Amount_of,NewAmount,Sortinghead),
      length(Sortingtail,Z),
      (Z>0->count_numbers(Sortingtail,NewAmount);
      sum_list(NewAmount,Sum),build_list(Sorted,Sum),length(Sorted,L),fill_list(NewAmount,Sorted,0,L)
      ).

      fill_list([],A,_,_):-write(A).
      fill_list([Amount_of_Head|[]],[Sorted],N,L).

      fill_list([Amount_of_Head|Amount_of_Tail],Sorted,N,L):-%Filling ARG2           based on values in ARG1,with ARG3 values on ARG4 position.
      Amount_of_Head>0-          >decrement_nth_in_list([Amount_of_Head|Amount_of_Tail],NewAmount,0),L1 is L-          1,replace(Sorted,L1,N,NewSorted),fill_list(NewAmount,NewSorted,N,L1)
      ;N1 is N+1,fill_list(Amount_of_Tail,Sorted,N1,L).

Solution

  • The second argument Z in your call corresponds to the variable Sorted in the last clause of mysort/2. But that clause never uses that variable, so it can never be bound to the solution. You will have to add arguments to fill_list/4 and count_numbers/2 that you bind to the solution when you are done, at the same point where you now do a write. (You might be able to reuse existing arguments; your code is badly formatted and your variable names do not help understand it.)