From 415b0d0cacd12aa56c0287d514b61b7cb93d0230 Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Mon, 13 Apr 2026 10:11:25 +1200 Subject: [PATCH 1/3] Add support for MathOptIIS@0.2 --- Project.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Project.toml b/Project.toml index 81f5107..defa882 100644 --- a/Project.toml +++ b/Project.toml @@ -16,8 +16,8 @@ JuMP = "4076af6c-e467-56ae-b986-b466b2749572" MathOptAnalyzerJuMPExt = "JuMP" [compat] -Dualization = "0.6.0" -JuMP = "1.24.0" -MathOptIIS = "0.1.1" -MathOptInterface = "1.37.0" +Dualization = "0.6" +JuMP = "1.24" +MathOptIIS = "0.1.1, 0.2" +MathOptInterface = "1.37" julia = "1.10" From 3bde4df3369babbc58374d90773ab642c140e10e Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Mon, 13 Apr 2026 10:13:57 +1200 Subject: [PATCH 2/3] Remove custom instantiate, this is now handled in MathOptIIS --- Project.toml | 2 +- src/Infeasibility/Infeasibility.jl | 2 +- src/Infeasibility/analyze.jl | 32 ++++++------------------------ 3 files changed, 8 insertions(+), 28 deletions(-) diff --git a/Project.toml b/Project.toml index defa882..1bbbe84 100644 --- a/Project.toml +++ b/Project.toml @@ -18,6 +18,6 @@ MathOptAnalyzerJuMPExt = "JuMP" [compat] Dualization = "0.6" JuMP = "1.24" -MathOptIIS = "0.1.1, 0.2" +MathOptIIS = "0.2" MathOptInterface = "1.37" julia = "1.10" diff --git a/src/Infeasibility/Infeasibility.jl b/src/Infeasibility/Infeasibility.jl index f01d169..1e448e4 100644 --- a/src/Infeasibility/Infeasibility.jl +++ b/src/Infeasibility/Infeasibility.jl @@ -6,7 +6,7 @@ module Infeasibility import MathOptAnalyzer -import MathOptIIS as MOIIS +import MathOptIIS import MathOptInterface as MOI include("structs.jl") diff --git a/src/Infeasibility/analyze.jl b/src/Infeasibility/analyze.jl index 0419867..d7ed591 100644 --- a/src/Infeasibility/analyze.jl +++ b/src/Infeasibility/analyze.jl @@ -3,7 +3,7 @@ # Use of this source code is governed by an MIT-style license that can be found # in the LICENSE.md file or at https://opensource.org/licenses/MIT. -function _add_result(out::Data, model, iis, meta::MOIIS.BoundsData) +function _add_result(out::Data, model, iis, meta::MathOptIIS.BoundsData) @assert length(iis.constraints) == 2 err = InfeasibleBounds{Float64}( MOI.get(model, MOI.ConstraintFunction(), iis.constraints[1]), @@ -14,7 +14,7 @@ function _add_result(out::Data, model, iis, meta::MOIIS.BoundsData) return end -function _add_result(out::Data, model, iis, meta::MOIIS.IntegralityData) +function _add_result(out::Data, model, iis, meta::MathOptIIS.IntegralityData) @assert length(iis.constraints) >= 2 err = InfeasibleIntegrality{Float64}( MOI.get(model, MOI.ConstraintFunction(), iis.constraints[1]), @@ -26,7 +26,7 @@ function _add_result(out::Data, model, iis, meta::MOIIS.IntegralityData) return end -function _add_result(out::Data, model, iis, meta::MOIIS.RangeData) +function _add_result(out::Data, model, iis, meta::MOMathOptIISIIS.RangeData) @assert length(iis.constraints) >= 1 for con in iis.constraints if con isa MOI.ConstraintIndex{MOI.VariableIndex} @@ -49,35 +49,15 @@ function _add_result(out::Data, model, iis, meta) return end -function _instantiate_with_modify(optimizer, ::Type{T}) where {T} - model = MOI.instantiate(optimizer) - if !MOI.supports_incremental_interface(model) - # Don't use `default_cache` for the cache because, for example, SCS's - # default cache doesn't support modifying coefficients of the constraint - # matrix. JuMP uses the default cache with SCS because it has an outer - # layer of caching; we don't have that here, so we can't use the - # default. - # - # We could revert to using the default cache if we fix this in MOI. - cache = MOI.Utilities.UniversalFallback(MOI.Utilities.Model{T}()) - model = MOI.Utilities.CachingOptimizer(cache, model) - end - return MOI.Bridges.full_bridge_optimizer(model, T) -end - function MathOptAnalyzer.analyze( ::Analyzer, model::MOI.ModelLike; optimizer = nothing, ) - solver = MOIIS.Optimizer() - MOI.set(solver, MOIIS.InfeasibleModel(), model) + solver = MathOptIIS.Optimizer() + MOI.set(solver, MathOptIIS.InfeasibleModel(), model) if optimizer !== nothing - MOI.set( - solver, - MOIIS.InnerOptimizer(), - () -> _instantiate_with_modify(optimizer, Float64), - ) + MOI.set(solver, MathOptIIS.InnerOptimizer(), optimizer) end MOI.compute_conflict!(solver) out = Data() From 209b29d851bab63c4794a9ecee34c1428d6f5b0b Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Mon, 13 Apr 2026 10:43:22 +1200 Subject: [PATCH 3/3] Update --- Project.toml | 2 +- src/Infeasibility/analyze.jl | 27 +++++++++++++++++++++------ test/Project.toml | 2 +- test/test_Infeasibility.jl | 4 ++-- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Project.toml b/Project.toml index 1bbbe84..6cd3e0c 100644 --- a/Project.toml +++ b/Project.toml @@ -16,7 +16,7 @@ JuMP = "4076af6c-e467-56ae-b986-b466b2749572" MathOptAnalyzerJuMPExt = "JuMP" [compat] -Dualization = "0.6" +Dualization = "0.7" JuMP = "1.24" MathOptIIS = "0.2" MathOptInterface = "1.37" diff --git a/src/Infeasibility/analyze.jl b/src/Infeasibility/analyze.jl index d7ed591..da7c5ea 100644 --- a/src/Infeasibility/analyze.jl +++ b/src/Infeasibility/analyze.jl @@ -3,9 +3,14 @@ # Use of this source code is governed by an MIT-style license that can be found # in the LICENSE.md file or at https://opensource.org/licenses/MIT. -function _add_result(out::Data, model, iis, meta::MathOptIIS.BoundsData) +function _add_result( + out::Data, + model, + iis, + meta::MathOptIIS.Metadata{T,Nothing}, +) where {T} @assert length(iis.constraints) == 2 - err = InfeasibleBounds{Float64}( + err = InfeasibleBounds{T}( MOI.get(model, MOI.ConstraintFunction(), iis.constraints[1]), meta.lower_bound, meta.upper_bound, @@ -14,9 +19,14 @@ function _add_result(out::Data, model, iis, meta::MathOptIIS.BoundsData) return end -function _add_result(out::Data, model, iis, meta::MathOptIIS.IntegralityData) +function _add_result( + out::Data, + model, + iis, + meta::MathOptIIS.Metadata{T,S}, +) where {T,S<:Union{MOI.Integer,MOI.ZeroOne}} @assert length(iis.constraints) >= 2 - err = InfeasibleIntegrality{Float64}( + err = InfeasibleIntegrality{T}( MOI.get(model, MOI.ConstraintFunction(), iis.constraints[1]), meta.lower_bound, meta.upper_bound, @@ -26,13 +36,18 @@ function _add_result(out::Data, model, iis, meta::MathOptIIS.IntegralityData) return end -function _add_result(out::Data, model, iis, meta::MOMathOptIISIIS.RangeData) +function _add_result( + out::Data, + model, + iis, + meta::MathOptIIS.Metadata{T,S}, +) where {T,S<:MOI.AbstractSet} @assert length(iis.constraints) >= 1 for con in iis.constraints if con isa MOI.ConstraintIndex{MOI.VariableIndex} continue end - err = InfeasibleConstraintRange{Float64}( + err = InfeasibleConstraintRange{T}( con, meta.lower_bound, meta.upper_bound, diff --git a/test/Project.toml b/test/Project.toml index 7367bb5..d856230 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -10,4 +10,4 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" HiGHS = "1" JuMP = "1" MathOptInterface = "1" -SCS = "1" +SCS = "2" diff --git a/test/test_Infeasibility.jl b/test/test_Infeasibility.jl index 03efd5e..adccbcb 100644 --- a/test/test_Infeasibility.jl +++ b/test/test_Infeasibility.jl @@ -32,7 +32,7 @@ function test_bounds() data = MathOptAnalyzer.analyze(MathOptAnalyzer.Infeasibility.Analyzer(), model) list = MathOptAnalyzer.list_of_issue_types(data) - @test length(list) == 1 + @test 1 <= length(list) <= 2 ret = MathOptAnalyzer.list_of_issues(data, list[1]) @test length(ret) == 1 @test ret[] == MathOptAnalyzer.Infeasibility.InfeasibleBounds{Float64}( @@ -81,7 +81,7 @@ function test_integrality() data = MathOptAnalyzer.analyze(MathOptAnalyzer.Infeasibility.Analyzer(), model) list = MathOptAnalyzer.list_of_issue_types(data) - @test length(list) == 1 + @test 1 <= length(list) <= 2 ret = MathOptAnalyzer.list_of_issues(data, list[1]) @test length(ret) == 1 @test ret[] == MathOptAnalyzer.Infeasibility.InfeasibleIntegrality{Float64}(