Files
lean4/tests/elab/funinduction_generalize.lean
Garmelon 08eb78a5b2 chore: switch to new test/bench suite (#12590)
This PR sets up the new integrated test/bench suite. It then migrates
all benchmarks and some related tests to the new suite. There's also
some documentation and some linting.

For now, a lot of the old tests are left alone so this PR doesn't become
even larger than it already is. Eventually, all tests should be migrated
to the new suite though so there isn't a confusing mix of two systems.
2026-02-25 13:51:53 +00:00

214 lines
5.1 KiB
Lean4
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/-!
Checks the generalization behavior of `fun_induction`.
In particular that it behaves the same as `induction … using ….induct`.
-/
variable (xs ys : List Nat)
variable (P : {α}, List α Prop)
-- We re-define this here to avoid stage0 complications
def zipWith (f : α β γ) : (xs : List α) (ys : List β) List γ
| x::xs, y::ys => f x y :: zipWith f xs ys
| _, _ => []
/--
error: unsolved goals
case case1
xs ys : List Nat
P : {α : Type} → List α → Prop
x✝ : Nat
xs✝ : List Nat
y✝ : Nat
ys✝ : List Nat
ih1✝ : P (xs✝.zip ys✝)
⊢ P ((x✝ :: xs✝).zip (y✝ :: ys✝))
case case2
xs ys : List Nat
P : {α : Type} → List α → Prop
t✝ ys✝ : List Nat
x✝ : ∀ (x : Nat) (xs : List Nat) (y : Nat) (ys : List Nat), t✝ = x :: xs → ys✝ = y :: ys → False
⊢ P (t✝.zip ys✝)
-/
#guard_msgs in
example : P (List.zip xs ys) := by
fun_induction zipWith _ xs ys
/--
error: unsolved goals
case case1
xs ys : List Nat
P : {α : Type} → List α → Prop
x✝ : Nat
xs✝ : List Nat
y✝ : Nat
ys✝ : List Nat
ih1✝ : xs✝.isEmpty = true → P (xs✝.zip ys✝)
h : (x✝ :: xs✝).isEmpty = true
⊢ P ((x✝ :: xs✝).zip (y✝ :: ys✝))
case case2
xs ys : List Nat
P : {α : Type} → List α → Prop
t✝ ys✝ : List Nat
x✝ : ∀ (x : Nat) (xs : List Nat) (y : Nat) (ys : List Nat), t✝ = x :: xs → ys✝ = y :: ys → False
h : t✝.isEmpty = true
⊢ P (t✝.zip ys✝)
-/
#guard_msgs in
example (h : xs.isEmpty) : P (List.zip xs ys) := by
fun_induction zipWith _ xs ys
/--
error: unsolved goals
case case1
xs ys : List Nat
P : {α : Type} → List α → Prop
x✝ : Nat
xs✝ : List Nat
y✝ : Nat
ys✝ : List Nat
ih1✝ : xs✝.isEmpty = true → P (xs✝.zip ys)
h : (x✝ :: xs✝).isEmpty = true
⊢ P ((x✝ :: xs✝).zip ys)
case case2
xs ys : List Nat
P : {α : Type} → List α → Prop
t✝ ys✝ : List Nat
x✝ : ∀ (x : Nat) (xs : List Nat) (y : Nat) (ys : List Nat), t✝ = x :: xs → ys✝ = y :: ys → False
h : t✝.isEmpty = true
⊢ P (t✝.zip ys)
-/
#guard_msgs in
example (h : xs.isEmpty) : P (List.zip xs ys) := by
fun_induction zipWith _ xs (ys.take 2)
/--
error: unsolved goals
case case1
xs ys : List Nat
P : {α : Type} → List α → Prop
x✝ : Nat
xs✝ : List Nat
y✝ : Nat
ys✝ : List Nat
ih1✝ : xs✝.isEmpty = true → P (xs✝.zip ys)
h : (x✝ :: xs✝).isEmpty = true
⊢ P ((x✝ :: xs✝).zip ys)
case case2
xs ys : List Nat
P : {α : Type} → List α → Prop
t✝ ys✝ : List Nat
x✝ : ∀ (x : Nat) (xs : List Nat) (y : Nat) (ys : List Nat), t✝ = x :: xs → ys✝ = y :: ys → False
h : t✝.isEmpty = true
⊢ P (t✝.zip ys)
-/
#guard_msgs in
example (h : xs.isEmpty) : P (List.zip xs ys) := by
induction xs, ys.take 2 using zipWith.induct
/--
error: unsolved goals
case case1
xs ys : List Nat
P : {α : Type} → List α → Prop
h : xs.isEmpty = true
x✝ : Nat
xs✝ : List Nat
y✝ : Nat
ys✝ : List Nat
ih1✝ : P (xs.zip ys✝)
⊢ P (xs.zip (y✝ :: ys✝))
case case2
xs ys : List Nat
P : {α : Type} → List α → Prop
h : xs.isEmpty = true
t✝ ys✝ : List Nat
x✝ : ∀ (x : Nat) (xs : List Nat) (y : Nat) (ys : List Nat), t✝ = x :: xs → ys✝ = y :: ys → False
⊢ P (xs.zip ys✝)
-/
#guard_msgs in
example (h : xs.isEmpty) : P (List.zip xs ys) := by
fun_induction zipWith _ (xs.take 2) ys
/--
error: unsolved goals
case case1
xs ys : List Nat
P : {α : Type} → List α → Prop
h : xs.isEmpty = true
x✝ : Nat
xs✝ : List Nat
y✝ : Nat
ys✝ : List Nat
ih1✝ : P (xs.zip ys✝)
⊢ P (xs.zip (y✝ :: ys✝))
case case2
xs ys : List Nat
P : {α : Type} → List α → Prop
h : xs.isEmpty = true
t✝ ys✝ : List Nat
x✝ : ∀ (x : Nat) (xs : List Nat) (y : Nat) (ys : List Nat), t✝ = x :: xs → ys✝ = y :: ys → False
⊢ P (xs.zip ys✝)
-/
#guard_msgs in
example (h : xs.isEmpty) : P (List.zip xs ys) := by
induction xs.take 2, ys using zipWith.induct
/--
error: unsolved goals
case case1
P : {α : Type} → List α → Prop
x✝ : Nat
xs✝ : List Nat
y✝ : Nat
ys✝ : List Nat
ih1✝ : ∀ (xs : List Nat), xs.isEmpty = true → P (xs.zip ys✝)
xs : List Nat
h : xs.isEmpty = true
⊢ P (xs.zip (y✝ :: ys✝))
case case2
P : {α : Type} → List α → Prop
t✝ ys✝ : List Nat
x✝ : ∀ (x : Nat) (xs : List Nat) (y : Nat) (ys : List Nat), t✝ = x :: xs → ys✝ = y :: ys → False
xs : List Nat
h : xs.isEmpty = true
⊢ P (xs.zip ys✝)
-/
#guard_msgs in
example (h : xs.isEmpty) : P (List.zip xs ys) := by
fun_induction zipWith _ (xs.take 2) ys generalizing xs
/--
error: unsolved goals
case case1
P : {α : Type} → List α → Prop
x✝ : Nat
xs✝ : List Nat
y✝ : Nat
ys✝ : List Nat
ih1✝ : ∀ (xs : List Nat), xs.isEmpty = true → P (xs.zip ys✝)
xs : List Nat
h : xs.isEmpty = true
⊢ P (xs.zip (y✝ :: ys✝))
case case2
P : {α : Type} → List α → Prop
t✝ ys✝ : List Nat
x✝ : ∀ (x : Nat) (xs : List Nat) (y : Nat) (ys : List Nat), t✝ = x :: xs → ys✝ = y :: ys → False
xs : List Nat
h : xs.isEmpty = true
⊢ P (xs.zip ys✝)
-/
#guard_msgs in
example (h : xs.isEmpty) : P (List.zip xs ys) := by
induction xs.take 2, ys using zipWith.induct generalizing xs