Is it possible to copy every ith element from a list to a sublist with just one ternary predicate sublist(Element, List1, List2) and built-in length and append? I know, with 4-element auxiliary predicates, it becomes rather trivial, but it isn't what I need. Can anybody suggest a strategy?
0
				votes
			2 Answers
2  
				votes
			with some builtins a declarative solution is really easy:
sublist(Element, List1, List2) :-
    findall(E, (nth1(I, List1, E), 0 is I mod Element), List2).
while explicitly iterating:
sublist(Element, List1, List2) :-
    (   N is Element-1,
        length(T, N),
        append(T, [E|R], List1)
    ->  sublist(Element, R, ListR),
        List2 = [E|ListR]
    ;   List2 = []
    ).
where you can see the how to use Boris' suggestion
1  
				votes
			You can use lentgth/2 with the first argument a variable and the second an integer, to create a list of not instantiated variables, like this:
?- length(L, 4).
L = [_G936, _G939, _G942, _G945].
If you now use append/3 with this list as the first argument, and a variable as the second, it will split the list in your third argument:
?- length(A, 4), append(A, B, [a,b,c,d,e,f,g,h]).
A = [a, b, c, d],
B = [e, f, g, h].
So if you want say the 5th element of a list, you could take the head of the second argument:
?- length(A, 4), append(A, [Fifth|Rest], [a,b,c,d,e,f,g,h]).
A = [a, b, c, d],
Fifth = e,
Rest = [f, g, h].
This is not a solution but a valid strategy:
every_ith(I, In, [X|Ys]) :-
    N is I - 1,
    length(Prefix, N),
    append(Prefix, [X|Xs], In),
    every_ith(I, Xs, Ys).