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
.
小智 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
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
将给定的表达式解释为命题公式,并且在此上下文中,=:=
表示布尔表达式的相等性.