# MOI: Re-evaluate custom bridge & \`direct\_model(...)\` bridging

**URL:** <https://discourse.julialang.org/t/moi-re-evaluate-custom-bridge-direct-model-bridging/94219>\
**Category:** Optimization (Mathematical)\
**Created:** [February 7, 2023, 3:38pm UTC](https://discourse.julialang.org/t/moi-re-evaluate-custom-bridge-direct-model-bridging/94219 "2023-02-07T15:38:20Z")\
**Posts on this page:** 1\
**Showing post:** 3

<div class="post-metadata">

**Author:** ![sstroemer](https://avatars.discourse-cdn.com/v4/letter/s/a88e4f/32.png) [@sstroemer](https://discourse.julialang.org/u/sstroemer)\
**Post date:** [February 7, 2023, 9:46pm UTC](https://discourse.julialang.org/t/moi-re-evaluate-custom-bridge-direct-model-bridging/94219/3 "2023-02-07T21:46:13Z")

</div>

Thanks for the hint, besides all the digging into MOI, I somehow missed that JuMP has the `add_bridge` too… 🙂

MWE below, short preface: I’ve got a quadratic constraint, that I want to reformulate in a way that HiGHS can handle it; the MWE just deletes the constraint.

The bridge looks like ([based on your answer here](https://discourse.julialang.org/t/help-understanding-moi-bridges-even-proof-of-concept-doesnt-work/43152/2)):

```julia
struct MyCustomBridge{T} <: MOI.Bridges.Constraint.AbstractBridge end

function MOI.Bridges.Constraint.concrete_bridge_type(
    ::Type{<:MyCustomBridge}, 
    F::Type{<:MOI.ScalarQuadraticFunction},
    S::Type{<:MOI.AbstractScalarSet},
)
    return MyCustomBridge{Float64}
end

function MOI.supports_constraint(
    ::Type{<:MyCustomBridge},
	::Type{<:MOI.ScalarQuadraticFunction},
	::Type{<:MOI.AbstractScalarSet},
)
	return true
end

function MOI.Bridges.added_constrained_variable_types(::Type{<:MyCustomBridge}) 
	return Tuple{DataType}[]
end

function MOI.Bridges.added_constraint_types(::Type{<:MyCustomBridge})
	return []
end

function MOI.Bridges.Constraint.bridge_constraint(
    ::Type{<:MyCustomBridge}, 
    m::MOI.ModelLike, 
    f::MOI.ScalarQuadraticFunction, 
    s::MOI.AbstractScalarSet,
)
    @info "Bridging now"
    return MyCustomBridge{Float64}()
end

```

The model building looks like:

```julia
model = JuMP.Model(HiGHS.Optimizer)
JuMP.add_bridge(model, MyCustomBridge)

x = JuMP.@variable(model, [1:3], lower_bound=0)
c = JuMP.@constraint(model, x[1] + x[2]^2 - 3*x[3] >= 0)

JuMP.@objective(model, Min, x[1] + 0)

JuMP.optimize!(model) # calling the bridge here

JuMP.fix(x[2], 5; force=true) # fixing this variable would make the constraint viable for HiGHS

JuMP.optimize!(model) # not calling the bride here - constraint is still deleted

JuMP.set_normalized_rhs(c, JuMP.normalized_rhs(c))

JuMP.optimize!(model) # calling the bridge here

```

The important part is `JuMP.fix(x[2], 5; force=true)`, where the user may change the constraint (by fixing the variable that complicates the constraint into a quadratic one) - essentially reducing the constraint to an affine one. Now the next `optimize!(...)` does not call the bridge - as far as I understand because it actually does not “know of the change” (since `fix()` just creates an additional MOI Equal).

If however I force an “update” of the respective constraint, e.g. using `JuMP.set_normalized_rhs(c, JuMP.normalized_rhs(c))`, then the following `optimize!(...)` will invoke the bridge - allowing me to react to the change that the user made.

While it makes sense (at least to me 😅), that this happens, I’m looking for a “less hacky” way to trigger that update.

---

_[View the full topic](https://discourse.julialang.org/t/moi-re-evaluate-custom-bridge-direct-model-bridging/94219)._
