Skip to content

Route add_enforced_linear_constraint through the enforced helper setters - #5303

Merged
Mizux merged 1 commit into
google:mainfrom
winklemad:fix-enforced-linear-constraint-helper-setters
Aug 27, 2026
Merged

Route add_enforced_linear_constraint through the enforced helper setters#5303
Mizux merged 1 commit into
google:mainfrom
winklemad:fix-enforced-linear-constraint-helper-setters

Conversation

@winklemad

Copy link
Copy Markdown

Fixes #5302

Model.add_enforced_linear_constraint and the BoundedLinearExpression branch of _add_enforced_linear_constraint_to_helper wrote the indicator constraint's name, bounds and terms through the non-enforced helper setters (set_constraint_name / set_constraint_lower_bound / set_constraint_upper_bound / add_terms_to_constraint) while passing the enforced constraint's index.

Enforced constraints live in MPModelProto.general_constraint[i], but those setters address MPModelProto.constraint[i]. The index spaces are disjoint, so the data landed on an unrelated linear constraint — silently destroying it and leaving the indicator constraint empty — or, when no linear constraint existed at that index, mutable_constraint(i) read out of bounds and the process segfaulted (the DCHECK is compiled out in the release wheel).

This change routes every setter in the enforced paths through the set_enforced_* / add_terms_to_enforced_constraint variants, matching the bool branch of the same helper (which was already correct) and the Java and C# ports.

Added two regression tests:

  • test_add_enforced_linear_constraint_without_regular_constraint — an enforced constraint on a model with no prior regular constraint now builds a well-formed general_constraint instead of crashing.
  • test_add_enforced_linear_constraint_keeps_prior_constraint — a prior regular constraint keeps its own name, bounds and terms, and the enforced constraint carries its own, instead of the two being conflated.

Both fail on main (the first as a segfault, the second on the corrupted proto) and pass with this change.

Model.add_enforced_linear_constraint and the BoundedLinearExpression
branch of _add_enforced_linear_constraint_to_helper wrote the indicator
constraint's name, bounds and terms through the non-enforced helper
setters (set_constraint_name / set_constraint_lower_bound /
set_constraint_upper_bound / add_terms_to_constraint) using the enforced
constraint index. Enforced constraints are stored in
MPModelProto.general_constraint[i] while those setters address
MPModelProto.constraint[i], so the call either crashed on an
out-of-range index when no regular constraint existed there, or silently
overwrote an unrelated regular constraint's name, bounds and terms and
left the indicator constraint empty, dropping the enforced constraint.

Use the enforced variants, matching the bool branch just above and the
Java and C# ports of ModelBuilder.
@Mizux
Mizux requested a review from lperron August 24, 2026 06:22
@Mizux Mizux self-assigned this Aug 24, 2026
@Mizux Mizux added Solver: Linear Solver Related to all Linear Solver (GLOP, BOP, CBC etc...) Lang: Python Python wrapper issue labels Aug 24, 2026
@Mizux Mizux added this to the v10.0 Beta milestone Aug 24, 2026
@Mizux
Mizux merged commit 92f6aed into google:main Aug 27, 2026
11 of 12 checks passed
winklemad added a commit to winklemad/winklemad that referenced this pull request Aug 28, 2026
winklemad added a commit to winklemad/winklemad.github.io that referenced this pull request Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Lang: Python Python wrapper issue Solver: Linear Solver Related to all Linear Solver (GLOP, BOP, CBC etc...)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants