From f98f14801c04b69dec99754116f7c7d6d9774087 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Fri, 3 Apr 2026 20:38:12 +0200 Subject: [PATCH 1/3] Use Base.convert instead of custom _convert --- src/bridge.jl | 83 +-------------------------------------------------- 1 file changed, 1 insertion(+), 82 deletions(-) diff --git a/src/bridge.jl b/src/bridge.jl index c0d5611..4e98214 100644 --- a/src/bridge.jl +++ b/src/bridge.jl @@ -36,7 +36,7 @@ function MOI.Bridges.Constraint.bridge_constraint( func.iterators[k].values[idx[k]] for k in eachindex(func.iterators) ] expanded = _expand(func.func, values) - scalar_func = _convert(F, expanded) + scalar_func = convert(F, expanded) ci = MOI.Utilities.normalize_and_add_constraint( model, scalar_func, @@ -164,84 +164,3 @@ function _eval_op(head::Symbol, args::Vector) ) end end - -# --- Conversion from expanded ScalarNonlinearFunction to target type F --- - -function _convert( - ::Type{MOI.ScalarNonlinearFunction}, - expr::MOI.ScalarNonlinearFunction, -) - return expr -end -_convert(::Type{F}, expr::F) where {F} = expr - -function _convert( - ::Type{MOI.ScalarAffineFunction{T}}, - expr::MOI.ScalarNonlinearFunction, -) where {T} - terms, constant = _collect_affine_terms(T, expr) - if terms === nothing - throw(InexactError(:convert, MOI.ScalarAffineFunction{T}, expr)) - end - return MOI.ScalarAffineFunction(terms, T(constant)) -end - -function _collect_affine_terms( - ::Type{T}, - expr::MOI.ScalarNonlinearFunction, -) where {T} - if expr.head == :+ && length(expr.args) == 2 - t1, c1 = _collect_affine_terms(T, expr.args[1]) - t2, c2 = _collect_affine_terms(T, expr.args[2]) - (t1 === nothing || t2 === nothing) && return (nothing, zero(T)) - return (vcat(t1, t2), c1 + c2) - elseif expr.head == :- && length(expr.args) == 2 - t1, c1 = _collect_affine_terms(T, expr.args[1]) - t2, c2 = _collect_affine_terms(T, expr.args[2]) - (t1 === nothing || t2 === nothing) && return (nothing, zero(T)) - neg_t2 = [MOI.ScalarAffineTerm(-t.coefficient, t.variable) for t in t2] - return (vcat(t1, neg_t2), c1 - c2) - elseif expr.head == :- && length(expr.args) == 1 - t1, c1 = _collect_affine_terms(T, expr.args[1]) - t1 === nothing && return (nothing, zero(T)) - neg_t1 = [MOI.ScalarAffineTerm(-t.coefficient, t.variable) for t in t1] - return (neg_t1, -c1) - elseif expr.head == :* && length(expr.args) == 2 - a1, a2 = expr.args - if a1 isa Number && a2 isa MOI.VariableIndex - return ([MOI.ScalarAffineTerm(T(a1), a2)], zero(T)) - elseif a2 isa Number && a1 isa MOI.VariableIndex - return ([MOI.ScalarAffineTerm(T(a2), a1)], zero(T)) - elseif a1 isa Number && a2 isa MOI.ScalarNonlinearFunction - t2, c2 = _collect_affine_terms(T, a2) - t2 === nothing && return (nothing, zero(T)) - scaled = [ - MOI.ScalarAffineTerm(T(a1) * t.coefficient, t.variable) for - t in t2 - ] - return (scaled, T(a1) * c2) - elseif a2 isa Number && a1 isa MOI.ScalarNonlinearFunction - t1, c1 = _collect_affine_terms(T, a1) - t1 === nothing && return (nothing, zero(T)) - scaled = [ - MOI.ScalarAffineTerm(T(a2) * t.coefficient, t.variable) for - t in t1 - ] - return (scaled, T(a2) * c1) - elseif a1 isa Number && a2 isa Number - return (MOI.ScalarAffineTerm{T}[], T(a1 * a2)) - else - return (nothing, zero(T)) - end - else - return (nothing, zero(T)) - end -end - -function _collect_affine_terms(::Type{T}, x::MOI.VariableIndex) where {T} - return ([MOI.ScalarAffineTerm(one(T), x)], zero(T)) -end - -function _collect_affine_terms(::Type{T}, x::Number) where {T} - return (MOI.ScalarAffineTerm{T}[], T(x)) -end From 60a08a4bf40e1f10e01e7e0a79c0c20a28885578 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Fri, 3 Apr 2026 20:57:12 +0200 Subject: [PATCH 2/3] remove test --- test/bridge.jl | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/test/bridge.jl b/test/bridge.jl index 0edadb8..7217f8a 100644 --- a/test/bridge.jl +++ b/test/bridge.jl @@ -217,18 +217,6 @@ function test_expand_with_variable_in_expr() @test result.args[2] == 3.0 end -function test_convert_to_affine() - x1 = MOI.VariableIndex(1) - # x1 - 1.0 should convert to ScalarAffineFunction - func = MOI.ScalarNonlinearFunction(:-, Any[x1, 1.0]) - result = GenOpt._convert(MOI.ScalarAffineFunction{Float64}, func) - @test result isa MOI.ScalarAffineFunction{Float64} - @test length(result.terms) == 1 - @test result.terms[1].coefficient == 1.0 - @test result.terms[1].variable == x1 - @test result.constant == -1.0 -end - function test_simple_constraint_group() # min sum(x) s.t. x[i] >= 1 for i in 1..3 optimizer = _create_optimizer() From b9a815f917e4f8e5b27b104b25b8052c05cb0076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Tue, 28 Apr 2026 08:34:16 +0200 Subject: [PATCH 3/3] bump moi --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 0f5cda4..99971af 100644 --- a/Project.toml +++ b/Project.toml @@ -11,5 +11,5 @@ MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" [compat] ExaModels = "0.9" JuMP = "1.29" -MathOptInterface = "1.46" +MathOptInterface = "1.51" julia = "1.10"