This PR updates various error messages produced by or associated with built-in tactics and adapts their formatting to current conventions.
421 lines
8.5 KiB
Text
421 lines
8.5 KiB
Text
namespace Ex1
|
||
|
||
variable (P : Nat → Prop)
|
||
|
||
def ackermann : (Nat × Nat) → Nat
|
||
| (0, m) => m + 1
|
||
| (n+1, 0) => ackermann (n, 1)
|
||
| (n+1, m+1) => ackermann (n, ackermann (n + 1, m))
|
||
termination_by p => p
|
||
|
||
/--
|
||
error: Failed: `fail` tactic was invoked
|
||
case case1
|
||
P : Nat → Prop
|
||
m✝ : Nat
|
||
⊢ P (m✝ + 1)
|
||
|
||
case case2
|
||
P : Nat → Prop
|
||
n✝ : Nat
|
||
ih1✝ : P (ackermann (n✝, 1))
|
||
⊢ P (ackermann (n✝, 1))
|
||
|
||
case case3
|
||
P : Nat → Prop
|
||
n✝ m✝ : Nat
|
||
ih2✝ : P (ackermann (n✝ + 1, m✝))
|
||
ih1✝ : P (ackermann (n✝, ackermann (n✝ + 1, m✝)))
|
||
⊢ P (ackermann (n✝, ackermann (n✝ + 1, m✝)))
|
||
-/
|
||
#guard_msgs in
|
||
example : P (ackermann p) := by
|
||
fun_induction ackermann p
|
||
fail
|
||
|
||
/--
|
||
error: Failed: `fail` tactic was invoked
|
||
case case1
|
||
P : Nat → Prop
|
||
m✝ : Nat
|
||
⊢ P (m✝ + 1)
|
||
|
||
case case2
|
||
P : Nat → Prop
|
||
n✝ : Nat
|
||
⊢ P (ackermann (n✝, 1))
|
||
|
||
case case3
|
||
P : Nat → Prop
|
||
n✝ m✝ : Nat
|
||
⊢ P (ackermann (n✝, ackermann (n✝ + 1, m✝)))
|
||
-/
|
||
#guard_msgs in
|
||
example : P (ackermann p) := by
|
||
fun_cases ackermann p
|
||
fail
|
||
|
||
/--
|
||
error: unsolved goals
|
||
case case1
|
||
P : Nat → Prop
|
||
n m m✝ : Nat
|
||
⊢ P (m✝ + 1)
|
||
|
||
case case2
|
||
P : Nat → Prop
|
||
n m n✝ : Nat
|
||
ih1✝ : P (ackermann (n✝, 1))
|
||
⊢ P (ackermann (n✝, 1))
|
||
|
||
case case3
|
||
P : Nat → Prop
|
||
n m n✝ m✝ : Nat
|
||
ih2✝ : P (ackermann (n✝ + 1, m✝))
|
||
ih1✝ : P (ackermann (n✝, ackermann (n✝ + 1, m✝)))
|
||
⊢ P (ackermann (n✝, ackermann (n✝ + 1, m✝)))
|
||
-/
|
||
#guard_msgs in
|
||
example : P (ackermann (n, m)) := by
|
||
fun_induction ackermann (n, m)
|
||
|
||
/--
|
||
error: unsolved goals
|
||
case case1
|
||
P : Nat → Prop
|
||
n m m✝ : Nat
|
||
⊢ P (m✝ + 1)
|
||
|
||
case case2
|
||
P : Nat → Prop
|
||
n m n✝ : Nat
|
||
⊢ P (ackermann (n✝, 1))
|
||
|
||
case case3
|
||
P : Nat → Prop
|
||
n m n✝ m✝ : Nat
|
||
⊢ P (ackermann (n✝, ackermann (n✝ + 1, m✝)))
|
||
-/
|
||
#guard_msgs in
|
||
example : P (ackermann (n, m)) := by
|
||
fun_cases ackermann (n, m)
|
||
|
||
-- Testing Generalization:
|
||
|
||
/--
|
||
error: unsolved goals
|
||
case case1
|
||
P : Nat → Prop
|
||
n m m✝ : Nat
|
||
⊢ P (ackermann (n, m))
|
||
|
||
case case2
|
||
P : Nat → Prop
|
||
n m n✝ : Nat
|
||
⊢ P (ackermann (n, m))
|
||
|
||
case case3
|
||
P : Nat → Prop
|
||
n m n✝ m✝ : Nat
|
||
⊢ P (ackermann (n, m))
|
||
-/
|
||
#guard_msgs in
|
||
example : P (ackermann (n, m)) := by
|
||
fun_cases ackermann (n+n, m)
|
||
|
||
end Ex1
|
||
|
||
namespace Ex2
|
||
|
||
variable (P : Nat → Prop)
|
||
|
||
def ackermann : Nat → Nat → Nat
|
||
| 0, m => m + 1
|
||
| n+1, 0 => ackermann n 1
|
||
| n+1, m+1 => ackermann n (ackermann (n + 1) m)
|
||
termination_by n m => (n, m)
|
||
|
||
/--
|
||
error: unsolved goals
|
||
case case1
|
||
P : Nat → Prop
|
||
m✝ : Nat
|
||
⊢ P (m✝ + 1)
|
||
|
||
case case2
|
||
P : Nat → Prop
|
||
n✝ : Nat
|
||
ih1✝ : P (ackermann n✝ 1)
|
||
⊢ P (ackermann n✝ 1)
|
||
|
||
case case3
|
||
P : Nat → Prop
|
||
n✝ m✝ : Nat
|
||
ih2✝ : P (ackermann (n✝ + 1) m✝)
|
||
ih1✝ : P (ackermann n✝ (ackermann (n✝ + 1) m✝))
|
||
⊢ P (ackermann n✝ (ackermann (n✝ + 1) m✝))
|
||
-/
|
||
#guard_msgs in
|
||
example : P (ackermann n m) := by
|
||
fun_induction ackermann n m
|
||
|
||
/--
|
||
error: Expected fully applied application of 'ackermann' with 2 arguments, but found 1 arguments
|
||
-/
|
||
#guard_msgs in
|
||
example : P (ackermann n m) := by
|
||
fun_induction ackermann n
|
||
|
||
end Ex2
|
||
|
||
namespace Ex3
|
||
|
||
variable (P : List α → Prop)
|
||
|
||
def ackermann {α} (inc : List α) : List α → List α → List α
|
||
| [], ms => ms ++ inc
|
||
| _::ns, [] => ackermann inc ns inc
|
||
| n::ns, _::ms => ackermann inc ns (ackermann inc (n::ns) ms)
|
||
termination_by ns ms => (ns, ms)
|
||
|
||
/--
|
||
error: unsolved goals
|
||
case case1
|
||
α : Type u_1
|
||
P : List α → Prop
|
||
inc ms✝ : List α
|
||
⊢ P (ms✝ ++ inc)
|
||
|
||
case case2
|
||
α : Type u_1
|
||
P : List α → Prop
|
||
inc : List α
|
||
head✝ : α
|
||
ns✝ : List α
|
||
ih1✝ : P (ackermann inc ns✝ inc)
|
||
⊢ P (ackermann inc ns✝ inc)
|
||
|
||
case case3
|
||
α : Type u_1
|
||
P : List α → Prop
|
||
inc : List α
|
||
n✝ : α
|
||
ns✝ : List α
|
||
head✝ : α
|
||
ms✝ : List α
|
||
ih2✝ : P (ackermann inc (n✝ :: ns✝) ms✝)
|
||
ih1✝ : P (ackermann inc ns✝ (ackermann inc (n✝ :: ns✝) ms✝))
|
||
⊢ P (ackermann inc ns✝ (ackermann inc (n✝ :: ns✝) ms✝))
|
||
-/
|
||
#guard_msgs in
|
||
example : P (ackermann inc n m) := by
|
||
fun_induction ackermann inc n m
|
||
|
||
/--
|
||
error: Expected fully applied application of 'ackermann' with 4 arguments, but found 3 arguments
|
||
-/
|
||
#guard_msgs in
|
||
example : P (ackermann inc n m) := by
|
||
fun_induction ackermann inc n
|
||
|
||
/--
|
||
error: Expected fully applied application of 'ackermann' with 4 arguments, but found 2 arguments
|
||
-/
|
||
#guard_msgs in
|
||
example : P (ackermann inc n m) := by
|
||
fun_induction ackermann inc
|
||
|
||
end Ex3
|
||
|
||
namespace Structural
|
||
|
||
variable (P : Nat → Prop)
|
||
|
||
def fib : Nat → Nat
|
||
| 0 => 0
|
||
| 1 => 1
|
||
| n+2 => fib n + fib (n+1)
|
||
termination_by structural x => x
|
||
|
||
/--
|
||
error: Failed: `fail` tactic was invoked
|
||
case case1
|
||
P : Nat → Prop
|
||
⊢ P 0
|
||
|
||
case case2
|
||
P : Nat → Prop
|
||
⊢ P 1
|
||
|
||
case case3
|
||
P : Nat → Prop
|
||
n✝ : Nat
|
||
ih2✝ : P (fib n✝)
|
||
ih1✝ : P (fib (n✝ + 1))
|
||
⊢ P (fib n✝ + fib (n✝ + 1))
|
||
-/
|
||
#guard_msgs in
|
||
example : P (fib n) := by
|
||
fun_induction fib n
|
||
fail
|
||
|
||
example : n ≤ fib (n + 2) := by
|
||
fun_induction fib n
|
||
case case1 => simp [fib]
|
||
case case2 => simp [fib]
|
||
case case3 n ih1 ih2 => simp_all [fib]; omega
|
||
|
||
example : n ≤ fib (n + 2) := by
|
||
fun_induction fib n with
|
||
| case1 | case2 => simp [fib]
|
||
| case3 => simp_all [fib]; omega
|
||
|
||
|
||
end Structural
|
||
|
||
namespace StructuralWithOmittedParam
|
||
|
||
variable (P : Nat → Prop)
|
||
|
||
variable (inc : Nat)
|
||
def fib : Nat → Nat
|
||
| 0 => 0
|
||
| 1 => inc
|
||
| n+2 => fib n + fib (n+1)
|
||
termination_by structural x => x
|
||
|
||
/--
|
||
info: StructuralWithOmittedParam.fib.induct (motive : Nat → Prop) (case1 : motive 0) (case2 : motive 1)
|
||
(case3 : ∀ (n : Nat), motive n → motive (n + 1) → motive n.succ.succ) (a✝ : Nat) : motive a✝
|
||
-/
|
||
#guard_msgs in
|
||
#check fib.induct -- NB: No inc showing up
|
||
|
||
/--
|
||
error: Failed: `fail` tactic was invoked
|
||
case case1
|
||
P : Nat → Prop
|
||
inc : Nat
|
||
⊢ P (fib 2 0)
|
||
|
||
case case2
|
||
P : Nat → Prop
|
||
inc : Nat
|
||
⊢ P (fib 2 1)
|
||
|
||
case case3
|
||
P : Nat → Prop
|
||
inc n✝ : Nat
|
||
ih2✝ : P (fib 2 n✝)
|
||
ih1✝ : P (fib 2 (n✝ + 1))
|
||
⊢ P (fib 2 n✝.succ.succ)
|
||
-/
|
||
#guard_msgs in
|
||
example : P (fib 2 n) := by
|
||
fun_induction fib 3 n
|
||
fail
|
||
|
||
/--
|
||
error: Failed: `fail` tactic was invoked
|
||
case case1
|
||
P : Nat → Prop
|
||
inc : Nat
|
||
⊢ P 0
|
||
|
||
case case2
|
||
P : Nat → Prop
|
||
inc : Nat
|
||
⊢ P 2
|
||
|
||
case case3
|
||
P : Nat → Prop
|
||
inc n✝ : Nat
|
||
ih2✝ : P (fib 2 n✝)
|
||
ih1✝ : P (fib 2 (n✝ + 1))
|
||
⊢ P (fib 2 n✝ + fib 2 (n✝ + 1))
|
||
-/
|
||
#guard_msgs in
|
||
example : P (fib 2 n) := by
|
||
fun_induction fib _ n
|
||
fail
|
||
|
||
end StructuralWithOmittedParam
|
||
|
||
namespace StructuralIndices
|
||
|
||
-- Testing recursion on an indexed data type
|
||
inductive Finn : Nat → Type where
|
||
| fzero : {n : Nat} → Finn n
|
||
| fsucc : {n : Nat} → Finn n → Finn (n+1)
|
||
|
||
def Finn.min (x : Bool) {n : Nat} (m : Nat) : Finn n → (f : Finn n) → Finn n
|
||
| fzero, _ => fzero
|
||
| _, fzero => fzero
|
||
| fsucc i, fsucc j => fsucc (Finn.min (not x) (m + 1) i j)
|
||
termination_by structural i => i
|
||
|
||
def Finn.min' (x : Bool) {n : Nat} (m : Nat) : Finn n → (f : Finn n) → Finn n
|
||
| fzero, _ => fzero
|
||
| _, fzero => fzero
|
||
| fsucc i, fsucc j => fsucc (Finn.min' (not x) (m + 1) i j)
|
||
termination_by structural _ j => j
|
||
|
||
def Finn.min'' (x : Bool) {n : Nat} (m : Nat) : Finn n → (f : Finn n) → Finn n
|
||
| fzero, _ => fzero
|
||
| _, fzero => fzero
|
||
| fsucc i, fsucc j => fsucc (Finn.min'' (not x) (m + 1) i j)
|
||
termination_by structural n
|
||
|
||
def Finn.le : Finn n → Finn n → Bool
|
||
| fzero, _ => true
|
||
| _, fzero => false
|
||
| fsucc i, fsucc j => Finn.le i j
|
||
|
||
theorem Finn.min_le_right₀ : (Finn.min x m i j).le j := by
|
||
induction x, m, i, j using @Finn.min.induct <;> simp_all [Finn.min, Finn.le]
|
||
|
||
theorem Finn.min_le_right : (Finn.min x m i j).le j := by
|
||
fun_induction Finn.min x m i j <;> simp_all [Finn.min, Finn.le]
|
||
|
||
theorem Finn.min_le_right' : (Finn.min' x m i j).le j := by
|
||
fun_induction Finn.min' x m i j <;> simp_all [Finn.min', Finn.le]
|
||
|
||
theorem Finn.min_le_right'' : (Finn.min'' x m i j).le j := by
|
||
fun_induction Finn.min'' x m i j <;> simp_all [Finn.min'', Finn.le]
|
||
|
||
end StructuralIndices
|
||
|
||
namespace Nonrec
|
||
|
||
def foo := 1
|
||
|
||
/-- error: No functional induction theorem for 'foo', or function is mutually recursive -/
|
||
#guard_msgs in
|
||
example : True := by
|
||
fun_induction foo
|
||
|
||
|
||
end Nonrec
|
||
|
||
namespace Mutual
|
||
|
||
inductive Tree (α : Type u) : Type u where
|
||
| node : α → (Bool → List (Tree α)) → Tree α
|
||
|
||
-- Recursion over nested inductive
|
||
|
||
mutual
|
||
def Tree.size : Tree α → Nat
|
||
| .node _ tsf => 1 + size_aux (tsf true) + size_aux (tsf false)
|
||
termination_by structural t => t
|
||
def Tree.size_aux : List (Tree α) → Nat
|
||
| [] => 0
|
||
| t :: ts => size t + size_aux ts
|
||
end
|
||
|
||
/-- error: No functional induction theorem for 'Tree.size', or function is mutually recursive -/
|
||
#guard_msgs in
|
||
example (t : Tree α) : True := by
|
||
fun_induction Tree.size t
|
||
|
||
end Mutual
|