feat: a decided variable becomes a supplied number, so a subproblem is a call on the whole model - #748
Closed
FBumann wants to merge 11 commits into
Conversation
…s a call on the whole model Spec.fix(*names) turns each named variable into a parameter with the same name. A binary or integer becomes an int. Its bounds become an assumption. A row that named only fixed variables becomes an assumption too. A masked variable with absence: undefined keeps its meaning: every read outside a sum must stand under its mask, fix adds the mask to a constraint's where:, or it refuses and names the reader. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
Documentation build overview
60 files changed ·
|
FBumann
added this pull request to stack #754
September 28, 2026 10:56
…claude/mathspec-analysis-features-zy7x4n-fix Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
…claude/mathspec-analysis-features-zy7x4n-fix Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
…claude/mathspec-analysis-features-zy7x4n-fix examples/pypsa.yaml now carries the multi-period and stochastic classes (#736): Link_n_mod and Process_n_mod are capacity decisions like Generator_n_mod, and the CVaR columns span every snapshot by design. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
…claude/mathspec-analysis-features-zy7x4n-fix Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
…claude/mathspec-analysis-features-zy7x4n-fix Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
…claude/mathspec-analysis-features-zy7x4n-fix Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
…claude/mathspec-analysis-features-zy7x4n-fix Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
…claude/mathspec-analysis-features-zy7x4n-fix Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
…claude/mathspec-analysis-features-zy7x4n-fix Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
This was referenced Sep 29, 2026
Contributor
Author
Note The following content was generated by AI. Superseded by #824, which carries this diff onto Generated by Claude Code |
FBumann
pushed a commit
that referenced
this pull request
Oct 2, 2026
… so a subproblem is a call on the whole model Each named variable becomes a parameter under the same name: binary and integer become int, continuous becomes float. Its bounds become the assumption <name>_within_bounds, and a constraint that named only fixed variables becomes an assumption. A masked variable with absence: undefined keeps its meaning: each read outside a sum is proven guarded, masked at its row, or refused with the reader named. Ported from #748 onto main, without its base (#746, #747). A given variable is refused with a message that names it as given. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XjTvqu5LubaVCgWeKogCqj
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.
What this changes
spec.fix(*names)turns each named variable into a parameter with the same name. A masked variable keeps its meaning: each read outside a sum is proven guarded, masked at its row, or refused with the reader named. Closes #303. Stacked on #747.Rules, evidence, gates, open questions
The rewrite
binaryandintegerbecomeint; continuous becomesfloat. The description is kept.0and1, become the assumption<name>_within_bounds, under the variable'swhere:.where:and description. The loader refuses such a row, and its message names this rewrite.spec.expand().fix(...)works.fix('a').fix('b')equalsfix('a', 'b').The masked variable (what #249 found, re-made on current
main)A variable with
where:andabsence: undefineddoes not exist outside its mask, and a row reading it there is not built. A parameter reads0there, so the row stands:p <= cap * availbecomesp <= 0. #249 answered withcoverage: masked, whichmainno longer has. This PR proves each read instead:sum,sum(by=)orsum_back, an absent summand and a0one give the same sum.where:, or a case'swhen) is guarded.where:.shiftorat, or in an unguarded case, is refused, and the message names the reader.Evidence
examples/pypsa.yamlonmainat 22cdebd, fixing the seven*_nom_extcapacities and the three*_n_modmodule counts:where:. Every pointwise read already stands under..._extendable._ext_*_nom_lower/upper,_nom_set,_p_nom_modularity,Carrier_growth_limitandGlobalConstraint_*_expansion_*families.separability['snapshot'].linking_columnsgoes from 13 variables to the three CVaR columns, which the risk measure spans across snapshots by design.Before #736 folded the stochastic and multi-period classes into this file, the same test fixed six variables and the snapshot axis linked no column.
specsolve's
examples/benders/monolith:fix('cap')gives an LP whosesnapshotaxis links no column. specsolve ships that subproblem as a second file,sub.yaml, withcaprenamed tocap_hat.Guards
intabsence: zeroneeds no checkzero-outside-the-mask-is-what-a-missing-row-readsthrough-a-shiftin-a-case-its-mask-does-not-guardpypsaincludedGates
pixi run lint: pass.pixi run test: 2714 passed, on the merge ofmainat 22cdebd.docs-buildandcompile-texwere not run in the session (network). CI runs both.Open, for review
0. It is documented in the docstring, not refused.dual(c)of a constraint that becomes an assumption stops resolving; the reload names it.(<row where>) AND (<variable where>), text on text. It is proven only where the variable's dims are in the row's frame.Why
#303: a hand-written fix in a driver is wrong twice and silently, and two drivers would decide it differently.
🤖 Generated with Claude Code
https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
Generated by Claude Code