在执行此任务时遇到一些麻烦。
目前我已经尝试了这个,我知道这是错误的,因为我不确定如何将L分为头部和尾部,但这是我想要的那种想法。
second(L,E) :- [H | E | T]
我认为E必须在头部之后才能成为第二个元素。不过我是这门语言的新手,想要一些见解。如何从谓词的编写方式中获得这个头和尾。对此问题的一些见解将非常感激。谢谢。
答案 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 元素表示,其后可选地由尾部表示(尾部在后面指定)垂直条|
),它本身可以是列表或空列表[]
。许多元素的列表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
实例化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 “)。