Powerful append/2 is powerful. Here is how to split a list at position N
For example split the list of length 12 a position 2, leaving a frontlist of 2 elements, the element at position 1 and the backlist of 9 element.
[a,b,c,d,e,f,g,h,i,j,k,l] =2=> [a,b] c [d,e,f,g,h,i,j,k,l]
Code:
splinter(List, N, Elem, Front, Back) :-
length(Front, N),
append(Front, [Elem|Back], List).
Test:
:-begin_tests(splinter).
% negative index
test(oorange,[throws(error(_,_))]) :- splinter([a,b],-1,_,_,_).
% out of bounds on list
test(oob0,[fail]) :- splinter([],0,_,_,_).
test(oob1,[fail]) :- splinter([],1,_,_,_).
test(oob2,[fail]) :- splinter([a,b],2,_,_,_).
longlist([a,b,c,d,e,f,g,h]).
% generating splinters+element from list+index
test(fwd) :-
longlist(List),length(List,Len),Nmax is Len-1,
foreach(between(0,Nmax,N),fwd(List,N)).
% recomposing list+index from splinters+element
test(bwd) :-
longlist(List),length(List,Len),Nmax is Len-1,
foreach(between(0,Nmax,N),tb(List,N)).
% -- helpers --
tb(List,N) :-
splinter(List,N,Elem,Front,Back), % splinter it
bwd(Elem,Front,Back). % see whether splinter can recompose it
fwd(List,N) :-
splinter(List,N,Ew,Fw,Bw),
format("~w N=~w ==> ~w ~w ~w\n",[List,N,Fw,Ew,Bw]),
% test consist in checking the spec!
append([Fw,[Ew],Bw],List),length(Fw,N).
bwd(Elem,Front,Back) :-
splinter(Lw,Nw,Elem,Front,Back),
format("~w ~w ~w ==> ~w N=~w\n",[Front,Elem,Back,Lw,Nw]),
% test consist in checking the spec!
append([Front,[Elem],Back],Lw),length(Front,Nw).
:-end_tests(splinter).
rt :- run_tests(splinter).