35

Prolog 中有一些特殊的运算符,其中之一是is,但是,最近我遇到了=:=运算符,不知道它是如何工作的。

有人能解释一下这个运算符的作用吗?我在哪里可以找到这些特殊运算符的预定义列表以及它们的作用?

4

8 回答 8

100

不过,我认为上面的答案值得在这里解释几句。

提前说明:Prolog 中的算术表达式只是术语(“一切都是 Prolog 中的术语”),不会自动计算。(如果您有 Lisp 背景,请考虑引用列表)。So3 + 4与 相同+(3,4),它自己什么都不做。评估这些术语是各个谓词的责任。

几个内置谓词进行隐式评估,其中包括算术比较运算符=:=is。While=:=计算两个参数并比较结果,is只接受并计算其正确的参数作为算术表达式。

左边的参数必须是一个原子,或者一个数字常量(然后将其与右操作数的评估结果进行比较),或者一个变量。如果它是一个绑定变量,它的值必须是数字并与前一种情况一样与右操作数进行比较。如果它是未绑定的变量,则右操作数的计算结果将绑定到该变量。is通常在后一种情况下使用,以绑定变量。

要从上面链接的 Prolog 字典中选择一个示例:要测试数字 N 是否为偶数,您可以使用这两个运算符:

0 is N mod 2  % true if N is even
0 =:= N mod 2 % dito

但是如果你想捕获操作的结果,你只能使用第一个变体。如果 X 未绑定,则:

X is N mod 2   % X will be 0 if N is even
X =:= N mod 2  % !will bomb with argument/instantiation error!

经验法则:如果您只需要算术比较,请使用=:=. 如果要捕获评估结果,请使用is.

于 2009-12-23T17:18:21.730 回答
27
?- 2+3 =:= 6-1.
true.

?- 2+3 is 6-1.
false.

另请参阅文档http://www.swi-prolog.org/pldoc/man?predicate=is/2

于 2009-09-13T11:09:14.797 回答
20

作为现有答案的补充,我想补充几点:

运营商就是运营商

首先,运营商 =:=,顾名思义,就是运营商。在 Prolog 中,我们可以使用谓词current_op/3来了解有关运算符的更多信息。例如:

?- current_op(Prec, Type, =:=)。
Prec = 700,
类型 = xfx。

这意味着运算符=:=优先级为 700 并且类型为 xfx。这意味着它是一个二元中运算符。

这意味着如果您愿意,您可以写一个类似 等价于的术语。在这两种情况下,项的函子都是 ,项的元数是 2。您可以使用来验证这一点:=:=(X, Y) X =:= Y=:=write_canonical/1

?- write_canonical(a =:= b)。
=:=(a,b)

谓词不是运算符

到目前为止,一切都很好!这完全是一个纯粹的句法特征。但是,您实际上要问的是predicate (=:=)/2,其名称为 is=:=并且需要 2 个 arguments

正如其他人已经解释的那样,谓词 (=:=)/2表示两个算术表达式的算术相等。如果它的论点评估相同的数字,则它是正确的。

例如,让我们尝试最通用的查询,通过它我们要求任何解决方案,使用变量作为参数:

?- X =:= Y.
错误:参数没有充分实例化

因此,这个谓词不是真正的关系,因为我们不能用它来生成结果!这是这个谓词的一个非常严重的缺点,与您通常所说的“声明式编程”相冲突。

谓词仅适用于两个参数都已完全实例化的非常特定的情况。例如:

?- 1 + 2 =:= 3.
是的。

我们称此类谓词为模式,因为它们只能用于特定的使用模式。对于绝大多数初学者来说,使用模态谓词是一场噩梦,因为它们要求您从程序上考虑您的程序,这在开始时非常困难,以后也很难。此外,模式谓词严重限制了程序的通用性,因为您不能在可以使用纯谓词的所有方向上使用它们。

约束是更通用的选择

Prolog 还以算术约束的形式提供了更通用的算术谓词。

例如,在整数的情况下,试试你的 Prolog 系统的CLP(FD) 约束。最重要的 CLP(FD) 约束之一表示算术相等,称为 (#=)/2. 与 完全类比(=:=)/2运算符 (#=)/2也被定义为中运算符,因此您可以编写例如:

| ?- 1 + 2 #= 3。

是的

我使用 GNU Prolog 作为一个特定示例,许多其他 Prolog 系统也提供 CLP(FD) 实现。

约束的一个主要吸引力在于它们的普遍性。例如,与 相比(=:=)/2,我们得到谓词 (#=)/2

| ?- X + 2 #= 3。

X = 1

| ?- 1 + Y #= 3。

Y = 2

我们甚至可以问最一般的查询

| ?- X #= Y。

X = _#0(0..268435455)
Y = _#0(0..268435455)

注意这些谓词是多么自然地融入 Prolog 并充当整数表达式之间的关系,可以在所有方向上查询。

根据感兴趣的领域,我的建议是使用 CLP(FD)、CLP(Q)、CLP(B) 等,而不是使用更多的低级算术谓词。

另请参阅了解更多信息。

巧合的是,CLP(B) 使用的运算符具有 完全不同的含义:=:=

?- 饱和(A =:= B+1)。
A = 1,
坐(B=:=B)。

这表明您必须区分运算符谓词。在上述情况下,谓词 sat/1将给定表达式解释为命题公式,并且在这种情况下,=:=表示布尔表达式的相等性。

于 2017-04-21T13:15:06.937 回答
5

我找到了自己的答案,http://www.cse.unsw.edu.au/~billw/prologdict.html

于 2009-09-13T09:02:11.573 回答
4

它是一个 ISO 核心标准谓词运算符,不能从统一 (=)/2 或语法相等 (==)/2 引导。它在第 8.7 节算术比较中定义。它的基本行为如下:

E =:= F :- 
    X is E, 
    Y is F, 
    arithmetic_compare(=, X, Y).

因此,左侧 (LHS) 和右侧 (RHS) 都必须是算术表达式,在进行比较之前对其进行求值。算术比较可以跨数值类型进行比较。所以我们有:

   GNU Prolog 1.4.5 (64 bits)

   ?- 0 = 0.0.
   no

   ?- 0 == 0.0
   no

   ?- 0 =:= 0.0.
   yes
于 2019-01-30T20:35:31.710 回答
1

在 Erlang 中,我认为最好将其注释为语法与 Prolog 最相似。

=:=表达式是完全相等的意思。

例如在 JavaScript 中,您还可以使用它===来查看变量的类型是否相同。基本上它是相同的逻辑,但=:=在 Prolog、Erlang 等函数式语言中使用。

信息不多,但希望它可以在某种程度上有所帮助。

于 2020-11-06T22:49:54.460 回答
0

=:= 是一个比较运算符。如果表达式 A1 和 A2 的值相等,则 A1 =:= A2 成功。如果 A1 和 A2 项相同,则 A1 == A2 成功;

于 2014-03-14T10:21:01.373 回答
-2

第一个运算符 =:= 检查是否相等?例如 在此处输入图像描述

它返回 true。但这返回 false 在此处输入图像描述

于 2017-04-21T12:36:59.643 回答