Repository navigation
feat!: specsolve requires mathspec 0.4.0, where missing: neutral is gone and a file names the value that a missing row or a masked variable reads as - #2054
Draft
FBumann wants to merge 4 commits into
Conversation
… gone and a file names the value that a missing row or a masked variable reads as A parameter under `missing: 0` or `missing: false` keeps its table as the data gave it, as `neutral` did, and reads the zero in a bound, on a constant side and in a comparison. A masked variable stands as its `missing:` number outside the mask. The program classes follow mathspec's renames. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A2crTbivTGt2WzGpTebdmf
mathspec now gives a given parameter a class of its own, and specsolve refuses a program that reads one anyway. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A2crTbivTGt2WzGpTebdmf
…e the value of a missing row Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A2crTbivTGt2WzGpTebdmf
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A2crTbivTGt2WzGpTebdmf
This was referenced Oct 21, 2026
This branch has not been deployed
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.
specsolve builds the files of mathspec 0.4.0 (energy-models/mathspec#894):
neutralis gone, a parameter reads a missing row as the value it names, and a masked variable stands as itsmissing:number. The PR waits for mathspec 0.4.0 to be released.What a missing row reads as
missing: 0ormissing: falsetable stays as the data gave it, as aneutralone did (Scope.reads_zero). A term it multiplies is no term, and a row left with no term is not built. The zero is read where a position reads the value itself:0(Compiler.bounds);0, so the gap is not refused (coverage.constant_side);wherecomparison compares0(predicates, which also stops counting such a name as one the mask is certain of);0for a piece with such a factor (Compiler.summed_onto).missing:number compiles to its term plus a constant piece: the number where the mask leaves the variable out, and0where it exists (Compiler._standing_in). A read fills the number wheremissing: 0filled zero.fillna(missing). A bare name of a parameter with no dims now asks whether the data has the row, as it already did for a parameter with dims (given_rows).The port to mathspec 0.4.0
ParameterDeclarationisParameter, and the oldParameterisParameterReference.VariableandVariableDeclarationfollow the same pattern.NamedExpressionisExpressionReference,NamedMaskisMaskReference, and each other*Declarationdrops the suffix. One mapping applied all of them at once, so no name was renamed twice.mathspec.validationismathspec._validation(energy-models/mathspec#878), for the one test that spies onto_spec.missing: neutralwrites0, orfalseon aboolparameter. The PyPSA rungs declare*_nom_modmissing: absent, as mathspec's own PyPSA file does: mathspec refuses amissing: 0divisor at load, andGenerator_p_nom_moddivides in*_maint_modstatus_*.pyproject.tomlpinsmathspec>=0.4.0,<0.5, and thefloorsenvironment pins==0.4.0.Tests changed, and where their coverage moved
missing: 0divisor refused at data time, through a power, an addition, the objective, a constant side, a sum, a case region and a reported expression (test_arithmetic_laws.py,test_cases.py,test_expression_reader.py). mathspec'stest_a_divisor_that_reads_a_missing_row_as_zero_is_refusedholds that refusal now.test_absence.py,test_cases.py) now assert the objective on both lanes. The build-time bound refusals intest_relational.pyandtest_linopy_lane.pyare replaced bytest_a_missing_bound_reads_its_value_on_both_lanes.missing: absent:test_an_absent_divisor_takes_its_row_with_it.dual(...)on an integer model instead of dividing by a sparse parameter (test_api.py,test_strategy.py).wherecomparison of a parameter and of an expression, a masked variable that stands as its number in a row, and the same variable read at a point.Verification
pixi runcannot solve the environment until mathspec 0.4.0 is on PyPI, so each gate ran with the environment's own Python, with the mathspec of energy-models/mathspec#894 at20fc215installed into it. On3011a4c:ruff check .andruff format --check .pass.pyrefly checkand the linopy references'pyrefly checkreport 0 errors.pytest -n auto: 5750 passed, 574 skipped, 4 xfailed.mainwith mathspec 0.3.0 gives 5760 passed, 574 skipped, 4 xfailed: this PR removes 18 tests and adds 8.pytest bench/test_harness.py: 482 passed, 15 skipped, run on an idle machine.Mutation table. A script deleted each guard and ran the full suite. It restored the file with
git checkout --, dropped__pycache__before and after each run, and the tree came back clean. Most guards are inline expressions thattools/mutate.pycannot delete line by line, so the script mutates by text instead. The first eight rows were taken on0811ae7; the last three rows first stayed green, got the tests of3011a4c, and were taken again on3011a4c.test_a_sparse_coefficient_is_still_a_zero_coefficientandtest_rows_a_restriction_removed_and_rows_with_no_terms_are_counted_togethertest_a_missing_bound_reads_its_value_on_both_lanestest_a_missing_constant_reads_as_its_value_on_both_lanes, 3 casestest_a_comparison_reads_the_value_of_a_missing_row_on_both_lanes[true-at-the-zero]test_a_masked_variable_stands_as_its_missing_number_on_both_lanestest_a_dimensionless_parameter_with_no_row_switches_off_what_it_maskstest_a_masked_variable_stands_as_its_missing_number_on_both_lanestest_a_comparison_reads_the_value_of_a_missing_row_on_both_lanes[an-expression-true-at-the-zero]test_a_read_values_a_masked_variable_at_its_missing_number_on_both_lanesDepartures from AGENTS.md. The gates ran without
pixi run, as above. The mutation table came from a script rather thantools/mutate.py. The renames of #855 and #878 ride in this PR, because specsolve does not import mathspec 0.4.0 without them.Not done
uv.lockstill resolves mathspec 0.3.0. Refreshing it needs 0.4.0 on PyPI, so CI fails to resolve until the release. That is why this PR is a draft.0.0is built by the relational lane and dropped by the linopy lane. That is true onmaintoo, and it is a separate issue.attaching._filledjoins withoutmaintain_order, so a parameter filled with a value can sum in a different order between two builds. With themissing: 0tables kept sparse, no test here reaches it. It is a separate fix.Generated by Claude Code