Skip to content

build(deps): a quantity that changes by regime is stated once, so ten of the ladder's recorded differences from PyPSA are gone - #1466

Merged
FBumann merged 1 commit into
build/pin-alpha-51from
build/pin-alpha-52
Aug 31, 2026
Merged

FBumann merged 1 commit into
build/pin-alpha-51from
build/pin-alpha-52

Conversation

@FBumann

@FBumann FBumann commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Prompt: "292 merged." — the corpus adopting cases:, which this follows.

Note

The following content was generated by AI.

Stacked on #1464, which teaches both engines cases:. This is the corpus arriving:
math-spec v0.0.0-alpha.51 → v0.0.0-alpha.52, where the PyPSA file states each split
constraint once.

Ten recorded differences from PyPSA are gone — every one of the regime splits, which
were the only class with a route to closing. All 15 rungs still MATCH, and five of them
now carry no structural difference at all.

before after
recorded deviations 32 22
PyPSA names carrying one 26 19
rungs with a region difference 7 4
rung_02_storage         2 region -> 0        rung_08_modular_big_m   6 region -> 0
rung_03_expansion       9 region -> 3        rung_12_linearized_uc   4 region -> 0
rung_04_ramps           4 region -> 0        rung_05_global_limits   4 region -> 2
rung_07_commitment      4 region -> 0

What the remaining 22 are

None is a language gap, and none can be closed by stating the file differently.

  • 4 are checked rather than excused. The negated: entries (fix(differential): a dual the file writes negated is held to the negative of PyPSA's rather than excused #1444) assert
    ours + theirs == 0 at max_abs_diff 0.0. They are proofs living in the same file.
  • 5 are the sense-splits — one block per ==, <=, >= where PyPSA writes one row
    per labelled constraint whatever its sense. cases: is value-level and cannot reach an
    operator; that is
    math-spec#239, closed
    not planned.
  • 13 are PyPSA's own bookkeeping, which the file is right not to imitate: the
    objective_constant fixed variable (3), the capacity floor and cap copied once per
    scenario over one variable (5), a binary bounded at 1 and capped by a row (4), and one
    degenerate dual.

The rung projection keeps a cased quantity whole

projection.py cuts each rung's file to what that rung builds. It cannot cut inside a
cased quantity: doing so decides from the names a region reads whether that region
applies, which only the region's mask is entitled to say — and a mask reads the other way
as often as not, not committable being true exactly where committable is absent. A
first cut that dropped a region on that basis lost a term worth 75 on rung 3 and was
caught by the projection gate, which holds each cut to the full file's objective.

Kept whole, a cased quantity states what the file states, and the declarations it names
are kept whether or not the rung fills them — as the file itself does. The visible
consequence is that three tables (Generator_status_initial,
Generator_ramp_limit_start_up, Generator_ramp_limit_shut_down) are now first declared
on rung 3 rather than rung 7, the ramp allowance's boundary region naming them there
even though its mask is empty.

Verified

  • PyPSA parity's own runner against the corpus at v0.0.0-alpha.52: all 15 rungs
    MATCH, exit 0, and the committed certificate, projections and tables are what a re-run
    produces. The gate that reports a reason no rung needs is what named the ten stale
    entries, so their removal is measured rather than asserted.
  • pixi run lint / format-check clean; pyrefly 0 errors, both legs.
  • pixi run test — 3461 passed, 254 skipped, 94 failed, every failure xpress (the
    expired local licence, matched by file and parameter id). The three extra skips against
    feat(language): a quantity defined by cases may mix a constant, a parameter and a variable across its regions #1464 are test_merge_markers on the three tables that moved rung.
  • tools.ladder --check clean; the index and all 15 rung pages regenerated.
  • Not run: pixi run test-bench — no bench/ file changed.

Deliberately not done

  • No deviation was retired by hand. The runner named all ten; nothing else was touched.
  • The sense-splits are left recorded, feat!: absence propagates and drops the row, plus defined(v) #239 being closed not planned upstream.
  • The projection is not made tighter than "keep a cased quantity whole" — a tighter cut
    would have to reason about masks, which is what made the first attempt wrong.

… of the ladder's recorded differences from PyPSA are gone

math-spec v0.0.0-alpha.51 -> v0.0.0-alpha.52, whose PyPSA file states each of the
split constraints once through `cases:`. The rung projection keeps a cased
quantity whole, there being no sound way to cut inside one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TZbCoSM1Ah7YWg6K4Ps5sU
@codspeed

codspeed Bot commented Aug 31, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 16 untouched benchmarks
⏩ 42 skipped benchmarks1


Comparing build/pin-alpha-52 (66f9b14) with build/pin-alpha-51 (2a5b0db)

Open in CodSpeed

Footnotes

  1. 42 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@FBumann
FBumann merged commit 9eeac2c into main Aug 31, 2026
11 of 12 checks passed
@FBumann
FBumann deleted the build/pin-alpha-52 branch August 31, 2026 15:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant