Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: decide! tactic for using kernel reduction #5665

Merged
merged 5 commits into from
Oct 11, 2024

Conversation

kmill
Copy link
Collaborator

@kmill kmill commented Oct 9, 2024

The decide! tactic is like decide, but when it tries reducing the Decidable instance it uses kernel reduction rather than the elaborator's reduction.

The kernel ignores transparency, so it can unfold all definitions (for better or for worse). Furthermore, by using kernel reduction we can cache the result as an auxiliary lemma — this is more efficient than decide, which needs to reduce the instance twice: once in the elaborator to check whether the tactic succeeds, and once again in the kernel during final typechecking.

While RFC #5629 proposes a decide! that skips checking altogether during elaboration, with this PR's decide! we can use decide! as more-or-less a drop-in replacement for decide, since the tactic will fail if kernel reduction fails.

This PR also includes two small fixes:

  • blameDecideReductionFailure now uses withIncRecDepth.
  • Lean.Meta.zetaReduce now instantiates metavariables while zeta reducing.

Some profiling:

set_option maxRecDepth 2000
set_option trace.profiler true
set_option trace.profiler.threshold 0

theorem thm1 : 0 < 1 := by decide!
theorem thm1' : 0 < 1 := by decide
theorem thm2 : ∀ x < 400, x * x ≤ 160000 := by decide!
theorem thm2' : ∀ x < 400, x * x ≤ 160000 := by decide
/-
[Elab.command] [0.003655] theorem thm1 : 0 < 1 := by decide!
[Elab.command] [0.003164] theorem thm1' : 0 < 1 := by decide
[Elab.command] [0.133223] theorem thm2 : ∀ x < 400, x * x ≤ 160000 := by decide!
[Elab.command] [0.252310] theorem thm2' : ∀ x < 400, x * x ≤ 160000 := by decide
-/

@kmill kmill requested a review from Kha as a code owner October 9, 2024 23:37
@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 Oct 10, 2024
leanprover-community-mathlib4-bot added a commit to leanprover-community/batteries that referenced this pull request Oct 10, 2024
leanprover-community-mathlib4-bot added a commit to leanprover-community/mathlib4 that referenced this pull request Oct 10, 2024
@leanprover-community-bot leanprover-community-bot added the builds-mathlib CI has verified that Mathlib builds against this PR label Oct 10, 2024
@leanprover-community-bot
Copy link
Collaborator

leanprover-community-bot commented Oct 10, 2024

Mathlib CI status (docs):

  • ✅ Mathlib branch lean-pr-testing-5665 has successfully built against this PR. (2024-10-10 01:13:31) View Log
  • ✅ Mathlib branch lean-pr-testing-5665 has successfully built against this PR. (2024-10-10 17:06:40) View Log
  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase 8e88e8061a8b497d74f95e2232314c73b335b8a9 --onto d10d41bc07942ca6d8f3081a637045321db15c5a. (2024-10-11 06:44:23)
  • ✅ Mathlib branch lean-pr-testing-5665 has successfully built against this PR. (2024-10-11 06:58:46) View Log

if kernelOnly then
-- Reduce the decidable instance to (hopefully!) `isTrue` by passing `pf` to the kernel.
-- The `mkAuxLemma` function caches the result in two ways:
-- 1. First, the function makes use of a `type`-indexed cache per module.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder if this will still work with parallelism. Also is it not a bit strange to have a per module cache, and penalize users for splitting modules?

How is the matcher caching auxiliary definitions?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm not sure whether cross-decide! caching will still be supported with parallelism. I just know that mkAuxLemma is used by simp when processing simp lemmas.

The matcher uses its own cache, and the key function is Lean.Meta.Match.mkMatcherAuxDefinition

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah, right, you are basically getting this for free by using mkAuxLemma? So whatever will happen to that feature of simp will also happen to decide!. That’s fine.

- Since it uses kernel reduction instead of elaboratior reduction, it ignores transparancy and can unfold everything.
- While `decide` needs to reduce the `Decidable` instance twice (once during elaboration to verify whether the tactic succeeds,
and once during kernel type checking), the `decide!` tactic reduces it exactly once.
- When `decide!` is successful, the result is cached for the current module.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe remove that from the docstring. We don’t want people to relying on that behavior if we don't know if and how that will work post-parallelism.

Suggested change
- When `decide!` is successful, the result is cached for the current module.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sure. How does leaving the caching test sound, so we know when this finally has broken?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Absolutely!

leanprover-community-mathlib4-bot added a commit to leanprover-community/batteries that referenced this pull request Oct 10, 2024
leanprover-community-mathlib4-bot added a commit to leanprover-community/mathlib4 that referenced this pull request Oct 10, 2024
src/Lean/Parser/Tactic.lean Outdated Show resolved Hide resolved
@kmill kmill enabled auto-merge October 11, 2024 05:40
@kmill kmill added this pull request to the merge queue Oct 11, 2024
leanprover-community-mathlib4-bot added a commit to leanprover-community/batteries that referenced this pull request Oct 11, 2024
leanprover-community-mathlib4-bot added a commit to leanprover-community/mathlib4 that referenced this pull request Oct 11, 2024
@kmill kmill removed this pull request from the merge queue due to a manual request Oct 11, 2024
@kmill kmill requested review from hargoniX and mhuisi as code owners October 11, 2024 06:19
kmill and others added 5 commits October 10, 2024 23:26
The `decide!` tactic is like `decide`, but when it tries reducing the `Decidable` instance it uses kernel reduction rather than the elaborator's reduction.

The kernel ignores transparency, so it can unfold all definitions. Furthermore, by using kernel reduction we can cache the result as an auxiliary lemma — this is more efficient than `decide`, which needs to reduce the instance once in the elaborator to check whether the tactic suceeds, and once again in the kernel during final typechecking.

This implements a variant of RFC leanprover#5629, which proposes instead to skip checking altogether during elaboration. With this PR's `decide`, we can use `decide!` as more-or-less a drop-in replacement for `decide`.
Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>
@kmill kmill enabled auto-merge October 11, 2024 06:29
@kmill kmill added this pull request to the merge queue Oct 11, 2024
Merged via the queue into leanprover:master with commit fe0fbc6 Oct 11, 2024
13 checks passed
@nomeata nomeata mentioned this pull request Oct 15, 2024
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 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