You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[FileFormats] the MPS and LP writers mishandle the constant of a constraint function #3109
import MathOptInterface as MOI
for Model in (MOI.FileFormats.MPS.Model, MOI.FileFormats.LP.Model)
model =Model()
MOI.Utilities.loadfromstring!(
model,
""" variables: x minobjective: 1.0 * x x >= 0.0 c: 2.0 * x + -5.0 >= 0.0""",
)
print(sprint(write, model))
end
The MPS file has rhs c 0, so it says 2x >= 0 instead of 2x >= 5, and MOI reads it back that way. JuMP users can hit this by converting an LP file containing c: 2 x - 5 >= 0 to MPS with read_from_file and write_to_file.
The LP file has c: -5 + 2 x >= 0. That is valid in the grammar in the LP docs, and MOI reads it back correctly, but Gurobi reads 5 as a new variable and HiGHS 1.15.1 drops the -5, so both return an optimum of 0 instead of 2.5. HiGHS latest also ignores it, with a warning.
Indicators do the same: [z, 2x - 5] in Indicator{ACTIVATE_ON_ONE}(GreaterThan(0.0)) writes rhs c 0 in MPS and c: z = 1 -> -5 + 2 x >= 0 in LP.
For MPS, which has no field for a row constant, the options I can see:
Record each nonzero constant while COLUMNS is collected (the writer already gets every function there), and subtract it in write_rhs. This passes one more argument through the _collect_* and _write_rhs calls.
Get the function again in _write_rhs and subtract its constant. This is a smaller change, but it copies the constraint functions again.
Throw an error when a function has a nonzero constant.
For LP:
Move the constant to the right-hand side with MOI.Utilities.normalize_constant. This changes the expected output of three existing tests, for example c6: -1.4 + 1.3 x >= -0.1 becomes c6: 1.3 x >= 1.2999999999999998.
Keep the output and document it in the "Differences" section of the LP docs.
I have prototypes of option 1 for both, with tests. Which would you prefer?
I think the right answer or MPS is (3). We should throw an error when attempting to write LHS constants.
I actually like the current LP behaviour. It's arguably the most correct. It's not our problem if there is a constant on the LHS and HiGHS.jl errors when there is a constant on the LHS. We read and write the model as written by the user.
Activity
odow commentedon Oct 17, 2026
I’m undecided on this. It is not valid in the LP as implemented by the solvers.
odow commentedon Oct 18, 2026
I think the right answer or MPS is (3). We should throw an error when attempting to write LHS constants.
I actually like the current LP behaviour. It's arguably the most correct. It's not our problem if there is a constant on the LHS and HiGHS.jl errors when there is a constant on the LHS. We read and write the model as written by the user.