diff --git a/src/constraints.jl b/src/constraints.jl index b42ea4495ca..5db80f7ca12 100644 --- a/src/constraints.jl +++ b/src/constraints.jl @@ -1543,18 +1543,31 @@ function relax_with_penalty!( return relax_with_penalty!(model, Dict(); default = default) end -struct _BooleanEqualTo end +struct _DoNotConvertSet{S} <: MOI.AbstractScalarSet + set::S +end + +model_convert(::AbstractModel, set::_DoNotConvertSet) = set + +function moi_set(constraint::ScalarConstraint{F,<:_DoNotConvertSet}) where {F} + return constraint.set.set +end + +function _build_boolean_equal_to(::Function, lhs, rhs) + set = _DoNotConvertSet(MOI.EqualTo(true)) + return ScalarConstraint(op_equal_to(lhs, rhs), set) +end -function build_constraint(::Function, lhs, rhs, ::_BooleanEqualTo) - return ScalarConstraint(op_equal_to(lhs, rhs), MOI.EqualTo(true)) +function _build_boolean_equal_to(::Function, lhs::Bool, rhs) + return ScalarConstraint(rhs, _DoNotConvertSet(MOI.EqualTo(lhs))) end -function build_constraint(::Function, lhs::Bool, rhs, ::_BooleanEqualTo) - return ScalarConstraint(rhs, MOI.EqualTo(lhs)) +function _build_boolean_equal_to(::Function, lhs, rhs::Bool) + return ScalarConstraint(lhs, _DoNotConvertSet(MOI.EqualTo(rhs))) end -function build_constraint(::Function, lhs, rhs::Bool, ::_BooleanEqualTo) - return ScalarConstraint(lhs, MOI.EqualTo(rhs)) +function _build_boolean_equal_to(error_fn::Function, lhs::Bool, rhs::Bool) + return error_fn("cannot add the trivial constraint `$lhs := $rhs`") end function parse_constraint_head(error_fn::Function, ::Val{:(:=)}, lhs, rhs) @@ -1564,8 +1577,6 @@ function parse_constraint_head(error_fn::Function, ::Val{:(:=)}, lhs, rhs) $parse_code_lhs $parse_code_rhs end - build_code = quote - build_constraint($error_fn, $new_lhs, $new_rhs, _BooleanEqualTo()) - end + build_code = :(_build_boolean_equal_to($error_fn, $new_lhs, $new_rhs)) return false, parse_code, build_code end diff --git a/src/macros.jl b/src/macros.jl index 2a5127bfc34..9cb281d0315 100644 --- a/src/macros.jl +++ b/src/macros.jl @@ -1160,10 +1160,6 @@ function model_convert(model::AbstractModel, set::MOI.AbstractScalarSet) return set end -function model_convert(model::GenericModel{Bool}, set::MOI.EqualTo{Bool}) - return set -end - function model_convert(model::AbstractModel, α::Number) T = value_type(typeof(model)) V = variable_ref_type(model) diff --git a/test/test_constraint.jl b/test/test_constraint.jl index 98a0ce4e3b0..02e5dd009e8 100644 --- a/test/test_constraint.jl +++ b/test/test_constraint.jl @@ -1766,34 +1766,34 @@ function test_def_equal_to_operator_float() c = @constraint(model, x[1] := x[2]) o = constraint_object(c) @test isequal_canonical(o.func, op_equal_to(x[1], x[2])) - @test o.set == MOI.EqualTo(1.0) + @test o.set == MOI.EqualTo(true) # x[1] == x[2] := false c = @constraint(model, x[1] == x[2] := false) o = constraint_object(c) @test isequal_canonical(o.func, op_equal_to(x[1], x[2])) - @test o.set == MOI.EqualTo(0.0) + @test o.set == MOI.EqualTo(false) # x[1] && x[2] := false c = @constraint(model, x[1] && x[2] := false) o = constraint_object(c) @test isequal_canonical(o.func, op_and(x[1], x[2])) - @test o.set == MOI.EqualTo(0.0) + @test o.set == MOI.EqualTo(false) # x[1] && x[2] := true c = @constraint(model, x[1] && x[2] := true) o = constraint_object(c) @test isequal_canonical(o.func, op_and(x[1], x[2])) - @test o.set == MOI.EqualTo(1.0) + @test o.set == MOI.EqualTo(true) # x[1] || x[2] := y y = true c = @constraint(model, x[1] || x[2] := y) o = constraint_object(c) @test isequal_canonical(o.func, op_or(x[1], x[2])) - @test o.set == MOI.EqualTo(1.0) + @test o.set == MOI.EqualTo(true) # y := x[1] || x[2] y = true c = @constraint(model, y := x[1] || x[2]) o = constraint_object(c) @test isequal_canonical(o.func, op_or(x[1], x[2])) - @test o.set == MOI.EqualTo(1.0) + @test o.set == MOI.EqualTo(true) return end