SWI prolog中#=和=:=之间的区别是什么

时间:2017-10-15 15:40:45

标签: math prolog operator-keyword clpfd

SWI prolog中?- 3=:=3. true. ?- (3-2) =:= (9-8). true. ?- 3 #= 3. true. ?- (3-2) #= (9-8). true. 和{{1}}之间有什么区别 我从SWI prolog中找到了这个定义,但仍然对此感到困惑 http://www.swi-prolog.org/pldoc/man?section=arithpreds enter image description here

http://www.swi-prolog.org/pldoc/man?section=clpfd-arith-constraints
enter image description here

{{1}}

2 个答案:

答案 0 :(得分:3)

  

SWI prolog中#=和=:=的区别是什么?

不同之处在于#=/2是一个CLPFD库操作符(您需要执行:use_module(library(clpfd)).才能使用它)并且它用于算术约束并包含is/2=:=/2 整数。这意味着你只能将它用于整数:

例如使用list会引发错误:

?- 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之间的关系,绑定一个变量可以导致推理另一个。

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

答案 1 :(得分: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,并且不适用于未实例化=:=是一个检查表达式相等的简单运算符:

?- solve_equation_1(1).
true.

?- solve_equation_1(2).
false.

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

#=不是这种情况。它并没有真正检查任何东西 - 它只是声明某些变量和某些数字以某种特定的方式受到约束 - 例如他们形成一个等式。实际检查和计算将在以后进行,除非约束/等式非常简单,可以立即解决。这就是为什么非常简单的案例(例如您的示例)#=可能看起来像=:=

请参阅这些示例 - =:=都不可能,并且它们表明#=的结果不是某些true / false布尔值,而是新约束:

?- 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