No, it was not "easy", as it doesn't work, unfortunately. halve([1,2,3]-[],A,B)
doesn't work; halve_pom([1,2,3]-[],A,B)
doesn't work either. Also, it is unclear which of the splitting schemes you prefer, [1,2,3,4,5,6,7] -> ([1,3,5,7] , [2,4,6])
or -> ([1,2,3,4] , [5,6,7])
.
If your halve
predicate worked, all you'd have left to do is to define merge
, which would merge the two halves of a list, in order. Then,
mergesort(A,S):- halve(A,B-[],C-[]), mergesort(B,SB), mergesort(C,SC),
merge(SB,SC,S-[]).
Note that you probably would call it with a normal list A
, i.e. the halve
predicate should expect its first argument as a normal list (i.e. not a difference-list).
See also What does the "-" symbol mean in Prolog when dealing with lists? . The '-'
is unnecessary; instead, its two constituents should be used as two separate arguments to a predicate.
So, one way to code halve
is
halve([A,B|C],[A|X]-ZX,[B|Y]-ZY):- halve(C,X-ZX,Y-ZY).
halve([A],[A|X]-X,Y-Y).
halve([],X-X,Y-Y).
The same approach can be used to code merge
:
merge(SB,SC,S-Z):- SB=[A|B], SC=[C|D], A=<C, S=[A|T], merge(B,SC,T-Z).
merge(SB,SC,S-Z):- SB=[A|B], SC=[C|D], A>C, ... , ... .
merge(SB,SC,S-Z):- SB=[A|B], SC=[], ... , ... .
merge(SB,SC,S-Z):- SB=[], SC=[C|D], S=[C|T], ... .
merge([],[],Z-Z).