From 92a16a596ca7d8d195320da5a2eb1fd86fc0a795 Mon Sep 17 00:00:00 2001 From: jalving Date: Fri, 12 Jan 2024 10:15:44 -0800 Subject: [PATCH] start adding edge copy --- src/jump_interop.jl | 24 +++++----- src/moi_aggregate.jl | 41 ++++++++++++----- src/moi_graph_backend.jl | 96 +++++++++++++++++++++------------------- src/optiedge.jl | 22 ++++++++- src/optigraph.jl | 24 +++++++++- src/optinode.jl | 54 +++++++++++----------- 6 files changed, 164 insertions(+), 97 deletions(-) diff --git a/src/jump_interop.jl b/src/jump_interop.jl index 245966b..2f812ce 100644 --- a/src/jump_interop.jl +++ b/src/jump_interop.jl @@ -61,7 +61,7 @@ function JuMP.GenericAffExpr{C,NodeVariableRef}( ) where {C} aff = GenericAffExpr{C,NodeVariableRef}(f.constant) for t in f.terms - node_var_index = graph_backend(node).graph_to_node_map[t.variable].index + node_var_index = graph_backend(node).graph_to_element_map[t.variable].index JuMP.add_to_expression!( aff, t.coefficient, @@ -86,7 +86,7 @@ function JuMP.GenericAffExpr{C,NodeVariableRef}( aff = GenericAffExpr{C,NodeVariableRef}(f.constant) # build JuMP Affine Expression over edge variables for t in f.terms - node_var = graph_backend(edge).graph_to_node_map[t.variable] + node_var = graph_backend(edge).graph_to_element_map[t.variable] node = node_var.node node_index = node_var.index JuMP.add_to_expression!( @@ -114,7 +114,7 @@ function JuMP.GenericAffExpr{C,NodeVariableRef}( # build JuMP Affine Expression over func variables for t in f.terms gb = graph_backend(graph) - node_var = gb.graph_to_node_map[t.variable] + node_var = gb.graph_to_element_map[t.variable] node = node_var.node node_index = node_var.index JuMP.add_to_expression!( @@ -175,8 +175,8 @@ function JuMP.GenericQuadExpr{C,NodeVariableRef}( ), ) for t in f.quadratic_terms - v1 = graph_backend(node).graph_to_node_map[t.variable_1].index - v2 = graph_backend(node).graph_to_node_map[t.variable_2].index + v1 = graph_backend(node).graph_to_element_map[t.variable_1].index + v2 = graph_backend(node).graph_to_element_map[t.variable_2].index coef = t.coefficient if v1 == v2 coef /= 2 @@ -223,12 +223,12 @@ function JuMP.GenericQuadExpr{C,NodeVariableRef}( end # variable index 1 - node_var_1 = graph_backend(edge).graph_to_node_map[v1] + node_var_1 = graph_backend(edge).graph_to_element_map[v1] node1 = node_var_1.node var_index_1 = node_var_1.index # variable index 2 - node_var_2 = graph_backend(edge).graph_to_node_map[v2] + node_var_2 = graph_backend(edge).graph_to_element_map[v2] node2 = node_var_2.node var_index_2 = node_var_2.index @@ -275,12 +275,12 @@ function JuMP.GenericQuadExpr{C,NodeVariableRef}( end # variable index 1 - node_var_1 = gb.graph_to_node_map[v1] + node_var_1 = gb.graph_to_element_map[v1] node1 = node_var_1.node var_index_1 = node_var_1.index # variable index 2 - node_var_2 = gb.graph_to_node_map[v2] + node_var_2 = gb.graph_to_element_map[v2] node2 = node_var_2.node var_index_2 = node_var_2.index @@ -305,7 +305,7 @@ JuMP.jump_function(::OptiNode, x::Number) = convert(Float64, x) function JuMP.jump_function(node::OptiNode, vidx::MOI.VariableIndex) gb = graph_backend(node) - node_var = gb.graph_to_node_map[vidx] + node_var = gb.graph_to_element_map[vidx] return NodeVariableRef(node, node_var.index) end @@ -337,7 +337,7 @@ JuMP.variable_ref_type(::Type{OptiEdge{OptiGraph}}) = NodeVariableRef JuMP.jump_function(::OptiEdge, x::Number) = convert(Float64, x) function JuMP.jump_function(edge::OptiEdge, vidx::MOI.VariableIndex) - node_var = graph_backend(edge).graph_to_node_map[vidx] + node_var = graph_backend(edge).graph_to_element_map[vidx] node = node_var.node node_idx = node_var.index return NodeVariableRef(node, node_idx) @@ -371,7 +371,7 @@ JuMP.variable_ref_type(::Type{OptiGraph}) = NodeVariableRef JuMP.jump_function(::OptiGraph, x::Number) = convert(Float64, x) function JuMP.jump_function(graph::OptiGraph, vidx::MOI.VariableIndex) - node_var = graph_backend(graph).graph_to_node_map[vidx] + node_var = graph_backend(graph).graph_to_element_map[vidx] node = node_var.node node_idx = node_var.index return NodeVariableRef(node, node_idx) diff --git a/src/moi_aggregate.jl b/src/moi_aggregate.jl index 077df9e..183f286 100644 --- a/src/moi_aggregate.jl +++ b/src/moi_aggregate.jl @@ -5,17 +5,23 @@ Aggregate the moi backends from each subgraph within `graph` to create a single """ function aggregate_backends!(graph::OptiGraph) for subgraph in get_subgraphs(graph) - _aggregate_subgraph_nodes!(subgraph) - _aggregate_subgraph_edges!(subgraph) + _aggregate_subgraph_nodes!(graph, subgraph) + # _aggregate_subgraph_edges!(subgraph) end end -function _aggregate_subgraph_nodes!(graph::OptiGraph) - for node in all_nodes(graph) +function _aggregate_subgraph_nodes!(graph::OptiGraph, subgraph::OptiGraph) + for node in all_nodes(subgraph) _append_node_to_backend!(graph, node) end end +function _aggregate_subgraph_edges!(graph::OptiGraph, subgraph::OptiGraph) + for edges in all_edges(subgraph) + _append_edge_to_backend!(graph, node) + end +end + function _append_node_to_backend!(graph::OptiGraph, node::OptiNode) src = graph_backend(node) dest = graph_backend(graph) @@ -50,7 +56,7 @@ function _append_node_to_backend!(graph::OptiGraph, node::OptiNode) nonvariable_constraint_types ) - # TODO: pass non-objective attributes (use MOI Filter?) + # TODO: pass non-objective graph attributes (use an MOI Filter?) return end @@ -64,15 +70,15 @@ function _copy_node_variables( node_variables = all_variables(node) # map existing variables in index_map - existing_vars = intersect(node_variables, keys(dest.node_to_graph_map.var_map)) + existing_vars = intersect(node_variables, keys(dest.element_to_graph_map.var_map)) for var in existing_vars src_graph_index = graph_index(var) - dest_graph_index = dest.node_to_graph_map[var] + dest_graph_index = dest.element_to_graph_map[var] index_map[src_graph_index] = dest_graph_index end # create and add new variables - vars_to_add = setdiff(node_variables, keys(dest.node_to_graph_map.var_map)) + vars_to_add = setdiff(node_variables, keys(dest.element_to_graph_map.var_map)) for var in vars_to_add src_graph_index = graph_index(var) dest_graph_index = _add_variable_to_backend(dest, var) @@ -85,7 +91,6 @@ function _copy_node_variables( return end -# TODO: update graph backend mappings function _copy_node_constraints( dest::GraphMOIBackend, node::OptiNode, @@ -129,7 +134,8 @@ function _copy_node_constraints( for ci in cis_src f = MOI.get(src.moi_backend, MOI.ConstraintFunction(), ci) s = MOI.get(src.moi_backend, MOI.ConstraintSet(), ci) - cref = src.graph_to_node_map[ci] + cref = src.graph_to_element_map[ci] + cref in keys(dest.element_to_graph_map.con_map) && return dest_index = _add_node_constraint_to_backend( dest, cref, @@ -139,4 +145,19 @@ function _copy_node_constraints( index_map_FS[ci] = dest_index end return +end + +function _append_edge_to_backend!(graph::OptiGraph, edge::OptiEdge) + src = graph_backend(edge) + dest = graph_backend(graph) + index_map = MOIU.IndexMap() + + constraint_types = MOI.get(edge, MOI.ListOfConstraintTypesPresent()) + _copy_edge_constraints( + dest, + edge, + index_map, + constraint_types + ) + return end \ No newline at end of file diff --git a/src/moi_graph_backend.jl b/src/moi_graph_backend.jl index 57dad44..0d6dc08 100644 --- a/src/moi_graph_backend.jl +++ b/src/moi_graph_backend.jl @@ -1,32 +1,32 @@ """ Mapping of node variables and constraints to the optigraph backend. """ -mutable struct NodeToGraphMap +mutable struct ElementToGraphMap var_map::OrderedDict{NodeVariableRef,MOI.VariableIndex} con_map::OrderedDict{ConstraintRef,MOI.ConstraintIndex} end -function NodeToGraphMap() - return NodeToGraphMap( +function ElementToGraphMap() + return ElementToGraphMap( OrderedDict{NodeVariableRef,MOI.VariableIndex}(), OrderedDict{ConstraintRef,MOI.ConstraintIndex}(), ) end -function Base.setindex!(n2g_map::NodeToGraphMap, idx::MOI.VariableIndex, vref::NodeVariableRef) +function Base.setindex!(n2g_map::ElementToGraphMap, idx::MOI.VariableIndex, vref::NodeVariableRef) n2g_map.var_map[vref] = idx return end -function Base.getindex(n2g_map::NodeToGraphMap, vref::NodeVariableRef) +function Base.getindex(n2g_map::ElementToGraphMap, vref::NodeVariableRef) return n2g_map.var_map[vref] end -function Base.setindex!(n2g_map::NodeToGraphMap, idx::MOI.ConstraintIndex, cref::ConstraintRef) +function Base.setindex!(n2g_map::ElementToGraphMap, idx::MOI.ConstraintIndex, cref::ConstraintRef) n2g_map.con_map[cref] = idx return end -function Base.getindex(n2g_map::NodeToGraphMap, cref::ConstraintRef) +function Base.getindex(n2g_map::ElementToGraphMap, cref::ConstraintRef) return n2g_map.con_map[cref] end @@ -34,33 +34,33 @@ end Mapping of graph backend variable and constraint indices to node variables and constraints. """ -mutable struct GraphToNodeMap +mutable struct GraphToElementMap var_map::OrderedDict{MOI.VariableIndex,NodeVariableRef} con_map::OrderedDict{MOI.ConstraintIndex,ConstraintRef} end -function GraphToNodeMap() - return GraphToNodeMap( +function GraphToElementMap() + return GraphToElementMap( OrderedDict{MOI.VariableIndex,NodeVariableRef}(), OrderedDict{MOI.ConstraintIndex,ConstraintRef}(), ) end -function Base.setindex!(g2n_map::GraphToNodeMap, vref::NodeVariableRef, idx::MOI.VariableIndex) - g2n_map.var_map[idx] = vref +function Base.setindex!(g2element_map::GraphToElementMap, vref::NodeVariableRef, idx::MOI.VariableIndex) + g2element_map.var_map[idx] = vref return end -function Base.getindex(g2n_map::GraphToNodeMap, idx::MOI.VariableIndex) - return g2n_map.var_map[idx] +function Base.getindex(g2element_map::GraphToElementMap, idx::MOI.VariableIndex) + return g2element_map.var_map[idx] end -function Base.setindex!(g2n_map::GraphToNodeMap, cref::ConstraintRef, idx::MOI.ConstraintIndex) - g2n_map.con_map[idx] = cref +function Base.setindex!(g2element_map::GraphToElementMap, cref::ConstraintRef, idx::MOI.ConstraintIndex) + g2element_map.con_map[idx] = cref return end -function Base.getindex(g2n_map::GraphToNodeMap, idx::MOI.ConstraintIndex) - return g2n_map.con_map[idx] +function Base.getindex(g2element_map::GraphToElementMap, idx::MOI.ConstraintIndex) + return g2element_map.con_map[idx] end # acts as an intermediate optimizer, except it uses references to underlying nodes in the graph @@ -68,13 +68,18 @@ end # try to support Direct, Manual, and Automatic modes on an optigraph. mutable struct GraphMOIBackend <: MOI.AbstractOptimizer optigraph::AbstractOptiGraph - # TODO (maybe): legacy nlp model - # nlp_model::MOI.Nonlinear.Model moi_backend::MOI.AbstractOptimizer - node_to_graph_map::NodeToGraphMap - graph_to_node_map::GraphToNodeMap + + element_to_graph_map::ElementToGraphMap + graph_to_element_map::GraphToElementMap + + # map of variables and constraints on nodes and edges to graph backend indices node_variables::OrderedDict{OptiNode,Vector{MOI.VariableIndex}} node_constraints::OrderedDict{OptiNode,Vector{MOI.ConstraintIndex}} + edge_constraints::OrderedDict{OptiEdge,Vector{MOI.ConstraintIndex}} + + # TODO (maybe): legacy JuMP nonlinear support + # nlp_model::MOI.Nonlinear.Model end """ @@ -89,10 +94,11 @@ function GraphMOIBackend(optigraph::AbstractOptiGraph) return GraphMOIBackend( optigraph, cache, - NodeToGraphMap(), - GraphToNodeMap(), + ElementToGraphMap(), + GraphToElementMap(), OrderedDict{OptiNode,Vector{MOI.VariableIndex}}(), - OrderedDict{OptiNode,Vector{MOI.ConstraintIndex}}() + OrderedDict{OptiNode,Vector{MOI.ConstraintIndex}}(), + OrderedDict{OptiEdge,Vector{MOI.ConstraintIndex}}() ) end @@ -114,12 +120,12 @@ function MOI.get(gb::GraphMOIBackend, attr::MOI.AnyAttribute) end function MOI.get(gb::GraphMOIBackend, attr::MOI.AnyAttribute, ref::ConstraintRef) - graph_index = gb.node_to_graph_map[ref] + graph_index = gb.element_to_graph_map[ref] return MOI.get(gb.moi_backend, attr, graph_index) end function MOI.get(gb::GraphMOIBackend, attr::MOI.AnyAttribute, ref::NodeVariableRef) - graph_index = gb.node_to_graph_map[ref] + graph_index = gb.element_to_graph_map[ref] return MOI.get(gb.moi_backend, attr, graph_index) end @@ -161,8 +167,7 @@ function _moi_constrain_node_variable( info, ::Type{T}, ) where {T} - - graph_index = gb.node_to_graph_map[vref] + graph_index = gb.element_to_graph_map[vref] if info.has_lb con = JuMP.ScalarConstraint(vref, MOI.GreaterThan{T}(info.lower_bound)) _moi_add_node_constraint(vref.node, con) @@ -198,12 +203,12 @@ function _add_variable_to_backend( vref::NodeVariableRef ) # return if variable already in backend - vref in keys(graph_backend.node_to_graph_map.var_map) && return + vref in keys(graph_backend.element_to_graph_map.var_map) && return # add variable, track index graph_var_index = MOI.add_variable(graph_backend.moi_backend) - graph_backend.node_to_graph_map[vref] = graph_var_index - graph_backend.graph_to_node_map[graph_var_index] = vref + graph_backend.element_to_graph_map[vref] = graph_var_index + graph_backend.graph_to_element_map[graph_var_index] = vref # create key for node if necessary if !haskey(graph_backend.node_variables, vref.node) @@ -256,12 +261,13 @@ function _add_node_constraint_to_backend( func::F, set::S ) where {F<:MOI.AbstractFunction,S<:MOI.AbstractSet} + cref in keys(graph_backend.element_to_graph_map.con_map) && return if !haskey(graph_backend.node_constraints, cref.model) graph_backend.node_constraints[cref.model] = MOI.ConstraintIndex[] end graph_con_index = MOI.add_constraint(graph_backend.moi_backend, func, set) - graph_backend.node_to_graph_map[cref] = graph_con_index - graph_backend.graph_to_node_map[graph_con_index] = cref + graph_backend.element_to_graph_map[cref] = graph_con_index + graph_backend.graph_to_element_map[graph_con_index] = cref push!(graph_backend.node_constraints[cref.model], graph_con_index) return graph_con_index end @@ -293,7 +299,7 @@ function _create_graph_moi_func( moi_func::MOI.VariableIndex, jump_func::NodeVariableRef ) - return backend.node_to_graph_map[jump_func] + return backend.element_to_graph_map[jump_func] end """ @@ -314,7 +320,7 @@ function _create_graph_moi_func( for (i, term) in enumerate(JuMP.linear_terms(jump_func)) coeff = term[1] var = term[2] - backend_var_idx = backend.node_to_graph_map[var] + backend_var_idx = backend.element_to_graph_map[var] moi_func_graph.terms[i] = MOI.ScalarAffineTerm{Float64}(coeff, backend_var_idx) end return moi_func_graph @@ -331,8 +337,8 @@ function _create_graph_moi_func( coeff = term[1] var1 = term[2] var2 = term[3] - var_idx_1 = backend.node_to_graph_map[var1] - var_idx_2 = backend.node_to_graph_map[var2] + var_idx_1 = backend.element_to_graph_map[var1] + var_idx_2 = backend.element_to_graph_map[var2] moi_func_graph.quadratic_terms[i] = MOI.ScalarQuadraticTerm{Float64}( coeff, @@ -345,7 +351,7 @@ function _create_graph_moi_func( for (i, term) in enumerate(JuMP.linear_terms(jump_func)) coeff = term[1] var = term[2] - backend_var_idx = backend.node_to_graph_map[var] + backend_var_idx = backend.element_to_graph_map[var] moi_func_graph.affine_terms[i] = MOI.ScalarAffineTerm{Float64}(coeff, backend_var_idx) end return moi_func_graph @@ -372,7 +378,7 @@ function _update_nonlinear_func!( if jump_arg isa JuMP.GenericNonlinearExpr _update_nonlinear_func!(backend, moi_arg, jump_arg) elseif typeof(jump_arg) == NodeVariableRef - moi_func.args[i] = backend.node_to_graph_map[jump_arg] + moi_func.args[i] = backend.element_to_graph_map[jump_arg] end end return @@ -386,7 +392,7 @@ function _add_backend_variables( jump_func::JuMP.GenericAffExpr ) vars = [term[2] for term in JuMP.linear_terms(jump_func)] - vars_to_add = setdiff(vars, keys(backend.node_to_graph_map.var_map)) + vars_to_add = setdiff(vars, keys(backend.element_to_graph_map.var_map)) for var in vars_to_add _add_variable_to_backend(backend, var) end @@ -400,7 +406,7 @@ function _add_backend_variables( vars_aff = [term[2] for term in JuMP.linear_terms(jump_func)] vars_quad = vcat([[term[2], term[3]] for term in JuMP.quad_terms(jump_func)]...) vars_unique = unique([vars_aff;vars_quad]) - vars_to_add = setdiff(vars_unique, keys(backend.node_to_graph_map.var_map)) + vars_to_add = setdiff(vars_unique, keys(backend.element_to_graph_map.var_map)) for var in vars_to_add _add_variable_to_backend(backend, var) end @@ -420,7 +426,7 @@ function _add_backend_variables( push!(vars, jump_arg) end end - vars_to_add = setdiff(vars, keys(backend.node_to_graph_map.var_map)) + vars_to_add = setdiff(vars, keys(backend.element_to_graph_map.var_map)) for var in vars_to_add _add_variable_to_backend(backend, var) end @@ -466,8 +472,8 @@ function _add_edge_constraint_to_backend( set::S ) where {F<:MOI.AbstractFunction,S<:MOI.AbstractSet} graph_con_index = MOI.add_constraint(graph_backend.moi_backend, func, set) - graph_backend.node_to_graph_map[cref] = graph_con_index - graph_backend.graph_to_node_map[graph_con_index] = cref + graph_backend.element_to_graph_map[cref] = graph_con_index + graph_backend.graph_to_element_map[graph_con_index] = cref return graph_con_index end diff --git a/src/optiedge.jl b/src/optiedge.jl index a8236e8..bfc2c24 100644 --- a/src/optiedge.jl +++ b/src/optiedge.jl @@ -68,6 +68,26 @@ function MOI.get(edge::OptiEdge, attr::MOI.AbstractConstraintAttribute, ref::Con return MOI.get(graph_backend(edge), attr, ref) end +function MOI.get(edge::OptiEdge, attr::MOI.ListOfConstraintTypesPresent) + cons = graph_backend(edge).edge_constraints[edge] + con_types = unique(typeof.(cons)) + type_tuple = [(type.parameters[1],type.parameters[2]) for type in con_types] + return type_tuple +end + +function MOI.get( + edge::OptiEdge, + attr::MOI.ListOfConstraintIndices{F,S} +) where {F <: MOI.AbstractFunction, S <: MOI.AbstractSet} + con_inds = MOI.ConstraintIndex{F,S}[] + for con in graph_backend(edge).edge_constraints[edge] + if (typeof(con).parameters[1] == F && typeof(con).parameters[2] == S) + push!(con_inds, con) + end + end + return con_inds +end + function JuMP.object_dictionary(edge::OptiEdge) return edge.source_graph.edge_obj_dict end @@ -82,7 +102,7 @@ function JuMP.num_constraints( ::Type{S} )::Int64 where {F<:MOI.AbstractFunction,S<:MOI.AbstractSet} # TODO: more efficent method to track number of constraints on nodes and edges - g2e = graph_backend(edge).graph_to_node_map + g2e = graph_backend(edge).graph_to_element_map cons = MOI.get(JuMP.backend(edge),MOI.ListOfConstraintIndices{F,S}()) refs = [g2e[con] for con in cons] return length(filter((cref) -> cref.model == edge, refs)) diff --git a/src/optigraph.jl b/src/optigraph.jl index caca828..f5b7765 100644 --- a/src/optigraph.jl +++ b/src/optigraph.jl @@ -117,9 +117,31 @@ function add_node( return optinode end +""" + get_subgraphs(graph::OptiGraph)::Vector{OptiGraph} + +Retrieve the local subgraphs of `graph`. +""" +function get_subgraphs(optigraph::OptiGraph) + return optigraph.subgraphs +end + +""" + all_nodes(graph::OptiGraph)::Vector{OptiNode} + +Recursively collect all optinodes in `graph` by traversing each of its subgraphs. +""" +function all_nodes(graph::OptiGraph) + nodes = graph.optinodes + for subgraph in graph.subgraphs + nodes = [nodes; all_nodes(subgraph)] + end + return nodes +end + function JuMP.index(graph::OptiGraph, vref::NodeVariableRef) gb = graph_backend(graph) - return gb.node_to_graph_map[vref] + return gb.element_to_graph_map[vref] end ### Add Edges diff --git a/src/optinode.jl b/src/optinode.jl index 7d7d2c1..c73b084 100644 --- a/src/optinode.jl +++ b/src/optinode.jl @@ -77,6 +77,27 @@ function MOI.get(node::OptiNode, attr::MOI.AbstractConstraintAttribute, ref::Con return MOI.get(graph_backend(node), attr, ref) end +# TODO: look into caching constraint types in graph backend versus using unique and filters +function MOI.get(node::OptiNode, attr::MOI.ListOfConstraintTypesPresent) + cons = graph_backend(node).node_constraints[node] + con_types = unique(typeof.(cons)) + type_tuple = [(type.parameters[1],type.parameters[2]) for type in con_types] + return type_tuple +end + +function MOI.get( + node::OptiNode, + attr::MOI.ListOfConstraintIndices{F,S} +) where {F <: MOI.AbstractFunction, S <: MOI.AbstractSet} + con_inds = MOI.ConstraintIndex{F,S}[] + for con in graph_backend(node).node_constraints[node] + if (typeof(con).parameters[1] == F && typeof(con).parameters[2] == S) + push!(con_inds, con) + end + end + return con_inds +end + function JuMP.object_dictionary(node::OptiNode) return node.source_graph.node_obj_dict end @@ -85,11 +106,10 @@ function JuMP.backend(node::OptiNode) return JuMP.backend(graph_backend(node)) end -# TODO: determine if caching node references is possible without dict-of-dicts function JuMP.all_variables(node::OptiNode) gb = graph_backend(node) graph_indices = gb.node_variables[node] - return getindex.(Ref(gb.graph_to_node_map), graph_indices) + return getindex.(Ref(gb.graph_to_element_map), graph_indices) end function JuMP.num_variables(node::OptiNode) @@ -102,7 +122,7 @@ function JuMP.num_constraints( ::Type{F}, ::Type{S} )::Int64 where {F<:MOI.AbstractFunction,S<:MOI.AbstractSet} - g2n = graph_backend(node).graph_to_node_map + g2n = graph_backend(node).graph_to_element_map cons = MOI.get(JuMP.backend(node), MOI.ListOfConstraintIndices{F,S}()) refs = [g2n[con] for con in cons] return length(filter((cref) -> cref.model == node, refs)) @@ -123,7 +143,7 @@ Base.show(io::IO, vref::NodeVariableRef) = Base.print(io, vref) Base.broadcastable(vref::NodeVariableRef) = Ref(vref) function graph_index(vref::NodeVariableRef) - return graph_backend(vref.node).node_to_graph_map[vref] + return graph_backend(vref.node).element_to_graph_map[vref] end """ @@ -158,12 +178,12 @@ end function JuMP.name(vref::NodeVariableRef) gb = graph_backend(vref.node) - return MOI.get(JuMP.backend(vref.node), MOI.VariableName(), gb.node_to_graph_map[vref]) + return MOI.get(JuMP.backend(vref.node), MOI.VariableName(), gb.element_to_graph_map[vref]) end function JuMP.set_name(vref::NodeVariableRef, s::String) gb = graph_backend(vref.node) - MOI.set(gb.moi_backend, MOI.VariableName(), gb.node_to_graph_map[vref], s) + MOI.set(gb.moi_backend, MOI.VariableName(), gb.element_to_graph_map[vref], s) return end @@ -180,26 +200,4 @@ function JuMP.add_constraint( con = JuMP.model_convert(node, con) cref = _moi_add_node_constraint(node, con) return cref -end - -### MOI extensions for optinode -# TODO: cache constraint types in graph backend versus using unique and filters? -function MOI.get(node::OptiNode, attr::MOI.ListOfConstraintTypesPresent) - cons = graph_backend(node).node_constraints[node] - con_types = unique(typeof.(cons)) - type_tuple = [(type.parameters[1],type.parameters[2]) for type in con_types] - return type_tuple -end - -function MOI.get( - node::OptiNode, - attr::MOI.ListOfConstraintIndices{F,S} -) where {F <: MOI.AbstractFunction, S <: MOI.AbstractSet} - con_inds = MOI.ConstraintIndex{F,S}[] - for con in graph_backend(node).node_constraints[node] - if (typeof(con).parameters[1] == F && typeof(con).parameters[2] == S) - push!(con_inds, con) - end - end - return con_inds end \ No newline at end of file