def sorted_to_var [x: LE α] [DecidableRel x.le] (a: Array α) (i: Nat) (h : i + 1 < a.size) : Bool := match i with | 0 => true | i+1 => have : i + 1 < a.size := Nat.lt_of_succ_lt h a[i] ≤ a[i+1] && sorted_to_var a i this termination_by structural i attribute [irreducible] sorted_to_var def check_sorted [x: LE α] [DecidableRel x.le] (a: Array α): Bool := if h : a.size ≤ 1 then true else sorted_to_var a (a.size - 2) (by omega) /-- error: Tactic `rfl` failed: The left-hand side check_sorted #[0, 3, 3, 5, 8, 10, 10, 10] is not definitionally equal to the right-hand side true ⊢ check_sorted #[0, 3, 3, 5, 8, 10, 10, 10] = true -/ #guard_msgs in example: check_sorted #[0, 3, 3, 5, 8, 10, 10, 10] = true := by rfl -- fails because `rfl` uses `.default` transparency, and `sorted_from_var` is marked as irreducible /-- error: Tactic `decide` failed for proposition check_sorted #[0, 3, 3, 5, 8, 10, 10, 10] = true because 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`, `Bool.decEq`, and `Nat.decLe`, 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_to_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