Did you know ... Search Documentation:
Title for wiki('Annotation--annotation')
0 upvotes 0 0 downvotes
Picture of user LogicalCaptain.

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).