本文介绍了附加列表和原子的序言的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 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]carcarcode>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:

按照惯例,列表的尾部总是一个列表.

如果给你一个列表,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 既不是列表也不是空列表,和...这样的结构应该小心对待在列表尾部使用时.

有趣的是,当给定 [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).

这篇关于附加列表和原子的序言的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-10 23:49