# Prolog: Take the first & ldquo; N & rdquo; Elements of a list

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
```
```

How can one take 2 elements from `Xs` to get `Ys`?
And there are 3 different answers. If `Xs` is empty, then so is `Ys`. If `Xs` is a list with one element, then so is `Ys`. If `Xs` has at least 2 elements, then those two are `Ys`.
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 `arg(-1,s(1),2)`