Prolog 附加列表和原子的序言

Prolog 附加列表和原子的序言,prolog,Prolog,我对prolog非常陌生,我尝试了以下方法: | ?- append([1],2,R). R = [1|2] yes 我不知道符号[1 | 2]是什么意思。试着搜索这个很痛苦,我什么也找不到。我猜这类似于由(cons12)产生的lisp(1.2)。有人能解释/参考关于这方面的解释吗 如果这对任何人都很重要的话,我正在使用GNU prolog 1.3.0版这是[H | T]的“通用”形式 列表表示法[H | T]是'(H,T)的语法糖,它是通过头和尾定义列表的谓词。例如,列表[1,2,3]也

我对prolog非常陌生,我尝试了以下方法:

| ?- append([1],2,R).

R = [1|2]

yes
我不知道符号
[1 | 2]
是什么意思。试着搜索这个很痛苦,我什么也找不到。我猜这类似于由
(cons12)
产生的lisp
(1.2)
。有人能解释/参考关于这方面的解释吗

如果这对任何人都很重要的话,我正在使用GNU prolog 1.3.0版

这是
[H | T]
的“通用”形式

列表表示法
[H | T]
'(H,T)
的语法糖,它是通过头和尾定义列表的谓词。例如,列表
[1,2,3]
也可以写为
'(1'。(2'。(3,[])。
(在prolog提示符下尝试,
X='。(1'。(2'。(3,[])。

既然您似乎熟悉Lisp,那么在这些术语中,
X
是列表
[X|T]
car
T
是列表
[X|T]
cdr

append/3
通常与列表参数一起使用,因此要将一个原子(称为
atom
)追加到列表
L
,结果是
R
,您可以这样做:

append(L, [atom], R).
或者更具体地说:

append([1], [2], R).
收益率:
R=[1,2]

在使用
append/3
定义
rev/2
的实现时,Clocksin&Mellish,Prolog编程,第五版,第157页状态,在该上下文中:

按照惯例,列表的尾部始终是一个列表

如果给您一个列表,
L
,您可以通过将其与
[H | T]
表单统一来检索头部(汽车)和尾部(cdr):

L = [H|T]
例如:

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

H = 1
L = [1,2,3,4]
T = [2,3,4]

yes
| ?-
您也可以随心所欲地完成以下任务:

| ?- L = [1,2,3,4], L = [A,B,C|T].

A = 1
B = 2
C = 3
L = [1,2,3,4]
T = [4]

yes
如果您尝试执行太多操作,则会失败:

| ?- L = [1,2,3], L = [A,B,C,D|T].

no
[H | T]
表单在列表处理谓词方面非常方便,尤其是递归谓词:

my_list_process_predicate([H|T], [Result|Results]) :-
    % Do some stuff here, determing "Result" from "H" perhaps
    my_list_processing_predicate(T, Results).  % Get the rest of the results
                                               % from the rest of the list
如果您要以
[H | T]
格式编写一个列表,比如说,
[1,2,3]
,您可以使用以下任何等价项:

[1,2,3|[]]
[1,2|[3]]
[1,2|[3|[]]]
[1|[2,3]]
[1|[2,3|[]]]
[1|[2|[3]]]
[1|[2|[3|[]]]]
T
是一个原子时,列表形式
[H|T]

如果您有一个列表
[X | T]
,则表示
X
是列表的头部,而
T
是尾部(通常是列表本身)。虽然Prolog允许您构造这样一个列表,其中
T
是一个原子,但它似乎并不常用,至少不像Lisp中那样。但是,是的,
[1 | 2]
确实像Lisp中的
(1.2)
。Lisp有一些内置函数,可以在
(a.b)
列表上作为键值对等进行操作。Prolog没有任何内置函数可以利用我所知道的
[a | b]
结构。与仅使用
[a,b]
相比,它们可能没有更多的优势。我还搜索了对
[a | b]
(或
[a1,…,a | b]
)表单的引用,并在Clocksin&Mellish,第53页中找到了一个,引用了一个将
[white | Q]
[p | horse]
统一的示例:

…可以使用列表表示法创建 类似于列表,但不会以空列表结尾。一个 这种结构,
[white | horse]
,表示具有头部的结构
白色
和尾巴
。常量
horse
既不是列表也不是 空列表,以及。。。此类结构应仔细处理 在列表末尾使用时

有趣的是,当给定
[a1,…,a | b]
表单时,处理列表的大多数其他内置Prolog谓词实际上都会失败。例如,在GNU序言中:

| ?- X = [1,2,3|4], length(X, L).

no
| ?- X = [1,2,3,4], length(X, L).

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

yes
SWI Prolog引发异常:

?- X = [1,2,3|4], length(X, L).
ERROR: length/2: Type error: `list' expected, found `4'
其他谓词也会出现类似的结果
maplist
将处理此类列表的所有元素,但将忽略尾部原子<只要第一个列表的尾部没有原子,code>append/3就可以工作

关于原子作为列表中的尾巴的问题是一个很好的问题。Prolog似乎允许它(例如,您可以统一
X=[1 | 2]。
),而
append/3
内置处理它(可能是由于其简单的设计而无意中)。我可以用作数据的有效表单,
[a1,…,an | b]
,并且可以与类似的表单统一。但大多数内置软件似乎并没有有意识地正确处理它。它也不是一般的2参数函子(试图统一
X=3 | 4.
将失败)

因此,形式
[a1,…,an | b]
(其中
b
是一个原子)是一个有效的Prolog数据结构,但它作为列表的行为必须小心处理,因为大多数谓词都假设列表的尾部是一个列表,“最终”尾部是空列表,
[
。因此,如果需要,它可以合法使用,但要谨慎(正如C&M所指出的)