From 9c5d218544a8a3d6e3060d565af4c148faeb2e0e Mon Sep 17 00:00:00 2001 From: odow Date: Wed, 20 Sep 2023 12:15:50 +1200 Subject: [PATCH 1/5] Fix various JET errors --- .../Constraint/bridges/all_different_reif.jl | 11 ++++---- .../Constraint/bridges/set_dot_scaling.jl | 5 ++-- src/Bridges/Variable/map.jl | 4 +-- src/FileFormats/MOF/read.jl | 2 +- .../ReverseAD/mathoptinterface_api.jl | 27 +++++++++++-------- src/Utilities/copy.jl | 6 ++--- src/Utilities/functions.jl | 18 +++++++++++-- src/Utilities/model.jl | 4 --- src/Utilities/objective_container.jl | 16 +++++++++-- src/functions.jl | 3 ++- 10 files changed, 63 insertions(+), 33 deletions(-) diff --git a/src/Bridges/Constraint/bridges/all_different_reif.jl b/src/Bridges/Constraint/bridges/all_different_reif.jl index 86cba1bb7c..9c4b64d567 100644 --- a/src/Bridges/Constraint/bridges/all_different_reif.jl +++ b/src/Bridges/Constraint/bridges/all_different_reif.jl @@ -174,11 +174,11 @@ end function MOI.get( bridge::ReifiedAllDifferentToCountDistinctBridge, ::MOI.ListOfVariableIndices, -)::Vector{MOI.VariableIndex} +) if bridge.y === nothing return MOI.VariableIndex[] end - return [bridge.y] + return MOI.VariableIndex[something(bridge.y)] end function MOI.get( @@ -195,11 +195,12 @@ function MOI.get( bridge::ReifiedAllDifferentToCountDistinctBridge{T}, ::MOI.ListOfConstraintIndices{MOI.VariableIndex,MOI.EqualTo{T}}, ) where {T} + F, S = MOI.VariableIndex,MOI.EqualTo{T} + ret = MOI.ConstraintIndex{F,S}[] if bridge.y === nothing - return MOI.ConstraintIndex{MOI.VariableIndex,MOI.EqualTo{T}}[] + push!(ret, MOI.ConstraintIndex{F,S}(something(bridge.y).value)) end - ci = MOI.ConstraintIndex{MOI.VariableIndex,MOI.EqualTo{T}}(bridge.y.value) - return [ci] + return ret end function MOI.get( diff --git a/src/Bridges/Constraint/bridges/set_dot_scaling.jl b/src/Bridges/Constraint/bridges/set_dot_scaling.jl index 7c0f209746..0eef72de82 100644 --- a/src/Bridges/Constraint/bridges/set_dot_scaling.jl +++ b/src/Bridges/Constraint/bridges/set_dot_scaling.jl @@ -22,7 +22,8 @@ in `S` to constraints in [`MOI.Scaled{S}`](@ref MOI.Scaled). * `F` in [`MOI.Scaled{S}`](@ref MOI.Scaled) """ -struct SetDotScalingBridge{T,S,F,G} <: SetMapBridge{T,MOI.Scaled{S},S,F,G} +struct SetDotScalingBridge{T,S<:MOI.AbstractVectorSet,F,G} <: + SetMapBridge{T,MOI.Scaled{S},S,F,G} constraint::MOI.ConstraintIndex{F,MOI.Scaled{S}} end @@ -125,7 +126,7 @@ in the `MOI.Scaled{S}` to constraints in the `S`. * `F` in `S` """ -struct SetDotInverseScalingBridge{T,S,F,G} <: +struct SetDotInverseScalingBridge{T,S<:MOI.AbstractVectorSet,F,G} <: SetMapBridge{T,S,MOI.Scaled{S},F,G} constraint::MOI.ConstraintIndex{F,S} end diff --git a/src/Bridges/Variable/map.jl b/src/Bridges/Variable/map.jl index 014c4847b3..9563d0c6f0 100644 --- a/src/Bridges/Variable/map.jl +++ b/src/Bridges/Variable/map.jl @@ -320,13 +320,13 @@ function add_key_for_bridge( index = -bridge_index variable = MOI.VariableIndex(index) if map.unbridged_function !== nothing - mappings = unbridged_map(map.bridges[bridge_index], variable) + mappings = unbridged_map(something(map.bridges[bridge_index]), variable) if mappings === nothing map.unbridged_function = nothing else for mapping in mappings push!( - map.unbridged_function, + something(map.unbridged_function), mapping.first => (bridge_index, mapping.second), ) end diff --git a/src/FileFormats/MOF/read.jl b/src/FileFormats/MOF/read.jl index 368de7959d..000b37751f 100644 --- a/src/FileFormats/MOF/read.jl +++ b/src/FileFormats/MOF/read.jl @@ -297,7 +297,7 @@ function function_to_moi( object::Object, name_map::Dict{String,MOI.VariableIndex}, ) - return MOI.VectorOfVariables([ + return MOI.VectorOfVariables(MOI.VariableIndex[ name_map[variable] for variable::String in object["variables"] ]) end diff --git a/src/Nonlinear/ReverseAD/mathoptinterface_api.jl b/src/Nonlinear/ReverseAD/mathoptinterface_api.jl index e75c07ddec..f7fcd9615d 100644 --- a/src/Nonlinear/ReverseAD/mathoptinterface_api.jl +++ b/src/Nonlinear/ReverseAD/mathoptinterface_api.jl @@ -45,7 +45,7 @@ function MOI.initialize(d::NLPEvaluator, requested_features::Vector{Symbol}) # main_expressions = [c.expression.nodes for (_, c) in d.data.constraints] if d.data.objective !== nothing - pushfirst!(main_expressions, d.data.objective.nodes) + pushfirst!(main_expressions, something(d.data.objective).nodes) end d.subexpression_order, individual_order = _order_subexpressions( main_expressions, @@ -96,9 +96,9 @@ function MOI.initialize(d::NLPEvaluator, requested_features::Vector{Symbol}) end max_chunk = 1 if d.data.objective !== nothing - d.objective = _FunctionStorage( + objective = _FunctionStorage( main_expressions[1], - d.data.objective.values, + something(d.data.objective).values, N, coloring_storage, d.want_hess, @@ -109,8 +109,9 @@ function MOI.initialize(d::NLPEvaluator, requested_features::Vector{Symbol}) subexpression_variables, moi_index_to_consecutive_index, ) - max_expr_length = max(max_expr_length, length(d.objective.nodes)) - max_chunk = max(max_chunk, size(d.objective.seed_matrix, 2)) + max_expr_length = max(max_expr_length, length(objective.nodes)) + max_chunk = max(max_chunk, size(objective.seed_matrix, 2)) + d.objective = objective end for (k, (_, constraint)) in enumerate(d.data.constraints) idx = d.data.objective !== nothing ? k + 1 : k @@ -157,11 +158,9 @@ function MOI.initialize(d::NLPEvaluator, requested_features::Vector{Symbol}) d.max_chunk = max_chunk if d.want_hess d.hessian_sparsity = Tuple{Int64,Int64}[] - if d.objective !== nothing - append!( - d.hessian_sparsity, - zip(d.objective.hess_I, d.objective.hess_J), - ) + obj = d.objective + if obj !== nothing + append!(d.hessian_sparsity, zip(obj.hess_I, obj.hess_J)) end for c in d.constraints append!(d.hessian_sparsity, zip(c.hess_I, c.hess_J)) @@ -277,8 +276,14 @@ end function MOI.hessian_objective_structure(d::NLPEvaluator) @assert d.want_hess + ret = Tuple{Int64,Int64}[] obj = d.objective - return Tuple{Int64,Int64}[(i, j) for (i, j) in zip(obj.hess_I, obj.hess_J)] + if obj !== nothing + for (i, j) in zip(obj.hess_I, obj.hess_J) + push!(ret, (i, j)) + end + end + return ret end function MOI.hessian_constraint_structure(d::NLPEvaluator, c::Integer) diff --git a/src/Utilities/copy.jl b/src/Utilities/copy.jl index 9af59c7df7..11a76c3ba9 100644 --- a/src/Utilities/copy.jl +++ b/src/Utilities/copy.jl @@ -326,9 +326,9 @@ function _pass_constraints( _copy_constraints(dest, src, index_map, cis) end all_constraint_types = MOI.get(src, MOI.ListOfConstraintTypesPresent()) - nonvariable_constraint_types = Any[ - (F, S) for (F, S) in all_constraint_types if !_is_variable_function(F) - ] + nonvariable_constraint_types = filter(all_constraint_types) do (F, S) + return !_is_variable_function(F) + end pass_nonvariable_constraints( dest, src, diff --git a/src/Utilities/functions.jl b/src/Utilities/functions.jl index 03baca4d20..3c436b43a7 100644 --- a/src/Utilities/functions.jl +++ b/src/Utilities/functions.jl @@ -2121,7 +2121,15 @@ vectorize(x::AbstractVector{<:Number}) = x Returns the vector of scalar affine functions in the form of a `MOI.VectorAffineFunction{T}`. """ -vectorize(x::AbstractVector{MOI.VariableIndex}) = MOI.VectorOfVariables(x) +function vectorize(x::AbstractVector{MOI.VariableIndex}) + # Explicitly construct the output vector here because don't know that `x` + # has a `convert` method to `Vector`. + y = Vector{MOI.VariableIndex}(undef, length(x)) + for (i, xi) in enumerate(x) + y[i] = xi + end + return MOI.VectorOfVariables(y) +end """ vectorize(funcs::AbstractVector{MOI.ScalarAffineFunction{T}}) where T @@ -2175,7 +2183,13 @@ function vectorize( end function vectorize(x::AbstractVector{MOI.ScalarNonlinearFunction}) - return MOI.VectorNonlinearFunction(x) + # Explicitly construct the output vector here because don't know that `x` + # has a `convert` method to `Vector`. + y = Vector{MOI.ScalarNonlinearFunction}(undef, length(x)) + for (i, xi) in enumerate(x) + y[i] = xi + end + return MOI.VectorNonlinearFunction(y) end scalarize(f::AbstractVector, ::Bool = false) = f diff --git a/src/Utilities/model.jl b/src/Utilities/model.jl index b385b9d376..c29c4b1278 100644 --- a/src/Utilities/model.jl +++ b/src/Utilities/model.jl @@ -34,10 +34,6 @@ function MOI.add_variable(model::AbstractModel) return x end -function MOI.add_variables(model::AbstractModel, n::Integer) - return [MOI.add_variable(model) for i in 1:n] -end - """ remove_variable(f::MOI.AbstractFunction, s::MOI.AbstractSet, vi::MOI.VariableIndex) diff --git a/src/Utilities/objective_container.jl b/src/Utilities/objective_container.jl index 30fa031c52..78d397bc5e 100644 --- a/src/Utilities/objective_container.jl +++ b/src/Utilities/objective_container.jl @@ -118,8 +118,20 @@ end function MOI.get( o::ObjectiveContainer{T}, - ::MOI.ObjectiveFunction{F}, -) where {T,F} + attr::MOI.ObjectiveFunction{F}, +) where { + T, + F<:Union{ + MOI.VariableIndex, + MOI.ScalarAffineFunction{T}, + MOI.ScalarQuadraticFunction{T}, + MOI.ScalarNonlinearFunction, + MOI.VectorOfVariables, + MOI.VectorAffineFunction{T}, + MOI.VectorQuadraticFunction{T}, + MOI.VectorNonlinearFunction, + } +} if o.scalar_affine !== nothing return convert(F, something(o.scalar_affine)) elseif o.single_variable !== nothing diff --git a/src/functions.jl b/src/functions.jl index a99c4a3fa4..b2e1ce05ce 100644 --- a/src/functions.jl +++ b/src/functions.jl @@ -549,7 +549,8 @@ function VectorAffineFunction{T}(f::VectorOfVariables) where {T} terms = map(1:output_dimension(f)) do i return VectorAffineTerm(i, ScalarAffineTerm(one(T), f.variables[i])) end - return VectorAffineFunction(terms, zeros(T, output_dimension(f))) + constants = zeros(T, output_dimension(f))::Vector{T} + return VectorAffineFunction(terms, constants) end """ From f5449516180d1b0b51f81566d686984e9c6652bf Mon Sep 17 00:00:00 2001 From: odow Date: Wed, 20 Sep 2023 12:24:31 +1200 Subject: [PATCH 2/5] Update --- src/FileFormats/NL/sol.jl | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/FileFormats/NL/sol.jl b/src/FileFormats/NL/sol.jl index 9d7f9e1967..d6527e6850 100644 --- a/src/FileFormats/NL/sol.jl +++ b/src/FileFormats/NL/sol.jl @@ -111,13 +111,16 @@ function MOI.get( return sol.variable_primal[MOI.VariableIndex(ci.value)] end +# Helper function to assert that the model is not nothing +_model(sol::SolFileResults) = sol.model::Model + function MOI.get( sol::SolFileResults, attr::MOI.ConstraintPrimal, ci::MOI.ConstraintIndex{<:MOI.ScalarAffineFunction}, ) MOI.check_result_index_bounds(sol, attr) - return _evaluate(sol.model.h[ci.value].expr, sol.variable_primal) + return _evaluate(_model(sol).h[ci.value].expr, sol.variable_primal) end function MOI.get( @@ -126,7 +129,7 @@ function MOI.get( ci::MOI.ConstraintIndex{F}, ) where {F<:Union{MOI.ScalarQuadraticFunction,MOI.ScalarNonlinearFunction}} MOI.check_result_index_bounds(sol, attr) - return _evaluate(sol.model.g[ci.value].expr, sol.variable_primal) + return _evaluate(_model(sol).g[ci.value].expr, sol.variable_primal) end function MOI.get( @@ -136,7 +139,7 @@ function MOI.get( ) MOI.check_result_index_bounds(sol, attr) dual = get(sol.zU_out, MOI.VariableIndex(ci.value), 0.0) - return sol.model.sense == MOI.MIN_SENSE ? dual : -dual + return _model(sol).sense == MOI.MIN_SENSE ? dual : -dual end function MOI.get( @@ -146,7 +149,7 @@ function MOI.get( ) MOI.check_result_index_bounds(sol, attr) dual = get(sol.zL_out, MOI.VariableIndex(ci.value), 0.0) - return sol.model.sense == MOI.MIN_SENSE ? dual : -dual + return _model(sol).sense == MOI.MIN_SENSE ? dual : -dual end function MOI.get( @@ -157,7 +160,7 @@ function MOI.get( MOI.check_result_index_bounds(sol, attr) x = MOI.VariableIndex(ci.value) dual = get(sol.zL_out, x, 0.0) + get(sol.zU_out, x, 0.0) - return sol.model.sense == MOI.MIN_SENSE ? dual : -dual + return _model(sol).sense == MOI.MIN_SENSE ? dual : -dual end function MOI.get( @@ -168,7 +171,7 @@ function MOI.get( MOI.check_result_index_bounds(sol, attr) x = MOI.VariableIndex(ci.value) dual = get(sol.zL_out, x, 0.0) + get(sol.zU_out, x, 0.0) - return sol.model.sense == MOI.MIN_SENSE ? dual : -dual + return _model(sol).sense == MOI.MIN_SENSE ? dual : -dual end function MOI.get( @@ -177,8 +180,8 @@ function MOI.get( ci::MOI.ConstraintIndex{<:MOI.ScalarAffineFunction}, ) MOI.check_result_index_bounds(sol, attr) - dual = sol.constraint_dual[length(sol.model.g)+ci.value] - return sol.model.sense == MOI.MIN_SENSE ? dual : -dual + dual = sol.constraint_dual[length(_model(sol).g)+ci.value] + return _model(sol).sense == MOI.MIN_SENSE ? dual : -dual end function MOI.get( @@ -188,13 +191,13 @@ function MOI.get( ) where {F<:Union{MOI.ScalarQuadraticFunction,MOI.ScalarNonlinearFunction}} MOI.check_result_index_bounds(sol, attr) dual = sol.constraint_dual[ci.value] - return sol.model.sense == MOI.MIN_SENSE ? dual : -dual + return _model(sol).sense == MOI.MIN_SENSE ? dual : -dual end function MOI.get(sol::SolFileResults, attr::MOI.NLPBlockDual) MOI.check_result_index_bounds(sol, attr) - dual = sol.constraint_dual[1:sol.model.nlpblock_dim] - return sol.model.sense == MOI.MIN_SENSE ? dual : -dual + dual = sol.constraint_dual[1:_model(sol).nlpblock_dim] + return _model(sol).sense == MOI.MIN_SENSE ? dual : -dual end """ From b348bc06deac03745f93ede54fd8b1347ebe1a43 Mon Sep 17 00:00:00 2001 From: odow Date: Wed, 20 Sep 2023 13:25:00 +1200 Subject: [PATCH 3/5] More updates --- .../Constraint/bridges/all_different_reif.jl | 2 +- src/FileFormats/MOF/read.jl | 8 +++++--- src/Nonlinear/evaluator.jl | 17 +++++++++-------- src/Utilities/objective_container.jl | 2 +- src/Utilities/parser.jl | 4 ++-- src/Utilities/print.jl | 6 +++--- src/Utilities/product_of_sets.jl | 6 +++--- src/Utilities/vector_of_constraints.jl | 14 +++++++++----- 8 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/Bridges/Constraint/bridges/all_different_reif.jl b/src/Bridges/Constraint/bridges/all_different_reif.jl index 9c4b64d567..fa1848f714 100644 --- a/src/Bridges/Constraint/bridges/all_different_reif.jl +++ b/src/Bridges/Constraint/bridges/all_different_reif.jl @@ -195,7 +195,7 @@ function MOI.get( bridge::ReifiedAllDifferentToCountDistinctBridge{T}, ::MOI.ListOfConstraintIndices{MOI.VariableIndex,MOI.EqualTo{T}}, ) where {T} - F, S = MOI.VariableIndex,MOI.EqualTo{T} + F, S = MOI.VariableIndex, MOI.EqualTo{T} ret = MOI.ConstraintIndex{F,S}[] if bridge.y === nothing push!(ret, MOI.ConstraintIndex{F,S}(something(bridge.y).value)) diff --git a/src/FileFormats/MOF/read.jl b/src/FileFormats/MOF/read.jl index 000b37751f..78df5254df 100644 --- a/src/FileFormats/MOF/read.jl +++ b/src/FileFormats/MOF/read.jl @@ -297,9 +297,11 @@ function function_to_moi( object::Object, name_map::Dict{String,MOI.VariableIndex}, ) - return MOI.VectorOfVariables(MOI.VariableIndex[ - name_map[variable] for variable::String in object["variables"] - ]) + return MOI.VectorOfVariables( + MOI.VariableIndex[ + name_map[variable] for variable::String in object["variables"] + ], + ) end # ========== Typed vector functions ========== diff --git a/src/Nonlinear/evaluator.jl b/src/Nonlinear/evaluator.jl index 2414ac7db1..c8cdc491cf 100644 --- a/src/Nonlinear/evaluator.jl +++ b/src/Nonlinear/evaluator.jl @@ -102,15 +102,16 @@ function MOI.constraint_expr(evaluator::Evaluator, i::Int) constraint.expression; moi_output_format = true, ) - if constraint.set isa MOI.LessThan - return :($f <= $(constraint.set.upper)) - elseif constraint.set isa MOI.GreaterThan - return :($f >= $(constraint.set.lower)) - elseif constraint.set isa MOI.EqualTo - return :($f == $(constraint.set.value)) + set = constraint.set + if set isa MOI.LessThan + return :($f <= $(set.upper)) + elseif set isa MOI.GreaterThan + return :($f >= $(set.lower)) + elseif set isa MOI.EqualTo + return :($f == $(set.value)) else - @assert constraint.set isa MOI.Interval - return :($(constraint.set.lower) <= $f <= $(constraint.set.upper)) + @assert set isa MOI.Interval + return :($(set.lower) <= $f <= $(set.upper)) end end diff --git a/src/Utilities/objective_container.jl b/src/Utilities/objective_container.jl index 78d397bc5e..d8fd4db793 100644 --- a/src/Utilities/objective_container.jl +++ b/src/Utilities/objective_container.jl @@ -130,7 +130,7 @@ function MOI.get( MOI.VectorAffineFunction{T}, MOI.VectorQuadraticFunction{T}, MOI.VectorNonlinearFunction, - } + }, } if o.scalar_affine !== nothing return convert(F, something(o.scalar_affine)) diff --git a/src/Utilities/parser.jl b/src/Utilities/parser.jl index 01e942cd8d..8b030be9ce 100644 --- a/src/Utilities/parser.jl +++ b/src/Utilities/parser.jl @@ -60,10 +60,10 @@ function _parse_function(ex, ::Type{T} = Float64) where {T} if isa(ex, Symbol) return _ParsedVariableIndex(ex) elseif Meta.isexpr(ex, :vect) - if all(s -> isa(s, Symbol), ex.args) + if all(Base.Fix2(isa, Symbol), ex.args) return _ParsedVectorOfVariables(copy(ex.args)) else - singlefunctions = _parse_function.(ex.args, T) + singlefunctions = map(Base.Fix2(_parse_function, T), ex.args) affine_terms = _ParsedVectorAffineTerm{T}[] quadratic_terms = _ParsedVectorQuadraticTerm{T}[] constant = T[] diff --git a/src/Utilities/print.jl b/src/Utilities/print.jl index 41d3e747bc..0c282d17eb 100644 --- a/src/Utilities/print.jl +++ b/src/Utilities/print.jl @@ -113,10 +113,10 @@ function _to_string( var_name = replace(var_name, "^" => "\\^") # Convert any x[args] to x_{args} so that indices on x print as subscripts. m = match(r"^(.*)\[(.+)\]$", var_name) - if m !== nothing - var_name = m[1] * "_{" * m[2] * "}" + if m === nothing + return var_name end - return var_name + return string(m[1]::AbstractString, "_{", m[2]::AbstractString, "}") end function _shorten(options::_PrintOptions, x::Float64) diff --git a/src/Utilities/product_of_sets.jl b/src/Utilities/product_of_sets.jl index cc2973e82d..cc7ac78512 100644 --- a/src/Utilities/product_of_sets.jl +++ b/src/Utilities/product_of_sets.jl @@ -219,7 +219,7 @@ function rows( ci::MOI.ConstraintIndex{MOI.ScalarAffineFunction{T},S}, ) where {T,S} @assert sets.final_touch - i = set_index(sets, S) + i = set_index(sets, S)::Int return (i == 1 ? 0 : sets.num_rows[i-1]) + ci.value end @@ -228,7 +228,7 @@ function rows( ci::MOI.ConstraintIndex{MOI.VectorAffineFunction{T},S}, ) where {T,S} @assert sets.final_touch - i = set_index(sets, S) + i = set_index(sets, S)::Int offset = i == 1 ? 0 : sets.num_rows[i-1] return (offset + ci.value - 1) .+ (1:sets.dimension[(i, ci.value)]) end @@ -263,7 +263,7 @@ Return the number of rows corresponding to a set of type `S`. That is, it is the sum of the dimensions of the sets of type `S`. """ function num_rows(sets::OrderedProductOfSets, ::Type{S}) where {S} - i = set_index(sets, S) + i = set_index(sets, S)::Int if !sets.final_touch || i == 1 return sets.num_rows[i] end diff --git a/src/Utilities/vector_of_constraints.jl b/src/Utilities/vector_of_constraints.jl index 886447edd5..6033121118 100644 --- a/src/Utilities/vector_of_constraints.jl +++ b/src/Utilities/vector_of_constraints.jl @@ -102,7 +102,8 @@ function MOI.get( ci::MOI.ConstraintIndex{F,S}, ) where {F,S} MOI.throw_if_not_valid(v, ci) - return v.constraints[ci][1] + f, _ = v.constraints[ci]::Tuple{F,S} + return f end function MOI.get( @@ -111,7 +112,8 @@ function MOI.get( ci::MOI.ConstraintIndex{F,S}, ) where {F,S} MOI.throw_if_not_valid(v, ci) - return v.constraints[ci][2] + _, s = v.constraints[ci]::Tuple{F,S} + return s end function MOI.set( @@ -121,7 +123,8 @@ function MOI.set( func::F, ) where {F,S} MOI.throw_if_not_valid(v, ci) - v.constraints[ci] = (func, v.constraints[ci][2]) + _, s = v.constraints[ci]::Tuple{F,S} + v.constraints[ci] = (func, s) return end @@ -132,7 +135,8 @@ function MOI.set( set::S, ) where {F,S} MOI.throw_if_not_valid(v, ci) - v.constraints[ci] = (v.constraints[ci][1], set) + f, _ = v.constraints[ci]::Tuple{F,S} + v.constraints[ci] = (f, set) return end @@ -162,7 +166,7 @@ function MOI.modify( ci::MOI.ConstraintIndex{F,S}, change::MOI.AbstractFunctionModification, ) where {F,S} - func, set = v.constraints[ci] + func, set = v.constraints[ci]::Tuple{F,S} v.constraints[ci] = (modify_function!(func, change), set) return end From d0239abbcbaefdf12da2164a0da91b6979e3034d Mon Sep 17 00:00:00 2001 From: odow Date: Wed, 20 Sep 2023 15:09:55 +1200 Subject: [PATCH 4/5] Update --- src/Bridges/Constraint/map.jl | 2 +- src/Bridges/Variable/map.jl | 14 ++++++++------ src/Bridges/bridge_optimizer.jl | 9 ++++++--- src/Bridges/lazy_bridge_optimizer.jl | 22 ++++++++++++++-------- src/Utilities/functions.jl | 2 +- src/Utilities/matrix_of_constraints.jl | 2 +- src/Utilities/objective_container.jl | 8 ++++---- src/Utilities/struct_of_constraints.jl | 2 +- src/Utilities/universalfallback.jl | 2 +- 9 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/Bridges/Constraint/map.jl b/src/Bridges/Constraint/map.jl index 95a6d63e16..38cfbb11d7 100644 --- a/src/Bridges/Constraint/map.jl +++ b/src/Bridges/Constraint/map.jl @@ -86,7 +86,7 @@ function Base.getindex( end function Base.delete!(map::Map, ci::MOI.ConstraintIndex) - _unregister_for_final_touch(map, map.bridges[_index(ci)]) + _unregister_for_final_touch(map, map.bridges[_index(ci)]::AbstractBridge) map.bridges[_index(ci)] = nothing return map end diff --git a/src/Bridges/Variable/map.jl b/src/Bridges/Variable/map.jl index 9563d0c6f0..7b9e98adb0 100644 --- a/src/Bridges/Variable/map.jl +++ b/src/Bridges/Variable/map.jl @@ -208,7 +208,7 @@ function number_with_set(map::Map, S::Type{<:MOI.AbstractSet}) end function constraint(map::Map, vi::MOI.VariableIndex) - S = constrained_set(map, vi) + S = constrained_set(map, vi)::Type{<:MOI.AbstractSet} F = MOI.Utilities.variable_function_type(S) return MOI.ConstraintIndex{F,S}(-bridge_index(map, vi)) end @@ -235,12 +235,14 @@ Return a list of all the different types `(F, S)` of `F`-in-`S` constraints in function list_of_constraint_types(map::Map) list = Set{Tuple{Type,Type}}() for i in eachindex(map.bridges) - if map.bridges[i] !== nothing - S = map.sets[i] - if S != MOI.Reals - push!(list, (MOI.Utilities.variable_function_type(S), S)) - end + if map.bridges[i] === nothing + continue + end + S = map.sets[i] + if S === nothing || S == MOI.Reals + continue end + push!(list, (MOI.Utilities.variable_function_type(S), S)) end return list end diff --git a/src/Bridges/bridge_optimizer.jl b/src/Bridges/bridge_optimizer.jl index 22aba001c9..c0af0b3440 100644 --- a/src/Bridges/bridge_optimizer.jl +++ b/src/Bridges/bridge_optimizer.jl @@ -1225,7 +1225,7 @@ end function MOI.set( b::AbstractBridgeOptimizer, attr::MOI.AbstractVariableAttribute, - index::MOI.Index, + index::MOI.VariableIndex, value, ) value = bridged_function(b, value) @@ -1240,7 +1240,7 @@ end function MOI.set( b::AbstractBridgeOptimizer, attr::MOI.AbstractVariableAttribute, - indices::Vector{<:MOI.Index}, + indices::Vector{MOI.VariableIndex}, values::Vector, ) if any(index -> is_bridged(b, index), indices) @@ -2004,7 +2004,10 @@ function bridged_variable_function( vi::MOI.VariableIndex, ) if is_bridged(b, vi) - func = bridged_function(bridge(b, vi), _index(b, vi)...) + func = bridged_function( + bridge(b, vi)::Variable.AbstractBridge, + _index(b, vi)..., + ) # If two variable bridges are chained, `func` may still contain # bridged variables. return bridged_function(b, func) diff --git a/src/Bridges/lazy_bridge_optimizer.jl b/src/Bridges/lazy_bridge_optimizer.jl index daac29de41..fb5c9703f8 100644 --- a/src/Bridges/lazy_bridge_optimizer.jl +++ b/src/Bridges/lazy_bridge_optimizer.jl @@ -128,9 +128,12 @@ end Return the list of `VariableNode` that would be added if `BT` is used in `b`. """ -function _variable_nodes(b::LazyBridgeOptimizer, ::Type{BT}) where {BT} +function _variable_nodes( + b::LazyBridgeOptimizer, + ::Type{BT}, +) where {BT<:AbstractBridge} return VariableNode[ - node(b, S) for (S,) in added_constrained_variable_types(BT) + node(b, S)::VariableNode for (S,) in added_constrained_variable_types(BT) ] end @@ -139,7 +142,10 @@ end Return the list of `ConstraintNode` that would be added if `BT` is used in `b`. """ -function _constraint_nodes(b::LazyBridgeOptimizer, ::Type{BT}) where {BT} +function _constraint_nodes( + b::LazyBridgeOptimizer, + ::Type{BT}, +) where {BT<:AbstractBridge} return ConstraintNode[ node(b, F, S) for (F, S) in added_constraint_types(BT) ] @@ -168,10 +174,10 @@ function _edge( ) return ObjectiveEdge( index, - _variable_nodes(b, BT), - _constraint_nodes(b, BT), - node(b, set_objective_function_type(BT)), - bridging_cost(BT), + _variable_nodes(b, BT)::Vector{VariableNode}, + _constraint_nodes(b, BT)::Vector{ConstraintNode}, + node(b, set_objective_function_type(BT))::ObjectiveNode, + bridging_cost(BT)::Float64, ) end @@ -321,7 +327,7 @@ function node(b::LazyBridgeOptimizer, F::Type{<:MOI.AbstractFunction}) push!(b.objective_types, (F,)) for (i, BT) in enumerate(b.objective_bridge_types) if Objective.supports_objective_function(BT, F) - bridge_type = Objective.concrete_bridge_type(BT, F) + bridge_type = Objective.concrete_bridge_type(BT, F)::Type{<:Objective.AbstractBridge} edge = _edge(b, i, bridge_type)::ObjectiveEdge add_edge(b.graph, objective_node, edge) end diff --git a/src/Utilities/functions.jl b/src/Utilities/functions.jl index 3c436b43a7..53fefc8da8 100644 --- a/src/Utilities/functions.jl +++ b/src/Utilities/functions.jl @@ -150,7 +150,7 @@ function eval_variables(value_fn::Function, f::MOI.ScalarQuadraticFunction) end function eval_variables(value_fn::Function, f::MOI.VectorOfVariables) - return value_fn.(f.variables) + return map(value_fn, f.variables) end function eval_variables(value_fn::Function, f::MOI.VectorAffineFunction) diff --git a/src/Utilities/matrix_of_constraints.jl b/src/Utilities/matrix_of_constraints.jl index 10bdac499f..843f2262cc 100644 --- a/src/Utilities/matrix_of_constraints.jl +++ b/src/Utilities/matrix_of_constraints.jl @@ -271,7 +271,7 @@ function rows end MOI.is_empty(v::MatrixOfConstraints) = MOI.is_empty(v.sets) -function MOI.empty!(v::MatrixOfConstraints{T}) where {T} +function MOI.empty!(v::MatrixOfConstraints{T,AT,BT,ST}) where {T,AT,BT,ST} MOI.empty!(v.coefficients) empty!(v.constants) MOI.empty!(v.sets) diff --git a/src/Utilities/objective_container.jl b/src/Utilities/objective_container.jl index d8fd4db793..59f046d8a0 100644 --- a/src/Utilities/objective_container.jl +++ b/src/Utilities/objective_container.jl @@ -123,12 +123,12 @@ function MOI.get( T, F<:Union{ MOI.VariableIndex, - MOI.ScalarAffineFunction{T}, - MOI.ScalarQuadraticFunction{T}, + MOI.ScalarAffineFunction, + MOI.ScalarQuadraticFunction, MOI.ScalarNonlinearFunction, MOI.VectorOfVariables, - MOI.VectorAffineFunction{T}, - MOI.VectorQuadraticFunction{T}, + MOI.VectorAffineFunction, + MOI.VectorQuadraticFunction, MOI.VectorNonlinearFunction, }, } diff --git a/src/Utilities/struct_of_constraints.jl b/src/Utilities/struct_of_constraints.jl index 41d6f83cda..b383ceeb5c 100644 --- a/src/Utilities/struct_of_constraints.jl +++ b/src/Utilities/struct_of_constraints.jl @@ -283,7 +283,7 @@ function struct_of_constraint_code(struct_name, types, field_types = nothing) typed_struct = :($(struct_name){$T}) type_parametrized = field_types === nothing if type_parametrized - field_types = [Symbol("C$i") for i in eachindex(types)] + field_types = Symbol[Symbol("C$i") for i in eachindex(types)] append!(typed_struct.args, field_types) end code = quote diff --git a/src/Utilities/universalfallback.jl b/src/Utilities/universalfallback.jl index db1e624867..0c90656c41 100644 --- a/src/Utilities/universalfallback.jl +++ b/src/Utilities/universalfallback.jl @@ -579,7 +579,7 @@ function MOI.modify( if uf.objective === nothing MOI.modify(uf.model, obj, change) else - uf.objective = modify_function(uf.objective, change) + uf.objective = modify_function(something(uf.objective), change) end return end From 910287dafb01020fce62ca1bb35c91582088ff30 Mon Sep 17 00:00:00 2001 From: odow Date: Wed, 20 Sep 2023 16:07:14 +1200 Subject: [PATCH 5/5] Update --- .../Constraint/bridges/all_different_reif.jl | 2 +- src/Bridges/lazy_bridge_optimizer.jl | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Bridges/Constraint/bridges/all_different_reif.jl b/src/Bridges/Constraint/bridges/all_different_reif.jl index fa1848f714..21f374bd6b 100644 --- a/src/Bridges/Constraint/bridges/all_different_reif.jl +++ b/src/Bridges/Constraint/bridges/all_different_reif.jl @@ -197,7 +197,7 @@ function MOI.get( ) where {T} F, S = MOI.VariableIndex, MOI.EqualTo{T} ret = MOI.ConstraintIndex{F,S}[] - if bridge.y === nothing + if bridge.y !== nothing push!(ret, MOI.ConstraintIndex{F,S}(something(bridge.y).value)) end return ret diff --git a/src/Bridges/lazy_bridge_optimizer.jl b/src/Bridges/lazy_bridge_optimizer.jl index fb5c9703f8..5bfe1ac29c 100644 --- a/src/Bridges/lazy_bridge_optimizer.jl +++ b/src/Bridges/lazy_bridge_optimizer.jl @@ -132,9 +132,9 @@ function _variable_nodes( b::LazyBridgeOptimizer, ::Type{BT}, ) where {BT<:AbstractBridge} - return VariableNode[ - node(b, S)::VariableNode for (S,) in added_constrained_variable_types(BT) - ] + return map(added_constrained_variable_types(BT)) do (S,) + return node(b, S)::VariableNode + end end """ @@ -310,7 +310,7 @@ end Return the `ObjectiveNode` associated with constraint `F` in `b`. """ -function node(b::LazyBridgeOptimizer, F::Type{<:MOI.AbstractFunction}) +function node(b::LazyBridgeOptimizer, ::Type{F}) where {F<:MOI.AbstractFunction} # If we support the objective function, the node is 0. if MOI.supports(b.model, MOI.ObjectiveFunction{F}()) return ObjectiveNode(0) @@ -327,7 +327,10 @@ function node(b::LazyBridgeOptimizer, F::Type{<:MOI.AbstractFunction}) push!(b.objective_types, (F,)) for (i, BT) in enumerate(b.objective_bridge_types) if Objective.supports_objective_function(BT, F) - bridge_type = Objective.concrete_bridge_type(BT, F)::Type{<:Objective.AbstractBridge} + bridge_type = Objective.concrete_bridge_type( + BT, + F, + )::Type{<:Objective.AbstractBridge} edge = _edge(b, i, bridge_type)::ObjectiveEdge add_edge(b.graph, objective_node, edge) end