看來你正在與CLP(FD)打交道。這些求解器區分設置階段和解決約束問題的標註階段。
CLP(FD)求解器在設置階段並未完全減少問題。因爲它有機會在貼標籤階段減少可變範圍。因此,在安裝過程中可能會出現一個問題,可能會被其他求解器降低爲「否」,但不會使用CLP(FD)解算器。只有在標籤過程中才會檢測到「否」。
在設置階段完成多少減少很大程度上取決於給定的CLP(FD)系統。一些CLP(FD)系統在設置階段進行更多的減少,而其他的則更少。例如,GNU Prolog使用一些索引傳播,而SWI Prolog則不使用。因此我們發現,例如,沒有你的例子:
SWI-Prolog的:
?- X #< Y, Y #< Z, Z #< X.
Z#=<X+ -1,
X#=<Y+ -1,
Y#=<Z+ -1.
GNU序言:
?- X #< Y, Y #< Z, Z #< X.
(7842 ms) no
另外,由於使用的是物化的限制也要看一點點有多聰明物化完成。但我猜在目前的情況下,它只是一個傳播問題。我們現在找到你的例子:
SWI-Prolog的:
?- X #< 4 #==> X #< 7.
X+1#=_G1330,
X+1#=_G1342,
7#>=_G1330#<==>_G1354,
_G1354 in 0..1,
_G1377#==>_G1354,
_G1377 in 0..1,
4#>=_G1342#<==>_G1377.
GNU序言:
?- X #< 4 #==> X #< 7.
X = _#22(0..268435455)
有這樣的設置階段更加減少,留下更多的工作之間的權衡標籤階段。整個事情也取決於給定的例子。但是,當你還設置旁邊標註,你不會看到在結果方面的任何差異:
SWI-Prolog的:
?- X in 0..9, X #< 4 #==> X #< 7, label([X]).
X = 0 ;
X = 1 ;
X = 2 ;
X = 3 ;
X = 4 ;
X = 5 ;
X = 6 ;
X = 7 ;
X = 8 ;
X = 9.
GNU序言:
?- fd_domain(X,0,9), X #< 4 #==> X #< 7, fd_labeling([X]).
X = 0 ? ;
X = 1 ? ;
X = 2 ? ;
X = 3 ? ;
X = 4 ? ;
X = 5 ? ;
X = 6 ? ;
X = 7 ? ;
X = 8 ? ;
X = 9
我沒有測試使用SICStus Prolog或B-Prolog。但我想他們會在SWI-Prolog和GNU Prolog的合適位置上表現出色。
如果你的域是真正的FD,CLP(Q)是沒有真正的選擇,因爲它會錯過一些「否」減少,CLP(FD)不會錯過。例如,下面是CLP(FD),不可滿足的,但CLP(Q)可滿足:
X = Y + 1, Y < Z, Z < X.
再見
非常感謝,我處理的線性不等式。我試圖自動查找一組連接(可能是否定的)約束的範圍。因此,我希望能夠通過(例如)X#<4,\#(X#> 2),它工作。我還想傳遞更復雜的內容,例如X#<4,#\\(X#> 2,X#<1),它不起作用,因爲#\被視爲二元運算符。同樣,給它X#<4,#\\((X#> 2,X#<1))也會導致錯誤。 – Nir 2010-11-06 11:18:15
要否定連接,必須使用#/ \,例如:#\(A#/ \ B)。 – mat 2011-02-01 18:31:02