在Prolog中获取列表的第二个元素

时间:2014-05-03 16:17:11

标签: prolog

在执行此任务时遇到一些麻烦。

目前我已经尝试了这个,我知道这是错误的,因为我不确定如何将L分为头部和尾部,但这是我想要的那种想法。

second(L,E) :- [H | E | T]

我认为E必须在头部之后才能成为第二个元素。不过我是这门语言的新手,想要一些见解。如何从谓词的编写方式中获得这个头和尾。对此问题的一些见解将非常感激。谢谢。

2 个答案:

答案 0 :(得分:7)

您可以将统一转移到条款的开头,只需写下:

second([_, Second| _], Second).

列表的表示法是用逗号分隔初始元素,然后用垂直条分隔列表尾部,即包含其余元素的列表。您可以在Prolog顶级解释器上尝试的一些示例应该更清楚:

?- [1, 2, 3] = [Head| Tail].
Head = 1,
Tail = [2, 3].

?- [1, 2, 3] = [First, Second| Tail].
First = 1,
Second = 2,
Tail = [3].

?- [1, 2, 3] = [First, Second, Third| Tail].
First = 1,
Second = 2,
Third = 3,
Tail = [].

答案 1 :(得分:2)

[详细模式开]

Prolog中的列表是空列表[] head tail ,技术上由Prolog中的“点”仿函数'.'(H,T),但Prolog提供了语法上更友好的表示,[H|T] head H是一个元素, tail T本身就是一个列表。如果你看一下LISP,它们分别是列表的 car cdr 。在Prolog中,垂直条| head tail 分开。

在Prolog提示符下,您可以输入X = '.'(H,T).并查看获得的内容:

| ?- X ='.'(H,T).

X = [H|T]

yes
| ?-

如果您有一个元素的列表,那么它将是[X],但技术上是[X|[]]'.'(X,[])。如果你有两个元素的列表,可以写成:

[X,Y]
[X|[Y]]
'.'(X,[Y])
[X|'.'(Y,[])]
'.'(X,'.'(Y,[]))

所有这些形式都有效,但最常见的形式是[X,Y],或者,如果您需要头/尾表示,则根据上下文[X|[Y]]。你很少需要使用点符号。

在语法友好(非点)形式中,非空列表可以由一个或多个离散的 head 元素表示,其后可选地由尾部表示(尾部在后面指定)垂直条|),它本身可以是列表或空列表[]。许多元素的列表E1E2,...,En可以用多种方式编写,概括了上述想法:

[E1,E2,...,En]
[E1|T]                   % T = [E2,E3,...,En]
[E1,E2|T]                % T = [E3,E4,...,En]
[E1,...,Ek|T]            % T = [Ek+1,Ek+2,...,En]
[E1|[E2|T]]              % T = [E3,E4,...,En]
[E1|[E2|...[Ek|T]]...]]  % T = [Ek+1,Ek+2,...,En]

因此,两个竖线(|)在[X|Y|T]形式中没有意义,但它们的形式为[X|[Y|T]]。由于尾部T本身就是一个列表(或[]),它遵循与原始列表相同的表示规则。因此,列表本质上是一种适合递归的结构。 Prolog中的许多谓词在列表上运行,通过在头上操作,然后在尾部调用自身,并在看到空列表[]时结束时递归执行。

如果我统一了两个列表L1 = L2,并且我希望它成功,那么(1)列表需要具有相同的长度,并且(2)L1中的每个元素必须是与L2中的相应元素一致。所以,如果我在Prolog提示符处这样做:

| ?- [X,2,Z] = [1,Y,3].

X = 1
Y = 2
Z = 3

yes
| ?-

我与变量显示的值成功统一。我也可以这样做:

| ?- [X|T] = [1,2,3,4].

T = [2,3,4]
X = 1

yes
| ?-

如果使用X实例化1并且使用T实例化尾[2,3],则Prolog可以统一这两个列表。我也可以这样做:

| ?- [X,Y|T] = [1,2,3,4].

T = [3,4]
X = 1
Y = 2

yes
| ?-

正如Paolo所指出的那样,这显示了你如何得到第二个元素。你也可以这样做:

| ?- [X|[Y|T]] = [1,2,3,4].

T = [3,4]
X = 1
Y = 2

yes
| ?-

它实际上意味着同样的事情,只是用不同的语法看:第二个元素是列表尾部的头部(或者,在LISP中,“ car CDR “)。