The `decide` tactic produces error messages that users find to be obscure. Now: 1. If the `Decidable` instance reduces to `isFalse`, it reports that `decide` failed because the proposition is false. 2. If the `Decidable` instance fails to reduce, it explains what proposition it failed for, and it shows the reduced `Decidable` instance rather than the `Decidable.decide` expression. That expression tends to be less useful since it shows the unreduced `Decidable` argument (plus it's a lot longer!) Examples: ```lean example : 1 ≠ 1 := by decide /- tactic 'decide' proved that the proposition 1 ≠ 1 is false -/ opaque unknownProp : Prop open scoped Classical in example : unknownProp := by decide /- tactic 'decide' failed for proposition unknownProp since its 'Decidable' instance reduced to Classical.choice ⋯ rather than to the 'isTrue' constructor. -/ ``` When reporting the error, `decide` only shows the whnf of the `Decidable` instance. In the future we could consider having it reduce all decidable instances present in the term, which can help with determining the cause of failure (this was explored in 8cede580690faa5ce18683f168838b08b372bacb).
12 lines
664 B
Text
12 lines
664 B
Text
2161.lean:15:48-15:54: error: tactic 'decide' failed for proposition
|
|
mul (mul (mul 4 1) 1) 1 = 4
|
|
since its 'Decidable' instance reduced to
|
|
Decidable.rec (fun h => (fun h => isFalse ⋯) h) (fun h => (fun h => h ▸ isTrue ⋯) h)
|
|
(instDecidableEqNat (mul (mul (mul 4 1) 1) 1).num 4)
|
|
rather than to the 'isTrue' constructor.
|
|
2161.lean:22:48-22:54: error: tactic 'decide' failed for proposition
|
|
add (add (add 4 1) 1) 1 = 4
|
|
since its 'Decidable' instance reduced to
|
|
Decidable.rec (fun h => (fun h => isFalse ⋯) h) (fun h => (fun h => h ▸ isTrue ⋯) h)
|
|
(instDecidableEqNat (add (add (add 4 1) 1) 1).num 4)
|
|
rather than to the 'isTrue' constructor.
|