Prolog 中有一些特殊的运算符,其中之一是is
,但是,最近我遇到了=:=
运算符,不知道它是如何工作的。
有人能解释一下这个运算符的作用吗?我在哪里可以找到这些特殊运算符的预定义列表以及它们的作用?
Prolog 中有一些特殊的运算符,其中之一是is
,但是,最近我遇到了=:=
运算符,不知道它是如何工作的。
有人能解释一下这个运算符的作用吗?我在哪里可以找到这些特殊运算符的预定义列表以及它们的作用?
不过,我认为上面的答案值得在这里解释几句。
提前说明: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
.
?- 2+3 =:= 6-1.
true.
?- 2+3 is 6-1.
false.
作为现有答案的补充,我想补充几点:
首先,运营商 =:=
,顾名思义,就是运营商。在 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
将给定表达式解释为命题公式,并且在这种情况下,=:=
表示布尔表达式的相等性。
它是一个 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
在 Erlang 中,我认为最好将其注释为语法与 Prolog 最相似。
=:=
表达式是完全相等的意思。
例如在 JavaScript 中,您还可以使用它===
来查看变量的类型是否相同。基本上它是相同的逻辑,但=:=
在 Prolog、Erlang 等函数式语言中使用。
信息不多,但希望它可以在某种程度上有所帮助。
=:= 是一个比较运算符。如果表达式 A1 和 A2 的值相等,则 A1 =:= A2 成功。如果 A1 和 A2 项相同,则 A1 == A2 成功;