我对prolog很新,我尝试了以下内容:
| ?- append([1],2,R).
R = [1|2]
yes
我不知道符号[1 | 2]
的含义。试图搜索这是痛苦的,我找不到任何东西。我想这类似于(1 . 2)
产生的lisp (cons 1 2)
。有人可以解释/参考有关此问题的解释吗?
如果对任何人都很重要,我正在使用GNU-prolog版本1.3.0
答案 0 :(得分:3)
[H|T]
列表符号[H|T]
是'.'(H,T)
的语法糖,它是按头部和尾部定义列表的谓词。例如,列表[1,2,3]
也可以写成'.'(1,'.'(2,'.'(3,[]))).
(在prolog提示符下尝试X = '.'(1,'.'(2,'.'(3,[]))).
)。
由于您似乎熟悉Lisp,因此在这些术语中,X
是列表car
的{{1}}而[X|T]
是T
的{{1}}列出cdr
。
[X|T]
通常与列表参数一起使用,因此要将一个原子(称为append/3
)附加到列表atom
并将结果添加到L
,您就可以执行此操作像这样:
R
或更具体地说:
append(L, [atom], R).
收益率:append([1], [2], R).
。
使用R = [1,2]
定义append/3
的实现,Clocksin& Mellish,在Prolog中编程,第五版,第157页,在该背景下:
按照惯例,列表的尾部始终是列表。
如果您获得了一个列表rev/2
,则可以通过将其与L
表单统一来检索头部(汽车)和尾部(cdr):
[H|T]
例如:
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
形式写一个列表,比如[1,2,3]
,那么您将拥有以下任何等价物:
[H|T]
[1,2,3|[]]
[1,2|[3]]
[1,2|[3|[]]]
[1|[2,3]]
[1|[2,3|[]]]
[1|[2|[3]]]
[1|[2|[3|[]]]]
为原子时的列表表单[H|T]
如果您有列表T
,则表示[X|T]
是列表的头部,X
是尾部(通常是列表本身)。虽然Prolog允许你构造一个T
是一个原子的列表,但它似乎并不常用,至少不像Lisp那样。但是,是的,T
确实类似于Lisp中的[1|2]
。 Lisp有一些内置函数,它们在(1 . 2)
列表上作为键值对等运行.Prolog没有任何内置函数可以利用我所知道的(a . b)
结构的。他们可能没有比使用[a|b]
更有优势了。我也搜索过[a,b]
(或[a|b]
)表单的引用,并在Clocksin& Mellish,第53页,参考将[a1,...,an|b]
与[white|Q]
统一起来的示例:
...可以使用列表表示法来创建结构 类似于列表,但不以空列表终止。一 这种结构
[P|horse]
表示具有头部的结构[white|horse]
和尾white
。常量horse
既不是列表也不是 空列表,......这样的结构应该小心对待 当在列表的尾部使用时。
有趣的是,大多数其他内置Prolog谓词在处理列表时实际上会在给出horse
形式时失败。例如,在GNU Prolog中:
[a1,...,an|b]
SWI Prolog抛出异常:
| ?- 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
其他谓词也会出现类似的结果。 ?- X = [1,2,3|4], length(X, L).
ERROR: length/2: Type error: `list' expected, found `4'
将处理此类列表的所有元素,但会忽略尾部原子。只要第一个列表没有原子作为其尾部,maplist
就会起作用。
列表中关于原子作为尾部的问题非常好。似乎Prolog允许它(你可以统一append/3
),而X=[1|2].
内置处理它(可能是由于其简单的设计而无意中)。我可以用作数据的有效表单append/3
,并且可以与看起来像它的表单统一。但是大多数内置插件似乎没有有意识地正确处理它。它也不是一个通用的2参数函子(尝试统一[a1,...,an|b]
会失败)。
因此,形式X=3|4.
(其中[a1,...,an|b]
是一个原子)是一个有效的Prolog数据结构,但它作为列表的行为必须小心处理,因为大多数谓词假定列表的尾部是一个列表,“最终”尾部是空列表b
。因此,如果需要,它可以合法使用,但要谨慎(如C& M所示)。