Skip to content

Commit

Permalink
Fix error message if NonlinearExpression is mixed with new NL API
Browse files Browse the repository at this point in the history
  • Loading branch information
odow committed May 1, 2024
1 parent 2693f57 commit c4ba589
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
18 changes: 18 additions & 0 deletions src/nlp_expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ struct GenericNonlinearExpr{V<:AbstractVariableRef} <: AbstractJuMPScalar
) where {V<:AbstractVariableRef}
for arg in args
_throw_if_not_real(arg)
_throw_if_legacy(arg)
end
return new{V}(head, Any[a for a in args])
end
Expand All @@ -97,11 +98,28 @@ struct GenericNonlinearExpr{V<:AbstractVariableRef} <: AbstractJuMPScalar
) where {V<:AbstractVariableRef}
for arg in args
_throw_if_not_real(arg)
_throw_if_legacy(arg)
end
return new{V}(head, args)
end
end

_throw_if_legacy(::Any) = nothing

function _throw_if_legacy(arg::Union{NonlinearExpression,NonlinearParameter})
return error(
"Cannot create a nonlinear expression that mixes features from " *
"both the legacy (macros beginning with `@NL`) and new " *
"(`NonlinearExpr`) nonlinear interfaces. You must use one or " *
"the other. Got: $arg",
)
end

# This method is necessary to catch errors in an expression like p * x where
# p is a nonlinear parameter.
variable_ref_type(::NonlinearParameter) = GenericVariableRef{Float64}
variable_ref_type(::NonlinearExpression) = GenericVariableRef{Float64}

variable_ref_type(::Type{GenericNonlinearExpr}, ::Any) = nothing

function variable_ref_type(::Type{GenericNonlinearExpr}, x::AbstractJuMPScalar)
Expand Down
36 changes: 36 additions & 0 deletions test/test_nlp_expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1092,4 +1092,40 @@ function test_error_nonlinear_expr_complex_constructor()
return
end

function test_error_legacy_expression_constructor()
model = Model()
@variable(model, x)
@NLexpression(model, arg, x^3)
err = ErrorException(
"Cannot create a nonlinear expression that mixes features from " *
"both the legacy (macros beginning with `@NL`) and new " *
"(`NonlinearExpr`) nonlinear interfaces. You must use one or " *
"the other. Got: $arg",
)
@test_throws err GenericNonlinearExpr(:*, Any[x, arg])
@test_throws err GenericNonlinearExpr(:*, x, arg)
@test_throws err (x * arg)
@test_throws err (arg * x)
return
end

function test_error_legacy_parameter_constructor()
model = Model()
@variable(model, x)
@NLparameter(model, p == 1)
err = ErrorException(
"Cannot create a nonlinear expression that mixes features from " *
"both the legacy (macros beginning with `@NL`) and new " *
"(`NonlinearExpr`) nonlinear interfaces. You must use one or " *
"the other. Got: $p",
)
@test_throws err GenericNonlinearExpr(:*, Any[x, p])
@test_throws err GenericNonlinearExpr(:*, Any[p, x])
@test_throws err GenericNonlinearExpr(:*, x, p)
@test_throws err GenericNonlinearExpr(:*, p, x)
@test_throws err (x * p)
@test_throws err (p * x)
return
end

end # module

0 comments on commit c4ba589

Please sign in to comment.