For example, there are two JuMP models named M1 and M2:

using JuMP
M1 = Model()
@variable(M1, x <= 3)
@variable(M1, y <= 3)
@objective(M1, Max, x + y)
M2 = Model()
@variable(M2, x >= 1)
@variable(M2, y >= 1)
@constraint(M2, x + y <= 3)

How to merge M2 into M1, and if they have variables with the same names, rename the corresponding variables from M2 (except the variable is x)?

I donâ€™t know about JuMP.jl specifically, however Iâ€™ll note that JuMP is just a convenient higher-level interface for MathOptInterface.jl, and the latter might be better suited for your needs if youâ€™re having these kinds of issues. Personally I never use JuMP, instead relying on MOI directly.

Just so I understand your problem, how exactly this would work? Only one of the models has an objective function? (Otherwise, you would need some way to merge objective functions.) But if only the variables of one model appear in the objective function, and the variables of the two models are disjunct (you rename so they are not the same), then what you have in reality is really two models (not one).

Could you elaborate a bit on what this should mathematically mean?
As far as I understand you would like to rename the x in M2 â€śbefore margingâ€ť. So letâ€™s call it z.

If I would â€śmergeâ€ť these into M1, I would still be able to choose y and (now) z freely, since the objective does only depend on (M1s) x.
So that merge would mathematically have zero effect compared to just considering M1.

For example, there may be a main model that is open to the user to allow them to add some other constraints w.r.t. some certain variable such as the model M1 and the variable x in the OP.

Perhaps it can be written within the following function:

using JuMP
function fun(M2::Moldel)
M1 = Model()
@variable(M1, x <= 3)
@variable(M1, y <= 3)
@objective(M1, Max, x + y)
# Merge M2 into M1 here.
optimize!(M1)
return value(x)
end

Of course, I canâ€™t expect how the users would model the constraints w.r.t. x. Maybe they would introduce other variables like y as auxiliary variables. But do you think it would be the developerâ€™s duty to make sure the auxiliary variables from the input model (M2) donâ€™t conflict with the internal main model (M1)?

Wonâ€™t that be a legitimate need, or will there be any work-around?

function fun(M::Model)
x, y = M[:x], M[:y]
@objective(M, Max, x + y)
optimize!(M)
return value(x)
end

But do you think it would be the developerâ€™s duty to make sure the auxiliary variables from the input model (M2 ) donâ€™t conflict with the internal main model (M1 )?

Yes. JuMP supports anonymous variables for this use-case.

function fun(M::Model)
x = M[:x]
y = @variable(M, upper_bound = 3)
# This y is not the other y
@objective(M, Max, x + y)
optimize!(M)
return value(x)
end