作为一个好奇的家伙,我发现了以下陈述 哪些滥用特殊字符在语法上是正确的:
X=(a,a).
X=(a;a).
X=(a|a).
X=a:a.
X=a?a.
(正如你所看到的,最后两个人甚至不需要括号。奖励怪人指向左边和:|,;
是正确联想的。通过绑定力量对它们进行排序的超级奖励。)<登记/>
它们不是像[a|a]
那样的对。它们不是a_a
之类的原子。它们不是变量。它们不是像a=a
那样的布尔值。它们不是a+a
之类的术语(或者至少我不能将它们插入有意义的计算中)。
我创造了什么怪物?
答案 0 :(得分:4)
您对这些字词的一些说法是 true ,但以下是 false :
它们不是
a+a
之类的术语(或者至少我不能将它们插入有意义的计算中)。
这两个陈述都是 false :
首先,这些是,就像a+a
一个术语一样。在您展示的所有情况下,您使用的是中缀运算符,就像在a+a
中一样。
如果您不确定自己实际写下了什么,请使用write_canonical/1
获取任何Prolog术语的规范表示。
例如:
?- write_canonical(a+a). +(a,a)
啊哈!因此,a+a
是一个带有仿函数+
和两个参数的术语。
另一个例子:
?- write_canonical((a,a)). ','(a,a)
您的一个示例包含此术语作为子项:
?- write_canonical(X=(a,a)). =(_,','(a,a))
从您的示例中,不清楚您是否实际上发布这些术语作为Prolog 目标,或者将它们用作Prolog 事实。无论如何:在任何情况下,这些都只是像Prolog中出现的任何其他术语一样:它们有一个仿函数和一些参数。
有关详细信息,请参阅current_op/3
。例如:
?- current_op(P, T, :). P = 600, T = xfy.
我想知道600
和xfy
在这种情况下的含义是什么。每个Prolog系统都附带了许多预定义运算符。如果不是这种情况,那么我们必须在前缀表示法中编写所有术语(这会使Prolog代码像Lisp一样难以理解,我们也可能会不断地告诉自己这是一个好的事情,好像在许多情况下,中缀语法不再具有可读性)。
关于你的其他陈述:
它们不是
之类的对[a|a]
首先:
| ?- write_canonical([a|a]). '.'(a,a)
所以[a|a]
是一个带有仿函数.
和两个参数的术语。它不是 列表,因为a
(第二个参数)不是列表。但是,按照惯例,仿函数-
通常用于表示Prolog中的对,因此在这种情况下,我们宁愿将一对写为a-a
。
他们不是
之类的术语a=a
之类的布尔。它们不是a+a
再次,请参阅:
?- write_canonical(a=a). =(a,a)
在这里,您已经很自然地使用了“ crazy ”语法。它与您提供的所有示例中的相同概念:(=)/2
和(+)/2
是Prolog中的中缀运算符,因此您可以使用中缀表示法表示您必须分别以=(a,a)
和+(a,a)
撰写的条款。
当然,您可以在任何有意义的计算中使用所有这些术语,就像任何其他术语一样。
定义自定义运算符的能力是Prolog在某些应用程序中的主要吸引力,并且允许您在某些情况下编写适合您的问题域的Prolog代码。几个Prolog库还导出自定义运算符,这些运算符以一种自然适合该语言的方式扩展具有更多声明性功能的普通Prolog。像CLP(FD)这样的约束求解器就是一个很好的例子,特别是导出运算符(#=)/2
,(#<)/2
等等,这样你就可以简单地写X #= Y
来表示术语{{1} }。