Skip to content

Commit

Permalink
Merge 78f6960 into 798258d
Browse files Browse the repository at this point in the history
  • Loading branch information
blegat committed Jan 10, 2019
2 parents 798258d + 78f6960 commit 6fa048b
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 3 deletions.
43 changes: 40 additions & 3 deletions src/JuMP.jl
Original file line number Diff line number Diff line change
Expand Up @@ -549,21 +549,58 @@ function dual(cr::ConstraintRef{Model, <:MOICON})
dual_shape(cr.shape))
end

"""
struct OptimizeNotCalled <: Exception end
A result attribute cannot be queried before [`optimize!`](@ref) is called.
"""
struct OptimizeNotCalled <: Exception end

# Throws an error if `optimize!` has not been called, i.e., if there is no
# optimizer attached or if the termination statis is `MOI.OPTIMIZE_NOT_CALLED`.
function moi_get_result(model::MOI.ModelLike, args...)
if MOI.get(model, MOI.TerminationStatus()) == MOI.OPTIMIZE_NOT_CALLED
throw(OptimizeNotCalled())
end
return MOI.get(model, args...)
end
function moi_get_result(model::MOIU.CachingOptimizer, args...)
if MOIU.state(model) == MOIU.NO_OPTIMIZER ||
MOI.get(model, MOI.TerminationStatus()) == MOI.OPTIMIZE_NOT_CALLED
throw(OptimizeNotCalled())
end
return MOI.get(model, args...)
end

"""
get(m::JuMP.Model, attr::MathOptInterface.AbstractModelAttribute)
Return the value of the attribute `attr` from model's MOI backend.
"""
MOI.get(m::Model, attr::MOI.AbstractModelAttribute) = MOI.get(backend(m), attr)
function MOI.get(model::Model, attr::MOI.AbstractModelAttribute)
if MOI.is_set_by_optimize(attr)
moi_get_result(backend(model), attr)
else
MOI.get(backend(model), attr)
end
end
function MOI.get(model::Model, attr::MOI.AbstractVariableAttribute,
v::VariableRef)
check_belongs_to_model(v, model)
return MOI.get(backend(model), attr, index(v))
if MOI.is_set_by_optimize(attr)
return moi_get_result(backend(model), attr, index(v))
else
return MOI.get(backend(model), attr, index(v))
end
end
function MOI.get(model::Model, attr::MOI.AbstractConstraintAttribute,
cr::ConstraintRef)
check_belongs_to_model(cr, model)
return MOI.get(backend(model), attr, index(cr))
if MOI.is_set_by_optimize(attr)
return moi_get_result(backend(model), attr, index(cr))
else
return MOI.get(backend(model), attr, index(cr))
end
end

MOI.set(m::Model, attr::MOI.AbstractModelAttribute, value) = MOI.set(backend(m), attr, value)
Expand Down
13 changes: 13 additions & 0 deletions test/model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,19 @@ end
include("nonnegative_bridge.jl")

function test_model()
@testset "Result attributes" begin
err = JuMP.OptimizeNotCalled()
model = Model()
@variable(model, x)
c = @constraint(model, x 0)
@objective(model, Max, x)
@test_throws err JuMP.objective_value(model)
@test_throws err JuMP.objective_bound(model)
@test_throws err JuMP.value(x)
@test_throws err JuMP.value(c)
@test_throws err JuMP.dual(c)
end

@testset "Test variable/model 'hygiene'" begin
model_x = Model()
@variable(model_x, x)
Expand Down

0 comments on commit 6fa048b

Please sign in to comment.