Closed mhechthz closed 1 year ago
With MiniZinc.jl it should be at least possible to write a file readable for MiniZinc (and humans).
If you have a MiniZinc.Optimizer
, you can write it using
open("file.mzn", "w") do io
write(io, model)
end
We could make this friendlier.
Ok, looks good. But how to call/import write
the right way?
ERROR: LoadError: MethodError: no method matching write(::IOStream, ...
Currently I just do import MiniZinc
.
EDIT: Updated to version 0.2.0. Now I get:
ERROR: LoadError: UndefVarError: 'Reified' not defined
on running
MOI.add_constraint(
model,
MOI.VectorOfVariables([z[2], x[2], x[3]]),
MiniZinc.Reified(MOI.AllDifferent(2)),
)
But how to call/import write the right way?
How are you currently calling it? You'll need something like this:
model = MOI.Utilities.CachingOptimizer(
MiniZinc.Model{Int}(),
MiniZinc.Optimizer{Int}(MiniZinc.Chuffed()),
)
# ...
MOI.Utilities.attach_optimizer(model)
open("file.mzn", "w") do io
write(io, model.optimizer)
end
It's pretty clunky; we should improve this.
ERROR: LoadError: UndefVarError: 'Reified' not defined
Oops. I had a typo in the README: https://github.com/jump-dev/MiniZinc.jl/pull/19
Well I changed the code, but nevertheless the problem remains. I took your basic example in MiniZinc.jl 0.2.0 in Julia 1.8.3:
ENV["JULIA_LIBMINIZINC_DIR"] = "C:\\Users\\Michael\\AppData\\Local\\Programs\\MiniZinc"
import MiniZinc
const MOI = MiniZinc.MOI
function main()
model = MOI.Utilities.CachingOptimizer(
MiniZinc.Model{Int}(),
MiniZinc.Optimizer{Int}(MiniZinc.Chuffed()),
)
# xᵢ ∈ {1, 2, 3} ∀i=1,2,3
x = MOI.add_variables(model, 3)
MOI.add_constraint.(model, x, MOI.Interval(1, 3))
MOI.add_constraint.(model, x, MOI.Integer())
# zⱼ ∈ {0, 1} ∀j=1,2
z = MOI.add_variables(model, 2)
MOI.add_constraint.(model, z, MOI.ZeroOne())
# z₁ <-> x₁ != x₂
# MOI.add_constraint(
# model,
# MOI.VectorOfVariables([z[1], x[1], x[2]]),
# MiniZinc.Reified(MOI.AllDifferent(2)),
# )
# z₂ <-> x₂ != x₃
# MOI.add_constraint(
# model,
# MOI.VectorOfVariables([z[2], x[2], x[3]]),
# MiniZinc.Reified(MOI.AllDifferent(2)),
# )
# z₁ + z₂ = 1
MOI.add_constraint(model, 1 * z[1] + x[2], MOI.EqualTo(1))
open("file.mzn", "w") do io
write(io, model.optimizer)
end
MOI.optimize!(model)
x_star = MOI.get(model, MOI.VariablePrimal(), x)
z_star = MOI.get(model, MOI.VariablePrimal(), z)
return x_star, z_star
end
main()
with the part of Reified
deactivated because of the error message there.
I get
ERROR: MethodError: no method matching write(::IOStream, ::MiniZinc.Optimizer{Int64})
Closest candidates are:
write(::IO, ::Any) at io.jl:672
write(::IO, ::Any, ::Any...) at io.jl:673
write(::IO, ::Union{Float16, Float32, Float64, Int128, Int16, Int32, Int64, UInt128, UInt16, UInt32, UInt64}) at io.jl:686
...
Stacktrace:
[1] write(io::IOStream, x::MiniZinc.Optimizer{Int64})
@ Base .\io.jl:672
[2] (::var"#5#6"{MathOptInterface.Utilities.CachingOptimizer{MiniZinc.Optimizer{Int64}, MathOptInterface.Utilities.GenericModel{Int64, MathOptInterface.Utilities.ObjectiveContainer{Int64}, MathOptInterface.Utilities.VariablesContainer{Int64}, MiniZinc.ModelFunctionConstraints{Int64}}}})(io::IOStream)
@ Main c:\Micha\Programming\Julia\jlMiniZinc.jl:21
[3] open(::var"#5#6"{MathOptInterface.Utilities.CachingOptimizer{MiniZinc.Optimizer{Int64}, MathOptInterface.Utilities.GenericModel{Int64, MathOptInterface.Utilities.ObjectiveContainer{Int64}, MathOptInterface.Utilities.VariablesContainer{Int64}, MiniZinc.ModelFunctionConstraints{Int64}}}}, ::String, ::Vararg{String}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ Base .\io.jl:384
[4] open(::Function, ::String, ::String)
@ Base .\io.jl:381
[5] main()
@ Main c:\Micha\Programming\Julia\jlMiniZinc.jl:20
[6] top-level scope
@ c:\Micha\Programming\Julia\jlMiniZinc.jl:48
Let me take a look. I haven't actually tested this locally.
D'oh. I didn't need the Optimizer
part:
julia> import MiniZinc
julia> const MOI = MiniZinc.MOI
MathOptInterface
julia> function main()
model = MiniZinc.Model{Int}()
# xᵢ ∈ {1, 2, 3} ∀i=1,2,3
x = MOI.add_variables(model, 3)
MOI.add_constraint.(model, x, MOI.Interval(1, 3))
MOI.add_constraint.(model, x, MOI.Integer())
# zⱼ ∈ {0, 1} ∀j=1,2
z = MOI.add_variables(model, 2)
MOI.add_constraint.(model, z, MOI.ZeroOne())
# z₁ <-> x₁ != x₂
MOI.add_constraint(
model,
MOI.VectorOfVariables([z[1], x[1], x[2]]),
MOI.Reified(MOI.AllDifferent(2)),
)
# z₂ <-> x₂ != x₃
MOI.add_constraint(
model,
MOI.VectorOfVariables([z[2], x[2], x[3]]),
MOI.Reified(MOI.AllDifferent(2)),
)
# z₁ + z₂ = 1
MOI.add_constraint(model, 1 * z[1] + x[2], MOI.EqualTo(1))
open("file.mzn", "w") do io
write(io, model)
end
end
main (generic function with 1 method)
julia> main()
shell> cat file.mzn
include "alldifferent.mzn";
var 1 .. 3: x1;
var 1 .. 3: x2;
var 1 .. 3: x3;
var bool: x4;
var bool: x5;
constraint 1*x2 + 1*x4 = 1;
constraint x4 <-> alldifferent([x1, x2]);
constraint x5 <-> alldifferent([x2, x3]);
solve satisfy;
Ok. Changed MiniZinc.Reified()
to MOI.Reified()
and this error is gone.
For the write statement
open("file.mzn", "w") do io
write(io, model)
end
I get nevertheless
ERROR: MethodError: no method matching write(::IOStream, ::MathOptInterface.Utilities.CachingOptimizer{MiniZinc.Optimizer{Int64}, MathOptInterface.Utilities.GenericModel{Int64, MathOptInterface.Utilities.ObjectiveContainer{Int64}, MathOptInterface.Utilities.VariablesContainer{Int64}, MiniZinc.ModelFunctionConstraints{Int64}}})
Closest candidates are:
write(::IO, ::Any) at io.jl:672
write(::IO, ::Any, ::Any...) at io.jl:673
write(::IO, ::Union{Float16, Float32, Float64, Int128, Int16, Int32, Int64, UInt128, UInt16, UInt32, UInt64}) at io.jl:686
...
Stacktrace:
[1] write(io::IOStream, x::MathOptInterface.Utilities.CachingOptimizer{MiniZinc.Optimizer{Int64}, MathOptInterface.Utilities.GenericModel{Int64, MathOptInterface.Utilities.ObjectiveContainer{Int64}, MathOptInterface.Utilities.VariablesContainer{Int64}, MiniZinc.ModelFunctionConstraints{Int64}}})
@ Base .\io.jl:672
[2] (::var"#13#14"{MathOptInterface.Utilities.CachingOptimizer{MiniZinc.Optimizer{Int64}, MathOptInterface.Utilities.GenericModel{Int64, MathOptInterface.Utilities.ObjectiveContainer{Int64}, MathOptInterface.Utilities.VariablesContainer{Int64}, MiniZinc.ModelFunctionConstraints{Int64}}}})(io::IOStream)
@ Main c:\Micha\Programming\Julia\jlMiniZinc.jl:39
[3] open(::var"#13#14"{MathOptInterface.Utilities.CachingOptimizer{MiniZinc.Optimizer{Int64}, MathOptInterface.Utilities.GenericModel{Int64, MathOptInterface.Utilities.ObjectiveContainer{Int64}, MathOptInterface.Utilities.VariablesContainer{Int64}, MiniZinc.ModelFunctionConstraints{Int64}}}}, ::String, ::Vararg{String}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ Base .\io.jl:384
[4] open(::Function, ::String, ::String)
@ Base .\io.jl:381
[5] main()
@ Main c:\Micha\Programming\Julia\jlMiniZinc.jl:38
[6] top-level scope
@ c:\Micha\Programming\Julia\jlMiniZinc.jl:48
I changed the model to be
model = MiniZinc.Model{Int}()
:smiley:
Ok. So I did and it works for write()
, but now no optimization is possible, because you removed optimize!()
and I didn't (I usually like to do interactive debugging, like e.g. in LPsolve-IDE for lp files):
C:\Micha\Programming\Julia>julia jlMiniZinc.jl
ERROR: LoadError: MethodError: no method matching optimize!(::MathOptInterface.Utilities.GenericModel{Int64, MathOptInterface.Utilities.ObjectiveContainer{Int64}, MathOptInterface.Utilities.VariablesContainer{Int64}, MiniZinc.ModelFunctionConstraints{Int64}})
Closest candidates are:
optimize!(::Any, ::Any) at C:\Users\Michael\.julia\packages\MathOptInterface\Ht8hE\src\MathOptInterface.jl:84
optimize!(::MathOptInterface.Utilities.MockOptimizer) at C:\Users\Michael\.julia\packages\MathOptInterface\Ht8hE\src\Utilities\mockoptimizer.jl:205
optimize!(::MathOptInterface.Utilities.CachingOptimizer) at C:\Users\Michael\.julia\packages\MathOptInterface\Ht8hE\src\Utilities\cachingoptimizer.jl:302
...
Stacktrace:
[1] main()
@ Main C:\Micha\Programming\Julia\jlMiniZinc.jl:45
[2] top-level scope
@ C:\Micha\Programming\Julia\jlMiniZinc.jl:51
in expression starting at C:\Micha\Programming\Julia\jlMiniZinc.jl:51
Oh, you want both. How's this:
julia> function main()
model = MOI.Utilities.CachingOptimizer(
MiniZinc.Model{Int}(),
MiniZinc.Optimizer{Int}(MiniZinc.Chuffed()),
)
# xᵢ ∈ {1, 2, 3} ∀i=1,2,3
x = MOI.add_variables(model, 3)
MOI.add_constraint.(model, x, MOI.Interval(1, 3))
MOI.add_constraint.(model, x, MOI.Integer())
# zⱼ ∈ {0, 1} ∀j=1,2
z = MOI.add_variables(model, 2)
MOI.add_constraint.(model, z, MOI.ZeroOne())
# z₁ <-> x₁ != x₂
MOI.add_constraint(
model,
MOI.VectorOfVariables([z[1], x[1], x[2]]),
MOI.Reified(MOI.AllDifferent(2)),
)
# z₂ <-> x₂ != x₃
MOI.add_constraint(
model,
MOI.VectorOfVariables([z[2], x[2], x[3]]),
MOI.Reified(MOI.AllDifferent(2)),
)
# z₁ + z₂ = 1
MOI.add_constraint(model, 1 * z[1] + x[2], MOI.EqualTo(1))
open("file.mzn", "w") do io
write(io, model.model_cache)
end
MOI.optimize!(model)
x_star = MOI.get(model, MOI.VariablePrimal(), x)
z_star = MOI.get(model, MOI.VariablePrimal(), z)
return x_star, z_star
end
main (generic function with 1 method)
julia> main()
Warning: included file "count.mzn" overrides a global constraint file from the standard library. This is deprecated. For a solver-specific redefinition of a global constraint, override "fzn_<global>.mzn" instead.
Warning: included file "global_cardinality_low_up.mzn" overrides a global constraint file from the standard library. This is deprecated. For a solver-specific redefinition of a global constraint, override "fzn_<global>.mzn" instead.
([1, 1, 3], [0, 1])
shell> cat file.mzn
include "alldifferent.mzn";
var 1 .. 3: x1;
var 1 .. 3: x2;
var 1 .. 3: x3;
var bool: x4;
var bool: x5;
constraint 1*x2 + 1*x4 = 1;
constraint x4 <-> alldifferent([x1, x2]);
constraint x5 <-> alldifferent([x2, x3]);
solve satisfy;
I'm now here (writing and reading works):
ENV["JULIA_LIBMINIZINC_DIR"] = "C:\\bin\\MiniZinc"
import MiniZinc
const MOI = MiniZinc.MOI
function main()
model = MOI.Utilities.CachingOptimizer(
MiniZinc.Model{Int}(),
MiniZinc.Optimizer{Int}(MiniZinc.Chuffed()),
)
# xᵢ ∈ {1, 2, 3} ∀i=1,2,3
x = MOI.add_variables(model, 3)
MOI.add_constraint.(model, x, MOI.Interval(1, 3))
MOI.add_constraint.(model, x, MOI.Integer())
# zⱼ ∈ {0, 1} ∀j=1,2
z = MOI.add_variables(model, 2)
MOI.add_constraint.(model, z, MOI.ZeroOne())
# z₁ <-> x₁ != x₂
MOI.add_constraint(
model,
MOI.VectorOfVariables([z[1], x[1], x[2]]),
MOI.Reified(MOI.AllDifferent(2)),
)
# z₂ <-> x₂ != x₃
MOI.add_constraint(
model,
MOI.VectorOfVariables([z[2], x[2], x[3]]),
MOI.Reified(MOI.AllDifferent(2)),
)
# z₁ + z₂ = 1
MOI.add_constraint(model, 1 * z[1] + x[2], MOI.EqualTo(1))
# write it to MiniZinc
open("file.mzn", "w") do io
write(io, model.model_cache)
end
# read from MiniZinc file, just to check if it works --> it works!
open("file.mzn", "w") do io
model = read(io)
end
MOI.optimize!(model)
x_star = MOI.get(model, MOI.VariablePrimal(), x)
z_star = MOI.get(model, MOI.VariablePrimal(), z)
return x_star, z_star
end
main()
and get ...
EDIT: sorry had a typo, the error is
C:\Micha\Programming\Julia>julia jlMiniZinc.jl
ERROR: LoadError: MethodError: no method matching optimize!(::Vector{UInt8})
Closest candidates are:
optimize!(::Any, ::Any) at C:\Users\Michael\.julia\packages\MathOptInterface\Ht8hE\src\MathOptInterface.jl:84
optimize!(::MathOptInterface.Utilities.MockOptimizer) at C:\Users\Michael\.julia\packages\MathOptInterface\Ht8hE\src\Utilities\mockoptimizer.jl:205
optimize!(::MathOptInterface.Utilities.CachingOptimizer) at C:\Users\Michael\.julia\packages\MathOptInterface\Ht8hE\src\Utilities\cachingoptimizer.jl:302
...
Stacktrace:
[1] main()
@ Main C:\Micha\Programming\Julia\jlMiniZinc.jl:45
[2] top-level scope
@ C:\Micha\Programming\Julia\jlMiniZinc.jl:52
in expression starting at C:\Micha\Programming\Julia\jlMiniZinc.jl:52
We don't support reading mzn files.
We don't support reading mzn files.
Well, why it works?
Well, why it works?
Your model = read(io)
reads in a vector of bytes. It doesn't create a new MiniZinc.Model
.
Ok ... :confused: my fault. I red and wrote just the text, since optimize didn't work I didn't realize ...
I'm now at my work computer and it works in this version:
function main()
model = MOI.Utilities.CachingOptimizer(
MiniZinc.Model{Int}(),
MiniZinc.Optimizer{Int}(MiniZinc.Chuffed()),
)
# xᵢ ∈ {1, 2, 3} ∀i=1,2,3
x = MOI.add_variables(model, 3)
MOI.add_constraint.(model, x, MOI.Interval(1, 3))
MOI.add_constraint.(model, x, MOI.Integer())
# zⱼ ∈ {0, 1} ∀j=1,2
z = MOI.add_variables(model, 2)
MOI.add_constraint.(model, z, MOI.ZeroOne())
# z₁ <-> x₁ != x₂
MOI.add_constraint(
model,
MOI.VectorOfVariables([z[1], x[1], x[2]]),
MOI.Reified(MOI.AllDifferent(2)),
)
# z₂ <-> x₂ != x₃
MOI.add_constraint(
model,
MOI.VectorOfVariables([z[2], x[2], x[3]]),
MOI.Reified(MOI.AllDifferent(2)),
)
# z₁ + z₂ = 1
MOI.add_constraint(model, 1 * z[1] + x[2], MOI.EqualTo(1))
MOI.optimize!(model)
dest = MOI.FileFormats.Model(format = MOI.FileFormats.FORMAT_MOF)
# write as json
MOI.write_to_file(dest, "file.mof.json")
# write for MiniZinc-IDE
open("file.mzn", "w") do io
write(io, model.model_cache)
end
x_star = MOI.get(model, MOI.VariablePrimal(), x)
z_star = MOI.get(model, MOI.VariablePrimal(), z)
return x_star, z_star
end
So thank you. I'll try to figure out for myself where the problem is at my home computer.
Using
on a test problem results in
i.e. obviously well formatted but empty file.
Nevertheless, this is not the standard format for MiniZinc.
So how to write aproblem to file and how to write it in a format that MiniZinc-IDE understands? For a LP-problem one can write in lp or mps format for other solvers or to be visually inspected. With MiniZinc.jl it should be at least possible to write a file readable for MiniZinc (and humans).