Prolog中有一些特殊的操作符,其中一个是“是”,但是,最近我遇到了=:=运算符,我不知道它是如何工作的。
有人可以解释操作员的操作,以及我在哪里可以找到这些特殊操作符的预定义列表以及它们的作用?
感谢。
答案 0 :(得分:84)
我认为上面的答案在这里值得一些解释。
提前做一个简短说明:Prolog中的算术表达式只是术语(“一切都是Prolog中的术语”),不会自动评估。 (如果你有Lisp背景,请考虑引用的列表)。因此3 + 4
与+(3,4)
相同,=:=
本身不做任何事情。个别谓词的责任是评估这些术语。
几个内置谓词进行隐式评估,其中包括is
和=:=
等算术比较运算符。虽然is
计算两个参数并比较结果,但is
仅接受并评估其 right 参数作为算术表达式。
left 参数必须是一个原子,或者是数字常量(然后与右操作数的评估结果进行比较),或者是变量。如果它是 bound 变量,则其值必须为数字,并与前一种情况下的右操作数进行比较。如果它是未绑定的变量,则右操作数的计算结果将绑定到该变量。在后一种情况下经常使用0 is N mod 2 % true if N is even
0 =:= N mod 2 % dito
来绑定变量。
从上面链接的Prolog词典中选择一个例子:要测试N是否是偶数,你可以使用两个算子:
X is N mod 2 % X will be 0 if N is even
X =:= N mod 2 % !will bomb with argument/instantiation error!
但是如果你想捕获操作的结果,你只能使用第一个变体。如果X未绑定,则:
=:=
经验法则:如果您只需要算术比较,请使用is
。如果要捕获评估结果,请使用{{1}}。
答案 1 :(得分:23)
?- 2+3 =:= 6-1.
true.
?- 2+3 is 6-1.
false.
答案 2 :(得分:10)
补充现有答案,我想补充一点:
首先,运算符 =:=
,如名称所示,是运算符。在Prolog中,我们可以使用谓词current_op/3
来了解有关运算符的更多信息。例如:
?- current_op(Prec, Type, =:=). Prec = 700, Type = xfx.
这意味着,运营商=:=
的优先级 700,且类型 xfx
。这意味着它是二进制中缀运算符。
这意味着您可以,如果您想要,请将=:=(X, Y)
等效这样的字词写为X =:= Y
。在两种情况中,该术语的仿函数为=:=
,该术语的 arity 为2.您可以使用{ {1}}验证这一点:
?- write_canonical(a =:= b). =:=(a,b)
到目前为止,真好!这一切都是纯粹的语法功能。但是,您实际询问的是谓词 write_canonical/1
,其名称为(=:=)/2
,其中包含2个参数
正如其他人已经解释的那样,谓词=:=
表示两个算术表达式的算术相等。 true iff 其参数评估为相同的数字。
例如,让我们尝试使用变量作为参数的最常规查询,我们通过该查询请求任何解决方案:
?- X =:= Y. ERROR: Arguments are not sufficiently instantiated
因此,这个谓词不是一个真正的关系,因为我们不能将它用于生成结果!这是这个谓词的一个非常严重的缺点,与你通常所说的“声明性编程”相冲突。
谓词仅适用于特定的情况,即两个参数都已完全实例化。例如:
?- 1 + 2 =:= 3. true.
我们将此类谓词命名为 moded ,因为它们只能用于特定的模式。对于绝大多数初学者来说,模式谓词是一个噩梦要使用,因为它们要求你考虑你的程序程序性,这一开始很难,但也很难后来。此外,模式谓词严重限制程序的通用性,因为您无法在可以使用纯谓词的所有方向上使用它们。
Prolog还以算术约束的形式提供了许多更通用的算术谓词。
例如,在整数的情况下,请尝试Prolog系统的 CLP(FD)约束。最重要的CLP(FD)约束之一表示算术相等,称为(=:=)/2
。完全类比(#=)/2
,运算符 (=:=)/2
也被定义为中缀运算符,因此您可以编写例如:
| ?- 1 + 2 #= 3. yes
我使用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)等代替使用更多低级算术谓词。
巧合的是,运算符 (#=)/2
被CLP(B)用于完全不同的含义:
?- sat(A =:= B+1). A = 1, sat(B=:=B).
这表明您必须区分运算符和谓词。在上面的例子中,谓词 =:=
已将给定表达式解释为命题公式,在此上下文中,sat/1
表示布尔表达式的相等。
答案 3 :(得分:5)
答案 4 :(得分: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
答案 5 :(得分:0)
=:=是比较运算符.A1 =:= A2如果表达式A1和A2的值相等则成功。 如果术语A1和A2相同,则A1 == A2成功;
答案 6 :(得分:0)
在Erlang中,我认为最好注释一下,因为语法在大多数情况下类似于Prolog。
=:=表达式的含义完全相等。
例如在JavaScript中,您可以使用===来查看变量的类型是否相同。 基本上是相同的逻辑,但是=:=在功能语言中与Prolog,Erlang一起使用。
信息不多,但希望能以某种方式提供帮助。
答案 7 :(得分:-1)
第一个算子=:=检查是否相等? 例如 enter image description here
它的回归是真的。 但这会返回false enter image description here