Using xor with JuMP and MiniZinc

Hi,

With JuMP, I can create constraints with && and ||. I am trying to use xor and not. Is there a way to do this?

I can do the following:

using JuMP
using MiniZinc

model = Model(() -> MiniZinc.Optimizer{Float64}("chuffed"))

@variable(model, x, Bin)
@variable(model, y, Bin)
@constraint(model, x && y := true)

I want to also be able to do:

@constraint(model, not(x) := true)
@constraint(model, xor(x, y) := true)

Thank you

what about :

  • x := false for the not ?
  • two constraints x || y := true and x && y := false for the xor ?

I think such tricks would globally cover binary arithmetic

1 Like

My issue is that I want to have constraints a bit more complicated, like

(x && y && not(z)) || (x && not(y) && z) := true

and even if we can detect that it simplifies a bit with x := true for example, I don’t want to detect that as the solver can do it.

The other issue is that I actually don’t know that xor(x, y) := true but it would be something more like xor(x, y) == z := true and then I have constraints on z.

Still, I can simplify the xor (and I am currently using a workaround), but this does not apply for the not

1 Like

It should always simplify, but I agree that the solver should do it for you. Interested in what others have to say

1 Like

As a workaround, I currently replace expressions like

(x && y && not(z)) || (x && not(y) && z) := true

by

(x && y && (z == false)) || (x && (y == false) && z) := true

So a xor constraint like z == xor(x, y) becomes

(x && (y == false)) || (y && (x == false)) == z := true

This is undocumented, but MiniZinc has support for : MiniZinc.jl/src/MiniZinc.jl at 3bc82dc24feb869a1aa0784cb8dcc0d5b82fa104 · jump-dev/MiniZinc.jl · GitHub
and ! MiniZinc.jl/src/MiniZinc.jl at 3bc82dc24feb869a1aa0784cb8dcc0d5b82fa104 · jump-dev/MiniZinc.jl · GitHub

So you can do something like:

using JuMP
using MiniZinc
model = Model(() -> MiniZinc.Optimizer{Float64}("chuffed"))
@variable(model, x, Bin)
@variable(model, y, Bin)
Base.:⊻(x::VariableRef, y::VariableRef) = NonlinearExpr(:⊻, Any[x, y])
Base.:!(x::AbstractJuMPScalar) = NonlinearExpr(:!, Any[x])
@constraint(model, !(x ⊻ y) := true)
optimize!(model)
value(x), value(y)
1 Like

Thank you! I saw that MiniZinc.jl had support for it but I did not know the way to allow using and ! in @constraint.