Repository navigation
docs(language): the relations page states what decides a sum from a read - #597
Merged
Merged
Conversation
The page constrained only the column a call consumes: a key column for `sum`, value columns for `at`. Nothing said what either lands on, and every row of the table landed a sum on a value column. The page now states both ends, and a bare relation is one of the rows. Sentence measure on relations.md: n 41, avg 15.2, median 15, over25 4. Three of the four are the two sentences already on the page and a bold lead-in the script joins to the sentence after it; the fourth is the quoted refusal, which the script reads as prose because its fence is a `text` fence it does not skip. tests/test_dimensions.py gains the two rows the new table row claims: a sum through a bare relation, read each way. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011cd94pb8EUBg1D31B79khs
The page constrained the ends by kind of column, and neither end is fixed to one kind: a sum may consume a value column beside its key column, and a read may land on a value column and join on the key. What separates the two calls is whether the columns a call lands on and joins on hold the whole key. The section now states that question, gives the two ends per call as a table, and quotes both refusals — the sum that consumes no key column, and the read that consumes one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fqgv4wZBmwHp4xgokj2xQb
…is the choice A read covers the key by landing on it, so its ends are not a choice between kinds of column the way a sum's are. The table says so, and the claim that a read may land on a value column is gone with the test that pinned it: that call renders a produced dimension nothing ties down, which is a hole in the loader rather than a rule to document. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fqgv4wZBmwHp4xgokj2xQb
A read lands on the key however the call splits it between into= and the join, and a dim the operand carries and the read does not consume rides along. The section says both, and a dim-inference row holds the claim. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fqgv4wZBmwHp4xgokj2xQb
The section had grown a second heading, a second table and two quoted refusals for one idea. The rules are bullets under the call table again, each a claim a reader can act on, with the one refusal that teaches the split between a sum and a read. The page is 140 lines and 1173 words, from 161 and 1367; the sentence measure is `n 37 avg 15.6 median 15 over25 4`, from `n 43 avg 15.4 median 15 over25 7`, and each of the four long ones is a bold lead-in the script joins to the sentence after it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fqgv4wZBmwHp4xgokj2xQb
#598 added a bullet to this section saying a read lands on the key and nothing else. The bullets here say that and what a read's result carries, so the section keeps this branch's wording and #598's rule stands. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fqgv4wZBmwHp4xgokj2xQb
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.
The page constrained each call's ends by kind of column, which is not what the loader checks, and said nothing about what a read gives back. Both rules are now bullets under the one table, +10 lines on the page.
What this changes
docs/reference/language/relations.md, in Aggregates and reads:connection: { key: [generator, bus] }joinszone_ofin the preamble, and the call table gains the rowsum(p, by=connection, over=generator, into=bus)— consumesgenerator, joins on nothing, producesbus, result[bus, period].tests/test_dimensions.pygains four: a bare relation summed each way, a sum consuming a key column and a value column together, and a read whose result is the key plus the operand's spare dimension.Why
The page constrained only the left end — "$\sum_{g \in \mathcal{G} ,:, (g, b) \in \mathrm{connection}} p_{t,g} \le \mathrm{load}_{t,b}$ .
sumconsumes at least one key column, andatconsumes value columns only" — and every row of the table landed a sum on a value column. Two wrong readings follow. The first is that the split is keys on the left and values on the right, which is inverted forat. The second is that a sum's landing column must be a value column, which makes the bare many-to-many relation unwritable:connectionhas no value column, so a sum through it lands on a key column or cannot be written at all. That case is intests/typesetting/golden/model.yamlalready, and prints asStating the ends by kind of column cannot be made right, because the loader does not work that way. It computes one fact — whether the key lies inside what the call lands on and joins on — and refuses a read when it does not hold and a sum when it does. The page states that, and lets the rest be what each call may write.
Method, gate output, what was not run
The claims, checked against the loader rather than read off the page.
pixidoes not install in this session (the installer is blocked by the proxy with a 403), so the gates ran from auvvenv on Python 3.13 withruff==0.16.1.sum(f, by=gen_bt, over=[generator, bus], into=technology){key: generator, values: [bus, technology]}sum(p, by=connection, over=generator, into=bus){key: [generator, bus]}sum(price, by=zone_of, over=zone, into=generator){key: [generator, period], values: zone}The quoted refusal is this loader's output, not a paraphrase, from the model in the last row under a constraint named
cap.The sentence about a read's result was checked on four shapes, varying what the operand carries:
[bus]reads to[generator],[bus, technology]to[generator, technology],[zone, snapshot]to[generator, snapshot]withsnapshotarriving by the join, and[zone]with both key columns ininto=to[generator, snapshot]. The key is there in every one.Size. The section is five bullets under one table. The page is 140 lines and 1173 words, against 130 and 1038 on
main, so the rules and the refusal cost ten lines. The sentence measure, with the script in the docs-writing skill, isn 37 avg 15.6 median 15 over25 4, againstn 41 avg 15.2 median 15 over25 4onmain; each of the four long sentences is a bold lead-in the script joins to the sentence after it.A hole this turned up, fixed in #598.$w_{g,t} \le \mathrm{x}_{\mathrm{gen_bt.bus}(g),g} ;; \forall, g \in \mathcal{G},\ t \in \mathcal{T}$ — the read produced $t$ to $\mathrm{gen_bt.technology}(g)$ . #598 refuses it. This page states the rule the language means either way, so the two agree; the one bullet #598 adds to this section is superseded here.
at(x, by=gen_bt, over=bus, into=technology)loaded, and printedtechnologyand nothing tiedGates.
pytest -q -n 4: 1355 passed, 6 skipped, the whole suite. The new rows are-k a-sum-through-a-bare-relation-lands-on-a-key-column,-k and-the-same-table-summed-the-other-way,-k test_a_sum_consumes_a_key_column_and_a_value_column_togetherand-k test_a_read_carries_the_whole_key_and_what_the_operand_brings_beside_it.ruff check,ruff format --check: clean.prettier --checkon the changed page: clean.typoson both changed files: clean.mkdocs build: no link or anchor warning, and#aggregates-and-readsis untouched, whichexpressions.mdandoperators.mdlink to.--strictaborts here on fetchingdocs.python.org/objects.invthrough the proxy, which is this environment and not the page.Not run:
pixi run cias one command,pyrefly,reuse,zizmor,taplo,compile-tex. No generated file is touched, so no generator was re-run.Deliberately not done.
docs/reference/language/operators.mdordocs/howto/declare-a-column.md. One fact, one home.main, inmain's spelling. feat(language): a relation's direction is written inside by=, as relation(a -> b) #596 narrows it — there a sum's consumed end names dimensions of key columns, so a sum can no longer consume a value column — and that PR rewrites this section, carrying theconnectionrow and these rules into the new spelling. The sentence about a read's result holds in both spellings, because feat(language): a relation's direction is written inside by=, as relation(a -> b) #596 derives the split from the operand rather than from the call.🤖 Generated with Claude Code
https://claude.ai/code/session_01Fqgv4wZBmwHp4xgokj2xQb