Search code examples
prolog

Get set of elements from list (Prolog)


I am trying to get a set of elements from a list in prolog, such that a query:

get_elems([1, 2, 4, 10], [a, b, c, d, e], X).

yields: X = [a, b, d]

I would like to implement it without using the built in predicate nth. I have tried using the following, but it does not work:

minus_one([], []).
minus_one([X|Xs], [Y|Ys]) :- minus_one(Xs, Ys), Y is X-1.

get_elems([], _, []).
get_elems(_, [], []).
get_elems([1|Ns], [A|As], Z) :- get_elems(Ns, As, B), [A|B] = Z.
get_elems(Ns, [_|As], Z) :- minus_one(Ns, Bs), get_elems(Bs, As, Z).

Edit: The list of indices is guaranteed to be ascending, also I want to avoid implementing my own version of nth.


Solution

  • Give this a go:

    get_elems(Xs,Ys,Zs) :- get_elems(Xs,1,Ys,Zs).
    
    get_elems(Xs,_,Ys,[]) :- Xs = []; Ys = [].
    get_elems([N|Xs],N,[H|Ys],[H|Zs]) :- !, N1 is N + 1, get_elems(Xs,N1,Ys,Zs).
    get_elems(Xs,N,[_|Ys],Zs) :- N1 is N + 1, get_elems(Xs,N1,Ys,Zs).
    

    This just keeps counting up and when the head of the second term is equal to the current index it peels off the head and makes it the head of the current output term. If it doesn't match it just discards the head and keeps going.