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

RFC: decide! tactic variant #5629

Closed
nomeata opened this issue Oct 7, 2024 · 6 comments
Closed

RFC: decide! tactic variant #5629

nomeata opened this issue Oct 7, 2024 · 6 comments
Assignees
Labels
RFC Request for comments

Comments

@nomeata
Copy link
Collaborator

nomeata commented Oct 7, 2024

Proposal

In the equational_theories project there are many script-generated theorems with essentially by decide as the proof. In theses cases, we really know that the decide tactic will succeed (if not there is a bug somewhere), and it’s silly for decide to first run the decision procedure at elaboration time, and then again in the kernel.

Thus I propose to add a decide! variant of the tactic that causes this check to be skipped:

let r ← withAtLeastTransparency .default <| whnf s
if r.isAppOf ``isTrue then

This halfs the processing time of such files.

(The equational_theories project is currently using a tactic that has this effect.)

Community Feedback

(none yet)

Impact

Add 👍 to issues you consider important. If others benefit from the changes in this proposal being added, please ask them to add 👍 to it.

@nomeata nomeata added the RFC Request for comments label Oct 7, 2024
@nomeata nomeata self-assigned this Oct 7, 2024
@nomeata nomeata mentioned this issue Oct 7, 2024
@hrmacbeth
Copy link
Contributor

There's an inconsistency here with the meaning of ! in the mathlib3 decide tactic (which was there called dec_trivial). In that tactic, ! meant "revert everything first and then run decide". (Incidentally, I still miss that feature, it would be nice to have it in decide!)

This need not block using ! differently in Lean 4, just wanted to ensure it was a conscious choice.

@nomeata
Copy link
Collaborator Author

nomeata commented Oct 8, 2024

Thanks, I didn’t know that! Maybe it’s generally a bad habit to just reach for ! whenever one creates a variant of a tactic. Maybe a word like unchecked_decide or a flag like decide +force is better.

kmill added a commit to kmill/lean4 that referenced this issue 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. 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`.
kmill added a commit to kmill/lean4 that referenced this issue Oct 11, 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. 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`.
kmill added a commit to kmill/lean4 that referenced this issue Oct 11, 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. 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`.
github-merge-queue bot pushed a commit that referenced this issue Oct 11, 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:
```lean
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
-/
```

---------

Co-authored-by: Joachim Breitner <mail@joachim-breitner.de>
@kmill
Copy link
Collaborator

kmill commented Oct 13, 2024

With #5665 we now have a version of decide! that satisfies the motivation for this RFC — should we close it?

There are some ways that decide! really is stronger than decide, namely that it uses kernel reduction so can unfold everything in sight. Some possibilities to address ! and the old Lean 3 functionality:

  • add a decide (revert := true) option to both decide and decide!
  • or, rename decide! to kernel_decide and use a ! suffix to mean "revert the context" for both decide! and kernel_decide!.

@nomeata
Copy link
Collaborator Author

nomeata commented Oct 13, 2024

Yes, please close this (and feel free to do it yourself, so that credit goes where credit is due). I thought I edited that PRs description so that it would do it, but maybe didn't save.

I don't know much about the lean3 feature. Are people asking for it? Could it be the default behavior to always revert (maybe with a good explanation that this happened if no instance is found)?

@kmill kmill closed this as completed Oct 13, 2024
@kmill
Copy link
Collaborator

kmill commented Oct 13, 2024

@nomeata There are some cases where decide could succeed if it reverted variables the goal depends on, but I've gone back and forth whether this would be a good default. Maybe better would be a compositional approach, with a revert_deps tactic to revert just dependencies?

@nomeata
Copy link
Collaborator Author

nomeata commented Oct 13, 2024

Thats also plausible. Are there situations when reverting is not the right thing to do for decide?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RFC Request for comments
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants