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>
2 lines
65 B
Text
2 lines
65 B
Text
theorem foo.bla : 0 < 5 :=
|
|
of_decide_eq_true (id (Eq.refl true))
|