Skip to content

Throw NotAllowedError in get_fallback #1777

@blegat

Description

@blegat

Sometimes, a modification end up calling a getter. If MOI.get is not implemented, it ends up calling get_fallback which throws an ArgumentError. A CachingOptimizer calling this modification to the optimizer is waiting for a subtype of NotAllowedError to understand that this modification is not allowed and to automatically move to EMPTY_OPTIMIZER state.
However, as ArgumentError is not a subtype of NotAllowedError then this does not work as shown below:

using MathOptInterface
const MOI = MathOptInterface

MOI.Utilities.@model(
    NoFreeVariablesModel,
    (),
    (MOI.LessThan,),
    (MOI.Nonnegatives,),
    (),
    (),
    (MOI.ScalarAffineFunction,),
    (MOI.VectorOfVariables,),
    ()
)

function MOI.supports_constraint(
    ::NoFreeVariablesModel{T},
    ::Type{MOI.VectorOfVariables},
    ::Type{MOI.Reals},
) where {T}
    return false
end

function MOI.supports_add_constrained_variables(
    ::NoFreeVariablesModel,
    ::Type{MOI.Nonnegatives},
)
    return true
end

MOI.supports_add_constrained_variables(::NoFreeVariablesModel, ::Type{MOI.Reals}) = false

function MOI.get(model::NoFreeVariablesModel, attr::MOI.ConstraintFunction, ci::MOI.ConstraintIndex)
    return MOI.get_fallback(model, attr, ci)
end

function bug()
    inner = NoFreeVariablesModel{Float64}()
    bridged = MOI.Bridges.full_bridge_optimizer(inner, Float64)
    model = MOI.Utilities.CachingOptimizer(
        MOI.Utilities.UniversalFallback(MOI.Utilities.Model{Float64}()),
        bridged,
    )
    x = MOI.add_variable(model)
    c = MOI.add_constraint(model, 1.0 * x, MOI.LessThan(1.0))
    MOI.Utilities.attach_optimizer(model)
    MOI.set(model, MOI.ConstraintSet(), c, MOI.LessThan(2.0))
    return
end

bug()

I would suggest creating a new error type that is a subtype of NotAllowedError and to throw it in get_fallback.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions