Skip to content

Commit

Permalink
[Bridges] change supports for AbstractConstraintAttribute to OR formu…
Browse files Browse the repository at this point in the history
…lation
  • Loading branch information
odow committed Sep 27, 2023
1 parent 44e271c commit 2aca294
Showing 1 changed file with 18 additions and 39 deletions.
57 changes: 18 additions & 39 deletions src/Bridges/bridge_optimizer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1442,49 +1442,28 @@ function MOI.supports(
# This function is slightly confusing, because we need to account for
# the different ways in which a constraint might be added.
if F == MOI.Utilities.variable_function_type(S)
# These are VariableIndex and VectorOfVariable constraints.
if is_bridged(b, S)
# If S needs to be bridged, it usually means that either there is a
# variable bridge, or that there is a free variable followed by a
# constraint bridge (i.e., the two cases handled below).
#
# However, it might be the case, like the tests in
# Variable/flip_sign.jl, that the model supports F-in-S constraints,
# but force-bridges S sets. If so, we might be in the unusual
# situation where we support the attribute if the index was added
# via add_constraint, but not if it was added via
# add_constrained_variable. Because MOI lacks the ability to tell
# which happened just based on the type, we're going to default to
# asking the variable bridge, at the risk of a false negative.
if is_variable_bridged(b, S)
bridge = Variable.concrete_bridge_type(b, S)
return MOI.supports(recursive_model(b), attr, bridge)
else
bridge = Constraint.concrete_bridge_type(b, F, S)
return MOI.supports(recursive_model(b), attr, bridge)
end
else
# If S doesn't need to be bridged, it usually means that either the
# solver supports add_constrained_variable, or it supports free
# variables and add_constraint.
#
# In some cases, it might be that the solver supports
# add_constrained_variable, but ends up bridging add_constraint.
# Because MOI lacks the ability to tell which one was called based
# on the index type, asking the model might give a false negative
# (we support the attribute via add_constrained_variable, but the
# bridge doesn't via add_constraint because it will be bridged).
return MOI.supports(b.model, attr, MOI.ConstraintIndex{F,S})
# supports should return true if it is possible to support the
# attribute at any point, even if it does not currently support it.
#
# So check if the model supports it if we added via `add_constraint` and
# didn't bridge:
ret = MOI.supports(b.model, attr, MOI.ConstraintIndex{F,S})
# And if we added it via a variable bridge:
if is_variable_bridged(b, S)
bridge = Variable.concrete_bridge_type(b, S)
ret |= MOI.supports(recursive_model(b), attr, bridge)
end
else
# These are normal add_constraints, so we just check if they are
# bridged.
# And if we added it via a constraint bridge:
if is_bridged(b, F, S)
bridge = Constraint.concrete_bridge_type(b, F, S)
return MOI.supports(recursive_model(b), attr, bridge)
else
return MOI.supports(b.model, attr, MOI.ConstraintIndex{F,S})
ret |= MOI.supports(recursive_model(b), attr, bridge)
end
return ret
elseif is_bridged(b, F, S)
bridge = Constraint.concrete_bridge_type(b, F, S)
return MOI.supports(recursive_model(b), attr, bridge)
else
return MOI.supports(b.model, attr, MOI.ConstraintIndex{F,S})
end
end

Expand Down

0 comments on commit 2aca294

Please sign in to comment.