CLP(FD) 用于整数运算

传统上,Prolog 使用 is=:= 运算符执行算术运算。然而,一些当前的 Prolog 提供 CLP(FD)(有限域上的约束逻辑编程)作为整数算术的更清洁的替代方案。CLP(FD) 基于存储应用于整数值的约束并将它们组合在一起存储在内存中。

CLP(FD) 是支持它的大多数 Prolog 中的扩展,因此必须明确加载。一旦加载,#= 语法就可以代替 is=:=。例如,在 SWI-Prolog 中:

?- X is 2+2.
X = 4.

?- use_module(library(clpfd)).
?- X #= 2+2.
X = 4.

is 不同,#= 能够解决简单的方程并在两个方向上统一:

?- 4 is 2+X.
ERROR: is/2: Arguments are not sufficiently instantiated

?- 4 #= 2+X.
X = 2.

CLP(FD) 提供自己的生成器语法。

?- between(1,100,X).
X = 1;
X = 2;
X = 3...

?- X in 1..100.
X in 1..100.

请注意,生成器实际上并不运行:只存储范围约束,为以后的约束与之组合做好准备。可以使用 label 谓词强制运行生成器(和暴力约束):

?- X in 1..100, label([X]).
X = 1;
X = 2;
X = 3..

使用 CLP 可以允许一些智能减少暴力案件。例如,使用旧式整数运算:

?- trace.
?- between(1,10,X), Y is X+5, Y>10.
...
Exit: (8) 6 is 1+5 ? creep
Call: (8) 6 > 10 ? creep
...
X = 6, Y = 11; ...

Prolog 仍然循环通过值 1-5,即使从给定条件在数学上可证明这些值不可用。使用 CLP(FD)

?- X in 1..10, Y #= X+5, Y #> 10.
X is 6..10,
X+5 #= Y,
Y is 11..15.

CLP(FD) 立即进行数学运算并计算出可用范围。添加 label([Y]) 将导致 X 仅通过有用值 6..10 循环。在这个玩具示例中,这不会提高性能,因为如此小范围为 1-10,代数处理只需要循环就可以完成; 但是当处理更大范围的数字时,这可能会有效地减少计算时间。

支持 CLP(FD) 在 Prolog 之间是可变的。CLP(FD) 公认的最佳发展是在 SICStus Prolog 中,这是商业和昂贵的。SWI-Prolog 和其他开放的 Prolog 经常有一些实施。Visual Prolog 在其标准库中不包括 CLP(FD),尽管它的扩展库可用。