Prolog: Checking if something is the last item in the list?
dcg, list, prolog
Solution
You might want this:
last(X,[X]).
last(X,[_|Z]) :- last(X,Z).
The `|` denotes a 'tail' or 'the rest of the list.'
With `?- last(c,X).` Prolog produces lists (according to your first definition) that have c as the last item.
When you query `?- last(c,[a,b,c]).`, it returns false because you haven't defined a case for a list of only one item `[X]` or `[X|[]]`. So it fails when list is shorter than two items.
However, `last([c],[a,b,c])` succeeds because you get `[b|_29]` or whatever denoting that the tail part might be any list. So it '_29' can be '[c]', satisfying the first definition like `last([c],[b|[c]]).` Remember that a nonempty list in Prolog is actually a pair of the first list item (head) and a list of the rest (tail). Usually written as [head|tail].
Problem
I am new to prolog and am basically trying to write a clause that would evaluate as true if a given item is the last item in a given list. Here is what I have: ``` last(X,[Y|X]). last(X,[Y|Z]) :- last(X,Z). ``` I thought this would do the trick, but when I ask prolog: ``` ?- last(c,[a,b,c]). ``` Prolog returns false. I tried the following query to see what Prolog thinks should fit my definition of last: ``` ?- last(c,X). X = [_G530|c] ; X = [_G530, _G533|c] ; X = [_G530, _G533, _G536|c] ``` So, what I am not sure about is why the "|" symbol is still in the list? Update: last([c],[a,b,c]) produces the desired behavior. However, I'm not sure why my 1st argument has to be a list?