lean4-htt/tests/lean/run/4644.lean
Kyle Miller ce73bbe277
feat: detailed feedback on decide tactic failure (#4674)
When the `decide` tactic fails, it can try to give hints about the
failure:
- It tells you which `Decidable` instances it unfolded, by making use of
the diagnostics feature.
- If it encounters `Eq.rec`, it gives you a hint that one of these
instances was likely defined using tactics.
- If it encounters `Classical.choice`, it hints that you might have
classical instances in scope.
- During this, it tries to process `Decidable.rec`s and matchers to pin
blame on a particular instance that failed to reduce.

This idea comes from discussion with Heather Macbeth [on
Zulip](https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/Decidable.20with.20structures/near/449409870).
2024-07-11 20:08:29 +00:00

40 lines
1.4 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- NB: well-founded recursion, so irreducible
def sorted_from_var [x: LE α] [DecidableRel x.le] (a: Array α) (i: Nat): Bool :=
if h: i + 1 < a.size then
have : i < a.size := Nat.lt_of_succ_lt h
a[i] ≤ a[i+1] && sorted_from_var a (i + 1)
else
true
termination_by a.size - i
def check_sorted [x: LE α] [DecidableRel x.le] (a: Array α): Bool :=
sorted_from_var a 0
-- works (because `rfl` of closed terms resorts to kernel defeq, see #3772)
example: check_sorted #[0, 3, 3, 5, 8, 10, 10, 10] := by
rfl
/--
error: tactic 'decide' failed for proposition
check_sorted #[0, 3, 3, 5, 8, 10, 10, 10] = true
since its 'Decidable' instance
instDecidableEqBool (check_sorted #[0, 3, 3, 5, 8, 10, 10, 10]) true
did not reduce to 'isTrue' or 'isFalse'.
After unfolding the instances 'instDecidableEqBool' and 'Bool.decEq', reduction got stuck at the 'Decidable' instance
match check_sorted #[0, 3, 3, 5, 8, 10, 10, 10], true with
| false, false => isTrue ⋯
| false, true => isFalse ⋯
| true, false => isFalse ⋯
| true, true => isTrue ⋯
-/
#guard_msgs in
example: check_sorted #[0, 3, 3, 5, 8, 10, 10, 10] := by
decide -- fails because `decide` uses `.default` transparency, and `sorted_from_var` is marked as irreducible
unseal sorted_from_var in
example: check_sorted #[0, 3, 3, 5, 8, 10, 10, 10] := by
decide -- works
example: check_sorted #[0, 3, 3, 5, 8, 10, 10, 10] := by
with_unfolding_all decide -- should work