SWI Prolog中#=和=:=有什么区别?

4
2个回答

3
#=/2和=:=/2在SWI prolog中有什么区别?
区别在于#=/2是CLPFD库运算符(您需要执行:use_module(library(clpfd))才能使用它),用于算术约束,涵盖了整数上的is/2和=:=/2。这意味着您只能将其用于整数:
例如,使用列表会引发错误:
?- L #= [1,2,3].
ERROR: Domain error: `clpfd_expression' expected, found `[1,2,3]' 

(在=:=/2中使用列表也会引发错误,列表示例仅用于理解这两个运算符都用于表达式!)
对于整数,它可以在任何=:=可以使用的地方使用,但如上所述,它可以用作is/2,这意味着您可以将其用于一致性-简单地将变量与某些整数值绑定,例如:
?- X #= 2.
X = 2.

上述代码未检查X与数字2之间的相等性,因为X是一个无限制的变量,它所做的是将X绑定到值2。
这对于“=:=/2”运算符来说是不可能的:
?- X =:= 2.
ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR:    [8] _2494=:=2
ERROR:    [7] <user>

这是 #=/2=:=/2 之间的区别。两者都用于检查两个算术表达式之间的相等性,但是使用 =:=/2 时,所有变量都必须被实例化,而使用#=/2 时,对于这些变量会设置约束条件。

这是因为 =:=/2 只用于检查相等关系!!

?- X #= 2.
X = 2.      % constraints X to integer value 2

?- X + Y #= 2.
X+Y#=2.     % constraints X,Y such that sum equals to 2 see next example:

?- X + Y #= 2 , X = 3.
X = 3,
Y = -1.     % binds Y with -1 in order to succeed the constraint

?- X + Y #= 2 , X = 3 , Y > 0.
false.      % false since constraint can't succeed!

正如你所看到的,#=/2 更具关系性,即使有多个变量的约束条件,例如 X + Y #= 2. 这会在 X,Y 之间建立关系,绑定一个变量可以导致对另一个变量进行推理。

在你的测试中,你看不出任何区别,因为所有的变量都有值(例如它们都被实例化),而你只需要检查相等性,这两个运算符都能实现。


2

看这个例子:

:- use_module(library(clpfd)).

solve_equation_1(X) :- X + 1 =:= 2.
solve_equation_2(X) :- X + 1 #= 2.
solve_equation_3(X,Y,Z) :- X + Y #= Z.

正如您所预料的那样,solve_equation_1适用于已实例化的X,而对于未实例化的X不适用,因为=:=是一个简单的操作符,用于检查表达式的相等性:

?- solve_equation_1(1).
true.

?- solve_equation_1(2).
false.

?- solve_equation_1(X).
=:=/2: Arguments are not sufficiently instantiated

这并不适用于#=。它实际上并不会进行任何“检查” - 它只是声明某些变量和数字以某种特定的方式受限 - 例如,它们形成一个方程式。除非约束/方程式非常简单可以立即解决,否则实际的检查和计算会在稍后进行。这就是为什么对于非常简单的情况(例如您的示例),#=可能看起来像=:=
请看以下这些例子 - 所有这些都对=:=来说是不可能的,并且它们显示了#=的结果不是一些真/假布尔值,而是新的约束条件:
?- solve_equation_2(X).
X = 1.

?- solve_equation_3(X,Y,2).
X+Y#=2.

?- X #= Y + Z, solve_equation_2(X).
X = 1,
Y+Z#=1

#= 运算符出错 错误:在 SWI Prolog 8.3.24 中的模块加载后,语法错误:需要运算符。有什么想法吗?谢谢。 - Higinio Fuentes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接