diff --git a/src/MOI_wrapper.jl b/src/MOI_wrapper.jl index a0104fa..9ec6d2c 100644 --- a/src/MOI_wrapper.jl +++ b/src/MOI_wrapper.jl @@ -81,10 +81,10 @@ end MOI.supports_constraint(::Optimizer, ::Type{VI}, ::Type{<:ALS}) = true MOI.supports_constraint(::Optimizer, ::Type{SAF}, ::Type{<:ALS}) = true -MOI.supports_constraint(::Optimizer, ::Type{MOI.ScalarNonlinearFunction}, ::Type{<:ALS}) = true MOI.supports_constraint(::Optimizer, ::Type{VAF}, ::Type{<:VLS}) = true MOI.supports_constraint(::Optimizer, ::Type{SQF}, ::Type{<:ALS}) = true MOI.supports_constraint(::Optimizer, ::Type{VQF}, ::Type{<:VLS}) = true +MOI.supports_constraint(::Optimizer, ::Type{SNF}, ::Type{<:ALS}) = true function MOI.copy_to(dest::Optimizer, src::MOI.ModelLike) if !haskey(dest.options, "solver") diff --git a/src/utils.jl b/src/utils.jl index 423cefc..221789e 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -19,6 +19,11 @@ const SQF = MOI.ScalarQuadraticFunction{Float64} # ScalarQuadraticFunction{T}(a const VQF = MOI.VectorQuadraticFunction{Float64} # VectorQuadraticFunction{T}(affine_terms, quadratic_terms, constants) const QF = Union{SQF, VQF} +# ScalarNonlinearFunction and VectorNonlinearFunction +const SNF = MOI.ScalarNonlinearFunction +const VNF = MOI.VectorNonlinearFunction +const NF = Union{SNF, VNF} + # AffLinSets and VecLinSets const ALS = Union{ MOI.EqualTo{Float64}, @@ -375,11 +380,8 @@ function parser_MOI(moimodel, index_map, nvar) contypes = MOI.get(moimodel, MOI.ListOfConstraintTypesPresent()) for (F, S) in contypes - F <: AF || - F <: QF || - F == MOI.ScalarNonlinearFunction || - F == VI || - error("Function $F is not supported.") + (F == VNF) && error("The function $F is not supported. Please use `.<=`, `.==`, and `.>=` in your constraints to ensure compatibility with ScalarNonlinearFunction.") + F <: AF || F <: QF || F == SNF || F == VI || error("Function $F is not supported.") S <: LS || error("Set $S is not supported.") conindices = MOI.get(moimodel, MOI.ListOfConstraintIndices{F, S}()) @@ -431,7 +433,7 @@ _nlp_model(::MOI.Nonlinear.Model, ::MOI.ModelLike, ::Type, ::Type) = false function _nlp_model( dest::MOI.Nonlinear.Model, src::MOI.ModelLike, - F::Type{<:Union{MOI.ScalarNonlinearFunction, MOI.VectorNonlinearFunction}}, + F::Type{SNF}, S::Type, ) has_nonlinear = false @@ -460,7 +462,7 @@ function _nlp_model(model::MOI.ModelLike)::Union{Nothing, MOI.Nonlinear.Model} has_nonlinear |= _nlp_model(nlp_model, model, F, S) end F = MOI.get(model, MOI.ObjectiveFunctionType()) - if F <: MOI.ScalarNonlinearFunction + if F <: SNF MOI.Nonlinear.set_objective(nlp_model, MOI.get(model, MOI.ObjectiveFunction{F}())) has_nonlinear = true end diff --git a/test/nlp_problems/nf.jl b/test/nlp_problems/nf.jl new file mode 100644 index 0000000..18ae532 --- /dev/null +++ b/test/nlp_problems/nf.jl @@ -0,0 +1,10 @@ +function nf() + f(x::Vector{VariableRef}) = sqrt.(x) + g(x::Vector{VariableRef}) = x.^3 + h(x::Vector{VariableRef}) = sum(x.^4) + nlp = Model() + @variable(nlp, x[1:2]) + @constraint(nlp, f(x) .- g(x) .>= 0) + @objective(nlp, Max, h(x)) + return nlp +end diff --git a/test/runtests.jl b/test/runtests.jl index deae221..7125c6d 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -5,7 +5,7 @@ using Test, Printf nlp_problems = setdiff(NLPModelsTest.nlp_problems, ["MGH01Feas"]) nls_problems = NLPModelsTest.nls_problems -extra_nlp_problems = ["nohesspb", "hs61", "hs100", "hs219", "quadcon", "operatorspb"] +extra_nlp_problems = ["nohesspb", "hs61", "hs100", "hs219", "quadcon", "operatorspb", "nf"] extra_nls_problems = ["nlsnohesspb", "HS30", "HS43", "MGH07", "nlsqc"] for problem in lowercase.(nlp_problems ∪ extra_nlp_problems)