Reputation: 31
Given a list e.g [a,b,c] and an index I, I wanted to find the prefix of this list until that index. e.g [a,b,c] and index 1, should return [a,b], if index = 2, should return [a]. The index always has this formula (length-i). I have tried this:
prefix_by_index(List, I, Result):-
prefix(List, T),
length(Result, I),
Result = T.
Upvotes: 2
Views: 131
Reputation: 1813
This should do it:
prefix_by_index(N, List, Result) :-
length(List, Len),
N1 is Len-N,
extract_header(N1, List, Result).
extract_header(0, _, []).
extract_header(N, [H|T1], [H|T2]) :- N > 0,
N1 is N-1,
extract_header(N1, T1, T2).
extract_header(A1, A2, A3) returns A3=the first A1 elements of list A2.
?- prefix_by_index(1, [a,b,c], L).
L = [a, b] .
?- prefix_by_index(2, [a,b,c], L).
L = [a] .
A more complete version test the case where A1 > length of A2. Exercise for you.
Upvotes: 1
Reputation: 2436
Your attempt is almost correct. You need to put length/2 first, then prefix/2. You have also not shown your definition of prefix/2, but it can be defined in terms of append/3 like this:
prefix(List, Prefix) :- append(Prefix, _, List).
Assuming this definition, to take a prefix of length 2, you can do:
?- List = [a,b,c,d], length(Prefix, 2), prefix(List, Prefix).
List = [a, b, c, d],
Prefix = [a, b].
The way you have written your question, I don't understand how the index is supposed to work.
Upvotes: 3
Reputation: 878
1- prefix_by_index
predicate will take the Index I, the List [a,b,c], and will give the final output in Prefix.
2- length
predicate will calculate the length of the list and then subtract it with I as you have stated "The index always has this formula (length-i)". This value I1 is passed onto the p predicate that will act as a counter.
3- In the p
predicate [H|T]=[a,b,c], C=I1, and [H|Prefix]
will give us a list that will be our final output. C keeps decreasing and H at each iteration (a then b then c) is pushed into the [H|Prefix] list till the base case succeeds i.e. p(_,0,[])
, C becomes zero
.
prefix_by_index(I,List,Prefix):-
length(List,Len),
I1 is Len-I,
p(List,I1,Prefix).
p(_,0,[]):-!.
p([H|T],C,[H|Prefix]):-
C1 is C-1,
p(T,C1,Prefix).
Example:
?- prefix_by_index(1,[a,b,c],Prefix).
Prefix = [a, b]
?-prefix_by_index(2,[a,b,c],Prefix).
Prefix = [a]
?-prefix_by_index(3,[a,b,c],Prefix).
Prefix = []
Upvotes: -1