Search code examples
prologeclipse-clp

Apply OR constraint over the variables in a list


Suppose we have a list of variables. We want to apply a constraint over the variables, but the relation of these constraints are or. How we can do this in Eclipse CLP (prolog)?

We should notice that if the list is short like A is [X, Y, Z] the trivial solution is A[0] #= 0 or A[1] #= 0 or A[2] #= 0 (if the constraint is equality to zero). Hence, this does not work for a long list.


Solution

  • For general reifiable constraints, you can reflect their truth value into a 0/1 variable, and sum these up. E.g. to state that at least one element of Xs is greater than 3:

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

    Another option is to remember that Prolog is good at meta-programming, so you could symbolically construct the expression X1#>3 or X2#>3 or ... or Xn#>3 and then call it:

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

    For your specific example, where the constraint is "equal to zero" (or some other constant), it is actually easiest to use the global constraint atleast/3:

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