在 SWI-Prolog 中 [a|b|c] 的计算结果是什么?
prolog 中的管道运算符返回一个或多个原子头列表和一个尾列表。
?- [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.
我对任何寻找答案的技术更感兴趣,而不是回答这个边缘无用的问题。
编辑2
我显然对序言不太熟悉,一个简单的作业回答了我的问题...
?- R = [a|b|c].
R = [a| (b'|'c)].
(b'|'c)
究竟发生了什么?
The pipe operator in prolog returns one or more atomic Heads and a Tail list.
?- [a,b,c] = [a,b|[c]].
true.
Nesting multiple pipes in a single match can be done similar to this:
?- [a,b,c] = [a|[b|[c]]].
true.
What does the statement [a|b|c]
infer about a, b and c?
EDIT
So far, all I can deduce is:
?- [a,b,c] = [a|b|c].
false.
I am more interested in any techniques to find the answer rather than to answer this borderline useless question.
EDIT2
I'm clearly not too familiar with prolog, a simple assignment answered my question...
?- R = [a|b|c].
R = [a| (b'|'c)].
What exactly is going on with (b'|'c)
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
由于我是你们的讲师,所以这是我的答案。
(哦,我可以确认这不是作业,它与模拟考试有关)。
语法
[a|b|c]
实际上似乎不是标准的 Prolog,并且某些实现对它的解释不同。 (如果我知道这一点,我可能不会使用它。)有些人将其解释为
[a|[b|c]]
。 (正如我的意图。)但是对于 SWI Prolog(可能还有其他):
(b '|' c)
实际上是使用'|'
而不是构建的'.'
作为一个列表。因此,第二个|
根本不被解释为构建列表的一部分。为了确认这一点,以下内容成功:
这里的
'|'
似乎是另一个二元运算符,就像'.'
一样。Prolog 中的标准是使用
[a,b|c]
,而不是[a|b|c]
。(我只决定在编程范式中使用
[a|b|c]
,因为它与 F# 中的符号a::b::c
更直接相关,并且我们将来我只看到了 Prolog 的一小部分,我想我会与[a|[b|c]]
相关,然后给出[a,b|c]
作为缩写。)Since I'm your lecturer I, here's my answer.
(Oh, and I can confirm that this isn't homework, it's related to the practice exam).
The syntax
[a|b|c]
actually doesn't seem to be standard Prolog, and some implementations interpret it differently. (Had I known this I might not have used it.)Some interpret it as
[a|[b|c]]
. (As I intended.)But with SWI Prolog (and probably others):
The
(b '|' c)
is actually constructed using'|'
rather than'.'
as a list would be. So, the the second|
is not interpreted as being part of constructing a list at all.To confirm this, the following succeeds:
The
'|'
here seems to be a another binary operator on terms just like'.'
.Instead of
[a|b|c]
the standard in Prolog is to use[a,b|c]
.(I only decided to use
[a|b|c]
in Programming Paradigms because it more directly relates to the notationa::b::c
from F#, and we only saw a tiny glimpse of Prolog. In future I guess I'll relate to[a|[b|c]]
and then give[a,b|c]
as an abbreviation.)在 ISO-Prolog 中,
[a|b|c]
是无效语法。同时也在 SWI 内部。看来您使用的是旧版本。一些 Prolog 系统给了这个术语一些解释。唉,他们对这个术语的解释方式都非常精确。有些为[(a'|'b)|c]
或[a|(b'|'c)]
或[a|(b;c) )]
...好吧,你明白了。与此相关的是使用条作为中缀运算符
('|')/2
。包含 ISO/IEC 13211-1:1995/Cor.2:2012,技术勘误 2,2012 年 2 月发布-15 现在可以精确定义使用 bar
|
作为中缀运算符。在此之前,|
必须被引用。这里是其草案。现在,
'|'
可以定义为中缀运算符,但优先级必须高于 1000。通过这种方式,[a|b|c]
等不明确的情况在语法上仍然存在无效,但对 DCG 和 CHR 使用|
是有效的。如果您想通过尝试来学习语法,最好是使用
writeq/1
和write_canonical/1
。最符合 ISO-Prolog 语法的系统是 GNU Prolog。
Within ISO-Prolog,
[a|b|c]
is invalid syntax. And in the meantime also within SWI. It seems you used an older version. Some Prolog systems gave this term some interpretation. Alas, they all differed in the very precise way how they interpreted that term. Some as[(a'|'b)|c]
or[a|(b'|'c)]
or[a|(b;c)]
... well, you get it.Related to this is the use of the bar as an infix operator
('|')/2
.With ISO/IEC 13211-1:1995/Cor.2:2012, Technical Corrigendum 2, published 2012-02-15 the use of bar
|
as infix operator is now precisely defined. Prior to it,|
had to be quoted. Here is its draft.Now,
'|'
can be defined as an infix operator but only with a priority above 1000. In this manner otherwise ambiguous cases as[a|b|c]
remain syntactically invalid, but uses of|
for DCGs and CHR are valid.If you want to learn syntax by trying it out, the best is to use
writeq/1
andwrite_canonical/1
.The most conforming system w.r.t ISO-Prolog syntax is GNU Prolog.
它不是一个声明,而是一个术语,并且它根本不暗示任何有关
a
、b
或c
的内容。它只是构建了一个不正确的列表。详细说明:
[|]
语法实际上是.()
运算符的语法糖。列表是通过'.'(a,[])
内部构造的,但由于立即输入变得非常乏味,因此您可以改为编写[a]
。因此.
运算符应该采用一个事物和一个列表,然后构造一个更长的列表,但由于没有打字,没有人阻止您将其应用于两个原子或任何其他事物对。结果是一个结构,其中一些列表操作成功,而另一些则失败。这有时很有用(想想二叉树),但不像列表那么常见,因此没有特殊的读取语法。(Lisp 中的
cons
运算符也发生了同样的情况;如果你用 google 搜索“improper list”,你可能会得到更多关于 Lisp 的结果,但原理是完全相同的。)It isn't a statement, it's a term, and it doesn't imply anything at all about
a
,b
orc
. It just constructs an improper list.To elaborate: The
[|]
syntax is actually syntactic sugar for the.()
operator. Lists are internally constructed via'.'(a,[])
, but since that becomes extremely tedious to type right away, you are allowed to write[a]
instead. So the.
operator is supposed to take a thing and a list and then contructs a longer list, but since there is no typing, nobody prevents you from applying it to two atoms, or any other pair of things. The result is a structure on which some list operations succeed and others fail. This is sometimes useful (think binary trees), but not as common as lists, therefore there is no special read syntax for it.(Much the same happens with the
cons
operator in Lisp; if you google "improper list" you are liable to get many more results about Lisp, but the principle is exactly the same.)