This PR updates various error messages produced by or associated with built-in tactics and adapts their formatting to current conventions.
121 lines
3.4 KiB
Text
121 lines
3.4 KiB
Text
/-!
|
|
# Tests of the `decide` tactic
|
|
-/
|
|
|
|
/-!
|
|
Success
|
|
-/
|
|
#guard_msgs in
|
|
example : 2 + 2 ≠ 5 := by decide
|
|
|
|
|
|
/-!
|
|
False proposition
|
|
-/
|
|
|
|
/--
|
|
error: Tactic `decide` proved that the proposition
|
|
1 ≠ 1
|
|
is false
|
|
-/
|
|
#guard_msgs in
|
|
example : 1 ≠ 1 := by decide
|
|
|
|
|
|
/-!
|
|
Irreducible decidable instance
|
|
-/
|
|
opaque unknownProp : Prop
|
|
|
|
/--
|
|
error: Tactic `decide` failed for proposition
|
|
unknownProp
|
|
because its `Decidable` instance
|
|
Classical.propDecidable unknownProp
|
|
did not reduce to `isTrue` or `isFalse`.
|
|
|
|
After unfolding the instance `Classical.propDecidable`, reduction got stuck at the `Decidable` instance
|
|
Classical.choice ⋯
|
|
|
|
Hint: Reduction got stuck on `Classical.choice`, which indicates that a `Decidable` instance is defined using classical reasoning, proving an instance exists rather than giving a concrete construction. The `decide` tactic works by evaluating a decision procedure via reduction, and it cannot make progress with such instances. This can occur due to the `open scoped Classical` command, which enables the instance `Classical.propDecidable`.
|
|
-/
|
|
#guard_msgs in
|
|
open scoped Classical in
|
|
example : unknownProp := by decide
|
|
|
|
|
|
/-!
|
|
Reporting unfolded instances and give hint about Eq.rec.
|
|
From discussion with Heather Macbeth on Zulip
|
|
-/
|
|
structure Nice (n : Nat) : Prop where
|
|
(large : 100 ≤ n)
|
|
|
|
theorem nice_iff (n : Nat) : Nice n ↔ 100 ≤ n := ⟨Nice.rec id, Nice.mk⟩
|
|
|
|
def baz (n : Nat) : Decidable (Nice n) := by
|
|
rw [nice_iff]
|
|
infer_instance
|
|
|
|
instance : Decidable (Nice n) := baz n
|
|
|
|
/--
|
|
error: Tactic `decide` failed for proposition
|
|
Nice 102
|
|
because its `Decidable` instance
|
|
instDecidableNice
|
|
did not reduce to `isTrue` or `isFalse`.
|
|
|
|
After unfolding the instances `baz` and `instDecidableNice`, reduction got stuck at the `Decidable` instance
|
|
⋯ ▸ inferInstance
|
|
|
|
Hint: Reduction got stuck on `▸` (Eq.rec), which suggests that one of the `Decidable` instances is defined using tactics such as `rw` or `simp`. To avoid tactics, make use of functions such as `inferInstanceAs` or `decidable_of_decidable_of_iff` to alter a proposition.
|
|
-/
|
|
#guard_msgs in
|
|
example : Nice 102 := by decide
|
|
|
|
|
|
/-!
|
|
Following `Decidable.rec` to give better messages
|
|
-/
|
|
|
|
/--
|
|
error: Tactic `decide` failed for proposition
|
|
¬Nice 102
|
|
because its `Decidable` instance
|
|
instDecidableNot
|
|
did not reduce to `isTrue` or `isFalse`.
|
|
|
|
After unfolding the instances `baz`, `instDecidableNice`, and `instDecidableNot`, reduction got stuck at the `Decidable` instance
|
|
⋯ ▸ inferInstance
|
|
|
|
Hint: Reduction got stuck on `▸` (Eq.rec), which suggests that one of the `Decidable` instances is defined using tactics such as `rw` or `simp`. To avoid tactics, make use of functions such as `inferInstanceAs` or `decidable_of_decidable_of_iff` to alter a proposition.
|
|
-/
|
|
#guard_msgs in
|
|
example : ¬ Nice 102 := by decide
|
|
|
|
|
|
/-!
|
|
Reverting free variables.
|
|
-/
|
|
|
|
/--
|
|
error: Expected type must not contain free variables
|
|
x + 1 ≤ 5
|
|
|
|
Hint: Use the `+revert` option to automatically clean up and revert free variables
|
|
-/
|
|
#guard_msgs in
|
|
example (x : Nat) (h : x < 5) : x + 1 ≤ 5 := by decide
|
|
|
|
example (x : Nat) (h : x < 5) : x + 1 ≤ 5 := by decide +revert
|
|
|
|
|
|
/--
|
|
Can handle universe levels.
|
|
-/
|
|
|
|
instance (p : PUnit.{u} → Prop) [Decidable (p PUnit.unit)] : Decidable (∀ x : PUnit.{u}, p x) :=
|
|
decidable_of_iff (p PUnit.unit) (by constructor; rintro _ ⟨⟩; assumption; intro h; apply h)
|
|
|
|
example : ∀ (x : PUnit.{u}), x = PUnit.unit := by decide
|