I need to write a Prolog predicate
take(L, N, L1) which succeeds if list
L1 contains the first
N elements of list
L, in the same order. For example:
?- take([5,1,2,7], 3, L1). L1 = [5,1,2] ?- take([5,1,2,7], 10, L1). L1 = [5,1,2,7]
Prolog thus far is making little sense to me, and I'm having a hard time breaking it down. Here is what I have so far:
take([H|T], 0, ). take([H|T], N, L1) :- take(T, X, L2), X is N-1.
Can you please explain what I did wrong here?
Here is a definition that implements the relational counterpart to
take in functional languages like Haskell1. First, the argument order should be different which facilitates partial application. There is a cut, but only after the error checking built-in
(=<)/2 which produces an
instantiation_error should the argument contain a variable.
take(N, _, Xs) :- N =< 0, !, N =:= 0, Xs = . take(_, , ). take(N, [X|Xs], [X|Ys]) :- M is N-1, take(M, Xs, Ys). | ?- take(2, Xs, Ys). Xs = , Ys =  ? ; Xs = [_A], Ys = [_A] ? ; Xs = [_A,_B|_C], Ys = [_A,_B] ? ; no
Note how above query reads:
How can one take 2 elements from
And there are 3 different answers. If
Xs is empty, then so is
Xs is a list with one element, then so is
Xs has at least 2 elements, then those two are
1) The only difference being that
take(-1, Xs,Ys) fails (for all
Xs, Ys). Probably the best would be to issue a
domain_error similar to