Применить ИЛИ ограничение к переменным в списке

#prolog #eclipse-clp

#пролог #eclipse-clp

Вопрос:

Предположим, у нас есть список переменных. Мы хотим применить ограничение к переменным, но отношение этих ограничений таково or . Как мы можем сделать это в Eclipse CLP (prolog)?

Мы должны заметить, что если список короткий, как A is [X, Y, Z] тривиальное решение A[0] #= 0 or A[1] #= 0 or A[2] #= 0 (если ограничение равно нулю). Следовательно, это не работает для длинного списка.

Комментарии:

1. В clpfd для общего случая есть (#/)/2. Но часто возможна лучшая согласованность.

Ответ №1:

Для общих проверяемых ограничений вы можете отразить их значение истинности в переменной 0/1 и суммировать их. Например. чтобы указать, что по крайней мере один элемент Xs больше 3 :

 ( foreach(X,Xs),foreach(B,Bs)  do  B #= (X#>3) ),
sum(Bs) #> 0.
  

Другой вариант — помнить, что Prolog хорош в метапрограммировании, поэтому вы можете символически сконструировать выражение X1#>3 or X2#>3 or ... or Xn#>3 , а затем вызвать его:

 ( foreach(X,Xs),fromto(0,Cs,(Cs or X#>3),Dis)  do  true ),
call(Dis).
  

Для вашего конкретного примера, где ограничение «равно нулю» (или какой-либо другой константе), на самом деле проще всего использовать глобальное ограничение по крайней мере / 3:

 atleast(1, Xs, 0)              % at least 1 element of Xs is equal to 0
  

Комментарии:

1. Результатом (foreach(X, [](1, 32, 6)), foreach(B, Bs) do B #= (X #> 3)), sum(Bs) #> 0. является No .

2. @OmG foreach предназначен для списков. Для перебора массива используйте foreacharg , т.е. (foreacharg(X, [](1, 32, 6)), foreach(B, Bs) do B #= (X #> 3)), sum(Bs) #> 0.