mmgro27
mmgro27

Reputation: 505

Generate a sublist in prolog given first element and length

Given the start position and length, I want to generate a sublist of that length. I did it below using an accumulator:

get_sublist(_,_,0,Sublist,Sublist):-!.
get_sublist(List,Position,Length,Sublist,Acc):-
    nth1(Position,List,Element),
    append([Element],Acc,Acc1),
    Position1 is Position + 1,
    Length1 is Length - 1,
    get_sublist(List,Position1,Length1,Sublist,Acc1).

Is there a shorter/faster way to do this either by using more built in predicates or using an alternative method? Thanks.

Upvotes: 1

Views: 684

Answers (2)

CapelliC
CapelliC

Reputation: 60034

if I run your code, I get

?- get_sublist([a,b,c,d,e,f,g,h,i,j,k], 3, 6, X, []).
X = [h, g, f, e, d, c].

then, a reverse/2 is missing ? In case, I would propose the good old findall/3:

get_sublist(List,Position,Length,Sublist):-
    Stop is Position+Length-1,
    findall(X, (between(Position,Stop,P),nth1(P,List,X)), Sublist).

edit bagof/3, by means of declaration of scoped variables (just P here), will avoid problems introduced by findall:

get_sublist(List,Position,Length,Sublist):-
    Stop is Position+Length-1,
    bagof(X, P^(between(Position,Stop,P),nth1(P,List,X)), Sublist).

?- get_sublist([A,B,C,D,E,F,G,H,I,J,K], 3, 6, X).
X = [C, D, E, F, G, H].

Upvotes: 0

Wouter Beek
Wouter Beek

Reputation: 3407

I would go for:

sublist(List, Offset, Length, Sublist):-
  length(Prefix, Offset),
  append(Prefix, Rest, List),
  length(Sublist, Length),
  append(Sublist, _, Rest).

Example of use:

?- sublist([a,b,c,d,e,f,g,h,i,j,k], 3, 6, X).
X = [d, e, f, g, h, i].

Notice I'm using count-by-0 for the Offset argument here.

Upvotes: 3

Related Questions