我在prolog中写了一个快速的谓词。
problem(A, B) :-
A-B #= 320,
A #= 21*B.
当我在SWI中称呼它时,我会得到:
?- problem(A,B).
320+B#=A,
21*B#=A.
虽然在GNU中,我得到了正确的答案:
| ?- problem(A,B).
A = 336
B = 16
这里发生了什么?理想情况下,我想在SWI中获得正确的结果,因为它是一个更健壮的环境。
这是一个很好的观察。
乍一看,毫无疑问,Swi 的缺点似乎是不像Gnu gnu  prolog。
那样强烈地传播但是,这里还有其他因素。
核心问题
开始,请尝试在GNU Prolog中尝试以下查询:
|? - x#= x。
声明地,查询可以读取为: X
是 integer 。原因是:
-
(#=)/2
仅适用于整数 -
X #= X
不会以任何方式限制整数X
的域。
但是,至少在我的机器上,gnu prolog回答:
x = _#0( 0 .. 268435455 )
因此,实际上,整数X
的域即使我们没有以任何方式限制它!
为了进行比较,我们在sicstus prolog中得到了:
? - x#=X。 x in inf..sup。
这表明整数X
的域具有任何方式。
用CLP(Z)
复制结果让我们平整竞争环境。我们可以通过人工限制变量的域以有限间隔  0..2 64 :
? - 问题(a,b), 上#= 2^64, [a,b] ins 0..upper 。
作为回应,我们现在使用Swi-Prolog:
a = 336,b = 16,鞋面= 18446744073709551616。
因此,将域限制在整数的有限子集中,使我们能够从swi-prolog或其继任者或其继任者或其继任者(FD)求解器中复制我们从GNU  CLP(Z)。
此
的原因 Clp(Z)的野心是完全在用户中用高级声明性替代方案在用户中替换低级算术谓词,可以用作true 关系,当然也是 drop-in 替代品。因此,CLP(Z)支持未绑定的整数,它可以与计算机内存允许的范围一样大。在CLP(z)中,所有整数变量的默认域是 aled 整数的集合。这意味着,只要一个域之一是nbsp; nbsp; nbsp; nbsp; 例如: 这是A 条件答案:原始查询可满足 iff 所谓的残差约束可满足。 相反,我们获得有限域: 只要所有域都是有限的,我们期望涉及系统大致相同的传播强度。 整数上的求解方程是不可否认的。因此,对于CLP(Z),我们知道有 no 决策算法总是会产生正确的结果。 因此,您有时会得到残差约束而不是无条件的答案。通过有限整数集,方程当然是可决定的:如果所有域都是有限的,并且您没有得到具体的解决方案作为答案,请使用枚举之一  predices 详尽地搜索解决方案。 在可以推荐无限整数集的系统中,您迟早会遇到这种现象。? - x#>是的,y#>X。x#=< y -1,y#=< x -1。
? - x#>是的,y#>x, [x,y] ins -5000..2000 。 false。
固有的限制