Skip to content

Guard conflict-analysis walks over prevboundval_ against running past the chain start - #3193

Closed
EamonHetherton wants to merge 1 commit into
ERGO-Code:latestfrom
EamonHetherton:issue-3190
Closed

Guard conflict-analysis walks over prevboundval_ against running past the chain start#3193
EamonHetherton wants to merge 1 commit into
ERGO-Code:latestfrom
EamonHetherton:issue-3190

Conversation

@EamonHetherton

Copy link
Copy Markdown

Fixes #3190.

The eight backward walks over a column's bound-change chain assumed the chain terminal (predecessor position -1) is unreachable. The invariant is numeric and can break, after which the walk reads prevboundval_[-1] and chases garbage indices. The relaxation walks now stop at the chain's first entry, which stays in the explanation as a valid superset; the assert-guarded walks now report the bound change as unexplainable so the optional conflict cut is skipped.

🤖 Generated with Claude Code

… the chain start

ConflictSet walks a column's bound-change history backwards through
prevboundval_[pos] in eight places, all of the form

  while (relaxUb >= localdom.prevboundval_[locdomchg.pos].first)
    locdomchg.pos = localdom.prevboundval_[locdomchg.pos].second;

The chain terminates with .second == -1 at the column's first change.
All eight walks assumed the terminal is unreachable: the four
bound-relaxation walks in resolveLinearLeq/resolveLinearGeq had no
guard, and the four in explainInfeasibilityConflict/
explainBoundChangeConflict noted "pos should never become -1" and
backed it with only an assert. The assumed invariant is numeric and
breaks under extreme proof constraints (observed with a proof rhs of
8e-08 at mip_feasibility_tolerance 1e-9 on a model whose coefficients
span 13 orders of magnitude): pos becomes -1, the loop reads
prevboundval_[-1], and then chases the garbage index it finds there
through arbitrary heap memory until it faults.

Observed as intermittent production SIGSEGVs with two distinct crash
sites in the same solve: directly inside resolveLinearLeq (core dump
at the loop above), and later in explainBoundChange indexing
conflictPoolPropagation with a reason read through a garbage stack
position deposited by a walk that happened to survive.

The relaxation walks now stop at the chain's first entry, keeping that
entry in the explanation - a valid, conservative superset. The
explanation walks now report the bound change as unexplainable so the
optional conflict cut is skipped.

Fixes ERGO-Code#3190

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Aug 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.00000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 72.93%. Comparing base (187c624) to head (757a294).
⚠️ Report is 127 commits behind head on latest.

Files with missing lines Patch % Lines
highs/mip/HighsDomain.cpp 95.00% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           latest    #3193   +/-   ##
=======================================
  Coverage   72.92%   72.93%           
=======================================
  Files         436      436           
  Lines      106038   106094   +56     
  Branches    17071    17078    +7     
=======================================
+ Hits        77329    77375   +46     
- Misses      28433    28443   +10     
  Partials      276      276           

☔ View full report in Codecov by Harness.
📢 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.

@jajhall
jajhall requested review from Opt-Mucca and fwesselm August 3, 2026 11:07
@jajhall jajhall self-assigned this Aug 3, 2026
@jajhall jajhall added the MIP label Aug 3, 2026
@jajhall

jajhall commented Aug 3, 2026

Copy link
Copy Markdown
Member

When you get around to looking at #3190, @fwesselm and @Opt-Mucca, perhaps this fix is correct. As an AI-generated fix, we can't accept it as it is.

@jajhall jajhall closed this Aug 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants