feat(program): a sum through a relation is a sum over a join - #607
Merged
FBumann merged 2 commits intoSep 22, 2026
Conversation
`GroupSum` and `Lookup` are one node, `Join`, and `sum(by=)` lowers to the existing `Sum` over it, its `over` the dims the join drops; `at` lowers to the bare `Join`. The columns a call names move to `JoinColumns`. The YAML surface is unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWBcNGLjNH2i4AqRsfyxaN
FBumann
added this pull request to stack #608
September 22, 2026 12:02
Documentation build overview
15 files changed ·
|
Main's new uses of the relation nodes take the one Join node. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SWBcNGLjNH2i4AqRsfyxaN
FBumann
removed this pull request from stack #608
September 22, 2026 12:17
FBumann
merged commit Sep 22, 2026
53ba4a2
into
claude/mathspec-relations-proof-rwfu3w
6 checks passed
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
The program has one relation node,
Join.at(x, by=R, over=a, into=b)lowers toJoin(x, columns).sum(x, by=R, over=a, into=b)lowers toSum(Join(x, columns), over=<the dims the join drops>), theSumnode that already exists. The YAML surface is unchanged.Stacked on #605, which it needs for the words. Both carry
mainat alpha.111; its newProgram.names_readbranch over the relation nodes takes the oneJoin.The break.
GroupSumandLookupare gone. The struct #605 calledJoinisJoinColumns, since the node takes the name;JoinNode.joinisJoinNode.columns.fan_inreportsJoinas one-to-one and theSumover it as many-to-one, as before. No alias and no deprecation, per the alpha stream. lpspec follows on its own branch once this is released.Why it is the same model
The absence page already describes the composition. Out of a
Sum, an absent summand is one term fewer and the row stands; out of a bare join, absence spreads. Those are today'ssum(by=)andatsemantics, so nothing on that page moves. The frame rule composes the same way: the join adds the grouped dims and keeps the joined ones, the sum drops the dimsover=named. The dim checker and the typesetter read the resolved AST, not the program, so neither changed beyond the struct's name.Separability keeps its verdicts: a
Sumwhose operand is aJoinreports the grouping message for the dims it drops, and thatJoinis not also reported as an undecided coordinate read.tests/test_separability.pypasses unchanged.Coverage that moved
test_lowering.py: the lowering cases andtest_a_relation_lowers_with_the_join_each_call_namesassertSum(Join(...), over)andJoin(...); the fan-in table has the same two rows in the new shape;test_a_divisor_under_a_join_is_still_nameddescends throughJoin.tests/fixtures/every_program_node.yamlis unchanged:groupedandlooked_upboth reachJoin, andreducedreachesSum, sotest_every_program_node_is_one_some_file_lowers_toholds with one node fewer.test_golden.CARRIERSnamesJoinColumns.Gates
pixi is unavailable here, so the gates ran from a uv venv on Python 3.12, on the head with
mainmerged.pytestruff check,ruff format --checkmkdocs build --strictdocs.python.orginventory dropped for the run;tests/test_docs.pyholds every generated page current after itprettier --checktools.schemaand the page generatorscompile-tex,typos,reuse lint,pyreflyWhy
After #605 the two nodes carried the same
Joinand differed only in whether a group-by followed, decided at resolution. That welded the join and the sum into a third kind of reduction. With the join as its own node, the program is the relational algebra the words describe: one join, and the sum you already have over it. lpspec already computes it that way, one join with no aggregate and a drop of dims, both collapsing in the terminal group-by, so its engine loses a branch rather than gaining one.🤖 Generated with Claude Code
https://claude.ai/code/session_01SWBcNGLjNH2i4AqRsfyxaN