Nuno Andrade
Nuno Andrade

Reputation: 31

Prolog Prefix with index

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

Answers (3)

peter.cyc
peter.cyc

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

TA_intern
TA_intern

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

Reema Q Khan
Reema Q Khan

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

Related Questions