Skip to content

fix(language): an at that joins on a dimension it also consumes is refused, as a sum already was - #1696

Closed
FBumann wants to merge 1 commit into
mainfrom
claude/happy-maxwell-9ldgqa-direction
Closed

FBumann wants to merge 1 commit into
mainfrom
claude/happy-maxwell-9ldgqa-direction

Conversation

@FBumann

@FBumann FBumann commented Sep 19, 2026

Copy link
Copy Markdown
Collaborator

Prompt: Continue bumping to the head of #566

Note

The following content was generated by AI.

math-spec moves from 0.0.0-alpha.105 to c25984e, the head of energy-models/mathspec#566. at()'s joined-column check asked whether a joined dimension was produced, which the landing check already refuses, rather than whether it was consumed — so at(load, by=diag, over=rep, into=generator) loaded and landed with the joined dimension gone. sum already refused that shape.

The pin is a commit, not a tag, because math-spec#566 is open and stacked on two more unmerged PRs. This is an integration branch rather than a pin to merge on: it wants a tag once that stack lands.

Carrying the refusal is a port of the relation node API, which no consumer can tell apart.

The API that moved

Walk is now Direction, and Partition is split off as its own class rather than a direction with nothing consumed or produced. The accessors that inverted between the two operators are gone, so a node's ends are read off its direction and an At reads the direction the other way round at the four sites that care.

was is
program.Walk program.Direction
GroupSum.walk, At.walk .direction
GroupSum.over, .into .direction.consumed_dims, .produced_dims
At.over, .into .direction.produced_dims, .consumed_dims
.joined, .relation .direction.joined_dims, .name
partition Walk(rel, consumed, produced, joined) Partition(rel, along, group, joined)
partition .consumed, .produced, .consumed_dims .along, .group, .along_dim

67 call sites across seven modules in both lanes: relational/engines/polars/{compiler,relations,reindex}.py and linopy/{builder,loader,where}.py.

Coverage moved
  • test_by_takes_a_relation asserts position(by=)'s new refusals. A parameter and an undeclared name now take the message every operator's by= gives; a dimension is told that by= takes the map out of it.
  • test_a_call_walks_one_table_and_says_so follows "walks one table" to "reads one table".
  • GEN_BUS_WALK is GEN_BUS_DIRECTION.

The thirteen generated pages are tools.gallery_math and tools.ladder re-run. The diff is one legend line per page — "the order shift walks" becoming "the order shift steps along".

Gates

Run through uv rather than pixi, which is not installed in this environment — a departure from the pixi run check default. uv sync --group dev --extra linopy --extra gurobi --extra xpress matches what pixi's default environment installs. Re-run after the rebase onto main.

gate result
pytest -q -n auto 4016 passed, 251 skipped, 1 xfailed, 4 failed
ruff check . All checks passed
ruff format --check . 326 files already formatted
pyrefly check 2 errors

The four failures and both type errors are one thing, and it is not this PR's: math-spec#566 also adds ExpressionComparisonNode and ArithmeticComparisonNode, which neither lane evaluates yet. They go green in the PR stacked on this one, which is where math-spec#566's own body says that evaluator belongs.

Not run: test-bench, the sweep, and the docs build. The typst gallery cases skip for want of the binary, as they do in CI.

Deliberately not done: the mask expression evaluator, which is the stacked PR. No mutation table — this PR adds no correctness guard, it moves call sites onto a renamed API.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NHXujoUG77G2SoDbhau5mS


Generated by Claude Code

…fused, as a sum already was

math-spec moves from 0.0.0-alpha.105 to c25984e, the head of
energy-models/mathspec#566. The pin is a commit rather than a tag because
that PR is open and stacked on two more; it is not a pin to merge on.

The refusal is the outcome a model author sees. at()'s joined-column check
asked whether a joined dimension was produced, which the landing check
already refuses, rather than whether it was consumed, so
`at(load, by=diag, over=rep, into=generator)` loaded and landed with the
joined dimension gone. sum already refused the same shape.

Carrying it is a port of the relation node API, which no consumer can tell
apart. Walk is now Direction, with Partition split off as its own class
rather than a direction with nothing consumed or produced, and the
accessors that inverted between the two operators are gone: a node's ends
are read off its direction, and an At reads the direction the other way
round at the four sites that care. GroupSum.walk and At.walk are
.direction; .over, .into, .joined and .relation are
.direction.consumed_dims, .produced_dims, .joined_dims and .name, each
read in the operator's own terms.

Coverage moved: test_by_takes_a_relation asserts position(by=)'s new
refusals — a parameter and an undeclared name now take the message every
operator's by= gives, and a dimension is told by= takes the map out of it —
and test_a_call_walks_one_table_and_says_so follows "walks one table" to
"reads one table". The thirteen generated pages are tools.gallery_math and
tools.ladder re-run; the diff is one legend line per page, "the order shift
walks" becoming "the order shift steps along".

Not done here: math-spec#566 also adds ExpressionComparisonNode and
ArithmeticComparisonNode, which neither lane evaluates. Four tests are red
on that and land with the evaluator in the PR stacked on this one, as
#566's own body says they should.

pytest -q -n auto: 4016 passed, 251 skipped, 1 xfailed, 4 failed — the four
above. ruff check and ruff format clean. pyrefly reports 2 errors, both
assert_never on those same two nodes.

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

codspeed Bot commented Sep 19, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 24 untouched benchmarks
⏩ 58 skipped benchmarks1


Comparing claude/happy-maxwell-9ldgqa-direction (4fc4b9e) with main (556b558)

Open in CodSpeed

Footnotes

  1. 58 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. ↩

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.

2 participants