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)
,尽管它的扩展库可用。