Conversation
…so a table that breaks one is refused rather than solved A `checks:` block declares a `where` predicate the bound data must satisfy. It builds no row and changes no answer: it is the sentence a reader has to believe about the table before believing the constraints above it, and the consumer holding the numbers is the one that raises it. The vocabulary is the one a `piecewise:` block already uses — `Holds` joins the `Check` union, so a consumer dispatches on one closed set whether the condition was assumed by a curve or declared by the file. `check_message` takes the context rather than a block, and `Increasing` and `Curved` carry the method their sentence names. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ne3vr2aAFQ4pyxqvdoRsDD
Documentation build overview
11 files changed ·
|
…umer reading only the program says why the condition matters `Holds` keeps its block's `description:` and `check_message` appends it. For every other declaration a description is for the typeset page; for a check it is the second half of the refusal, and a consumer holding only the program could not reach it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ne3vr2aAFQ4pyxqvdoRsDD
… out, like the legend `typeset(..., checks=False)` and `--no-checks` drop the Data conditions section. They are conditions on the input rather than rows a solver holds, so a page about the math alone has no place for them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ne3vr2aAFQ4pyxqvdoRsDD
This was referenced Aug 31, 2026
Contributor
Author
|
Superseeded by #471 |
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
checks:declares awherepredicate the bound data must satisfy. It builds no row and changes no answer — it is the sentence a reader has to believe about the table before believing the constraints above it.No
foreach. The frame is read off the predicate's own names, so a check is asked at every coordinate they span and a scalar one is a single question.Why the vocabulary is the one that was already there
origin/mainalready carries aCheckunion —Increasing,Curved,AtLeastTwo,Contiguous— andcheck_message, for what apiecewise:block assumes of its curve. A declared condition is the same fact with a different provenance, soHoldsjoins that union rather than starting a second one: a consumer dispatches on one closed set whether a curve implied the condition or the file wrote it.That cost two small reshapes, flagged because they edit code #237 landed:
check_message(block, pw, check)→check_message(context, check). Thepwargument existed only to reachpw.method, soIncreasingandCurvednow carry the method their own sentence names, and the function is a pure dispatch on the check.tests/test_piecewise.py::test_every_check_has_a_sentencesweepsget_args(Check), so it demanded a sentence forHoldsthe moment it joined — it now sources checks from both provenances.And it typesets
A construct the loader admits, the typesetter renders.
Walk.where()already renders any predicate in all three formats, so this is aWalk.checks()and a fourth section; no new rendering code.examples/pypsa_stochastic.yaml, in markdown:A check over a dimension carries the quantifier its own names span —
$$\mathrm{p}^{\mathrm{max}}_{g} > 0 \wedge \mathrm{eta}_{g} \le 1 \qquad \forall\thinspace g \in \mathcal{G}$$— and a scalar one carries none.It is a section a page may leave out, like the legend:
typeset(..., checks=False)and--no-checks. A condition on the input is not a row a solver holds, so a page about the math alone drops it, and the rest is byte-identical to the same model with no checks at all (asserted, intest_the_data_conditions_are_left_out_on_request).What is decided at load, and what is not
No file determines whether a table satisfies a condition — the consumer binding the data raises it, in the language's own words (
check_message), the shape #242 established. What the file can decide, it does:TrueFalseWhat crosses the boundary
Two things, and nothing comes back — this repo never holds data, so there is no result type to own:
The consumer evaluates the predicate over
dimsand raises that sentence with its own account of what it saw — the shapecheck_messagehas had since #237, and the division #242 established.A check is the one declaration whose prose reaches the program.
reading.mdsays a program cannot answer what the file wrote, and this is the exception it now names: for every other declaration adescription:is for the typeset page, and here it is the second half of the refusal. Without it a consumer holding only the program prints the check's name and nothing about why it matters.Severity stays prose. Nothing carries "error or warning", exactly as
coverage:carries none — the must is the declaration, and #243 has lpspec raise aDataErroron the strength of the reference alone. What the failing coordinates look like is the consumer's, by the second edge of what-counts-as-language.Verified
pixi run cion this branch —lint,test(839 passed, 828 on the base — 11 new),docs-build --strict,compile-tex(26 documents, the stochastic example among them).schema/math-spec.schema.jsonandtests/typesetting/golden/*.outregenerated by their own tools.Mutation table
Each guard deleted in turn on a clean tree, restored with
git checkout --:The always-true arm is the one that matters: without it a check that holds whatever the data says reaches
_lower_check's assertion instead of a load error, which is the failure mode #223 was about.tests/typesetting/test_golden.py::test_the_golden_model_reaches_every_line_of_the_walkalso refused the first version —Walk.checks()was five unreached lines until the golden model declared two, one over a dimension and one scalar, so both quantifier branches print.The evidence this rests on
Sorted every parameter across the seven example models. The conditions that matter there are relational or reductive, not scalar ranges — which is why this is a predicate block and not
minimum:/maximum:attributes:0 <= CVaR_omega <= 1pypsa_stochastic.yamlCVaR_inv_tail >= 1pypsa_stochastic.yamlLink_efficiencyis a shareLine_loss_offset < 0(prose only today)pypsa_losses.yamlGenerator_p_min_pu <= Generator_p_max_pusum(scenario_weight, over=scenario) == 1pypsa_stochastic.yamlpypsa_stochastic.yaml:9says "the cost is the expectation over the scenarios' weights", and nothing enforces that they sum to one. That row is the strongest case for the feature and it is the one that has to wait.Deliberately not done
No parameter-to-parameter comparison.
holds: "Generator_p_min_pu <= Generator_p_max_pu"is refused today byresolution.py, and widening that is lpspec#851 — already decided yes upstream, with its own ledger rows inexamples/pypsa.yaml(Generator_partly_tightened,Generator_must_stay_up). Separate PR, separate decision.No reduction in a predicate. The sum-to-one row needs one, and the dim-algebra reason a
where:cannot reduce (lpspec#469) may not apply to a check, whose output shape is stated rather than inferred. Worth deciding on its own rather than behind this.No enforcement here, because there is nothing to enforce without data. No entry in the ten rules — a check states no rule about what the model means, and whether the front door's table should mention it is an editorial call that is yours.
Draft, because the two rows above are the ones that justify the block, and you may want them settled before this lands.
Closes #268