In a previous post, I eventually figured out how to write gprolog program that checks whether one list is a permutation of another. As far as I know, it works.
Now, I am creating a mysort
predicate that combines the permutation predicate with this one (also working, as far as I can tell):
sorted([]).
sorted([L]) :- !.
sorted([L|[T|TT]]) :- L @=< T, sorted([T|TT]).
Since my original perm
predicate was designed to terminate with !
as soon as it reached an answer, I made some modifications to allow mysort
to check through possibilities. Here is mysort
, its special backtrack_perm
, and the overlap with the old perm
(which I simply modified as a slight change to backtrack_perm
):
perm([],[]).
perm([LH|LT],R) :-
backtrack_perm([LH|LT],R),
!.
perm_recurse([],X).
perm_recurse([LH|LT],R) :-
member(LH,R),
select(LH,[LH|LT],X),
select(LH,R,Y),
perm_recurse(X,Y),
!.
mysort(L,M) :-
backtrack_perm(L,M),
sorted(M),
!.
backtrack_perm([],[]).
backtrack_perm([LH|LT],R) :-
length([LH|LT],A),
length(R,B),
A == B,
member(LH,R),
select(LH,[LH|LT],X),
select(LH,R,Y),
perm_recurse(X, Y).
Though its components appear to work fine as mentioned, mysort
causes a stack overflow on some inputs, such as mysort([5,3,2],X)
. In an already-sorted list, such as mysort([2,3,5],X)
, or even a partial one like mysort([3,2,5],X)
, the trace can be long, but it does get the answer. Because of this--and since a smaller completely-backwards list like [2,1]
works fine--I'm thinking the problem is just that the process itself is too space/time consuming with all of those permutations.
Without stepping too deeply into the longer traces, would it be safe to assume that this is the case? Or should Prolog/the computer be able to handle this without trouble, meaning I need to rethink the algorithms?