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)
,儘管它的擴充套件庫可用。