Skip to content

Commit 5d375f2

Browse files
authored
Support comparison operators (#35)
1 parent 78561ec commit 5d375f2

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

src/nonlinear_oracle.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ Parse `expr` into `f` and return a `_Node`.
173173
This function gets called recursively.
174174
"""
175175
function _Node(f::_Function, expr::Expr)
176+
if Meta.isexpr(expr, :||) || Meta.isexpr(expr, :&&)
177+
return _Node(f, expr.head, (_Node(f, arg) for arg in expr.args)...)
178+
end
176179
@assert Meta.isexpr(expr, :call)
177180
# Performance optimization: most calls will be unary or binary
178181
# operators. Therefore, we can specialize an if-statement to handle the
@@ -219,6 +222,10 @@ function _expr_to_symbolics(model::MOI.Nonlinear.Model, expr::_Node, p, x)
219222
args = [_expr_to_symbolics(model, c, p, x) for c in expr.children]
220223
if hasproperty(Base, expr.operation)
221224
return getproperty(Base, expr.operation)(args...)
225+
elseif expr.operation == :&&
226+
return (&)(args...)
227+
elseif expr.operation == :||
228+
return (|)(args...)
222229
end
223230
# If the function isn't defined in Base, defer to the operator registry.
224231
# We don't do this for all functions, because MOI uses NaNMath, which
@@ -518,6 +525,10 @@ function _to_expr(
518525
MOI.VariableIndex(variable_order[node.index])
519526
elseif node.type == MOI.Nonlinear.NODE_PARAMETER
520527
data.parameters[node.index]
528+
elseif node.type == MOI.Nonlinear.NODE_LOGIC
529+
Expr(data.operators.logic_operators[node.index])
530+
elseif node.type == MOI.Nonlinear.NODE_COMPARISON
531+
Expr(:call, data.operators.comparison_operators[node.index])
521532
else
522533
@assert node.type == MOI.Nonlinear.NODE_VALUE
523534
expr.values[node.index]

test/runtests.jl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,23 @@ function test_constant_subexpressions_expr()
421421
return
422422
end
423423

424+
function test_logic_comparison_expr()
425+
if VERSION < v"1.7"
426+
return # Symbolics doesn't support Base.ifelse in Julia v1.6
427+
end
428+
model = Model(Ipopt.Optimizer)
429+
@variable(model, -1 <= x <= 1)
430+
@objective(model, Max, ifelse(-0.5 <= x && x <= 0.5, 1 - x^2, 0))
431+
set_attribute(
432+
model,
433+
MOI.AutomaticDifferentiationBackend(),
434+
MathOptSymbolicAD.DefaultBackend(),
435+
)
436+
optimize!(model)
437+
Test.@test termination_status(model) == LOCALLY_SOLVED
438+
return
439+
end
440+
424441
end # module
425442

426443
RunTests.runtests()

0 commit comments

Comments
 (0)