diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2146de3de2..2c21dd8ce7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,6 +14,9 @@ jobs: # Since MOI doesn't have binary dependencies, only test on a subset of # possible platforms. include: + - version: 'nightly' + os: ubuntu-latest + arch: x64 - version: '1' os: ubuntu-latest arch: x64 diff --git a/src/FileFormats/LP/LP.jl b/src/FileFormats/LP/LP.jl index b8cd2d850a..f4371aa833 100644 --- a/src/FileFormats/LP/LP.jl +++ b/src/FileFormats/LP/LP.jl @@ -4,6 +4,21 @@ import ..FileFormats import MathOptInterface const MOI = MathOptInterface +# Julia 1.6 removes Grisu from Base. Previously, we went +# print_shortest(io, x) = Base.Grisu.print_shortest(io, x) +# To avoid adding Grisu as a dependency, use the following printing heuristic. +# TODO(odow): consider printing 1.0 as 1.0 instead of 1, i.e., without the +# rounding branch. +function print_shortest(io::IO, x::Real) + x_int = round(Int, x) + if isapprox(x, x_int) + print(io, x_int) + else + print(io, x) + end + return +end + MOI.Utilities.@model(Model, (MOI.ZeroOne, MOI.Integer), (MOI.EqualTo, MOI.GreaterThan, MOI.LessThan, MOI.Interval), @@ -86,17 +101,17 @@ function write_function( ) is_first_item = true if !(func.constant ≈ 0.0) - Base.Grisu.print_shortest(io, func.constant) + print_shortest(io, func.constant) is_first_item = false end for term in func.terms if !(term.coefficient ≈ 0.0) if is_first_item - Base.Grisu.print_shortest(io, term.coefficient) + print_shortest(io, term.coefficient) is_first_item = false else print(io, term.coefficient < 0 ? " - " : " + ") - Base.Grisu.print_shortest(io, abs(term.coefficient)) + print_shortest(io, abs(term.coefficient)) end print(io, " ", variable_names[term.variable_index]) @@ -107,34 +122,34 @@ end function write_constraint_suffix(io::IO, set::MOI.LessThan) print(io, " <= ", ) - Base.Grisu.print_shortest(io, set.upper) + print_shortest(io, set.upper) println(io) return end function write_constraint_suffix(io::IO, set::MOI.GreaterThan) print(io, " >= ", ) - Base.Grisu.print_shortest(io, set.lower) + print_shortest(io, set.lower) println(io) return end function write_constraint_suffix(io::IO, set::MOI.EqualTo) print(io, " = ", ) - Base.Grisu.print_shortest(io, set.value) + print_shortest(io, set.value) println(io) return end function write_constraint_suffix(io::IO, set::MOI.Interval) print(io, " <= ", ) - Base.Grisu.print_shortest(io, set.upper) + print_shortest(io, set.upper) println(io) return end function write_constraint_prefix(io::IO, set::MOI.Interval) - Base.Grisu.print_shortest(io, set.lower) + print_shortest(io, set.lower) print(io, " <= ") return end diff --git a/src/FileFormats/MPS/MPS.jl b/src/FileFormats/MPS/MPS.jl index dd31f93199..6eb6d21c71 100644 --- a/src/FileFormats/MPS/MPS.jl +++ b/src/FileFormats/MPS/MPS.jl @@ -5,6 +5,21 @@ import ..FileFormats import MathOptInterface const MOI = MathOptInterface +# Julia 1.6 removes Grisu from Base. Previously, we went +# print_shortest(io, x) = Base.Grisu.print_shortest(io, x) +# To avoid adding Grisu as a dependency, use the following printing heuristic. +# TODO(odow): consider printing 1.0 as 1.0 instead of 1, i.e., without the +# rounding branch. +function print_shortest(io::IO, x::Real) + x_int = round(Int, x) + if isapprox(x, x_int) + print(io, x_int) + else + print(io, x) + end + return +end + MOI.Utilities.@model(Model, (MOI.ZeroOne, MOI.Integer), (MOI.EqualTo, MOI.GreaterThan, MOI.LessThan, MOI.Interval), @@ -315,7 +330,7 @@ function write_columns(io::IO, model::Model, ordered_names, names) Card( f2 = variable, f3 = constraint, - f4 = sprint(Base.Grisu.print_shortest, coefficient), + f4 = sprint(print_shortest, coefficient), ) ) end @@ -344,7 +359,7 @@ function _write_rhs(io, model, S, sense_char) Card( f2 = "rhs", f3 = row_name, - f4 = sprint(Base.Grisu.print_shortest, value(set)), + f4 = sprint(print_shortest, value(set)), ) ) end @@ -390,7 +405,7 @@ function write_ranges(io::IO, model::Model) Card( f2 = "rhs", f3 = row_name, - f4 = sprint(Base.Grisu.print_shortest, set.upper - set.lower), + f4 = sprint(print_shortest, set.upper - set.lower), ) ) end @@ -423,7 +438,7 @@ function write_single_bound(io::IO, var_name::String, lower, upper) f1 = "FX", f2 = "bounds", f3 = var_name, - f4 = sprint(Base.Grisu.print_shortest, lower), + f4 = sprint(print_shortest, lower), ) ) elseif lower == -Inf && upper == Inf @@ -452,7 +467,7 @@ function write_single_bound(io::IO, var_name::String, lower, upper) f1 = "LO", f2 = "bounds", f3 = var_name, - f4 = sprint(Base.Grisu.print_shortest, lower), + f4 = sprint(print_shortest, lower), ) ) end @@ -472,7 +487,7 @@ function write_single_bound(io::IO, var_name::String, lower, upper) f1 = "UP", f2 = "bounds", f3 = var_name, - f4 = sprint(Base.Grisu.print_shortest, upper), + f4 = sprint(print_shortest, upper), ) ) end @@ -569,7 +584,7 @@ function write_sos_constraint(io::IO, model::Model, index, names) io, Card( f2 = names[variable], - f3 = sprint(Base.Grisu.print_shortest, weight), + f3 = sprint(print_shortest, weight), ) ) end diff --git a/src/Utilities/Utilities.jl b/src/Utilities/Utilities.jl index 992e2458eb..34a300e54d 100644 --- a/src/Utilities/Utilities.jl +++ b/src/Utilities/Utilities.jl @@ -1,7 +1,7 @@ module Utilities using LinearAlgebra # For dot -using OrderedCollections # for OrderedDict in UniversalFallback +using OrderedCollections # for OrderedDict in UniversalFallback import MutableArithmetics const MA = MutableArithmetics @@ -22,13 +22,18 @@ const VI = MOI.VariableIndex const CI{F,S} = MOI.ConstraintIndex{F,S} function print_with_acronym(io::IO, s::AbstractString) + print(io, replace_acronym(s)) +end + +function replace_acronym(s::AbstractString) s = replace(s, "MathOptInterface.Utilities" => "MOIU") s = replace(s, "MathOptInterface.Bridges" => "MOIB") s = replace(s, "MathOptInterface.Test" => "MOIT") s = replace(s, "MathOptInterface" => "MOI") - print(io, s) + return s end + """ _reverse_dict(src::AbstractDict) diff --git a/src/functions.jl b/src/functions.jl index 4ef91dcdb4..d464226778 100644 --- a/src/functions.jl +++ b/src/functions.jl @@ -27,6 +27,7 @@ output_dimension(::AbstractScalarFunction) = 1 Base.broadcastable(f::AbstractScalarFunction) = Ref(f) Base.ndims(::Type{<:AbstractScalarFunction}) = 0 +Base.ndims(::AbstractScalarFunction) = 0 """ AbstractVectorFunction diff --git a/test/Bridges/Constraint/functionize.jl b/test/Bridges/Constraint/functionize.jl index e715e7b067..9f38cd7cc7 100644 --- a/test/Bridges/Constraint/functionize.jl +++ b/test/Bridges/Constraint/functionize.jl @@ -65,9 +65,9 @@ config_with_basis = MOIT.TestConfig(basis = true) end attr = MOIT.UnknownConstraintAttribute() - err = ArgumentError("Bridge of type `MathOptInterface.Bridges.Constraint.ScalarFunctionizeBridge{Float64,MathOptInterface.GreaterThan{Float64}}` does not support setting the attribute `$attr` because `MOIB.Constraint.invariant_under_function_conversion($attr)` returns `false`.") + err = ArgumentError("Bridge of type `$(MathOptInterface.Bridges.Constraint.ScalarFunctionizeBridge{Float64,MathOptInterface.GreaterThan{Float64}})` does not support setting the attribute `$attr` because `MOIB.Constraint.invariant_under_function_conversion($attr)` returns `false`.") @test_throws err MOI.set(bridged_mock, attr, ci, 1.0) - err = ArgumentError("Bridge of type `MathOptInterface.Bridges.Constraint.ScalarFunctionizeBridge{Float64,MathOptInterface.GreaterThan{Float64}}` does not support accessing the attribute `$attr` because `MOIB.Constraint.invariant_under_function_conversion($attr)` returns `false`.") + err = ArgumentError("Bridge of type `$(MathOptInterface.Bridges.Constraint.ScalarFunctionizeBridge{Float64,MathOptInterface.GreaterThan{Float64}})` does not support accessing the attribute `$attr` because `MOIB.Constraint.invariant_under_function_conversion($attr)` returns `false`.") @test_throws err MOI.get(bridged_mock, attr, ci) @testset "delete" begin diff --git a/test/Bridges/Objective/slack.jl b/test/Bridges/Objective/slack.jl index 1e6069fbda..5ca49303b4 100644 --- a/test/Bridges/Objective/slack.jl +++ b/test/Bridges/Objective/slack.jl @@ -90,7 +90,7 @@ end end err = ArgumentError( - "Objective bridge of type `MathOptInterface.Bridges.Objective.SlackBridge{Float64,MathOptInterface.ScalarQuadraticFunction{Float64},MathOptInterface.ScalarQuadraticFunction{Float64}}`" * + "Objective bridge of type `$(MathOptInterface.Bridges.Objective.SlackBridge{Float64,MathOptInterface.ScalarQuadraticFunction{Float64},MathOptInterface.ScalarQuadraticFunction{Float64}})`" * " does not support modifying the objective sense. As a workaround, set" * " the sense to `MOI.FEASIBILITY_SENSE` to clear the objective function" * " and bridges." diff --git a/test/Bridges/Variable/vectorize.jl b/test/Bridges/Variable/vectorize.jl index 81f6ff58e4..af7278a69a 100644 --- a/test/Bridges/Variable/vectorize.jl +++ b/test/Bridges/Variable/vectorize.jl @@ -99,7 +99,7 @@ end @testset "get `UnknownVariableAttribute``" begin err = ArgumentError( - "Variable bridge of type `MathOptInterface.Bridges.Variable.VectorizeBridge{Float64,MathOptInterface.Nonpositives}`" * + "Variable bridge of type `$(MathOptInterface.Bridges.Variable.VectorizeBridge{Float64,MathOptInterface.Nonpositives})`" * " does not support accessing the attribute `MathOptInterface.Test.UnknownVariableAttribute()`." ) @test_throws err MOI.get(bridged_mock, MOIT.UnknownVariableAttribute(), y) diff --git a/test/Bridges/bridge_optimizer.jl b/test/Bridges/bridge_optimizer.jl index ccbdea48cd..4c19cfd463 100644 --- a/test/Bridges/bridge_optimizer.jl +++ b/test/Bridges/bridge_optimizer.jl @@ -142,7 +142,7 @@ bridged_mock = MOIB.Constraint.LessToGreater{Float64}(MOIB.Constraint.SplitInter @testset "Unsupported constraint attribute" begin attr = MOIT.UnknownConstraintAttribute() err = ArgumentError( - "Bridge of type `$MOI.Bridges.Constraint.SplitIntervalBridge{Float64,$MOI.SingleVariable,$MOI.Interval{Float64},$MOI.GreaterThan{Float64},$MOI.LessThan{Float64}}` " * + "Bridge of type `$(MOI.Bridges.Constraint.SplitIntervalBridge{Float64,MOI.SingleVariable,MOI.Interval{Float64},MOI.GreaterThan{Float64},MOI.LessThan{Float64}})` " * "does not support accessing the attribute `$attr`.") x = MOI.add_variable(bridged_mock) ci = MOI.add_constraint(bridged_mock, MOI.SingleVariable(x), @@ -269,10 +269,10 @@ end end @testset "Show" begin - @test sprint(show, bridged_mock) == raw""" - MOIB.Constraint.SingleBridgeOptimizer{MOIB.Constraint.LessToGreaterBridge{Float64,F,G} where G<:MOI.AbstractScalarFunction where F<:MOI.AbstractScalarFunction,MOIB.Constraint.SingleBridgeOptimizer{MOIB.Constraint.SplitIntervalBridge{Float64,F,S,LS,US} where US<:MOI.AbstractSet where LS<:MOI.AbstractSet where S<:MOI.AbstractSet where F<:MOI.AbstractFunction,MOIU.MockOptimizer{NoIntervalModel{Float64}}}} + @test sprint(show, bridged_mock) == MOI.Utilities.replace_acronym(""" + $(MOIB.Constraint.SingleBridgeOptimizer{MOIB.Constraint.LessToGreaterBridge{Float64,F,G} where G<:MOI.AbstractScalarFunction where F<:MOI.AbstractScalarFunction,MOIB.Constraint.SingleBridgeOptimizer{MOIB.Constraint.SplitIntervalBridge{Float64,F,S,LS,US} where US<:MOI.AbstractSet where LS<:MOI.AbstractSet where S<:MOI.AbstractSet where F<:MOI.AbstractFunction,MOIU.MockOptimizer{NoIntervalModel{Float64}}}}) with 1 constraint bridge - with inner model MOIB.Constraint.SingleBridgeOptimizer{MOIB.Constraint.SplitIntervalBridge{Float64,F,S,LS,US} where US<:MOI.AbstractSet where LS<:MOI.AbstractSet where S<:MOI.AbstractSet where F<:MOI.AbstractFunction,MOIU.MockOptimizer{NoIntervalModel{Float64}}} + with inner model $(MOIB.Constraint.SingleBridgeOptimizer{MOIB.Constraint.SplitIntervalBridge{Float64,F,S,LS,US} where US<:MOI.AbstractSet where LS<:MOI.AbstractSet where S<:MOI.AbstractSet where F<:MOI.AbstractFunction,MOIU.MockOptimizer{NoIntervalModel{Float64}}}) with 0 constraint bridges - with inner model MOIU.MockOptimizer{NoIntervalModel{Float64}}""" + with inner model $(MOIU.MockOptimizer{NoIntervalModel{Float64}})""") end diff --git a/test/Bridges/lazy_bridge_optimizer.jl b/test/Bridges/lazy_bridge_optimizer.jl index 73d4a6cbc9..9532b591d7 100644 --- a/test/Bridges/lazy_bridge_optimizer.jl +++ b/test/Bridges/lazy_bridge_optimizer.jl @@ -346,21 +346,21 @@ Bridge graph with 1 variable nodes, 0 constraint nodes and 0 objective nodes. [1] constrained variables in `MOI.PositiveSemidefiniteConeSquare` are not supported """ @test MOI.supports_constraint(bridged, MOI.VectorOfVariables, MOI.PositiveSemidefiniteConeSquare) - @test sprint(MOIB.print_graph, bridged) == """ + @test sprint(MOIB.print_graph, bridged) == MOI.Utilities.replace_acronym(""" Bridge graph with 1 variable nodes, 1 constraint nodes and 0 objective nodes. [1] constrained variables in `MOI.PositiveSemidefiniteConeSquare` are not supported - (1) `MOI.VectorOfVariables`-in-`MOI.PositiveSemidefiniteConeSquare` constraints are bridged (distance 1) by MOIB.Constraint.SquareBridge{$T,MOI.VectorOfVariables,MOI.ScalarAffineFunction{$T},MOI.PositiveSemidefiniteConeTriangle,MOI.PositiveSemidefiniteConeSquare}. -""" + (1) `MOI.VectorOfVariables`-in-`MOI.PositiveSemidefiniteConeSquare` constraints are bridged (distance 1) by $(MOIB.Constraint.SquareBridge{T,MOI.VectorOfVariables,MOI.ScalarAffineFunction{T},MOI.PositiveSemidefiniteConeTriangle,MOI.PositiveSemidefiniteConeSquare}). +""") MOIB.add_bridge(bridged, MOIB.Constraint.VectorFunctionizeBridge{T}) @test_throws MOI.UnsupportedConstraint{MOI.VectorOfVariables, MOI.PositiveSemidefiniteConeSquare} MOIB.bridge_type(bridged, MOI.PositiveSemidefiniteConeSquare) @test MOIB._dist(bridged.graph, MOIB.node(bridged, MOI.PositiveSemidefiniteConeSquare)) == 6 - @test sprint(MOIB.print_graph, bridged) == """ + @test sprint(MOIB.print_graph, bridged) == MOI.Utilities.replace_acronym(""" Bridge graph with 1 variable nodes, 3 constraint nodes and 0 objective nodes. [1] constrained variables in `MOI.PositiveSemidefiniteConeSquare` are supported (distance 6) by adding free variables and then constrain them, see (1). - (1) `MOI.VectorAffineFunction{$T}`-in-`MOI.PositiveSemidefiniteConeSquare` constraints are bridged (distance 3) by MOIB.Constraint.SquareBridge{$T,MOI.VectorAffineFunction{$T},MOI.ScalarAffineFunction{$T},MOI.PositiveSemidefiniteConeTriangle,MOI.PositiveSemidefiniteConeSquare}. - (2) `MOI.VectorAffineFunction{$T}`-in-`MOI.Zeros` constraints are bridged (distance 1) by MOIB.Constraint.ScalarizeBridge{$T,MOI.ScalarAffineFunction{$T},MOI.EqualTo{$T}}. - (3) `MOI.VectorAffineFunction{$T}`-in-`MOI.PositiveSemidefiniteConeTriangle` constraints are bridged (distance 2) by MOIB.Constraint.VectorSlackBridge{$T,MOI.VectorAffineFunction{$T},MOI.PositiveSemidefiniteConeTriangle}. -""" + (1) `MOI.VectorAffineFunction{$T}`-in-`MOI.PositiveSemidefiniteConeSquare` constraints are bridged (distance 3) by $(MOIB.Constraint.SquareBridge{T,MOI.VectorAffineFunction{T},MOI.ScalarAffineFunction{T},MOI.PositiveSemidefiniteConeTriangle,MOI.PositiveSemidefiniteConeSquare}). + (2) `MOI.VectorAffineFunction{$T}`-in-`MOI.Zeros` constraints are bridged (distance 1) by $(MOIB.Constraint.ScalarizeBridge{T,MOI.ScalarAffineFunction{T},MOI.EqualTo{T}}). + (3) `MOI.VectorAffineFunction{$T}`-in-`MOI.PositiveSemidefiniteConeTriangle` constraints are bridged (distance 2) by $(MOIB.Constraint.VectorSlackBridge{T,MOI.VectorAffineFunction{T},MOI.PositiveSemidefiniteConeTriangle}). +""") end @testset "Vectorize" begin @test !MOI.supports_constraint(bridged, MOI.ScalarAffineFunction{T}, MOI.GreaterThan{T}) @@ -424,22 +424,22 @@ Bridge graph with 1 variable nodes, 0 constraint nodes and 0 objective nodes. [1] constrained variables in `MOI.LessThan{$T}` are not supported """ MOIB.add_bridge(bridged, MOIB.Variable.VectorizeBridge{T}) - @test debug_string(MOIB.debug_supports_add_constrained_variable, S) == """ + @test debug_string(MOIB.debug_supports_add_constrained_variable, S) == MOI.Utilities.replace_acronym(""" Constrained variables in `MOI.LessThan{$T}` are not supported and cannot be bridged into supported constrained variables and constraints. See details below: [1] constrained variables in `MOI.LessThan{$T}` are not supported because: - Cannot use `MOIB.Variable.VectorizeBridge{$T,MOI.Nonpositives}` because: + Cannot use `$(MOIB.Variable.VectorizeBridge{T,MOI.Nonpositives})` because: [2] constrained variables in `MOI.Nonpositives` are not supported Cannot add free variables and then constrain them because free variables are bridged but no functionize bridge was added. [2] constrained variables in `MOI.Nonpositives` are not supported because no added bridge supports bridging it. Cannot add free variables and then constrain them because free variables are bridged but no functionize bridge was added. -""" +""") MOIB.add_bridge(bridged, MOIB.Variable.NonposToNonnegBridge{T}) @test debug_string(MOIB.debug_supports_add_constrained_variable, S) == "Constrained variables in `MOI.LessThan{$T}` are supported.\n" - @test sprint(MOIB.print_graph, bridged) == """ + @test sprint(MOIB.print_graph, bridged) == MOI.Utilities.replace_acronym(""" Bridge graph with 2 variable nodes, 0 constraint nodes and 0 objective nodes. - [1] constrained variables in `MOI.LessThan{$T}` are bridged (distance 2) by MOIB.Variable.VectorizeBridge{$T,MOI.Nonpositives}. - [2] constrained variables in `MOI.Nonpositives` are bridged (distance 1) by MOIB.Variable.NonposToNonnegBridge{$T}. -""" + [1] constrained variables in `MOI.LessThan{$T}` are bridged (distance 2) by $(MOIB.Variable.VectorizeBridge{T,MOI.Nonpositives}). + [2] constrained variables in `MOI.Nonpositives` are bridged (distance 1) by $(MOIB.Variable.NonposToNonnegBridge{T}). +""") end bridged = MOIB.LazyBridgeOptimizer(model) @testset "LessThan variables with ScalarFunctionizeBridge" begin @@ -458,25 +458,25 @@ Bridge graph with 1 variable nodes, 1 constraint nodes and 0 objective nodes. (1) `MOI.ScalarAffineFunction{$T}`-in-`MOI.LessThan{$T}` constraints are not supported """ MOIB.add_bridge(bridged, MOIB.Variable.VectorizeBridge{T}) - @test debug_string(MOIB.debug_supports_add_constrained_variable, S) == """ + @test debug_string(MOIB.debug_supports_add_constrained_variable, S) == MOI.Utilities.replace_acronym(""" Constrained variables in `MOI.LessThan{$T}` are not supported and cannot be bridged into supported constrained variables and constraints. See details below: [1] constrained variables in `MOI.LessThan{$T}` are not supported because: - Cannot use `MOIB.Variable.VectorizeBridge{$T,MOI.Nonpositives}` because: + Cannot use `$(MOIB.Variable.VectorizeBridge{T,MOI.Nonpositives})` because: [2] constrained variables in `MOI.Nonpositives` are not supported Cannot add free variables and then constrain them because: (1) `MOI.ScalarAffineFunction{$T}`-in-`MOI.LessThan{$T}` constraints are not supported [2] constrained variables in `MOI.Nonpositives` are not supported because no added bridge supports bridging it. Cannot add free variables and then constrain them because free variables are bridged but no functionize bridge was added. (1) `MOI.ScalarAffineFunction{$T}`-in-`MOI.LessThan{$T}` constraints are not supported because no added bridge supports bridging it. -""" +""") MOIB.add_bridge(bridged, MOIB.Variable.NonposToNonnegBridge{T}) @test debug_string(MOIB.debug_supports_add_constrained_variable, S) == "Constrained variables in `MOI.LessThan{$T}` are supported.\n" - @test sprint(MOIB.print_graph, bridged) == """ + @test sprint(MOIB.print_graph, bridged) == MOI.Utilities.replace_acronym(""" Bridge graph with 2 variable nodes, 1 constraint nodes and 0 objective nodes. - [1] constrained variables in `MOI.LessThan{$T}` are bridged (distance 2) by MOIB.Variable.VectorizeBridge{$T,MOI.Nonpositives}. - [2] constrained variables in `MOI.Nonpositives` are bridged (distance 1) by MOIB.Variable.NonposToNonnegBridge{$T}. + [1] constrained variables in `MOI.LessThan{$T}` are bridged (distance 2) by $(MOIB.Variable.VectorizeBridge{T,MOI.Nonpositives}). + [2] constrained variables in `MOI.Nonpositives` are bridged (distance 1) by $(MOIB.Variable.NonposToNonnegBridge{T}). (1) `MOI.ScalarAffineFunction{$T}`-in-`MOI.LessThan{$T}` constraints are not supported -""" +""") end bridged = MOIB.LazyBridgeOptimizer(model) @testset "Interval constraint" begin @@ -487,17 +487,17 @@ Bridge graph with 2 variable nodes, 1 constraint nodes and 0 objective nodes. (1) `MOI.ScalarAffineFunction{$T}`-in-`MOI.Interval{$T}` constraints are not supported because no added bridge supports bridging it. """ MOIB.add_bridge(bridged, MOIB.Constraint.SplitIntervalBridge{T}) - @test debug_string(MOIB.debug_supports_constraint, F, S) == """ + @test debug_string(MOIB.debug_supports_constraint, F, S) == MOI.Utilities.replace_acronym(""" `MOI.ScalarAffineFunction{$T}`-in-`MOI.Interval{$T}` constraints are not supported and cannot be bridged into supported constrained variables and constraints. See details below: (1) `MOI.ScalarAffineFunction{$T}`-in-`MOI.Interval{$T}` constraints are not supported because: - Cannot use `MOIB.Constraint.SplitIntervalBridge{$T,MOI.ScalarAffineFunction{$T},MOI.Interval{$T},MOI.GreaterThan{$T},MOI.LessThan{$T}}` because: + Cannot use `$(MOIB.Constraint.SplitIntervalBridge{T,MOI.ScalarAffineFunction{T},MOI.Interval{T},MOI.GreaterThan{T},MOI.LessThan{T}})` because: (2) `MOI.ScalarAffineFunction{$T}`-in-`MOI.GreaterThan{$T}` constraints are not supported (3) `MOI.ScalarAffineFunction{$T}`-in-`MOI.LessThan{$T}` constraints are not supported (2) `MOI.ScalarAffineFunction{$T}`-in-`MOI.GreaterThan{$T}` constraints are not supported because no added bridge supports bridging it. (3) `MOI.ScalarAffineFunction{$T}`-in-`MOI.LessThan{$T}` constraints are not supported because no added bridge supports bridging it. -""" +""") MOIB.add_bridge(bridged, MOIB.Constraint.ScalarSlackBridge{T}) - @test debug_string(MOIB.debug_supports_constraint, F, S) == """ + @test debug_string(MOIB.debug_supports_constraint, F, S) == MOI.Utilities.replace_acronym(""" `MOI.ScalarAffineFunction{$T}`-in-`MOI.Interval{$T}` constraints are not supported and cannot be bridged into supported constrained variables and constraints. See details below: [1] constrained variables in `MOI.GreaterThan{$T}` are not supported because no added bridge supports bridging it. Cannot add free variables and then constrain them because free variables are bridged but no functionize bridge was added. @@ -506,23 +506,23 @@ Bridge graph with 2 variable nodes, 1 constraint nodes and 0 objective nodes. [3] constrained variables in `MOI.Interval{$T}` are not supported because no added bridge supports bridging it. Cannot add free variables and then constrain them because free variables are bridged but no functionize bridge was added. (1) `MOI.ScalarAffineFunction{$T}`-in-`MOI.Interval{$T}` constraints are not supported because: - Cannot use `MOIB.Constraint.SplitIntervalBridge{$T,MOI.ScalarAffineFunction{$T},MOI.Interval{$T},MOI.GreaterThan{$T},MOI.LessThan{$T}}` because: + Cannot use `$(MOIB.Constraint.SplitIntervalBridge{T,MOI.ScalarAffineFunction{T},MOI.Interval{T},MOI.GreaterThan{T},MOI.LessThan{T}})` because: (2) `MOI.ScalarAffineFunction{$T}`-in-`MOI.GreaterThan{$T}` constraints are not supported (3) `MOI.ScalarAffineFunction{$T}`-in-`MOI.LessThan{$T}` constraints are not supported - Cannot use `MOIB.Constraint.ScalarSlackBridge{$T,MOI.ScalarAffineFunction{$T},MOI.Interval{$T}}` because: + Cannot use `$(MOIB.Constraint.ScalarSlackBridge{T,MOI.ScalarAffineFunction{T},MOI.Interval{T}})` because: [3] constrained variables in `MOI.Interval{$T}` are not supported (2) `MOI.ScalarAffineFunction{$T}`-in-`MOI.GreaterThan{$T}` constraints are not supported because: - Cannot use `MOIB.Constraint.ScalarSlackBridge{$T,MOI.ScalarAffineFunction{$T},MOI.GreaterThan{$T}}` because: + Cannot use `$(MOIB.Constraint.ScalarSlackBridge{T,MOI.ScalarAffineFunction{T},MOI.GreaterThan{T}})` because: [1] constrained variables in `MOI.GreaterThan{$T}` are not supported (3) `MOI.ScalarAffineFunction{$T}`-in-`MOI.LessThan{$T}` constraints are not supported because: - Cannot use `MOIB.Constraint.ScalarSlackBridge{$T,MOI.ScalarAffineFunction{$T},MOI.LessThan{$T}}` because: + Cannot use `$(MOIB.Constraint.ScalarSlackBridge{T,MOI.ScalarAffineFunction{T},MOI.LessThan{T}})` because: [2] constrained variables in `MOI.LessThan{$T}` are not supported -""" +""") MOIB.add_bridge(bridged, MOIB.Variable.VectorizeBridge{T}) - @test debug_string(MOIB.debug_supports_constraint, F, S) == """ + @test debug_string(MOIB.debug_supports_constraint, F, S) == MOI.Utilities.replace_acronym(""" `MOI.ScalarAffineFunction{$T}`-in-`MOI.Interval{$T}` constraints are not supported and cannot be bridged into supported constrained variables and constraints. See details below: [2] constrained variables in `MOI.LessThan{$T}` are not supported because: - Cannot use `MOIB.Variable.VectorizeBridge{$T,MOI.Nonpositives}` because: + Cannot use `$(MOIB.Variable.VectorizeBridge{T,MOI.Nonpositives})` because: [3] constrained variables in `MOI.Nonpositives` are not supported Cannot add free variables and then constrain them because free variables are bridged but no functionize bridge was added. [3] constrained variables in `MOI.Nonpositives` are not supported because no added bridge supports bridging it. @@ -530,14 +530,14 @@ Bridge graph with 2 variable nodes, 1 constraint nodes and 0 objective nodes. [4] constrained variables in `MOI.Interval{$T}` are not supported because no added bridge supports bridging it. Cannot add free variables and then constrain them because free variables are bridged but no functionize bridge was added. (1) `MOI.ScalarAffineFunction{$T}`-in-`MOI.Interval{$T}` constraints are not supported because: - Cannot use `MOIB.Constraint.SplitIntervalBridge{$T,MOI.ScalarAffineFunction{$T},MOI.Interval{$T},MOI.GreaterThan{$T},MOI.LessThan{$T}}` because: + Cannot use `$(MOIB.Constraint.SplitIntervalBridge{T,MOI.ScalarAffineFunction{T},MOI.Interval{T},MOI.GreaterThan{T},MOI.LessThan{T}})` because: (3) `MOI.ScalarAffineFunction{$T}`-in-`MOI.LessThan{$T}` constraints are not supported - Cannot use `MOIB.Constraint.ScalarSlackBridge{$T,MOI.ScalarAffineFunction{$T},MOI.Interval{$T}}` because: + Cannot use `$(MOIB.Constraint.ScalarSlackBridge{T,MOI.ScalarAffineFunction{T},MOI.Interval{T}})` because: [4] constrained variables in `MOI.Interval{$T}` are not supported (3) `MOI.ScalarAffineFunction{$T}`-in-`MOI.LessThan{$T}` constraints are not supported because: - Cannot use `MOIB.Constraint.ScalarSlackBridge{$T,MOI.ScalarAffineFunction{$T},MOI.LessThan{$T}}` because: + Cannot use `$(MOIB.Constraint.ScalarSlackBridge{T,MOI.ScalarAffineFunction{T},MOI.LessThan{T}})` because: [2] constrained variables in `MOI.LessThan{$T}` are not supported -""" +""") MOIB.add_bridge(bridged, MOIB.Variable.NonposToNonnegBridge{T}) @test debug_string(MOIB.debug_supports_constraint, F, S) == "`MOI.ScalarAffineFunction{$T}`-in-`MOI.Interval{$T}` constraints are supported.\n" end @@ -550,86 +550,86 @@ Objective function of type `MOI.ScalarQuadraticFunction{$T}` is not supported an |1| objective function of type `MOI.ScalarQuadraticFunction{$T}` is not supported because no added bridge supports bridging it. """ MOIB.add_bridge(bridged, MOIB.Objective.SlackBridge{T}) - @test debug_string(MOIB.debug_supports, attr) == """ + @test debug_string(MOIB.debug_supports, attr) == MOI.Utilities.replace_acronym(""" Objective function of type `MOI.ScalarQuadraticFunction{$T}` is not supported and cannot be bridged into a supported objective function by adding only supported constrained variables and constraints. See details below: (1) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.GreaterThan{$T}` constraints are not supported because no added bridge supports bridging it. (2) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.LessThan{$T}` constraints are not supported because no added bridge supports bridging it. |1| objective function of type `MOI.ScalarQuadraticFunction{$T}` is not supported because: - Cannot use `MOIB.Objective.SlackBridge{$T,MOI.ScalarQuadraticFunction{$T},MOI.ScalarQuadraticFunction{$T}}` because: + Cannot use `$(MOIB.Objective.SlackBridge{T,MOI.ScalarQuadraticFunction{T},MOI.ScalarQuadraticFunction{T}})` because: (1) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.GreaterThan{$T}` constraints are not supported (2) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.LessThan{$T}` constraints are not supported |2| objective function of type `MOI.SingleVariable` is not supported |2| objective function of type `MOI.SingleVariable` is not supported because no added bridge supports bridging it. -""" +""") MOIB.add_bridge(bridged, MOIB.Objective.FunctionizeBridge{T}) MOIB.add_bridge(bridged, MOIB.Constraint.QuadtoSOCBridge{T}) - @test debug_string(MOIB.debug_supports, attr) == """ + @test debug_string(MOIB.debug_supports, attr) == MOI.Utilities.replace_acronym(""" Objective function of type `MOI.ScalarQuadraticFunction{$T}` is not supported and cannot be bridged into a supported objective function by adding only supported constrained variables and constraints. See details below: (1) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.GreaterThan{$T}` constraints are not supported because: - Cannot use `MOIB.Constraint.QuadtoSOCBridge{$T}` because: + Cannot use `$(MOIB.Constraint.QuadtoSOCBridge{T})` because: (2) `MOI.VectorAffineFunction{$T}`-in-`MOI.RotatedSecondOrderCone` constraints are not supported (2) `MOI.VectorAffineFunction{$T}`-in-`MOI.RotatedSecondOrderCone` constraints are not supported because no added bridge supports bridging it. (3) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.LessThan{$T}` constraints are not supported because: - Cannot use `MOIB.Constraint.QuadtoSOCBridge{$T}` because: + Cannot use `$(MOIB.Constraint.QuadtoSOCBridge{T})` because: (2) `MOI.VectorAffineFunction{$T}`-in-`MOI.RotatedSecondOrderCone` constraints are not supported |1| objective function of type `MOI.ScalarQuadraticFunction{$T}` is not supported because: - Cannot use `MOIB.Objective.SlackBridge{$T,MOI.ScalarQuadraticFunction{$T},MOI.ScalarQuadraticFunction{$T}}` because: + Cannot use `$(MOIB.Objective.SlackBridge{T,MOI.ScalarQuadraticFunction{T},MOI.ScalarQuadraticFunction{T}})` because: (1) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.GreaterThan{$T}` constraints are not supported (3) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.LessThan{$T}` constraints are not supported -""" +""") MOIB.add_bridge(bridged, MOIB.Constraint.VectorSlackBridge{T}) - @test debug_string(MOIB.debug_supports, attr) == """ + @test debug_string(MOIB.debug_supports, attr) == MOI.Utilities.replace_acronym(""" Objective function of type `MOI.ScalarQuadraticFunction{$T}` is not supported and cannot be bridged into a supported objective function by adding only supported constrained variables and constraints. See details below: [1] constrained variables in `MOI.RotatedSecondOrderCone` are not supported because no added bridge supports bridging it. Cannot add free variables and then constrain them because free variables are bridged but no functionize bridge was added. (1) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.GreaterThan{$T}` constraints are not supported because: - Cannot use `MOIB.Constraint.QuadtoSOCBridge{$T}` because: + Cannot use `$(MOIB.Constraint.QuadtoSOCBridge{T})` because: (2) `MOI.VectorAffineFunction{$T}`-in-`MOI.RotatedSecondOrderCone` constraints are not supported (2) `MOI.VectorAffineFunction{$T}`-in-`MOI.RotatedSecondOrderCone` constraints are not supported because: - Cannot use `MOIB.Constraint.VectorSlackBridge{$T,MOI.VectorAffineFunction{$T},MOI.RotatedSecondOrderCone}` because: + Cannot use `$(MOIB.Constraint.VectorSlackBridge{T,MOI.VectorAffineFunction{T},MOI.RotatedSecondOrderCone})` because: [1] constrained variables in `MOI.RotatedSecondOrderCone` are not supported (3) `MOI.VectorAffineFunction{$T}`-in-`MOI.Zeros` constraints are not supported (3) `MOI.VectorAffineFunction{$T}`-in-`MOI.Zeros` constraints are not supported because no added bridge supports bridging it. (4) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.LessThan{$T}` constraints are not supported because: - Cannot use `MOIB.Constraint.QuadtoSOCBridge{$T}` because: + Cannot use `$(MOIB.Constraint.QuadtoSOCBridge{T})` because: (2) `MOI.VectorAffineFunction{$T}`-in-`MOI.RotatedSecondOrderCone` constraints are not supported |1| objective function of type `MOI.ScalarQuadraticFunction{$T}` is not supported because: - Cannot use `MOIB.Objective.SlackBridge{$T,MOI.ScalarQuadraticFunction{$T},MOI.ScalarQuadraticFunction{$T}}` because: + Cannot use `$(MOIB.Objective.SlackBridge{T,MOI.ScalarQuadraticFunction{T},MOI.ScalarQuadraticFunction{T}})` because: (1) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.GreaterThan{$T}` constraints are not supported (4) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.LessThan{$T}` constraints are not supported -""" +""") MOIB.add_bridge(bridged, MOIB.Variable.RSOCtoPSDBridge{T}) MOIB.add_bridge(bridged, MOIB.Constraint.ScalarFunctionizeBridge{T}) - @test debug_string(MOIB.debug_supports, attr) == """ + @test debug_string(MOIB.debug_supports, attr) == MOI.Utilities.replace_acronym(""" Objective function of type `MOI.ScalarQuadraticFunction{$T}` is not supported and cannot be bridged into a supported objective function by adding only supported constrained variables and constraints. See details below: (1) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.GreaterThan{$T}` constraints are not supported because: - Cannot use `MOIB.Constraint.QuadtoSOCBridge{$T}` because: + Cannot use `$(MOIB.Constraint.QuadtoSOCBridge{T})` because: (2) `MOI.VectorAffineFunction{$T}`-in-`MOI.RotatedSecondOrderCone` constraints are not supported (2) `MOI.VectorAffineFunction{$T}`-in-`MOI.RotatedSecondOrderCone` constraints are not supported because: - Cannot use `MOIB.Constraint.VectorSlackBridge{$T,MOI.VectorAffineFunction{$T},MOI.RotatedSecondOrderCone}` because: + Cannot use `$(MOIB.Constraint.VectorSlackBridge{T,MOI.VectorAffineFunction{T},MOI.RotatedSecondOrderCone})` because: (4) `MOI.VectorAffineFunction{$T}`-in-`MOI.Zeros` constraints are not supported (4) `MOI.VectorAffineFunction{$T}`-in-`MOI.Zeros` constraints are not supported because no added bridge supports bridging it. (5) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.LessThan{$T}` constraints are not supported because: - Cannot use `MOIB.Constraint.QuadtoSOCBridge{$T}` because: + Cannot use `$(MOIB.Constraint.QuadtoSOCBridge{T})` because: (2) `MOI.VectorAffineFunction{$T}`-in-`MOI.RotatedSecondOrderCone` constraints are not supported |1| objective function of type `MOI.ScalarQuadraticFunction{$T}` is not supported because: - Cannot use `MOIB.Objective.SlackBridge{$T,MOI.ScalarQuadraticFunction{$T},MOI.ScalarQuadraticFunction{$T}}` because: + Cannot use `$(MOIB.Objective.SlackBridge{T,MOI.ScalarQuadraticFunction{T},MOI.ScalarQuadraticFunction{T}})` because: (1) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.GreaterThan{$T}` constraints are not supported (5) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.LessThan{$T}` constraints are not supported -""" +""") MOIB.add_bridge(bridged, MOIB.Constraint.ScalarizeBridge{T}) @test debug_string(MOIB.debug_supports, attr) == "Objective function of type `MOI.ScalarQuadraticFunction{$T}` is supported.\n" - @test sprint(MOIB.print_graph, bridged) == """ + @test sprint(MOIB.print_graph, bridged) == MOI.Utilities.replace_acronym(""" Bridge graph with 1 variable nodes, 5 constraint nodes and 2 objective nodes. - [1] constrained variables in `MOI.RotatedSecondOrderCone` are bridged (distance 2) by MOIB.Variable.RSOCtoPSDBridge{$T}. - (1) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.GreaterThan{$T}` constraints are bridged (distance 5) by MOIB.Constraint.QuadtoSOCBridge{$T}. - (2) `MOI.VectorAffineFunction{$T}`-in-`MOI.RotatedSecondOrderCone` constraints are bridged (distance 4) by MOIB.Constraint.VectorSlackBridge{$T,MOI.VectorAffineFunction{$T},MOI.RotatedSecondOrderCone}. - (3) `MOI.SingleVariable`-in-`MOI.EqualTo{$T}` constraints are bridged (distance 1) by MOIB.Constraint.ScalarFunctionizeBridge{$T,MOI.EqualTo{$T}}. - (4) `MOI.VectorAffineFunction{$T}`-in-`MOI.Zeros` constraints are bridged (distance 1) by MOIB.Constraint.ScalarizeBridge{$T,MOI.ScalarAffineFunction{$T},MOI.EqualTo{$T}}. - (5) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.LessThan{$T}` constraints are bridged (distance 5) by MOIB.Constraint.QuadtoSOCBridge{$T}. - |1| objective function of type `MOI.ScalarQuadraticFunction{$T}` is bridged (distance 12) by MOIB.Objective.SlackBridge{$T,MOI.ScalarQuadraticFunction{$T},MOI.ScalarQuadraticFunction{$T}}. - |2| objective function of type `MOI.SingleVariable` is bridged (distance 1) by MOIB.Objective.FunctionizeBridge{$T}. -""" + [1] constrained variables in `MOI.RotatedSecondOrderCone` are bridged (distance 2) by $(MOIB.Variable.RSOCtoPSDBridge{T}). + (1) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.GreaterThan{$T}` constraints are bridged (distance 5) by $(MOIB.Constraint.QuadtoSOCBridge{T}). + (2) `MOI.VectorAffineFunction{$T}`-in-`MOI.RotatedSecondOrderCone` constraints are bridged (distance 4) by $(MOIB.Constraint.VectorSlackBridge{T,MOI.VectorAffineFunction{T},MOI.RotatedSecondOrderCone}). + (3) `MOI.SingleVariable`-in-`MOI.EqualTo{$T}` constraints are bridged (distance 1) by $(MOIB.Constraint.ScalarFunctionizeBridge{T,MOI.EqualTo{T}}). + (4) `MOI.VectorAffineFunction{$T}`-in-`MOI.Zeros` constraints are bridged (distance 1) by $(MOIB.Constraint.ScalarizeBridge{T,MOI.ScalarAffineFunction{T},MOI.EqualTo{T}}). + (5) `MOI.ScalarQuadraticFunction{$T}`-in-`MOI.LessThan{$T}` constraints are bridged (distance 5) by $(MOIB.Constraint.QuadtoSOCBridge{T}). + |1| objective function of type `MOI.ScalarQuadraticFunction{$T}` is bridged (distance 12) by $(MOIB.Objective.SlackBridge{T,MOI.ScalarQuadraticFunction{T},MOI.ScalarQuadraticFunction{T}}). + |2| objective function of type `MOI.SingleVariable` is bridged (distance 1) by $(MOIB.Objective.FunctionizeBridge{T}). +""") end bridged = MOIB.LazyBridgeOptimizer(model) @testset "Exponential constraint" begin @@ -641,30 +641,28 @@ Bridge graph with 1 variable nodes, 5 constraint nodes and 2 objective nodes. (1) `MOI.VectorAffineFunction{$T}`-in-`MOI.ExponentialCone` constraints are not supported because no added bridge supports bridging it. """ MOIB.add_bridge(bridged, MOIB.Constraint.VectorSlackBridge{T}) - @test debug_string(MOIB.debug_supports_constraint, F, S) == -""" + @test debug_string(MOIB.debug_supports_constraint, F, S) == MOI.Utilities.replace_acronym(""" `MOI.VectorAffineFunction{$T}`-in-`MOI.ExponentialCone` constraints are not supported and cannot be bridged into supported constrained variables and constraints. See details below: [1] constrained variables in `MOI.ExponentialCone` are not supported because no added bridge supports bridging it. Cannot add free variables and then constrain them because free variables are bridged but no functionize bridge was added. (1) `MOI.VectorAffineFunction{$T}`-in-`MOI.ExponentialCone` constraints are not supported because: - Cannot use `MOIB.Constraint.VectorSlackBridge{$T,MOI.VectorAffineFunction{$T},MOI.ExponentialCone}` because: + Cannot use `$(MOIB.Constraint.VectorSlackBridge{T,MOI.VectorAffineFunction{T},MOI.ExponentialCone})` because: [1] constrained variables in `MOI.ExponentialCone` are not supported (2) `MOI.VectorAffineFunction{$T}`-in-`MOI.Zeros` constraints are not supported (2) `MOI.VectorAffineFunction{$T}`-in-`MOI.Zeros` constraints are not supported because no added bridge supports bridging it. -""" +""") MOIB.add_bridge(bridged, MOIB.Constraint.VectorFunctionizeBridge{T}) - @test debug_string(MOIB.debug_supports_constraint, F, S) == -""" + @test debug_string(MOIB.debug_supports_constraint, F, S) ==MOI.Utilities.replace_acronym(""" `MOI.VectorAffineFunction{$T}`-in-`MOI.ExponentialCone` constraints are not supported and cannot be bridged into supported constrained variables and constraints. See details below: [1] constrained variables in `MOI.ExponentialCone` are not supported because no added bridge supports bridging it. Cannot add free variables and then constrain them because: (1) `MOI.VectorAffineFunction{$T}`-in-`MOI.ExponentialCone` constraints are not supported (1) `MOI.VectorAffineFunction{$T}`-in-`MOI.ExponentialCone` constraints are not supported because: - Cannot use `MOIB.Constraint.VectorSlackBridge{$T,MOI.VectorAffineFunction{$T},MOI.ExponentialCone}` because: + Cannot use `$(MOIB.Constraint.VectorSlackBridge{T,MOI.VectorAffineFunction{T},MOI.ExponentialCone})` because: [1] constrained variables in `MOI.ExponentialCone` are not supported (2) `MOI.VectorAffineFunction{$T}`-in-`MOI.Zeros` constraints are not supported (2) `MOI.VectorAffineFunction{$T}`-in-`MOI.Zeros` constraints are not supported because no added bridge supports bridging it. -""" +""") end end @@ -769,22 +767,22 @@ end @test !any(v -> MOIB.is_bridged(bridged, v), y) @test !MOIB.is_variable_bridged(bridged, cy) @test MOIB.bridge(bridged, cy) isa MOIB.Constraint.RSOCBridge{T} - @test sprint(MOIB.print_graph, bridged) == """ + @test sprint(MOIB.print_graph, bridged) == MOI.Utilities.replace_acronym(""" Bridge graph with 4 variable nodes, 9 constraint nodes and 0 objective nodes. [1] constrained variables in `MOI.RotatedSecondOrderCone` are supported (distance 2) by adding free variables and then constrain them, see (3). [2] constrained variables in `MOI.PositiveSemidefiniteConeTriangle` are not supported [3] constrained variables in `MOI.SecondOrderCone` are supported (distance 2) by adding free variables and then constrain them, see (1). [4] constrained variables in `MOI.Nonnegatives` are supported (distance 2) by adding free variables and then constrain them, see (6). - (1) `MOI.VectorOfVariables`-in-`MOI.SecondOrderCone` constraints are bridged (distance 1) by MOIB.Constraint.VectorFunctionizeBridge{$T,MOI.SecondOrderCone}. - (2) `MOI.VectorAffineFunction{$T}`-in-`MOI.RotatedSecondOrderCone` constraints are bridged (distance 1) by MOIB.Constraint.RSOCBridge{$T,MOI.VectorAffineFunction{$T},MOI.VectorAffineFunction{$T}}. - (3) `MOI.VectorOfVariables`-in-`MOI.RotatedSecondOrderCone` constraints are bridged (distance 1) by MOIB.Constraint.RSOCBridge{$T,MOI.VectorAffineFunction{$T},MOI.VectorOfVariables}. + (1) `MOI.VectorOfVariables`-in-`MOI.SecondOrderCone` constraints are bridged (distance 1) by $(MOIB.Constraint.VectorFunctionizeBridge{T,MOI.SecondOrderCone}). + (2) `MOI.VectorAffineFunction{$T}`-in-`MOI.RotatedSecondOrderCone` constraints are bridged (distance 1) by $(MOIB.Constraint.RSOCBridge{T,MOI.VectorAffineFunction{T},MOI.VectorAffineFunction{T}}). + (3) `MOI.VectorOfVariables`-in-`MOI.RotatedSecondOrderCone` constraints are bridged (distance 1) by $(MOIB.Constraint.RSOCBridge{T,MOI.VectorAffineFunction{T},MOI.VectorOfVariables}). (4) `MOI.VectorAffineFunction{$T}`-in-`MOI.PositiveSemidefiniteConeTriangle` constraints are not supported (5) `MOI.VectorOfVariables`-in-`MOI.PositiveSemidefiniteConeTriangle` constraints are not supported - (6) `MOI.VectorOfVariables`-in-`MOI.Nonnegatives` constraints are bridged (distance 1) by MOIB.Constraint.NonnegToNonposBridge{$T,MOI.VectorAffineFunction{$T},MOI.VectorOfVariables}. - (7) `MOI.SingleVariable`-in-`MOI.GreaterThan{$T}` constraints are bridged (distance 1) by MOIB.Constraint.GreaterToLessBridge{$T,MOI.ScalarAffineFunction{$T},MOI.SingleVariable}. - (8) `MOI.SingleVariable`-in-`MOI.EqualTo{$T}` constraints are bridged (distance 1) by MOIB.Constraint.VectorizeBridge{$T,MOI.VectorAffineFunction{$T},MOI.Zeros,MOI.SingleVariable}. - (9) `MOI.SingleVariable`-in-`MOI.LessThan{$T}` constraints are bridged (distance 1) by MOIB.Constraint.LessToGreaterBridge{$T,MOI.ScalarAffineFunction{$T},MOI.SingleVariable}. -""" + (6) `MOI.VectorOfVariables`-in-`MOI.Nonnegatives` constraints are bridged (distance 1) by $(MOIB.Constraint.NonnegToNonposBridge{T,MOI.VectorAffineFunction{T},MOI.VectorOfVariables}). + (7) `MOI.SingleVariable`-in-`MOI.GreaterThan{$T}` constraints are bridged (distance 1) by $(MOIB.Constraint.GreaterToLessBridge{T,MOI.ScalarAffineFunction{T},MOI.SingleVariable}). + (8) `MOI.SingleVariable`-in-`MOI.EqualTo{$T}` constraints are bridged (distance 1) by $(MOIB.Constraint.VectorizeBridge{T,MOI.VectorAffineFunction{T},MOI.Zeros,MOI.SingleVariable}). + (9) `MOI.SingleVariable`-in-`MOI.LessThan{$T}` constraints are bridged (distance 1) by $(MOIB.Constraint.LessToGreaterBridge{T,MOI.ScalarAffineFunction{T},MOI.SingleVariable}). +""") end MOIU.@model(OnlyNonnegVAF, diff --git a/test/Utilities/cachingoptimizer.jl b/test/Utilities/cachingoptimizer.jl index 511bec494b..d60b945b60 100644 --- a/test/Utilities/cachingoptimizer.jl +++ b/test/Utilities/cachingoptimizer.jl @@ -286,12 +286,12 @@ end # TODO: test more constraint modifications - @test sprint(show, m) == raw""" - MOIU.CachingOptimizer{MOI.AbstractOptimizer,MOIU.Model{Float64}} + @test sprint(show, m) == MOI.Utilities.replace_acronym(""" + $(MOIU.CachingOptimizer{MOI.AbstractOptimizer,MOIU.Model{Float64}}) in state NO_OPTIMIZER in mode MANUAL with model cache MOIU.Model{Float64} - with optimizer nothing""" + with optimizer nothing""") end @testset "CachingOptimizer AUTOMATIC mode" begin @@ -401,12 +401,12 @@ end @test MOIU.state(m) == MOIU.ATTACHED_OPTIMIZER end - @test sprint(show, m) == raw""" - MOIU.CachingOptimizer{MOI.AbstractOptimizer,MOIU.Model{Float64}} + @test sprint(show, m) == MOI.Utilities.replace_acronym(""" + $(MOIU.CachingOptimizer{MOI.AbstractOptimizer,MOIU.Model{Float64}}) in state ATTACHED_OPTIMIZER in mode AUTOMATIC with model cache MOIU.Model{Float64} - with optimizer MOIU.MockOptimizer{MOIU.Model{Float64}}""" + with optimizer MOIU.MockOptimizer{MOIU.Model{Float64}}""") end @testset "Constructor with optimizer" begin @@ -419,12 +419,12 @@ end @test MOIU.state(m) == MOIU.ATTACHED_OPTIMIZER @test MOIU.mode(m) == MOIU.AUTOMATIC @test MOI.get(m, MOI.SolverName()) == "Mock" - @test sprint(show, m) == raw""" - MOIU.CachingOptimizer{MOIU.MockOptimizer{MOIU.Model{Float64}},MOIU.Model{Float64}} + @test sprint(show, m) == MOI.Utilities.replace_acronym(""" + $(MOIU.CachingOptimizer{MOIU.MockOptimizer{MOIU.Model{Float64}},MOIU.Model{Float64}}) in state ATTACHED_OPTIMIZER in mode AUTOMATIC with model cache MOIU.Model{Float64} - with optimizer MOIU.MockOptimizer{MOIU.Model{Float64}}""" + with optimizer MOIU.MockOptimizer{MOIU.Model{Float64}}""") end @testset "Non-empty optimizer" begin s = MOIU.MockOptimizer(MOIU.Model{Float64}(), supports_names=false) diff --git a/test/Utilities/copy.jl b/test/Utilities/copy.jl index 5a16712d71..bfa48821e8 100644 --- a/test/Utilities/copy.jl +++ b/test/Utilities/copy.jl @@ -24,15 +24,6 @@ end map = MOIU.IndexMap(Dict(x => y), DoubleDicts.IndexDoubleDict()) map.conmap[cx] = cy @test length(map) == 2 - # `x=>y` in Julia <= 1.1 and `x => y` in Julia >= 1.2 - if VERSION < v"1.2" - x_y = string(x) * "=>" * string(y) - c_x_y = string(cx) * "=>" * string(cy) - else - x_y = string(x => y) - c_x_y = string(cx => cy) - end - compare_without_moi(sprint(show, map), "Utilities.IndexMap($x_y,$c_x_y)") end @testset "AUTOMATIC" begin @@ -327,7 +318,7 @@ MOI.supports_add_constrained_variable(::ReverseOrderConstrainedVariablesModel, : end @testset "Filtering copy: check based on index" begin - # Create a basic model. + # Create a basic model. src = MOIU.Model{Float64}() x = MOI.add_variable(src) c1 = MOI.add_constraint(src, x, MOI.LessThan{Float64}(1.0)) @@ -337,7 +328,7 @@ end # true is already well-tested by the above cases. # Only keep the constraint c1. f = (cidx) -> cidx == c1 - + # Perform the copy. dst = OrderConstrainedVariablesModel() index_map = MOI.copy_to(dst, src, filter_constraints=f) @@ -364,7 +355,7 @@ MOI.supports(::BoundModel, ::Type{MOI.NumberOfConstraints}) = true MOI.get(model::BoundModel, attr::MOI.NumberOfConstraints) = MOI.get(model.inner, attr) @testset "Filtering copy: check based on constraint type" begin - # Create a basic model. + # Create a basic model. src = MOIU.Model{Float64}() x = MOI.add_variable(src) c1 = MOI.add_constraint(src, x, MOI.LessThan{Float64}(10.0)) @@ -372,13 +363,13 @@ MOI.get(model::BoundModel, attr::MOI.NumberOfConstraints) = MOI.get(model.inner, # Filtering function: get rid of integrality constraint. f = (cidx) -> MOI.get(src, MOI.ConstraintSet(), cidx) != MOI.Integer() - + # Perform the unfiltered copy. This should throw an error (i.e. the implementation of BoundModel - # should be correct). + # should be correct). dst = BoundModel() @test_throws MOI.UnsupportedConstraint{MOI.SingleVariable, MOI.Integer} MOI.copy_to(dst, src) - - # Perform the filtered copy. This should not throw an error. + + # Perform the filtered copy. This should not throw an error. dst = BoundModel() MOI.copy_to(dst, src, filter_constraints=f) @test MOI.get(dst, MOI.NumberOfConstraints{MOI.SingleVariable, MOI.LessThan{Float64}}()) == 1 diff --git a/test/errors.jl b/test/errors.jl index 8b0ed28f2e..4cf9c9a024 100644 --- a/test/errors.jl +++ b/test/errors.jl @@ -41,7 +41,7 @@ include("dummy.jl") try f(model, func, MOI.EqualTo(0)) catch err - @test sprint(showerror, err) == "$MOI.UnsupportedConstraint{$MOI.SingleVariable,$MOI.EqualTo{$Int}}:" * + @test sprint(showerror, err) == "$(MOI.UnsupportedConstraint{MOI.SingleVariable,MOI.EqualTo{Int}}):" * " `$MOI.SingleVariable`-in-`$MOI.EqualTo{$Int}` constraint is" * " not supported by the model." end @@ -65,7 +65,7 @@ include("dummy.jl") try MOI.add_constraint(model, func, MOI.EqualTo(0.0)) catch err - @test sprint(showerror, err) == "$MOI.AddConstraintNotAllowed{$MOI.SingleVariable,$MOI.EqualTo{Float64}}:" * + @test sprint(showerror, err) == "$(MOI.AddConstraintNotAllowed{MOI.SingleVariable,MOI.EqualTo{Float64}}):" * " Adding `$MOI.SingleVariable`-in-`$MOI.EqualTo{Float64}`" * " constraints cannot be performed. You may want to use a" * " `CachingOptimizer` in `AUTOMATIC` mode or you may need to call" * @@ -124,8 +124,8 @@ include("dummy.jl") try MOI.delete(model, ci) catch err - @test sprint(showerror, err) == "MathOptInterface.DeleteNotAllowed{MathOptInterface.ConstraintIndex{MathOptInterface.SingleVariable,MathOptInterface.EqualTo{Float64}}}:" * - " Deleting the index MathOptInterface.ConstraintIndex{MathOptInterface.SingleVariable,MathOptInterface.EqualTo{Float64}}(1)" * + @test sprint(showerror, err) == "$(MathOptInterface.DeleteNotAllowed{MathOptInterface.ConstraintIndex{MathOptInterface.SingleVariable,MathOptInterface.EqualTo{Float64}}}):" * + " Deleting the index $(MathOptInterface.ConstraintIndex{MathOptInterface.SingleVariable,MathOptInterface.EqualTo{Float64}}(1))" * " cannot be performed. You may want to use a `CachingOptimizer`" * " in `AUTOMATIC` mode or you may need to call `reset_optimizer`" * " before doing this operation if the `CachingOptimizer` is in" * @@ -194,8 +194,8 @@ include("dummy.jl") @testset "Constraint" begin err = MOI.ModifyConstraintNotAllowed(ci, change) @test_throws err MOI.modify(model, ci, change) - @test sprint(showerror, err) == "MathOptInterface.ModifyConstraintNotAllowed{MathOptInterface.SingleVariable,MathOptInterface.EqualTo{Float64},MathOptInterface.ScalarConstantChange{Float64}}:" * - " Modifying the constraints MathOptInterface.ConstraintIndex{MathOptInterface.SingleVariable,MathOptInterface.EqualTo{Float64}}(1)" * + @test sprint(showerror, err) == "$(MathOptInterface.ModifyConstraintNotAllowed{MathOptInterface.SingleVariable,MathOptInterface.EqualTo{Float64},MathOptInterface.ScalarConstantChange{Float64}}):" * + " Modifying the constraints $(MathOptInterface.ConstraintIndex{MathOptInterface.SingleVariable,MathOptInterface.EqualTo{Float64}}(1))" * " with MathOptInterface.ScalarConstantChange{Float64}(1.0) cannot" * " be performed. You may want to use a `CachingOptimizer` in" * " `AUTOMATIC` mode or you may need to call `reset_optimizer`" * @@ -206,8 +206,8 @@ include("dummy.jl") attr = MOI.ObjectiveFunction{MOI.SingleVariable}() err = MOI.ModifyObjectiveNotAllowed(change) @test_throws err MOI.modify(model, attr, change) - @test sprint(showerror, err) == "MathOptInterface.ModifyObjectiveNotAllowed{MathOptInterface.ScalarConstantChange{Float64}}:" * - " Modifying the objective function with MathOptInterface.ScalarConstantChange{Float64}(1.0)" * + @test sprint(showerror, err) == "$(MathOptInterface.ModifyObjectiveNotAllowed{MathOptInterface.ScalarConstantChange{Float64}}):" * + " Modifying the objective function with $(MathOptInterface.ScalarConstantChange{Float64}(1.0))" * " cannot be performed. You may want to use a `CachingOptimizer`" * " in `AUTOMATIC` mode or you may need to call `reset_optimizer`" * " before doing this operation if the `CachingOptimizer` is in" *