Repository navigation
feat(api): a written LP or MPS file can name each variable and constraint by its declaration and coordinate - #1792
Merged
Conversation
…aint by its declaration and coordinate `names=True` on `sps.write` and `Model.write` writes `p(0,wind)` and `balance(0)` in place of `x0` and `c0`. A label keeps the characters LP and MPS readers take back and writes the rest as `_`; a dimensionless declaration is `total()`, so a keyword never stands alone as a name. Two coordinates that clean to one name are refused, naming both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CM4oeTkzkk5G5zE6zgikSE
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CM4oeTkzkk5G5zE6zgikSE
Merging this PR will not alter performance
Comparing Footnotes
|
Documentation build overview
4 files changed± about/architecture/index.html± about/changelog/index.html± howto/solvers/index.html± reference/api/index.html |
The two branches both knew which declaration owns which column and row at which coordinate. Merged, `file_names` reads `readback.declared`, the one home #1793 puts beside the handoff, and keeps its label cleaning as polars expressions over each run's coordinate frame. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CM4oeTkzkk5G5zE6zgikSE
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CM4oeTkzkk5G5zE6zgikSE # Conflicts: # src/specsolve/relational/engines/polars/engine.py
The named LP/MPS files land first. This branch keeps them and the `Declared` runs their names are spelled from, which own each column and row; the pyomo export, and the set runs only it reads, move to feat/pyomo-model, stacked on this branch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CM4oeTkzkk5G5zE6zgikSE
FBumann
pushed a commit
that referenced
this pull request
Sep 30, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CM4oeTkzkk5G5zE6zgikSE
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
The following content was generated by AI.
sps.write(..., names=True)andModel.write(path, names=True)writep(0,wind)andbalance(0)in place ofx0andc0, in both LP and MPS files. The default is unchanged, byte for byte.What a name is, and why
declaration(label,label). A declaration with no dims istotal(). A bare name can be an LP keyword: HiGHS and Gurobi both fail on a scalar namedend,storbounds. HiGHS also misreadsfreeandinf.\w(Unicode letters, digits,_) and!"#$%&'.;?@`{|}~. Every other character becomes_. The set is what HiGHS's LP reader takes back, probed character by character. Gurobi reads the same set, and non-ASCII letters, back. MPS takes everything except a space, but one rule keeps the two files naming a model the same way.(,)and,belong to the name, so a label cannot contain them.a banda_bboth clean toa_b. A reader would merge the two columns into one, or refuse the duplicate row, so the write raisesSpecsolveErrorand names both coordinates.explicit_coordinate_nameswritesp[0,wind]with brackets changed to parentheses. It appends#labelfor uniqueness and cleans only spaces in a label. This PR drops the#label, so JuMP'svariable_by_namefinds a name without knowing the solver index. The refusal replaces it as the uniqueness guarantee.Declared, insinks/handoff.pybesideHandoff, says which declaration owns each column and row, at which coordinate.readback.declaredbuilds it from the label frames.readback.file_namesspells each run's coordinate frame with polars expressions into aNamesvalue (inwriters/base.py, numbered by default), which both writers look names up in by solver index. The architecture page's table says whereDeclaredlives.Base of a stack
#1793 (the pyomo export) stacks on this PR and reads the same
Declared, adding the SOS-set runs only it needs. Merge this PR first.This branch carried the pyomo export for a while, when the stack went the other way. The last commit removes it again, and the diff against
mainholds only the named files andDeclared.Verification
51b1ad1has the same tree as65b4db2):pixi run check(lint, format, pyrefly, and the suite: 4662 passed, 522 skipped, 1 xfailed) andpixi run docs-build, both clean.pixi run test-floors(polars 1.30) anddocs-testran on the first commit.cmpon the LP and MPS files of the dispatch and MILP fixtures: identical.tests/test_named_files.py:examples/ports/) reaches the same optimum through a named LP and MPS file.Model.rowreads at that coordinate. That includes a masked variable and a constraint whose middle row is dropped, so later rows renumber.Mutation table (full suite each time; the tree came back clean after every row). The first three rows were taken on
af3dc44, whosefile_namesand guards this head carries unchanged:tools.mutate,readback.py:164)replace_all(by hand)test_a_quadratic_constraint_declared_first_keeps_its_namesSorting each label frame and sorting the declarations by
startboth survived the suite, so both sorts were removed.Declaredrelies on the same order, which the probe above holds.Not done or not checked
p(2030_01_01_06_00_00.000000). It is faithful and unique, but long.s0,s1.🤖 Generated with Claude Code
https://claude.ai/code/session_01CM4oeTkzkk5G5zE6zgikSE