4
votes

I have a list of complex terms with the same functor and arity, but different arguments. Something like this:

Elements = [element(a, 1), element(b,2), element(c,3)]

And from it I wish to generate a new list, containing only second arguments of the each complex term in the list, like this:

Numbers = [1,2,3]

Is there a way to design the predicate to solve this problem for any length of the input list?

1
Yes, this is very straight-forward. Do you have any attempts? Hint: you can make use of element(_, N) will provide all values of N on backtracking. Also, have a look at findall or setof. - lurker
Thanks for the comment. Yes, already spent couple of hours with no result (I'm very new to Prolog). Most of my attempts were spinning around element(_,N), but I find out that I understand how to make use of it only for a known number of arguments, which is not the case here. I'll try to use foreach & setof, thanks for the advice. - Timofey
That's findall not foreach. ;) If you show your attempts, you'll get more help on SO. :) - lurker
Finally solved with findall! Thank you, I'll post the solution. Now I'm wondering how to solve it with recursion. - Timofey
Okay as a newbie I'm not allowed to post answers to my own questions, so here is a solution: findall(X,member(element(_,X), Elements),Numbers). - Timofey

1 Answers

1
votes

Timofey's answer with findall/3: findall(X,member(element(_,X), Elements),Numbers).

Solution with a recursive predicate:

element_indexes([], []).
element_indexes([element(_,N)|Es],[N|Ns]) :-
    element_indexes(Es, Ns).