Skip to content

feat: accept match alternatives in an ensures clause - #14701

Merged
sgraf812 merged 4 commits into
masterfrom
sg/requires-fun-like
Aug 6, 2026
Merged

feat: accept match alternatives in an ensures clause#14701
sgraf812 merged 4 commits into
masterfrom
sg/requires-fun-like

Conversation

@sgraf812

@sgraf812 sgraf812 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

This PR lets the ensures clause of a def contract be written like a fun, so a postcondition may be stated per shape of the result: ensures | none => False | some v => 2 * v ≤ n. A contract clause now also starts on its own line when pretty printed, as it is written in source.

ensuresClause gains Term.matchAlts as an alternative and expandDefContract wraps it in the fun that becomes the postcondition of the specification theorem. I decided to keep requires as is, because matching on state arguments of the assertion is not a use case I intend to support.

This PR lets the `requires` clause of a `def` contract be written like a `fun`, so a precondition may destructure the arguments of the assertion: `requires | (a, b) => a = 0 ∧ b = n` matches on the state of a state monad. The term form `requires P` and the binder form `requires s => P s` are unchanged.

The clause parser gains `Term.matchAlts` as an alternative, and `expandDefContract` wraps it in the `fun` that becomes the precondition of the specification theorem.
@sgraf812 sgraf812 added the changelog-language Language features and metaprograms label Aug 6, 2026
@github-actions github-actions Bot added the toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN label Aug 6, 2026
@mathlib-lean-pr-testing

Copy link
Copy Markdown

Mathlib CI status (docs):

  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase c4e6b62c3d955ef20da94310797072f7c4c5fa2b --onto f2bcf2e8660ab2d16cf3cb50c8e127de0439a337. You can force Mathlib CI using the force-mathlib-ci label. (2026-08-06 07:50:57)

@leanprover-bot

Copy link
Copy Markdown
Collaborator

Reference manual CI status:

  • ❗ Reference manual CI will not be attempted unless your PR branches off the nightly-with-manual branch. Try git rebase c4e6b62c3d955ef20da94310797072f7c4c5fa2b --onto 23393b959b33e3a8d15796b2397f8a04c315b9f4. You can force reference manual CI using the force-manual-ci label. (2026-08-06 07:50:59)

Moves the fun-like clause body from `requires`, whose arguments are the assertion's own and carry no
shape to match on, to `ensures`, which binds the result. Both clauses now start on their own line
when pretty printed, so a clause can no longer trail the alternatives of the one before it.
@sgraf812 sgraf812 changed the title feat: accept match alternatives in a requires clause feat: accept match alternatives in an ensures clause Aug 6, 2026
@sgraf812
sgraf812 marked this pull request as ready for review August 6, 2026 08:43
@sgraf812

sgraf812 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

!bench

@sgraf812
sgraf812 enabled auto-merge August 6, 2026 08:43
@leanprover-radar

leanprover-radar commented Aug 6, 2026

Copy link
Copy Markdown

Benchmark results for 559fd19 against c4e6b62 are in. No significant results found. @sgraf812

  • 🟥 build//instructions: +3.0G (+0.03%)

Small changes (3🟥)

  • 🟥 build/module/Lean.Elab.PreDefinition//instructions: +16.9M (+1.82%)
  • 🟥 build/module/Lean.Elab.Tactic.Do.Contract//instructions: +77.1M (+1.95%)
  • 🟥 compiled/rbmap_fbip//maxrss: +324kiB (+0.32%)

@sgraf812
sgraf812 added this pull request to the merge queue Aug 6, 2026
Merged via the queue into master with commit ddc2f33 Aug 6, 2026
24 checks passed
@sgraf812
sgraf812 deleted the sg/requires-fun-like branch August 6, 2026 09:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog-language Language features and metaprograms toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants