Skip to content

feat: add cbv_eval attribute#12296

Draft
wkrozowski wants to merge 18 commits intoleanprover:masterfrom
wkrozowski:wojciech/cbv_theorems
Draft

feat: add cbv_eval attribute#12296
wkrozowski wants to merge 18 commits intoleanprover:masterfrom
wkrozowski:wojciech/cbv_theorems

Conversation

@wkrozowski
Copy link
Contributor

This (WIP) PR adds cbv_eval attribute that allows to evaluate functions in cbv tactic using pre-registered theorems.

@wkrozowski wkrozowski added the changelog-tactics User facing tactics label Feb 3, 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 Feb 3, 2026
@mathlib-lean-pr-testing
Copy link

mathlib-lean-pr-testing bot commented Feb 5, 2026

Mathlib CI status (docs):

  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase 96ef09186f1cfe31bf5af69adb6ead4fad218ced --onto 5ec3b8c9d2fed98e6d78782664dd545785e868d4. You can force Mathlib CI using the force-mathlib-ci label. (2026-02-05 11:30:29)
  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase 96ef09186f1cfe31bf5af69adb6ead4fad218ced --onto 75d7f7eb227bc54dc6ea3d8ead090ee4180debaf. You can force Mathlib CI using the force-mathlib-ci label. (2026-02-06 16:45:23)

@leanprover-bot
Copy link
Collaborator

leanprover-bot commented Feb 5, 2026

Reference manual CI status:

  • ❗ Reference manual CI will not be attempted unless your PR branches off the nightly-with-manual branch. Try git rebase 96ef09186f1cfe31bf5af69adb6ead4fad218ced --onto 42a0e9245300da6b3d971fa0033d726bb8e11cc3. You can force reference manual CI using the force-manual-ci label. (2026-02-05 11:30:31)
  • ❗ Reference manual CI will not be attempted unless your PR branches off the nightly-with-manual branch. Try git rebase 96ef09186f1cfe31bf5af69adb6ead4fad218ced --onto 75d7f7eb227bc54dc6ea3d8ead090ee4180debaf. You can force reference manual CI using the force-manual-ci label. (2026-02-06 16:45:26)

@wkrozowski wkrozowski changed the title [draft] feat: add cbv_eval attribute feat: add cbv_eval attribute Feb 5, 2026
github-merge-queue bot pushed a commit that referenced this pull request Feb 5, 2026
This PR adds a default `Inhabited` instance to `Theorem` type.

The need to do so came up in #12296 , as `Theorem` is one of the entries
of the structure which is the key entry of `SimpleScopedEnvExtension`.
Copy link
Collaborator

@nomeata nomeata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments

Comment on lines 17 to 20
structure CbvEvalEntry where
target : Name
thm : Theorem
deriving BEq, Inhabited
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this PR is a draft, so I am not sure much attention to polish I should give, but here are some comments necessary. In particular what is target? Is it always the head symbol of the LHS of the theorem? If so, is it worth keeping it as a separate field?

(Generally reviewing is easier if there are already comments)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, target is the extracted head symbol from LHS of the theorem.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your point. We could move the logic and do this when adding a Theorem object to the state of the extension, by inferring the type of an expression and extracting the name of the appFn on the LHS.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually no, we want the name of appFn of the LHS of the theorem to be the key of the NameMap stored in the expression, so the name of it should be known at the moment of calling add on the extension (which is pure, and hence we cannot compute it inside of add)

throwError "Invalid `cbv` theorem"
let fnName ← forallTelescope type fun _ body => do
let some (_, lhs, _) := body.eq? | throwError "Equality expected"
unless lhs.isApp do throwError "Application expected"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you really want to forbid cbv_eval on constants (nullary applications)? Maybe you can just drop this line; .getAppFn can still be used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, will do! I will also need to handle this case in Cbv.Main (so if I hit a constant that has an associated equation, we try to use it)

initial := {}
addEntry := CbvEvalState.addEntry
exportEntry? := fun level entry => do
guard (level == .private || !isPrivateName entry.target)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know the tests on the module system are still pending. Things to watch out: What if the target is public, but one of the arguments is private? What if the target is public but the theorem is private? (Maybe only look at whether the theorem itself is private)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there similar tests for simp annotations that could be an inspiration for me?

Comment on lines 91 to 98
let hasTheorems := (← getCbvEvalLemmas fnName).isSome
if hasTheorems then
let res ← (simpAppArgs >> tryCbvTheorems) e
match res with
| .rfl false => return .rfl (done := true)
| _ => return res
else
return .rfl (← isCbvOpaque fnName)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you even want to support theorem when `isOpaque = false?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! Imagine that we have a function that we have an optimisation for one set of inputs, but for the other ones, we would like to follow the standard path that involves using the associated equations/unfold equation.

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

Labels

changelog-tactics User facing tactics 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