`UndefVarError: x not defined` but x is in the model

Hi, I’m having the next problem:

I want to solve a given optimization problem using a JuMP model. In the algorithm that I am using I need to pass the model itself to another function having just the variables and I will construct the model (objective function and constraints) in this function. When I do that in the function I have the model but when I try to access to any variable I get the next Error:

>>@show m
m = A JuMP Model
Feasibility problem with:
Variables: 4
`VariableRef`-in-`MathOptInterface.EqualTo{Float64}`: 1 constraint
Model mode: AUTOMATIC
CachingOptimizer state: NO_OPTIMIZER
Solver name: No optimizer attached.
Names registered in the model: l, x, y

>>@show x
UndefVarError: x not defined

Can you help me?

You can do

x = m[:x]

See the doc for more details.

Thank you for your help, but I noticed right now that my problems isn’t that, but when I use Expressions and I want to use the eval() of this expressions as my objective function or constraints, like this:

m = Model()
@variable(m, x[1:2])
f = :(x[1])
@objective(m, Min, eval(f))

That works, but if I do exactly the same inside a function I get the next Error:

function fun()
    m = Model()
    @variable(m, x[1:2])
    f = :(x[1])
    @objective(m, Min, eval(f))
end

fun()
ERROR: VariableNotOwned{VariableRef}(x[1])

I want to keep using the expressions, it’s an important part of my algorithm. Please do you know why is this happening?

Using eval is generally a sign that you shouldn’t be doing what you are trying to do. In this case, eval is evaling things in the global-scope, not function scope.

What are you trying to do? And why/how are you building up f as an expression?

Ok, first at all thank you for your answer.

I’m trying to create a function that solve a class of problem doing an specific algorithm. This function must solve any problem of this class and isn’t just build the model and solve, so the idea is that I must pass to this function all the elements to build the model inside. My idea was passing the objective function and the constraints as expressions. Do you have any suggestion?

My idea was passing the objective function and the constraints as expressions. Do you have any suggestion?

I would pass a function that takes as argument the model and variables and calls the macro inside, e.g. instead of

function fun(f)
    m = Model()
    @variable(m, x[1:2])
    @objective(m, Min, eval(f))
end
fun(:(x[1]))

do

function fun(add_obj)
    m = Model()
    @variable(m, x[1:2])
    add_obj(m, x)
end
fun((m, x) -> @objective(m, Min, x[1]))