Prolog:检查某些内容是否是列表中的最后一项?

use*_*806 3 list prolog dcg

我是prolog的新手,我基本上试图写一个如果给定项目是给定列表中的最后一项,则评估为真的子句.这是我有的:

last(X,[Y|X]).
last(X,[Y|Z]) :- last(X,Z).
Run Code Online (Sandbox Code Playgroud)

我认为这可以解决问题,但是当我问prolog时:

?- last(c,[a,b,c]).
Run Code Online (Sandbox Code Playgroud)

Prolog返回false.我尝试了以下查询,看看Prolog认为应该适合我对last的定义:

?- last(c,X).
X = [_G530|c] ;
X = [_G530, _G533|c] ;
X = [_G530, _G533, _G536|c]
Run Code Online (Sandbox Code Playgroud)

那么,我不确定的是为什么"|" 符号仍然在列表中?

更新:last([c],[a,b,c])产生所需的行为.但是,我不确定为什么我的第一个论点必须是一个列表?

tra*_*tor 7

你可能想要这个:

 last(X,[X]).
 last(X,[_|Z]) :- last(X,Z).
Run Code Online (Sandbox Code Playgroud)

|表示一个"尾巴"或"列表的其余部分."

使用?- last(c,X).Prolog生成列表(根据您的第一个定义),将c作为最后一项.

查询时?- last(c,[a,b,c]).,它返回false,因为您没有为只有一个项目的列表定义案例[X][X|[]].因此,当列表短于两个项目时,它会失败.

但是,last([c],[a,b,c])成功是因为你得到[b|_29]或表示尾部可能是任何列表的任何东西.所以'_29'可以是'[c]',满足第一个定义,比如last([c],[b|[c]]).记住,Prolog中的非空列表实际上是第一个列表项(头部)和其余部分(尾部)的列表.通常写为[head | tail].

  • 最好避免单身:`last(X,[_ | Z]): - last(X,Z).` (4认同)