附加列表和原子的序言 [英] prolog appending a list and a atom
问题描述
我对 prolog 很陌生,我尝试了以下操作:
I'm quite new to prolog, and I tried the following:
| ?- append([1],2,R).
R = [1|2]
yes
我不知道符号是什么[1 |2]
的意思.试图搜索这个很痛苦,我找不到任何东西.我想这类似于 (cons 1 2)
导致的 lisp (1 . 2)
.有人可以解释/参考有关此的解释吗?
I have no idea what the notation [1 | 2]
means. Trying to search this was painful, and I couldn't find any thing. I guess this is something like the lisp (1 . 2)
resulted from (cons 1 2)
. Can someone explain/reference to explanations about this?
如果这对任何人都很重要,我使用的是 GNU-prolog 1.3.0 版
If it matters to anyone, I'm using GNU-prolog version 1.3.0
推荐答案
[H|T]
列表符号[H|T]
是'.'(H,T)
的语法糖,它是通过头和尾定义列表的谓词.例如,列表 [1,2,3]
也可以写成 '.'(1,'.'(2,'.'(3,[]))).
(try, X = '.'(1,'.'(2,'.'(3,[]))).
在序言提示符处).
The list notation [H|T]
is a syntactic sugar for '.'(H,T)
which is the predicate defining the list by head and tail. For example, the list [1,2,3]
could also be written '.'(1,'.'(2,'.'(3,[]))).
(try, X = '.'(1,'.'(2,'.'(3,[]))).
at the prolog prompt).
既然您似乎熟悉 Lisp,那么在这些术语中,X
是列表 [X|T]
和 car
的 car
code>T 是列表[X|T]
的cdr
.
Since you seem familiar with Lisp, then in those terms, X
is the car
of the list [X|T]
and T
is the cdr
of the list [X|T]
.
append/3
通常与列表参数一起使用,因此将原子(称为 atom
)附加到列表 L
并且结果为R
,你会这样做:
append/3
is typically used with list arguments, so to append an atom (called atom
) to a list L
and result being R
, you'd do it like this:
append(L, [atom], R).
或者更具体地说:
append([1], [2], R).
产量:R = [1,2]
.
在使用 append/3
定义 rev/2
的实现时,Clocksin &Mellish,Prolog 中的编程,第五版,第 157 页,在这种情况下:
In using append/3
to define an implementation for rev/2
, Clocksin & Mellish, Programming in Prolog, Fifth Edition, on p.157 state, in that context:
按照惯例,列表的尾部总是一个列表.
By convention, the tail of a list is always a list.
如果给你一个列表,L
,你可以通过将它与 [H|T]
统一来检索头(车)和尾(cdr)形式:
If you're given a list, L
, you can retrieve the head (car) and tail (cdr) by unifying it with the [H|T]
form:
L = [H|T]
例如:
| ?- L = [1,2,3,4], L = [H|T].
H = 1
L = [1,2,3,4]
T = [2,3,4]
yes
| ?-
您还可以根据需要制作尽可能多的元素:
You can also pull off as may elements as you wish:
| ?- L = [1,2,3,4], L = [A,B,C|T].
A = 1
B = 2
C = 3
L = [1,2,3,4]
T = [4]
yes
如果你尝试做太多,它就会失败:
It will fail if you try to do too many:
| ?- L = [1,2,3], L = [A,B,C,D|T].
no
[H|T]
形式在列表处理谓词中很方便,尤其是递归谓词:
The [H|T]
form is handy in list processing predicates, particularly recursive ones:
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]
形式,你会得到以下等价物:
If you were to write a list, say, [1,2,3]
literally in the [H|T]
form, you'd have any of the following equivalents:
[1,2,3|[]]
[1,2|[3]]
[1,2|[3|[]]]
[1|[2,3]]
[1|[2,3|[]]]
[1|[2|[3]]]
[1|[2|[3|[]]]]
当T
是一个原子时的列表形式[H|T]
The list form [H|T]
when T
is an atom
如果你有一个列表[X|T]
,表示X
是列表的头部,T
是列表的尾部(通常是一个列表本身).尽管 Prolog 允许您构造这样一个列表,其中 T
是一个原子,但它似乎并不常用,至少不像在 Lisp 中那样常用.但是,是的,[1|2]
确实就像 Lisp 中的 (1 . 2)
.Lisp 有一些内置函数,可以将 (a . b)
列表作为键值对等进行操作.Prolog 没有任何内置函数可以利用 [a|b]
我知道的结构.与仅使用 [a,b]
相比,它们可能没有更多优势.我还搜索了对 [a|b]
(或 [a1,...,an|b]
)形式的引用,并在 Clocksin & 中找到了一个.Mellish,第 53 页,参考将 [white|Q]
与 [P|horse]
统一的示例:
If you have a list [X|T]
, means X
is the head of the list, and T
is the tail (usually a list itself). Although Prolog lets you construct such a list in which T
is an atom, it doesn't seem commonly used, at least not as it is in Lisp. But, yes, [1|2]
is indeed like (1 . 2)
in Lisp. Lisp has some built-in functions which operate on lists of (a . b)
as key-value pairs, etc. Prolog doesn't have any built-ins that take advantage of the [a|b]
structure that I'm aware of. They may have no more advantage over just using [a,b]
. I also have searched for references to the [a|b]
(or [a1,...,an|b]
) form and found one in Clocksin & Mellish, p.53, in reference to an example unifying [white|Q]
with [P|horse]
:
...可以使用列表符号来创建结构类似于列表,但不以空列表终止.一这样的结构,[white|horse]
,表示具有头部的结构white
和尾巴horse
.常量 horse
既不是列表也不是空列表,和...这样的结构应该小心对待在列表尾部使用时.
...it is possible to use the list notation to create structures that resemble lists, but which do not terminate with the empty list. One such structure,
[white|horse]
, denotes a structure having headwhite
and tailhorse
. The constanthorse
is neither a list nor the empty list, and ... such structures should be treated carefully when used at the tail of a list.
有趣的是,当给定 [a1,...,an|b]
形式时,大多数处理列表的其他内置 Prolog 谓词实际上会失败.例如,在 GNU Prolog 中:
The interesting thing is that most of the other built-in Prolog predicates that process a list will actually fail when given the [a1,...,an|b]
form. For example, in GNU 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
SWI Prolog 抛出异常:
SWI Prolog throws an exception:
?- X = [1,2,3|4], length(X, L).
ERROR: length/2: Type error: `list' expected, found `4'
其他谓词也会出现类似的结果.maplist
将处理此类列表的所有元素,但会忽略尾原子.append/3
只要第一个列表的尾部没有原子就可以工作.
Similar results occur with other predicates. maplist
will work on all of the elements of such a list but will ignore the tail atom. append/3
will work as long as the first list does not have an atom as its tail.
关于原子作为列表尾部的问题是一个很好的问题.似乎 Prolog 允许它(例如,您可以统一 X=[1|2].
),并且 append/3
内置处理它(可能是无意中由于它的简单设计).I 可以用作数据的有效形式,[a1,...,an|b]
并且可以与看起来像它的形式统一.但是大多数内置插件似乎没有有意识地正确处理它.它也没有充当通用的 2 参数函子(尝试统一 X=3|4.
会失败).
The question about atom as tail in a list is a very good one. It seems Prolog allows it (you can unify X=[1|2].
for example), and the append/3
built-in handles it (perhaps inadvertently due to its simple design). I can be used as a valid form for data, [a1,...,an|b]
and can be unified with forms that look like it. But most of the built-ins don't seem to consciously handle it properly. It also isn't acting as a generic 2-argument functor (attempt to unify X=3|4.
would fail).
所以,形式 [a1,...,an|b]
(其中 b
是一个原子)是一个有效的 Prolog 数据结构,但它的行为如下必须小心处理列表,因为大多数谓词假定列表的尾部是列表,而最终"尾部是空列表,[]
.因此,如果需要,它可以合法使用,但要谨慎使用(如 C&M 所示).
So, the form [a1,...,an|b]
(where b
is an atom) is a valid Prolog data structure, but it's behavior as a list must be handled carefully since most predicates assume that the tail of a list is a list, and that the "final" tail is the empty list, []
. So it can be legitimately used if desired, but with caution (as C&M indicate).
这篇关于附加列表和原子的序言的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!