Prolog运算符=:=

nub*_*ela 27 prolog

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

有人可以解释操作员的作用,还可以在哪里找到这些特殊操作符的预定义列表以及它们的作用?

谢谢.

Tho*_*asH 87

我认为上面的答案值得在此处作一些解释.

提前简短说明:Prolog中的算术表达式只是术语("一切都是Prolog中的术语"),不会自动计算.(如果你有Lisp背景,请考虑引用的列表).所以3 + 4就是这样+(3,4),它本身没有任何作用.个别谓词负责评估这些术语.

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

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

从上面链接的Prolog词典中获取一个例子:要测试N是否是偶数,你可以使用两个运算符:

0 is N mod 2  % true if N is even
0 =:= N mod 2 % dito
Run Code Online (Sandbox Code Playgroud)

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

X is N mod 2   % X will be 0 if N is even
X =:= N mod 2  % !will bomb with argument/instantiation error!
Run Code Online (Sandbox Code Playgroud)

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

  • 为什么这不被选为正确的答案,我永远不会知道(._.) (7认同)
  • 这显然是这个帖子中最好的答案 (6认同)

小智 24

?- 2+3 =:= 6-1.
true.

?- 2+3 is 6-1.
false.
Run Code Online (Sandbox Code Playgroud)

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

  • 基本上是一个算术运算符,用于检查某些计算的结果是否以相同的结果结束?有点像 Variable 是 5+10 但两边计算然后统一,结果给出真或假。 (3认同)

mat*_*mat 15

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

运营商是运营商

首先,在运营商 =:=,正如其名称所示,一个运营商.在Prolog中,我们可以使用谓词current_op/3来了解有关运算符的更多信息.例如:

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

这意味着,操作者=:=具有的优先级 700和是的类型 xfx.这意味着它是一个二进制中运算符.

这意味着,如果您愿意,您可以对待一样写一个术语  .在这两种情况下,该术语的函子都是,并且该术语的arity是2.您可以用来验证这一点:=:=(X, Y) X =:= Y=:=write_canonical/1

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

谓词不是运算符

到现在为止还挺好!这一切都是纯粹的语法特征.但是,你实际要问的是谓词 (=:=)/2,它的名字是=:=2,它有2个  参数.

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

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

?- 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)等,而不是使用更多的低级算术谓词.

另请参阅,以获取更多信息.

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

?- sat(A =:= B+1).
A = 1,
sat(B=:=B).

这表明您必须区分运算符谓词.在上面的例子中,谓词 sat/1将给定的表达式解释为命题公式,并且在此上下文中,=:=表示布尔表达式的相等性.