Conversation
…e relation column it stands for Axis(dimension, column) is a position in a frame: the dimension whose labels it runs over, and the Column(relation, name) a join opened it for, or None for a dimension's own axis. Sum.over and JoinColumns.axes hold axes, and dims_of returns a frame of them. A declaration keeps its dims as strings, and frame_of is where the two meet. The dotted name a join axis had is gone, and so is the side table separability kept to map an axis back to its dimension. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PHNF149r8B4tGmGUKmAdUd
FBumann
added this pull request to stack #652
September 23, 2026 22:47
FBumann
removed this pull request from stack #652
September 24, 2026 08:35
FBumann
added this pull request to stack #670
September 24, 2026 09:44
…664 One conflict: piecewise.py imports this branch's Axis beside VariableBlock and VariableDeclaration, which main's leaves_ungated reads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GpnFcQDuvt2bExGngb6MYk
…wru-3, through the updated #664 #633 retired fan_in, quotients and divisor_parameters. This branch's Axis forms of their tests go with them, and the divisor tests assert through parameters_of over an Axis. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012JFQDAjuZ3sCndQ4cD77Gc
… into sync/665 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q8Y8AoPsJCyMsURHvgzm7h
…664 Main's given-term, declared-frame and composition checks compare frames of axes. Adds the changelog line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YUK4sePJqJfxJJZLhdvZnS
Documentation build overview
42 files changed ·
|
…wru-3 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019TMqXLvfDGYm8hRND63cs8
…wru-3, with #662 and #664 as one changelog line Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MKjqJocyxdRYvx7xin6NCM
FBumann
removed this pull request from stack #670
September 30, 2026 13:28
FBumann
added this pull request to stack #796
September 30, 2026 13:29
…sum over a join reads the axes it opens (#799) 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. Claude-Session: https://claude.ai/code/session_01CPwrjirBZhVS4CcndN6f4H Co-authored-by: Claude <noreply@anthropic.com>
…s dimension names Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CPwrjirBZhVS4CcndN6f4H
Merged
FBumann
pushed a commit
that referenced
this pull request
Oct 2, 2026
…nds for (#665) Axis(dimension, column) replaces the dotted axis names in Sum.over and JoinColumns.axes. A join's axis names its Column(relation, name), a dimension's own axis has no column, and frames stay sets of dimension names. Folded into #664, so its changelog line is #664's. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YVJQzL5G4boHcJDwrhgfag
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.
Axis(dimension, column)replaces the dotted axis names inSum.overandJoinColumns.axes. A join's axis names itsColumn(relation, name). A dimension's own axis has no column. Frames stay sets of dimension names. This PR includes #799.What this changes
Column(relation, name)andAxis(dimension, column=None)are public inmathspec.program.str()gives the user spelling:generator, orzone_of[generator]for a join's axis.Sum.overistuple[Axis, ...].sum(p, over=g)stores(Axis('g'),).sum(p, over=g, by=R[c])stores the join's axes. A dim that no column of the relation is over gets its ownSumof dimension axes around that.JoinColumns.axesistuple[Axis, ...]. Each axis runs over the dimension of the column the join drops, and stands for that column. A map into its own dimension gives the join axisAxis('snapshot', Column('rep_of', 'snapshot')), which is not equal toAxis('snapshot'). The type keeps them apart. Before, a naming trick did it.axis.columnto tell a grouping from a plain sum. The dictionary that mapped an axis string back to its dimension is removed.dims_ofstill returns a set of dimension names. It reads a sum over a join as one rule, so a join's axes never reach a frame (chore(program): a frame stays a set of dimension names, and only the sum over a join reads the axes it opens #799).Why
Agreed in the discussion on #662. With the dotted name, a join axis was kept apart from a dimension by a character, and every consumer had to know that. With
Axis, the type does it: pyrefly checks it, and a consumer readsaxis.dimensionoraxis.column. It does not branch on the kind of axis and does not parse strings.The axes are needed only between a join and the sum that closes it. The resolver is the only code that builds a sum over a join, and it always sums over exactly
join.axes. So frames do not carry axes (#799). That removed about 40% of this PR's diff, and one class of silent error: a string tested for membership in a set of axes.Method, guards, coverage moved, gates, not done
How this PR was made
The first version changed frames to
frozenset[Axis]as well. #799, stacked on this PR, changed them back to dimension names and was squash-merged into this branch as8aed330.3dfafa6changes the changelog line to this title. The branch is not rebased and not force-pushed.src/andtests/, against #664's headGuards and the tests that fail without them
Each guard was undone in turn, the suite was run, and the tree was restored. The first two were taken before #799, and #799 did not change their lines.
test_dim_inference[a-map-into-its-own-dimension-keeps-the-frame]test_a_grouping_that_sums_the_axis_away_couples_it#799 added two asserts in
dimensions.py:join.columns.axes.The resolver makes both true, so no test fails when either one is deleted. No probe builds such a node by hand. The three
Axis(d) in frameguards of the first version are removed together with the lines they guarded.Coverage that moved
tests/test_dimensions.pycompares frames to string sets, as on feat(language)!: a call names the columns of a relation as relation[column], and a sum through a relation is a sum over the axes its join opens #664. The self-map test assertsnode.over == (Axis('snapshot', Column('rep_of', 'snapshot')),)and the frame of the sum. It does not check the frame of the bare join, because that frame no longer exists.tests/test_lowering.pyandtests/test_expansion.pybuildSumwithAxisvalues.tests/typesetting/test_golden.pylistsAxisandColumninCARRIERS, because they are values that a node carries, not nodes.Gates, on
3dfafa6Pixi is not reachable here. The gates ran from a uv venv on Python 3.12, with the pinned
ruffandpyrefly.pytest -q -n autoruff check,ruff format --check .pyrefly checkonsrc/yamlstubs in the venvdocs-build,compile-tex, the git hooksdocs-buildandcompile-tex.Not done
JoinColumns.droppedand the other fields hold column names, andColumn.nameis that name. Theroletocolumnrename is separate.JoinColumns.joined_dimsand the other*_dimsproperties stay strings. They name dimensions.JoinColumns.kept_dims, which has no reader. That is separate work.Sum.over, and it must readaxis.dimension, andaxis.columnfor a grouping.🤖 Generated with Claude Code
https://claude.ai/code/session_01CPwrjirBZhVS4CcndN6f4H