Prolog =:= 运算符

Posted

技术标签:

【中文标题】Prolog =:= 运算符【英文标题】:Prolog =:= operator 【发布时间】:2010-11-27 21:13:18 【问题描述】:

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

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

【问题讨论】:

【参考方案1】:

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

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

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

left 参数必须是一个原子,或者是一个数字常量(然后将其与右操作数的计算结果进行比较),或者是一个变量。如果它是 bound 变量,则它的值必须是数字,并与前一种情况一样与右操作数进行比较。如果它是 unbound 变量,则右操作数的计算结果将绑定到该变量。在后一种情况下,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

【讨论】:

为什么这没有被选为正确答案,我永远不会知道 (._.) 当使用“is”时,左侧是否可以有多个变量?例如 X + Y = 2 +3。 @hiswendy 这应该是什么结果?!请记住,is 将其右侧计算为算术表达式。在您的示例中为 5。 5应该如何与X + Y这样的左侧术语统一?! - 您正在使用的=/2 谓词是一个最通用的统一函数,它试图匹配和绑定两个任意项。它不进行自动算术评估,因此也与此处讨论的=:= 有很大不同。 @ThomasH hiswendy 在技术上是正确的,尽管 ?- X + Y = 2 + 3. 产生了一个结果,并且该结果是 X = 2, Y = 3. 但是使用 CLP 算法,人们可以做 X + 4 #= 2 + 3. 并得到 X = 1. 这是更有用。 @ErikKaplun 我同意使用=。但是他的问题涉及is,这不起作用。【参考方案2】:
?- 2+3 =:= 6-1.
true.

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

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

【讨论】:

基本上是一个算术运算符,检查某些计算的结果是否以相同的结果结束?有点像变量是 5+10,但在两边计算然后统一,给出真假作为结果。【参考方案3】:

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

算子就是算子

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

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

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

这意味着您可以,如果您想要,将=:=(X, Y) 之类的术语等效地 写为X =:= Y。在两种情况中,项的函子=:=,项的arity是2。您可以使用write_canonical/1验证这一点:

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

谓词不是运算符

到目前为止,一切都很好!这都是纯粹的句法特性。但是,您实际上询问的是谓词 (=:=)/2,其名称为=:=,需要2个参数。 p>

正如其他人已经解释的那样,谓词(=:=)/2 表示两个算术表达式的算术相等true iff 它的参数 evaluate 为相同的数字。

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

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

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

谓词仅在两个参数都完全实例化的非常特定的情况下有效。例如:

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

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

约束是一种更通用的替代方法

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) 等。而不是使用更多低级算术谓词。 p>

有关详细信息,另请参阅 clpfd、clpq 和 clpb。

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

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

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

【讨论】:

一个非常好的答案,垫子。我特别喜欢你介绍 op 和 write_canonical 用法的方式。在我看来,op 是 prolog 的一个极其重要的功能。 但是,我强烈反对您关于 op 不是谓词的断言。在我看来,prolog 的天才之处在于每个 op 都是 funktor(谓词)。事实上,源代码的每个元素都成为谓词。这样可以看出prolog解释器中的tokenizing和parse的功能就是产生一个语法树,而这个语法树完全是通过functor指定的。【参考方案4】:

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

【讨论】:

【参考方案5】:

它是一个 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

【讨论】:

【参考方案6】:

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

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

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

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

【讨论】:

【参考方案7】:

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

【讨论】:

【参考方案8】:

第一个运算符 =:= 检查是否相等? 例如 enter image description here

它返回 true。 但这返回 false enter image description here

【讨论】:

以上是关于Prolog =:= 运算符的主要内容,如果未能解决你的问题,请参考以下文章

自定义 Prolog 算术函数

我的简单prolog代码抛出语法错误:运算符预期

; (或)Prolog中的运算符不会返回true,除非左侧为true,即使运算符的右侧本身返回true也是如此

@ <Prolog中的符号

Prolog解析证明器删除括号

MiniKanren 有“非”运算符吗?