Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prolog: Checking if something is the last item in the list?

Tags:

list

prolog

dcg

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?

like image 672
user3295806 Avatar asked Dec 01 '22 02:12

user3295806


2 Answers

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].

like image 169
traitor Avatar answered Mar 08 '23 12:03

traitor


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
like image 39
false Avatar answered Mar 08 '23 12:03

false