Skip to content

[Bridges] Remove the need of negative indices#3010

Draft
blegat wants to merge 3 commits into
masterfrom
bl/reserve_bridge
Draft

[Bridges] Remove the need of negative indices#3010
blegat wants to merge 3 commits into
masterfrom
bl/reserve_bridge

Conversation

@blegat

@blegat blegat commented Jun 10, 2026

Copy link
Copy Markdown
Member

Bridges use negative indices to distinguish some bridged constraints from the ones of the inner model. This prevents bridges to be stacked directly without a CachingOptimizer in between which is annoying when using SingleBridgeOptimizer and complicates a lot #2986 (comment).
Looking at it again, negative indices are only needed when variable bridges are used. For constraint-bridges, all constraints of the same types are either all bridged or not so there is no risk of clash between constraint indices.
With variable bridges, you may have clashes with the indices of the bridged variables with the ones of the inner model. Another example is in case the user creates a VectorOfVariables-in-S constraints where one of the variable is bridged. After substitution, this becomes a VectorAffineFunction-in-S so we need to bridge it with a functionize bridge so we need to create a VectorOfVariables-in-S constraint even if the user may support constraint of this type so that can cause clashes as well.
We used to create negative indices for this but this PR takes a different approach.
The idea of Claude is to create a variable in the inner model and then delete it. I am not such a big fan though, maybe we should just have different index spaces for the inner and outer models completely.

blegat added 3 commits June 7, 2026 17:29
Introduce MOI.Bridges.reserve_variable_index(model) and
reserve_constraint_index(model, F, S) so that bridge layers can allocate
identities that don't collide with the inner model's namespace.

The default reserve_variable_index adds a variable and immediately deletes
it. The default reserve_constraint_index adds a dummy F-in-S constraint
(building zero/empty function and a default S instance) and deletes it.
For VariableIndex/VectorOfVariables constraints, dummy variables are also
cleaned up. MOI models don't recycle deleted indices, so the returned
index is guaranteed unique in the inner namespace.

AbstractBridgeOptimizer cascades both calls down to b.model, so
reservation propagates all the way to the leaf model. This is the
foundation for stacking SingleBridgeOptimizers without a caching layer
in between.

No existing behavior is changed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant