Skip to content

feat: defeqParam gadget for delayed assignment metavariables#12854

Draft
kmill wants to merge 2 commits intomasterfrom
kmill_fix_8488
Draft

feat: defeqParam gadget for delayed assignment metavariables#12854
kmill wants to merge 2 commits intomasterfrom
kmill_fix_8488

Conversation

@kmill
Copy link
Copy Markdown
Collaborator

@kmill kmill commented Mar 9, 2026

This PR fixes an issue in the elaborator where delayed substitutions involving dependent let bindings could create type-incorrect terms. To address this, we encode the let value into the type of the metavariable involved in the delayed substitution, which is then checkable by Meta.check or rewriting tactics.

Implementation: it adds a defeqParam parameter gadget that is only meant to be used for metavariables created by the MetavarContext system when a metavariable depends on a dependent let that is being abstracted. In Meta.check, there is an additional check for applications that if the domain has @defeqParam t v then the argument is definitionally equal to v. This immediately fixes any tactic (like rw or clear_value) that uses Meta.check in its operation.

For example, after elaborating (let v := n + 1; ?m : Nat), we get a metavariable ?d and the expression let v := n + 1; ?d v, with a delayed assignment ?m := ?d v. Before this PR, the type of ?d was ?d : Nat -> Nat, but now it is ?d : defeqParam (n + 1) -> Nat. This defeqParam (n + 1) gadget is definitionally equal to Nat, but Meta.check will ensure the argument to ?d is definitionally equal to n + 1. If we were to zeta reduce the expression, we'd get ?d (n + 1), which is still type correct according to Meta.check. Trying to rewrite with Nat.add_comm will fail, since the motive needs to be ?d a for an abstract a : Nat, which is not definitionally equal to n + 1.

Note: This gadget is not meant to be used by users. It is only for the implementation of delayed assignments. It is also not part of Lean's type theory, since it is merely a hint used by the elaborator.

Closes #8488

This PR adds a gadget to support recording dependence of `let` variables in the MetavarContext system. The effect is that `Meta.check` can now detect when the values in delayed substitutions that are meant to be used for `let` variables are no longer definitionally equal to what they are supposed to be. For example, after elaborating `(let v := n + 1; ?m : Nat)`, we get a metavariable `?d` and the expression `let v := n + 1; ?d v`, with a delayed assignment `?m := ?d v`. Before, the type of `?d` was `?d : Nat -> Nat`, but now it is `?d : defeqParam (n + 1) -> Nat`. This `defeqParam (n + 1)` gadget is definitionally equal to `Nat`, but the `Meta.check` checker will ensure the argument to `?d` is definitionally equal to `n + 1`.  With this gadge, zeta reduction yields `?d (n + 1)`, which satisfies `Meta.check`. Trying to rewrite with `Nat.add_comm` will fail, since the motive needs to be `?d a` for an astract `a : Nat`, which is not definitionally equal to `n + 1`. **Note:** This gadget is ***not*** meant to be used by users. It is only for the implementation of delayed assignments. It is *not* part of Lean's type theory.

Closes #8488
@kmill kmill added the changelog-language Language features and metaprograms label Mar 9, 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 Mar 9, 2026
@leanprover-bot
Copy link
Copy Markdown
Collaborator

Reference manual CI status:

  • ❗ Reference manual CI can not be attempted yet, as the nightly-testing-2026-03-05 tag does not exist there yet. We will retry when you push more commits. If you rebase your branch onto nightly-with-manual, reference manual CI should run now. You can force reference manual CI using the force-manual-ci label. (2026-03-09 15:57:27)

mathlib-nightly-testing bot pushed a commit to leanprover-community/batteries that referenced this pull request Mar 9, 2026
@github-actions github-actions bot added the mathlib4-nightly-available A branch for this PR exists at leanprover-community/mathlib4-nightly-testing:lean-pr-testing-NNNN label Mar 9, 2026
mathlib-nightly-testing bot pushed a commit to leanprover-community/mathlib4-nightly-testing that referenced this pull request Mar 9, 2026
@mathlib-lean-pr-testing mathlib-lean-pr-testing bot added the builds-mathlib CI has verified that Mathlib builds against this PR label Mar 9, 2026
@mathlib-lean-pr-testing
Copy link
Copy Markdown

Mathlib CI status (docs):

mathlib-nightly-testing bot pushed a commit to leanprover-community/batteries that referenced this pull request Mar 10, 2026
mathlib-nightly-testing bot pushed a commit to leanprover-community/mathlib4-nightly-testing that referenced this pull request Mar 10, 2026
@mathlib-lean-pr-testing
Copy link
Copy Markdown

Mathlib CI status (docs):

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

Labels

builds-mathlib CI has verified that Mathlib builds against this PR changelog-language Language features and metaprograms mathlib4-nightly-available A branch for this PR exists at leanprover-community/mathlib4-nightly-testing:lean-pr-testing-NNNN 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.

Metavariables under binders can create terms that can become type incorrect after basic tactics

2 participants