Repository navigation
Conversation
…he door The pin follows math-spec #589, whose history carries #566, so this lands both halves the new pin asks for: an `assumptions:` entry is evaluated once every parameter is read, and a `where` may compare arithmetic over parameters on either lane. `PiecewiseDeclaration.checks` and `check_message` are gone upstream — a block's conditions stand in `Program.assumptions` beside the file's own entries — so `curves.py` reads them from there under the name a refusal quotes. 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 #589. An
assumptions:entry is evaluated at the door and the data refused in the language's own words, and awheremay compare arithmetic over parameters on both lanes — #589's history carries #566, so one pin asks for both.Stacked on this: #1706 (math-spec #592,
countandshiftover a predicate).What this changes
assumptions.py, the file's own entries.validate_assumptionsruns fromtidy_sourcesonce every parameter, dimension and lookup is read, so both lanes enter through the one door. Each entry's predicate is evaluated over the product of the dims its two masks name, cut by itswhere, through the relational lane's mask compiler — the one reader of a mask this package has that needs no model built first. The failing coordinates are the admitted product less the rows the predicate keeps, rather than the rows it drops: a mask certain of a parameter inner-joins, so a coordinate with no row is gone from the carrier before the predicate is read, and that is exactly the coordinate a missing row has to count as failing. The sentence isassumption_message's, with the count and the first five coordinates appended.curves.pyreads the block's conditions fromProgram.assumptions.PiecewiseDeclaration.checksandcheck_messageare gone upstream._onefinds the condition of a kind that a block's method implies, and_refusalwords it under the name it is filed as — which is the name a reader greps for,cost_curve increasing.Arithmetic over parameters in a
where, on both lanes. A side compiles to constant fragments alone and is added over the comparison's dims the way a constant side of a constraint is; a coordinate no fragment reaches stays null, so the comparison reads false there as every other atom over a missing value does. The eager lane evaluates each side as a constant position and compares element-wise. Both handlers reach their lane's expression evaluator through the one lazy import the grammar forces — a mask reads an expression and acasesexpression reads a mask — soDELIBERATE_LAZY_IMPORTSis no longer empty and hard rule 0 in ARCHITECTURE says why.ArithmeticComparisonis inprogram.Predicateand no lowered mask holds one, so it is excused from both lanes' census underNEVER_LOWERED, andtest_no_never_lowered_node_survives_loweringchecks that claim about upstream rather than trusting it.Which draft PRs this reuses, and why they are not the vehicle
The code comes from the two existing drafts; neither branch could carry it.
feat(data): what a file assumes of its data is checked at the door…) is the same door check, written against math-spec Track 2 — the operational surface #471. Track 2 — the operational surface #471 is replaced by refactor: one answer per question #589, which renamedcheck_message, moved a block's conditions intoProgram.assumptions, and dropped theParameterPairComparisonnode feat(data): what a file assumes of its data is checked at the door, and a where may compare two parameters #1637's other half was built on.assumptions.pyandtests/test_assumptions.pyare ported from it; the seven tests pass unchanged against refactor: one answer per question #589's API, which is the evidence that the two PRs mean the same thing.feat(language): a where may compare arithmetic over parameters on both lanes) is the perf(engine): a bound dense over the variable product is attached, not joined #566 consumer. Its stack forked before math-spec's node rename (ParameterComparisonNode→ParameterComparison, main's fix(data): an empty index keeps the dimension's declared dtype #585 / alpha.108) and before this repo's refactor: only the linopy lane and the solver sinks say Any #1699 and fix(language): a pullback that reads a column over the dimension it joins on is refused at load #1703, so merging it intomainconflicts in 14 files and pinning it forward to refactor: one answer per question #589 turns the suite red in 2104 places. The two handlers, the architecture census and the parity sweep are ported ontomaininstead.So both drafts are superseded rather than built on. Closing them is yours to decide — this PR does not touch them.
Gates
pixiis refused by this environment's egress proxy, so the gates ran from auvenvironment on Python 3.12 (uv sync --all-extras --group dev). That is a departure from the "prefix every command withpixi run" default, and the only one taken deliberately. The work was done in the primary checkout rather than a worktree, for the same reason: one solved environment per session.pytest -q -n automain: 4013 passed)ruff check .ruff format --check .pyrefly checkpython -m tools.gallery_mathdocs-build,test-bench,sweepbench/The 320 skips are this environment's: no
typstbinary, and the solver-licence cases.Mutation table
python -m tools.mutate, each guard deleted in turn, the suite run, the file restored and the tree checked clean.sources.py:108)assumptions.py:68-69)predicates.py:223-225)Tree clean after the run.
The third row is the guard the suite would otherwise survive deleting, because lowering refuses a variable on a where side first.
test_a_where_side_holding_a_variable_is_caught_rather_than_compiled_as_a_constantis the purpose-built probe that reaches it, which is why the row measures it from the compiler rather than from a model.Coverage moved, and what was deliberately left out
test_both_lanes_refuse_the_same_where[two-parameters-compared]is gone:p_max > costis now admitted, so it moves toACCEPTEDin the same file, next to0.5 * p_max > 0,sum(p_max, over=generator) > 0and1 > 0.ArithmeticComparisongoes inCOVERED_ELSEWHERE, pointing at the never-lowered probe, so the parity sweep's census still names a test for every resolved predicate.piecewisegallery pages gain their generated Assumptions section;docs/reference/data.mdgains the refusal row anddocs/about/linopy.mdthe lane's reading of a comparison of expressions.assumptions:entry from apiecewise:block — 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. The pin is a commit rather than a tag because refactor: one answer per question #589 is unmerged, which is also why this PR is a draft: it cannot merge before refactor: one answer per question #589 does.uv.lockmoves only the math-spec entry.🤖 Generated with Claude Code
https://claude.ai/code/session_01TWu2WSipjg5T3khNLfTXDK