9

prolog 中的管道运算符返回一个或多个原子 Heads 和一个 Tail 列表。

?- [a,b,c] = [a,b|[c]].
true.

在单个匹配中嵌套多个管道可以类似于以下方式完成:

?- [a,b,c] = [a|[b|[c]]].
true.

该陈述[a|b|c]对 a、b 和 c 的推断是什么?

编辑

到目前为止,我能推断的只有:

?- [a,b,c] = [a|b|c].
false.

我对找到答案的任何技术更感兴趣,而不是回答这个边缘无用的问题。

EDIT2
我显然对序言不太熟悉,一个简单的任务回答了我的问题......

?- R = [a|b|c].
R = [a| (b'|'c)].

到底是怎么回事(b'|'c)

4

3 回答 3

10

因为我是你的讲师,所以这是我的答案。
(哦,我可以确认这不是作业,它与练习考试有关)。

语法[a|b|c]实际上似乎不是标准的 Prolog,并且一些实现对它的解释不同。(如果我知道这一点,我可能不会使用它。)

有人将其解释为[a|[b|c]]. (如我所愿。)

但是对于 SWI Prolog(可能还有其他):

?- [a|b|c] = [a|[b|c]].
false.

(b '|' c)实际上是使用'|'而不是'.'作为列表构建的。因此,第二个|根本不被解释为构建列表的一部分。

为了确认这一点,以下成功:

   ?- X=(b|c), [a|b|c] = [a|X]。
   X = (b'|'c) 。

这里'|'似乎是另一个二元运算符,就像'.'.

Prolog中[a|b|c]的标准是使用[a,b|c].

(我只决定[a|b|c]在 Programming Paradigms 中使用,因为它更直接地与a::b::cF# 中的符号相关,而我们只看到了 Prolog 的一小部分。我想将来我会联系到[a|[b|c]]然后[a,b|c]作为缩写给出。)

于 2010-06-04T03:24:11.880 回答
5

它不是一个陈述,它是一个术语,它根本不暗示任何关于a,b或的东西c。它只是构建了一个不正确的列表。

详细说明:[|]语法实际上是.()运算符的语法糖。列表是通过 内部构造的'.'(a,[]),但是由于马上键入变得非常乏味,因此您可以改为编写[a]。所以.操作符应该获取一个事物和一个列表,然后构造一个更长的列表,但由于没有打字,没有人阻止你将它应用于两个原子或任何其他对事物。结果是一些列表操作成功而其他失败的结构。这有时很有用(想想二叉树),但不像列表那样常见,因此没有特殊的读取语法。

(Lisp 中的操作符也有同样的情况cons;如果你用谷歌搜索“不正确的列表”,你可能会得到更多关于 Lisp 的结果,但原理是完全相同的。)

于 2010-06-03T15:14:40.733 回答
5

在 ISO-Prolog 中,[a|b|c]语法无效。同时也在 SWI 内部。看来您使用的是旧版本。一些 Prolog 系统对这个术语做了一些解释。唉,他们在解释这个词的方式上都存在差异。一些作为[(a'|'b)|c][a|(b'|'c)][a|(b;c)]......好吧,你明白了。

与此相关的是使用 bar 作为中缀运算符('|')/2

借助ISO/IEC 13211-1:1995/Cor.2:2012技术勘误 2,于 2012-02-15 出版,|现在精确定义了使用 bar 作为中缀运算符。在此之前,|必须引用。这是它的草稿

现在,'|'可以将其定义为中缀运算符,但仅具有高于 1000 的优先级。以这种方式,否则歧义的情况[a|b|c]在语法上仍然无效,但|DCG 和 CHR 的使用是有效的。

如果您想通过尝试来学习语法,最好使用writeq/1and write_canonical/1

最符合 ISO-Prolog 语法的系统是 GNU Prolog。

于 2013-01-31T13:23:53.817 回答