Кажется, вы имеете дело с 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 Prolog:
?- 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 Prolog:
?- 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 Prolog:
?- 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.
CLP (Q) не является реальной альтернативой, если ваш домен действительно FD, так как он пропустит некоторые сокращения «Нет», которые CLP (FD) не пропустит. Например, следующий невыполнима в CLP (FD), но выполнимо CLP (Q):
X = Y + 1, Y < Z, Z < X.
Bye
Большое спасибо, я имею дело с линейными неравенствами. Я пытаюсь автоматически найти диапазоны для набора конъюнктивных (возможно, отрицаемых) ограничений. Таким образом, я хотел бы иметь возможность пройти (например) X # <4,\#(X#> 2), который работает. Я также хотел бы передать что-то более сложное, например. X # <4,#\\(X#> 2, X # <1), который не работает, поскольку # \ затем рассматривается как двоичный оператор. Аналогичным образом, придание ему X # <4,#\\((X#> 2, X # <1)) также приводит к ошибке. – Nir
Чтобы отменить соединение, вы должны использовать #/\, например: # \ (A #/\ B). – mat