あなたはCLP(FD)を扱っているようです。これらのソルバーは、制約問題を解決するセットアップ フェーズとラベル付けフェーズを区別します。
CLP(FD) ソルバーは、セットアップ段階で問題を完全に軽減するわけではありません。ラベル付け段階で変数範囲を減らす可能性があるためです。したがって、セットアップ中に問題が発生し、他のソルバーによって「いいえ」に削減される可能性がありますが、CLP(FD) ソルバーではそうではありません。ラベル付け中のみ「いいえ」が検出されます。
セットアップ段階でどの程度の削減が行われるかは、特定の CLP(FD) システムに大きく依存します。一部の CLP(FD) システムは、セットアップ段階でより多くの削減を行いますが、他のシステムはより少ない削減を行います。たとえば、GNU Prolog はいくつかのインデックス伝播を使用しますが、SWI Prolog は使用しません。したがって、たとえば、あなたの例ではありません。
SWI-プロローグ:
?- 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-プロローグ:
?- 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-プロローグ:
?- 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.
さよなら