/-! # 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