Bratko exercise 4.3 - define nth_member(N, L, M)
where M
is the N
th element in the list L
.
Assuming numbering is 1-based, not 0-based, my solution (which was identical to the author’s) was:
nth_member(1, [M|_], M).
nth_member(N, [_|T], M) :-
N1 #= N - 1,
nth_member(N1, T, M).
This works fine, but gives a choicepoint. I think I understand why (argument indexing can’t distinguish between the first argument as they are both integers), but can’t see a way to rewrite it so that it doesn’t give a choicepoint.
The usual (in my limited experience so far) was of avoiding choicepoints is to rewrite the predicate so that the first argument is a list that gets whittled away during recursion, leaving you with two clauses, one whose first argument is an empty list, and one whose first argument is a non-empty list.
However, I can’t see how to apply that idea here. It doesn’t seem to make sense to look for the 0th (or any) element of an empty list, so I’m not sure how you’d write the first clause.
I tried reordering the arguments, so it had a list first, but it didn’t help, as I still couldn’t manage to get an empty list in the first clause.
Anyone able to advise? Thanks