Search code examples
prolog

Why are solutions in the wrong order?


I have been asked to

define a predicate subseq/2, with signature subseq(-,+), which is true when both its arguments are lists, and its first argument can be constructed by removing zero or more elements from its second argument.

... with intended solution order:

?- subseq(X, [a, b, c]).
X = [a, b, c] ;
X = [a, b] ;
X = [a, c] ;
X = [a] ;
X = [b, c] ;
X = [b] ;
X = [c] ;
X = [].

My code:

subseq([], []).
subseq([], [_|_]).
subseq([X|XS], [X|YS]) :- subseq(XS, YS).
subseq([X|XS], [_|YS]) :- subseq([X|XS], YS).

My code's solution order:

?- subseq(X, [a, b, c]).
X = []
X = [a]
X = [a, b]
X = [a, b, c]
X = [a, c]
X = [b]
X = [b, c]
X = [c] ;
false.

How do I achieve the intended solution order?


Solution

  • In Prolog, the order of the rules is crucial. To get the desired output, simply change the order of the rules, like this:

    subseq([X|XS], [X|YS]) :- subseq(XS, YS).
    subseq([X|XS], [_|YS]) :- subseq([X|XS], YS).
    subseq([], []).
    subseq([], [_|_]).
    
    ?- subseq(X,[a,b,c]).
    X = [a, b, c]
    X = [a, b]
    X = [a, c]
    X = [a]
    X = [b, c]
    X = [b]
    X = [c]
    X = []