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?
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].
Why not view things from a grammatical viewpoint. So what is the last element in a list?
last(X, Xs) :-
phrase( ( ..., [X] ), Xs).
... --> [] | [_], ... . % any sequence
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With