Repository navigation
feat(language): a where counts the coordinates a predicate admits, and reads one at a neighbour - #1706
Closed
FBumann wants to merge 1 commit into
Closed
feat(language): a where counts the coordinates a predicate admits, and reads one at a neighbour#1706FBumann wants to merge 1 commit into
FBumann wants to merge 1 commit into
Conversation
…d reads one at a neighbour The pin follows math-spec #592, merged onto #589 so the stack keeps the assumptions this branch's base consumes: `count(<predicate>, over=)` answers a number and `shift(<predicate>, along=, offset=)` answers a predicate, on both lanes. The relational lane reads the counted predicate over its own product and joins the total back, so a coordinate it admits nowhere counts zero rather than losing its row; a shifted predicate carries its truth set forward along the axis, and a position the move runs off has no row to join, which is the false the language gives a vacated coordinate. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TWu2WSipjg5T3khNLfTXDK
Merging this PR will not alter performance
Comparing Footnotes
|
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 pin follows math-spec #592.
count(<predicate>, over=)answers a number andshift(<predicate>, along=, offset=)answers a predicate, on both lanes — the two atoms #582 needs a curve to state as language.Stacked on #1705 (math-spec #589,
assumptions:at the door).What this changes
The relational lane reads each of the two predicates over its own coordinate product, through the same
maskedthe outer mask came through, and joins one column back onto the carrier:pl.len()over the coordinates the predicate admits, grouped by what is left whenoveris reduced away, joined left. A coordinate the predicate admits nowhere has no row to join, so the column is null andfill_null(0)makes it the zero it is — a count is a number of coordinates, and "none" is an answer rather than a gap that drops the row.offsetpositions in the axis' own ordinal order and joins a boolean column. A position the move runs off the end of has no row to carry, joins null, and reads false throughfalsy_if_null— which is what a missing row already means in a mask, and why the predicate form states noedge=.The eager lane is two lines each: the predicate summed over
overand compared, andDataArray.shift(fill_value=False). Absence is already false in an evaluated mask on that lane, so both fall out of what it does with a bool array.Nothing new is refused here: a keyword the language does not admit (
by=,within=,edge='wrap'), a fractional bound, or a parameter on the right is refused at load, before a plan exists.Why the math-spec pin is a merge
#589 and #592 are siblings on #566 in math-spec, so no commit there carries both — and this branch's base consumes #589. The pin is therefore
energy-models/math-spec@2a9d0d5,claude/lpspec-589-592-update-qa51o2there: #592's branch merged into #589's, which is the merge commit #592's own description says whichever lands second will need. Its conflicts are the typesetter walk and the goldens; #589 folds six comparison members into oneAlignedComparisonprinted throughsides(), so #592's re-stated branches for four of them go and its two new ones stay. That merge's suite is 1426 passed, 16 skipped.When both land upstream the pin becomes an ordinary tag again.
Gates
pixiis refused by this environment's egress proxy, so the gates ran from auvenvironment on Python 3.12. Same departure as #1705, for the same reason, and the same single checkout rather than a worktree per topic.pytest -q -n autoruff check .ruff format --check .pyrefly checkdocs-build,test-bench,sweepbench/Mutation table
Five mutations, none of them a deletion
tools/mutate.pycan express — three changed constants and two changed reductions — so they were taken by hand with the tool's three precautions: a committed tree,git checkout --to restore, and__pycache__dropped on both sides of each. The tree was clean after the run, and that was checked rather than assumed.predicates.py,fill_null(0)dropped)predicates.py,+ offset→- offset)where.py,fill_value=Falsedropped)where.py,sum(dim=over)→sum())overplus what is left (predicates.py, the remaining dims dropped)Each ran
tests/test_where_count.py tests/test_resolution_parity.py.Coverage, and what was deliberately left out
tests/test_where_count.pyasserts the coordinates built, not their count: a predicate that inverted its sense would keep the complement, which is the same size on a symmetric case. Six claims — a count per remaining coordinate, a coordinate admitted nowhere counting zero, a vacated shift reading false, a count over a translated predicate counting run starts, a count over a dim the masked declaration does not span, and the four relations a count may be compared by.ACCEPTEDin the parity sweep gains three shapes, so both lanes build the same model from a count over either dimension and from a shifted predicate, andtest_every_resolved_predicate_is_parity_testednames a test for both new members.docs/about/linopy.mdgains the two rows for what the eager lane reads them as.piecewise:block emits anassumptions:entry using either atom — that is math-spec A modeller should not have to shrink the model to solve it #582's, on top of refactor: one answer per question #589.Maskjoining the golden node census is upstream's. And a count comparison keeps its own typesetter branch rather than joiningAlignedComparisonin the pinned merge, so a lone count in anassumptions:entry prints unaligned; the right home for that is refactor: cut the prose, keep the facts #592 or refactor: one answer per question #589 upstream, not a consumer.🤖 Generated with Claude Code
https://claude.ai/code/session_01TWu2WSipjg5T3khNLfTXDK
Generated by Claude Code