prolog附加一个列表和一个原子

时间:2014-03-16 19:12:52

标签: prolog

我对prolog很新,我尝试了以下内容:

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

R = [1|2]

yes

我不知道符号[1 | 2]的含义。试图搜索这是痛苦的,我找不到任何东西。我想这类似于(1 . 2)产生的lisp (cons 1 2)。有人可以解释/参考有关此问题的解释吗?

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

1 个答案:

答案 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所示)。