Skip to content

feat: advice names the assumption that proves a quadratic objective or row convex - #747

Open
FBumann wants to merge 11 commits into
claude/mathspec-analysis-features-zy7x4nfrom
claude/mathspec-analysis-features-zy7x4n-convexity-advice
Open

FBumann wants to merge 11 commits into
claude/mathspec-analysis-features-zy7x4nfrom
claude/mathspec-analysis-features-zy7x4n-convexity-advice

Conversation

@FBumann

@FBumann FBumann commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

Prompt: And should we warn if the problem class is not well defined? With a hint?
— Yes

Note

The following content was generated by AI.

What this changes

A new advice kind, convexity, names the one assumptions: entry that would prove an undecided quadratic objective or row convex. Stacked on #746; the base moves to main when #746 merges.

Rules, gate output, what was not done

When it fires

Per declaration: the parameters its quadratic terms leave unsigned are given one sign together, >= 0 then <= 0, and the verdict re-run. Where one sign proves the declaration convex, one note names them all. On examples/pypsa.yaml:

Constraint 'CVaR_excess' is convex for all data once 'Generator_marginal_cost_quadratic', 'Link_marginal_cost_quadratic', 'Process_marginal_cost_quadratic', 'StorageUnit_marginal_cost_quadratic', 'Store_marginal_cost_quadratic', 'period_weight_objective', 'snapshot_weightings_objective' are never negative, and no assumption states that, so only the data decides now.
State it: an assumptions: entry with no where: that holds "Generator_marginal_cost_quadratic >= 0 AND … AND snapshot_weightings_objective >= 0".

It is silent for a declaration proven nonconvex (a model the author may mean), for a cross term no sign decides, for an equality, and where the two terms need opposite signs. test_stating_what_the_note_says_proves_it_convex pastes the note's holds back into the spec and asserts convex is True and no note.

Fixture changes

  • tests/typesetting/golden/model.yaml maximizes sum(p * p * cost) with cost unsigned, and test_check_accepts_the_model_that_carries_every_construct holds it to no advice. It now states cost > 0, which proves that square nonconvex: no note, and the legend still reaches the nonconvex sentence the golden coverage test counts. Stating cost <= 0 would make it convex and leave the undecided and nonconvex legend lines unreached. tools/notation.py gains a heading for the new entry; golden output and docs/reference/notation.md are regenerated.
  • tests/test_advice.py: a fixture THREE_KINDS adds a squared x under c to main's never-an-axis and unbounded fixture, and the every-kind test reads it with main's given fixture, since the test pins that every AdviceKind is produced.
  • This PR once gave examples/pypsa_quadratic.yaml the note's assumption. main folded that file into examples/pypsa.yaml (docs(pypsa): the pypsa spec is also 24 topic files that merge back to it, each component adding its share of a sum by name #736), so the change went with it; no example changes here.

Guards

Guard deleted Fails
a note needs an unsigned parameter 28 tests, the note rows first
stop after the first sign that works two-at-once (both signs prove c * k convex)
<= tried with the non-positive sign maximized, an-at-least-row

A first draft skipped declarations whose verdict was not undecided. No test failed without it: a note needs an unsigned parameter, and neither a convex nor a nonconvex verdict turns on one. It was removed.

Gates

  • pixi run lint: pass.
  • pixi run test: 2688 passed, on the merge of main at 22cdebd.
  • docs-build and compile-tex did not run to completion in the session: its network blocks docs.python.org and the Tectonic bundle. CI runs both.

Open, for review

  • On examples/pypsa.yaml the objective's note asks for every quadratic cost, weight and CVaR_omega to be <= 0. The objective reads (1 - CVaR_omega), which only CVaR_omega <= 1 signs; a sign set of {-1, 0, 1} cannot state that bound, so >= 0 fails and <= 0 proves the objective convex. The proof holds, but PyPSA data never meets it.

Not done

  • A parameter that two declarations leave unsigned is named in a note for each.

Why

A spec whose convexity turns on an unstated sign usually has an author who knows the sign. The note turns that into the one line to write.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS

…r row convex

A new advice kind, convexity, fires where the problem class is undecided
and one stated sign for the declaration's unsigned parameters would prove
it convex. The note gives the single assumptions: entry to write. It is
silent for a nonconvex declaration and for a cross term that no sign
decides.

examples/pypsa_quadratic.yaml states the note's assumption and is now
provably convex. The golden model states cost > 0, which proves its
maximized square nonconvex, so it still draws no advice and its legend
still covers the nonconvex sentence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
…nalysis-features-zy7x4n-convexity-advice

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
…nalysis-features-zy7x4n-convexity-advice

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
…nalysis-features-zy7x4n-convexity-advice

examples/pypsa_quadratic.yaml is folded into examples/pypsa.yaml on main
(#736), so the assumption this branch added to it goes with the file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
…nalysis-features-zy7x4n-convexity-advice

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
…nalysis-features-zy7x4n-convexity-advice

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
…nalysis-features-zy7x4n-convexity-advice

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
…nalysis-features-zy7x4n-convexity-advice

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
…nalysis-features-zy7x4n-convexity-advice

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
@FBumann FBumann added the enhancement label Sep 29, 2026 — with Claude
…nalysis-features-zy7x4n-convexity-advice

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CvcU9JRnsinc9e9syvVcHS
FBumann pushed a commit that referenced this pull request Oct 2, 2026
… so a subproblem is a call on the whole model

Each named variable becomes a parameter under the same name: binary and
integer become int, continuous becomes float. Its bounds become the
assumption <name>_within_bounds, and a constraint that named only fixed
variables becomes an assumption. A masked variable with absence:
undefined keeps its meaning: each read outside a sum is proven guarded,
masked at its row, or refused with the reader named.

Ported from #748 onto main, without its base (#746, #747). A given
variable is refused with a message that names it as given.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XjTvqu5LubaVCgWeKogCqj

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants