Search code examples
sortingprologfailure-slice

Prolog - How do I get the tail to not be null


I have the following problem:

Define a predicate sorted(LL), that is satisfied when the list LL contains other lists that are sorted in order of increasing length. For example:

?- sorted([[],[1],[1,1],[1,1,1]]) -> yes.
?- sorted([[],[1],[1,1]]) -> yes.
?- sorted([[1],[],[1,1],[1,1,1]]) -> no.

And I have this code so far:

% shorter/2

shorter([],_).
shorter([_|T1], [_|T2]) :- shorter(T1,T2).

% sorted/1

sorted([]).
sorted([_]).
sorted([L1,L2 | T]) :- shorter2(L1, L2), sorted([L2,T]).

The problem is contained in the above line: sorted([L2,T]). When only one element is left in the list of lists, that call will append an empty list [] because of which shorter/2 will fail. It is depicted in the following SWIPL trace.

[trace]  ?- sorted([[1],[2,3]]).
   Call: (6) sorted([[1], [2, 3]]) ? creep
   Call: (7) shorter2([1], [2, 3]) ? creep
   Call: (8) shorter2([], [3]) ? creep
   Exit: (8) shorter2([], [3]) ? creep
   Exit: (7) shorter2([1], [2, 3]) ? creep
   Call: (7) sorted([[2, 3], []]) ? creep <-- empty list appended
   Call: (8) shorter2([2, 3], []) ? creep
   Fail: (8) shorter2([2, 3], []) ? creep
   Fail: (7) sorted([[2, 3], []]) ? creep
   Fail: (6) sorted([[1], [2, 3]]) ? creep

Solution

  • You have two typos in the last clause of the sorted/1 predicate, which should be:

    sorted([L1,L2| T]) :- shorter(L1, L2), sorted([L2| T]).