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

在Prolog中获取列表的第二个元素,prolog,Prolog,在这项任务中遇到了一些麻烦 目前我已经试过了,我知道这是错误的,因为我不知道如何把L分成它的头和尾,但这是我想要的想法 second(L,E) :- [H | E | T] 我认为E必须在头部之后,这将使它成为第二个元素。不过,我对这门语言还不熟悉,希望有一些见解。我如何从谓词的编写方式中得到这个头尾。如果您能对这个问题有所了解,我们将不胜感激。多谢各位 您可以将unification移到子句的开头,只需写下: second([_, Second| _], Second). 列表的表示法是写

在这项任务中遇到了一些麻烦

目前我已经试过了,我知道这是错误的,因为我不知道如何把L分成它的头和尾,但这是我想要的想法

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

我认为E必须在头部之后,这将使它成为第二个元素。不过,我对这门语言还不熟悉,希望有一些见解。我如何从谓词的编写方式中得到这个头尾。如果您能对这个问题有所了解,我们将不胜感激。多谢各位

您可以将unification移到子句的开头,只需写下:

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

您可以将unification移到子句的开头,只需写下:

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 = [].
[详细模式打开]

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

在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]]
。很少需要使用点符号

在语法友好(非点)形式中,非空列表可以由一个或多个离散的头元素表示,后面可选地跟一个尾部(尾部在垂直条之后指定,
|
),其本身可以是列表或空列表
[]
。许多元素的列表,
E1
E2
,…,
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,Y|T] = [1,2,3,4].

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

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

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

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

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

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

yes
| ?-
正如保罗所指出的,这显示了你如何获得第二个元素。您也可以这样做:

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

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

yes
| ?-
它实际上意味着同样的事情,只是用不同的语法来看:第二个元素是列表尾部的头(或者,在LISP中是“cdr的汽车”)。

[verbose mode ON]

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

在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]]
。很少需要使用点符号

在语法友好(非点)形式中,非空列表可以由一个或多个离散的头元素表示,后面可选地跟一个尾部(尾部在垂直条之后指定,
|
),其本身可以是列表或空列表
[]
。许多元素的列表,
E1
E2
,…,
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中的许多谓词操作o