jump-dev / JuMP.jl

Modeling language for Mathematical Optimization (linear, mixed-integer, conic, semidefinite, nonlinear)
http://jump.dev/JuMP.jl/
Other
2.22k stars 393 forks source link

Diagnostic for named constraint without constraint could be improved #3780

Closed LebedevRI closed 2 months ago

LebedevRI commented 2 months ago
using JuMP
import HiGHS

function foo()
    model = Model(
        optimizer_with_attributes(
            HiGHS.Optimizer,
            "time_limit" => 10.0,
        ),
    )

    N = 3
    M = 2

    x = [@variable(model, [1:N,1:N], base_name="a($m)", Symmetric, Bin) for m=1:M]
    y = @variable(model, [1:N,1:N], base_name="b", Symmetric, Bin)

    z = [[@variable(model, [1:N,1:N], base_name="c($m)[$k]", Symmetric, Bin) for k=1:N] for m=1:M-1]
    a = [[x[1][k,i] for i=1:N,j=1:N] for k=1:N]
    b = [[x[1][k,j] for i=1:N,j=1:N] for k=1:N]
    c = a+b-fill(fill(1, (N, N)), N)
    @assert all(LinearAlgebra.issymmetric.(c))
    c = LinearAlgebra.Symmetric.(c)
    @constraints(model, begin
        # This is fine
        c0, (z[1][1]) .>= (c[1])
        # Fails to parse
        c1, [k=1:N], (z[1][1]) .>= (c[1])
        # The actual wanted constraint
        # c2, [k=1:N], (z[1][k]) .>= (c[k])
    end); 

    print(model)
end

foo()
LoadError: At In[19]:28: `@constraint(model, c1, [k = 1:N], (z[1])[1] .>= c[1])`: Unsupported constraint expression: we don't know how to parse constraints containing expressions of type :vect.

If you are writing a JuMP extension, implement `parse_constraint_head(::Function, ::Val{:vect}, args...)
in expression starting at In[19]:28

Stacktrace:
 [1] error(::String, ::String)
   @ Base ./error.jl:44
 [2] (::JuMP.Containers.var"#error_fn#98"{String})(str::String)
   @ JuMP.Containers ~/.julia/packages/JuMP/7rBNn/src/Containers/macro.jl:331
 [3] parse_constraint_head(error_fn::JuMP.Containers.var"#error_fn#98"{String}, ::Val{:vect}, args::Expr)
   @ JuMP ~/.julia/packages/JuMP/7rBNn/src/macros/@constraint.jl:412
 [4] parse_constraint(error_fn::Function, expr::Expr)
   @ JuMP ~/.julia/packages/JuMP/7rBNn/src/macros/@constraint.jl:307
 [5] var"@constraint"(__source__::LineNumberNode, __module__::Module, input_args::Vararg{Any})
   @ JuMP ~/.julia/packages/JuMP/7rBNn/src/macros/@constraint.jl:140
blegat commented 2 months ago

Replace c1, [k=1:N] by c1[k=1:N]

LebedevRI commented 2 months ago

Replace c1, [k=1:N] by c1[k=1:N]

D'oh! Thank you.

odow commented 2 months ago

MWE:

julia> using JuMP

julia> model = Model();

julia> @variable(model, x)
x

julia> @constraint(model, c, [k in 1:2], x <= k)
ERROR: LoadError: At REPL[9]:1: `@constraint(model, c, [k in 1:2], x <= k)`: Unsupported constraint expression: we don't know how to parse constraints containing expressions of type :vect.

If you are writing a JuMP extension, implement `parse_constraint_head(::Function, ::Val{:vect}, args...)
Stacktrace:
 [1] error(::String, ::String)
   @ Base ./error.jl:44
 [2] (::JuMP.Containers.var"#error_fn#98"{String})(str::String)
   @ JuMP.Containers ~/.julia/dev/JuMP/src/Containers/macro.jl:331
 [3] parse_constraint_head(error_fn::JuMP.Containers.var"#error_fn#98"{String}, ::Val{:vect}, args::Expr)
   @ JuMP ~/.julia/dev/JuMP/src/macros/@constraint.jl:412
 [4] parse_constraint(error_fn::Function, expr::Expr)
   @ JuMP ~/.julia/dev/JuMP/src/macros/@constraint.jl:307
 [5] var"@constraint"(__source__::LineNumberNode, __module__::Module, input_args::Vararg{Any})
   @ JuMP ~/.julia/dev/JuMP/src/macros/@constraint.jl:140
in expression starting at REPL[9]:1

We can improve this particular error message.

@LebedevRI since you've now opened quite a few issues, I might ask that you try to make minimal reproducible examples: strip out all the unnecessary stuff, like HiGHS, the Symmetric, comments, etc, so that only the code necessary to reproduce the bug remains.

LebedevRI commented 2 months ago

Thank you for taking a look!

@LebedevRI since you've now opened quite a few issues, I might ask that you try to make minimal reproducible examples: strip out all the unnecessary stuff, like HiGHS, the Symmetric, comments, etc, so that only the code necessary to reproduce the bug remains.

FWIW, i'm already doing that, but i guess insufficiently.