This needs revisiting:
julia> using JuMP, Ipopt, MathOptComplements
julia> model = Model(() -> MathOptComplements.Optimizer(Ipopt.Optimizer()))
A JuMP Model
├ solver: Ipopt
├ objective_sense: FEASIBILITY_SENSE
├ num_variables: 0
├ num_constraints: 0
└ Names registered in the model: none
julia> @variable(model, x >= 1)
x
julia> @variable(model, y >= 0)
y
julia> @constraint(model, x ⟂ y)
[x, y] ∈ MathOptInterface.Complements(2)
julia> optimize!(model)
ERROR: AssertionError: lb1 == 0.0
Stacktrace:
[1] _relax_complementarity_lower_bound!(model::MathOptComplements.Optimizer{…}, relaxation::MathOptComplements.Bridges.ScholtesRelaxation{…}, x1::MathOptInterface.VariableIndex, x2::MathOptInterface.VariableIndex, lb2::Float64, ub2::Float64)
It's a valid MCP
julia> using JuMP, PATHSolver
julia> model = Model(PATHSolver.Optimizer)
A JuMP Model
├ solver: Path 5.1.99
├ objective_sense: FEASIBILITY_SENSE
├ num_variables: 0
├ num_constraints: 0
└ Names registered in the model: none
julia> @variable(model, x >= 1)
x
julia> @variable(model, y >= 0)
y
julia> @constraint(model, x ⟂ y)
[x, y] ∈ MathOptInterface.Complements(2)
julia> optimize!(model)
Path 5.1.99 (Mon Jul 24 14:47:28 2023)
Written by Todd Munson, Steven Dirkse, Youngdae Kim, and Michael Ferris
Zero: 2 Single: 0 Double: 0
Major Iterations. . . . 0
Minor Iterations. . . . 0
Restarts. . . . . . . . 0
Crash Iterations. . . . 0
Gradient Steps. . . . . 0
Function Evaluations. . 0
Gradient Evaluations. . 0
Basis Time. . . . . . . 0.000000
Total Time. . . . . . . 0.000181
Residual. . . . . . . . 0.000000e+00
Postsolved residual: 0.0000e+00
julia> value(x), value(y)
(1.0, 0.0)
This needs revisiting:
It's a valid MCP