Syntax 疯狂的Prolog语法

Syntax 疯狂的Prolog语法,syntax,prolog,Syntax,Prolog,作为一个好奇的人,我发现以下陈述 哪些特殊字符语法正确: X=(a,a). X=(a;a). X=(a|a). X=a:a. X=a?a. (如您所见,后两个甚至不需要括号。左键和右键关联会获得额外的古怪分数。:|,。通过绑定强度对它们进行排序会获得额外的奖励。) 它们不像[a | a]那样成对。它们不像a\u a那样是原子。它们不是变量。他们不是像a=a那样的布尔人。它们不像a+a(或者至少我不能将它们插入有意义的

作为一个好奇的人,我发现以下陈述 哪些特殊字符语法正确:

X=(a,a).             
X=(a;a).             
X=(a|a).
X=a:a.             
X=a?a.
(如您所见,后两个甚至不需要括号。左键和右键关联会获得额外的古怪分数。:|,。通过绑定强度对它们进行排序会获得额外的奖励。)
它们不像
[a | a]
那样成对。它们不像
a\u a
那样是原子。它们不是变量。他们不是像
a=a
那样的布尔人。它们不像
a+a
(或者至少我不能将它们插入有意义的计算中)。

我创造了什么怪物

您对这些术语所说的一些话是正确的,但以下是错误的:

它们不像
a+a
(或者至少我不能将它们插入有意义的计算中)

这两种说法都是错误的:

首先,这些是术语,就像
a+a
也是术语一样。在您显示的所有情况下,您都在使用中缀运算符,就像在
a+a
中一样

如果您不确定实际写下的内容,请使用
write_canonical/1
获取任何序言项的规范表达

例如:

?- write_canonical(a+a). +(a,a) ?- write_canonical((a,a)). ','(a,a) ?- current_op(P, T, :). P = 600, T = xfy. 您的一个示例包含此术语作为子术语:

?- write_canonical(X=(a,a)). =(_,','(a,a)) 我留下来想一想在这种情况下,
600
xfy
对您来说意味着什么。每个Prolog系统都带有许多预定义的
操作符。如果不是这样的话,那么我们就必须用前缀表示法来编写所有术语(这会使Prolog代码像Lisp一样不可读,我们可能还会不断地告诉自己这是件好事,就像中缀语法在许多情况下不可读一样)

关于你的其他陈述:

它们不是像
[a | a]

首先:

| ?- write_canonical([a|a]). '.'(a,a) 在这里,您已经很自然地使用了“疯狂”语法。它的概念与您给出的所有示例中的概念相同:
(=)/2
(+)/2
是序言中的中缀操作符,因此您可以使用中缀符号来表示您必须分别编写为
=(a,a)
+(a,a)
的术语

当然,您可以在任何有意义的计算中使用所有这些术语,就像任何其他术语一样


在某些应用程序中,定义自定义运算符的能力是Prolog的一个主要吸引力,它允许您在某些情况下编写适合您的问题域的Prolog代码。几个Prolog库还导出自定义操作符,这些操作符以自然适合该语言的方式扩展具有更多声明性功能的纯Prolog。像CLP(FD)这样的约束求解器就是一个很好的例子,特别是导出操作符
(#=)/2
(#您正在使用中缀运算符。对这些术语使用
write_canonical/1
,查看它们在规范记数法中的外观。右侧都是具有算术2和不同函子的术语。换句话说,您为什么认为
a+a
不同?这是一个具有函子
+
和两个参数的术语。@mat:这应该是b这可能是一个答案。
作为中缀是特定于SWI的。但所有其他运算符都是标准运算符。
a=a
不是布尔值。它是一个符号术语,与您显示的所有其他术语一样。它的解释取决于上下文。作为一个目标,它将检查等式并成功(而不是“return
True
”)类似地,
X是1+2
将符号项
+(1,2)
视为一个算术表达式,并将
X
与其算术求值的结果统一起来,
3
。您已经发现Prolog是一种终极符号编程语言,其中所有内容(即每个术语)都默认不求值。(“quoted”当我终于意识到变量不能是整数时,我意识到了这一点(愚蠢的我:-),它可以是布尔值。(我知道中缀符号。“疯狂”指的是|:?在其他情况下使用。)所以逗号/分号就是简单的和/或,就像在目标中一样。谢谢你指点我写| u canonical。还有-是重载来表示对吗?没有人告诉我我的Prolog课程……不过,这留下了|::?…:的语义:适用于布尔,a:真是真,a:假是假。SWIPL Online在这里没有帮助(因为我无法搜索它)逻辑上,一个变量代表任何一个术语。请仔细考虑这意味着什么,并列举可能的情况来更好地理解Prolog术语是什么。<代码>(-)/2代码/代码>在Prolog中按成对使用。一些谓词,如“代码>密钥排序/ 2 < /代码>使用<代码>(-)/2
为此,一些Prolog系统中的库,如
库(pairs)
库(assoc)
等,都使用
()/2
用于配对。请注意,Prolog术语没有固有的语义。您使用谓词来定义关系。请参阅我的个人资料页面,以获取一些参考资料,希望对您有所帮助。THX,这对下周的Prolog考试很有用。:-(尽管他们肯定不会问:“通常”是的。他们不会问:一点也不,它更多的是Prolog 101A。我在StOv上找到了它,它是用来定义模块的。我还找到了显示所有运算符的便捷的当前_op/3。)嗯,在几乎所有的Prolog程序中,您仍然至少使用一个运算符,即
(:-)/2
,因此您应该了解中缀运算符。如果没有运算符,您必须将规则编写为
:-(头部,身体)
,而不是
头部:-身体
。 ?- write_canonical(a=a). =(a,a)