Skip to content

chore(program): a frame stays a set of dimension names, and only the sum over a join reads the axes it opens - #799

Merged
FBumann merged 1 commit into
claude/serene-goldberg-m8xwru-3from
claude/ecstatic-hawking-33j3vv
Sep 30, 2026
Merged

FBumann merged 1 commit into
claude/serene-goldberg-m8xwru-3from
claude/ecstatic-hawking-33j3vv

Conversation

@FBumann

@FBumann FBumann commented Sep 30, 2026

Copy link
Copy Markdown
Contributor

Prompt: Please review the PR stack 665. Can we simplify it with a stacked PR? […] Do it as a stacked draft pr so i can judge the diff

Note

The following content was generated by AI.

On top of #665, frames stay sets of dimension names. dims_of reads a sum over a join as one rule, so no frame holds a join's axis. Axis and Column stay in Sum.over and JoinColumns.axes. #665 shrinks from +183/−107 to +106/−61.

What this changes

Why

The axes a join opens never leave the sum that closes them. The resolver is the only code that builds a Sum over a Join, and it always sums over exactly join.axes (_expression_resolver.py:305). The typesetter (walk.py:421) and separability already read the pair as one unit. So the dimension check does not need axes in its frames. Three of the five guards in #665's table exist only because a string tested against a set of axes is always false. With string frames, that kind of error cannot happen.

Size, guards, coverage moved, gates, not done

Size, src/ and tests/, against #664's head

files lines
#665 as is 13 +183 / −107
#665 with this PR 9 +106 / −61

dimensions.py goes from about 98 changed lines to 30.

Guards

This PR adds two asserts. Each one states something that the resolver makes true:

  • _sum_dims: a sum over a join closes exactly join.columns.axes.
  • dims_of: a join that opens axes is read only by the sum that closes them.

No test fails when either assert is deleted, because no input reaches its false arm. I did not add a probe that builds such a Sum by hand.

#665's last three guards (Axis(d) in carried, in found, in dims) no longer exist, because those lines test a string against a set of strings again.

Coverage that moved

Gates

Pixi is not reachable here. The gates ran from a uv venv on Python 3.12, with the pinned ruff and pyrefly.

gate result
pytest -q -n auto 2557 passed, 53 skipped
ruff check, ruff format --check . clean
pyrefly check on src/ 4 errors, all about missing yaml stubs in the venv. I did not compare this to #665's head.
docs-build, compile-tex, the git hooks not run

Not done

🤖 Generated with Claude Code

https://claude.ai/code/session_01CPwrjirBZhVS4CcndN6f4H


Generated by Claude Code

…sum over a join reads the axes it opens

The axes a join opens are closed by the sum over that join, which the
resolver always builds with exactly `join.axes`. So `dims_of` reads a sum
over a join as one rule, and no frame holds a join's axis. `Axis` and
`Column` stay in `Sum.over` and `JoinColumns.axes`, where consumers read
them. `frame_of`, `_names`, `_dimensions` and each `Axis(d) in frame`
membership test go.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CPwrjirBZhVS4CcndN6f4H
@read-the-docs-community

Copy link
Copy Markdown

@FBumann
FBumann marked this pull request as ready for review September 30, 2026 15:28
@FBumann
FBumann merged commit 8aed330 into claude/serene-goldberg-m8xwru-3 Sep 30, 2026
5 checks passed
FBumann pushed a commit that referenced this pull request Sep 30, 2026
…s dimension names

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CPwrjirBZhVS4CcndN6f4H
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