Skip to content

[breaking] a large refactoring of MathOptIIS#34

Open
odow wants to merge 2 commits intomainfrom
od/solver
Open

[breaking] a large refactoring of MathOptIIS#34
odow wants to merge 2 commits intomainfrom
od/solver

Conversation

@odow
Copy link
Member

@odow odow commented Feb 20, 2026

This commit is breaking because it:

  • Removes SkipFeasibilityCheck
  • Removes StopIfInfeasibleBounds
  • Removes StopIfInfeasibleRanges
  • Removes DeletionFilter
  • Removes ElasticFilterTolerance
  • Removes ElasticFilterIgnoreIntegrality

In addition, this commit will likely result in a different IIS being
returned for many models because it now exploits an infeasibility
certificate if one is present.

@odow
Copy link
Member Author

odow commented Feb 23, 2026

Okay. I've gone full Rambo and refactored everything so this is breaking.

I've also removed many of the "option" controlling attributes. I don't think we want flexibility in how the algorithm runs. We want a simple set-and-forget.

@codecov
Copy link

codecov bot commented Feb 23, 2026

Codecov Report

❌ Patch coverage is 99.55457% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 99.55%. Comparing base (f7b3b73) to head (9fffdc7).

Files with missing lines Patch % Lines
src/MathOptIIS.jl 99.54% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #34      +/-   ##
==========================================
+ Coverage   95.44%   99.55%   +4.11%     
==========================================
  Files           4        2       -2     
  Lines         395      449      +54     
==========================================
+ Hits          377      447      +70     
+ Misses         18        2      -16     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@odow odow force-pushed the od/solver branch 2 times, most recently from 2e98579 to cc35531 Compare February 24, 2026 02:19
@odow odow changed the title Rewrite solver.jl [breaking] a large refactoring of MathOptIIS Feb 24, 2026
Comment on lines +229 to +232
function _feasibility_check(
optimizer::Optimizer,
infeasible_model::MOI.ModelLike,
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a solver may say a model is feasible, eventhough its not, that was the reasoning behid the skip.

Maybe the manual needs to tell the user to run before solving in this case.

@odow
Copy link
Member Author

odow commented Mar 4, 2026

using JuMP, HiGHS
import MathOptIIS

function main(filename)
    model = backend(read_from_file(filename))
    solver = MathOptIIS.Optimizer()
    MOI.set(solver, MOI.Silent(), false)
    MOI.set(solver, MathOptIIS.InfeasibleModel(), model)
    MOI.set(solver, MathOptIIS.InnerOptimizer(), HiGHS.Optimizer)
    MOI.compute_conflict!(solver)
    filter_fn(::Any) = true
    function filter_fn(cref::MOI.ConstraintIndex)
        for i in 1:MOI.get(solver, MOI.ConflictCount())
            status = MOI.get(solver, MOI.ConstraintConflictStatus(i), cref)
            if status != MOI.NOT_IN_CONFLICT
                return true
            end
        end
        return false
    end
    new_model = MOI.Utilities.Model{Float64}()
    filtered_src = MOI.Utilities.ModelFilter(filter_fn, model)
    MOI.copy_to(new_model, filtered_src)
    MOI.set(new_model, MOI.ObjectiveSense(), MOI.FEASIBILITY_SENSE)
    return new_model
end
main("/Users/odow/Downloads/enlight4.mps")

@odow
Copy link
Member Author

odow commented Mar 10, 2026

@joaquimg want to take a look?

@joaquimg
Copy link
Member

will do

@joaquimg joaquimg self-requested a review March 10, 2026 21:11
@odow
Copy link
Member Author

odow commented Mar 10, 2026

using JuMP, HiGHS
import MathOptIIS

function main(filename)
    model = backend(read_from_file(filename))
    solver = MathOptIIS.Optimizer()
    MOI.set(solver, MOI.Silent(), false)
    MOI.set(solver, MathOptIIS.InfeasibleModel(), model)
    MOI.set(solver, MathOptIIS.InnerOptimizer(), HiGHS.Optimizer)
    MOI.compute_conflict!(solver)
    filter_fn(::Any) = true
    function filter_fn(cref::MOI.ConstraintIndex)
        for i in 1:MOI.get(solver, MOI.ConflictCount())
            status = MOI.get(solver, MOI.ConstraintConflictStatus(i), cref)
            if status != MOI.NOT_IN_CONFLICT
                return true
            end
        end
        return false
    end
    new_model = MOI.Utilities.Model{Float64}()
    filtered_src = MOI.Utilities.ModelFilter(filter_fn, model)
    MOI.copy_to(new_model, filtered_src)
    MOI.set(new_model, MOI.ObjectiveSense(), MOI.FEASIBILITY_SENSE)
    return new_model
end


julia> @time main("/Users/odow/Downloads/medium-size-infeasible-problem.mps")
[MathOptIIS] starting compute_conflict!
[MathOptIIS]   model termination status: OPTIMIZE_NOT_CALLED
[MathOptIIS] starting bound analysis
[MathOptIIS]   bound analysis found 0 infeasible subsets
[MathOptIIS] starting range analysis
[MathOptIIS]   analyzing MOI.ScalarAffineFunction{Float64} -in- MOI.EqualTo{Float64}
[MathOptIIS]   analyzing MOI.ScalarAffineFunction{Float64} -in- MOI.GreaterThan{Float64}
[MathOptIIS]   analyzing MOI.ScalarAffineFunction{Float64} -in- MOI.LessThan{Float64}
[MathOptIIS]   range analysis found 0 infeasible subsets
[MathOptIIS] starting elastic filter
[MathOptIIS]   relaxing integrality if required
[MathOptIIS]   constructing the penalty relaxation
[MathOptIIS]   using INFEASIBILITY_CERTIFICATE to construct candidate set
[MathOptIIS]     size of the candidate set: 11
[MathOptIIS]   starting the deletion filter
[MathOptIIS]     size of the candidate set: 4
[MathOptIIS]     size of the candidate set: 3
[MathOptIIS]   elastic filter found 1 infeasible subsets
384.417180 seconds (103.00 M allocations: 7.233 GiB, 0.65% gc time, 0.34% compilation time)
MOIU.Model{Float64}
├ ObjectiveSense: FEASIBILITY_SENSE
├ ObjectiveFunctionType: MOI.ScalarAffineFunction{Float64}
├ NumberOfVariables: 414224
└ NumberOfConstraints: 15
  ├ MOI.ScalarAffineFunction{Float64} in MOI.EqualTo{Float64}: 2
  ├ MOI.ScalarAffineFunction{Float64} in MOI.LessThan{Float64}: 1
  ├ MOI.VariableIndex in MOI.EqualTo{Float64}: 1
  ├ MOI.VariableIndex in MOI.GreaterThan{Float64}: 6
  └ MOI.VariableIndex in MOI.LessThan{Float64}: 5

This commit is breaking because it:

 * Removes SkipFeasibilityCheck
 * Removes StopIfInfeasibleBounds
 * Removes StopIfInfeasibleRanges
 * Removes DeletionFilter
 * Removes ElasticFilterTolerance
 * Removes ElasticFilterIgnoreIntegrality

In addition, this commit will likely result in a different IIS being
returned for many models because it now exploits an infeasibility
certificate if one is present.
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.

2 participants