Zulip Chat Archive
Stream: Is there code for X?
Topic: strong induction without `induction'`
Asei Inoue (Mar 08 2024 at 10:37):
/-- fibonacci sequence -/
def fibonacci : Nat → Nat
| 0 => 0
| 1 => 1
| n + 2 => fibonacci n + fibonacci (n + 1)
/-- linear time fibonacci -/
def fib (n : Nat) : Nat :=
(loop n).1
where
loop : Nat → Nat × Nat
| 0 => (0, 1)
| n + 1 =>
let p := loop n
(p.2, p.1 + p.2)
@[simp]
theorem fib_add (n : Nat) : fib n + fib (n + 1) = fib (n + 2) := by rfl
example : fibonacci = fib := by
ext n
-- strong induction on `n`
-- I would like to know if it is possible to do strong induction, as used here, with `induction` instead of `induction'`.
induction' n using Nat.strong_induction_on with n ih
match n with
| 0 => rfl
| 1 => rfl
| n + 2 => simp_all [fibonacci]
Ruben Van de Velde (Mar 08 2024 at 10:43):
theorem fib_eq : ∀ (n : Nat), fibonacci n = fib n
| 0 => rfl
| 1 => rfl
| n + 2 => by simp_all [fibonacci, fib_eq]
Asei Inoue (Mar 08 2024 at 10:47):
wao!!!
Asei Inoue (Mar 08 2024 at 10:48):
@Ruben Van de Velde Thank you very much! This is surprising...
Notification Bot (Mar 08 2024 at 10:50):
Asei Inoue has marked this topic as resolved.
Ruben Van de Velde (Mar 08 2024 at 10:57):
What happens here is that you can use a theorem while you're proving that same theorem, as long as you finish in finitely many steps. Lean is often smart enough to figure out that termination proof for you, though
Asei Inoue (Mar 08 2024 at 11:22):
In this case, is it possible to get out the inductive assumption without naming the theorem (i.e. with an example)?
def sum (n : Nat) : Rat :=
match n with
| 0 => 0
| n + 1 => (n + 1) + sum n
theorem sum_exp (n : Nat) : sum n = n * (n + 1) / 2 := by
match n with
| 0 => rfl
| n + 1 =>
have ih := sum_exp n
simp [sum, ih]
ring
Notification Bot (Mar 08 2024 at 11:22):
Asei Inoue has marked this topic as unresolved.
Eric Wieser (Mar 08 2024 at 11:41):
The answer to your original question is
induction n using Nat.strong_induction_on with
| h n ih =>
Eric Wieser (Mar 08 2024 at 11:41):
Where h
is the argument name in Nat.strong_induction_on
Kyle Miller (Mar 08 2024 at 16:17):
In the current dev version of Lean 4, there's now a way to do induction on the structure of the function itself, due to @Joachim Breitner.
/-- fibonacci sequence -/
def fibonacci : Nat → Nat
| 0 => 0
| 1 => 1
| n + 2 => fibonacci n + fibonacci (n + 1)
termination_by n => sizeOf n -- trick to get functional induction to work (causes it to be well-founded recursion)
-- In next Lean release. Creates `fibonacci.induct`
derive_functional_induction fibonacci
/-- linear time fibonacci -/
def fib (n : Nat) : Nat :=
(loop n).1
where
loop : Nat → Nat × Nat
| 0 => (0, 1)
| n + 1 =>
let p := loop n
(p.2, p.1 + p.2)
@[simp]
theorem fib_add (n : Nat) : fib n + fib (n + 1) = fib (n + 2) := by rfl
example : fibonacci = fib := by
ext n
induction n using fibonacci.induct
/-
⊢ fibonacci 0 = fib 0
-/
· rfl
/-
⊢ fibonacci 1 = fib 1
-/
· rfl
/-
n : Nat
ih1 : fibonacci n = fib n
ih2 : fibonacci (n + 1) = fib (n + 1)
⊢ fibonacci (Nat.succ (Nat.succ n)) = fib (Nat.succ (Nat.succ n))
-/
next n ih1 ih2 => simp [fibonacci, *]
Kyle Miller (Mar 08 2024 at 16:18):
(@Joachim Breitner Will there be a way to derive functional induction for definitions that are defined with plain recursion? I worked around it here by using an artificial termination_by
.)
Joachim Breitner (Mar 08 2024 at 16:25):
Eric Wieser said:
The answer to your original question is
induction n using Nat.strong_induction_on with | h n ih =>
Or
induction n using Nat.strong_induction_on with
| _ n ih =>
if you don’t care, or
induction n using Nat.strong_induction_on
next n ih =>
if you prefer next
/case
over the with | …
syntax.
Joachim Breitner (Mar 08 2024 at 16:26):
Kyle Miller said:
(Joachim Breitner Will there be a way to derive functional induction for definitions that are defined with plain recursion? I worked around it here by using an artificial
termination_by
.)
Yes! I experimented with that on monday, and it seems doable, and is somewhere on my roadmap not too far down, so it will work eventually.
Last updated: May 02 2025 at 03:31 UTC