lean4-htt/tests/elab/fib_correct.lean
Sebastian Graf 40e8f4c5fb
chore: turn on new do elaborator in Core (#12656)
This PR turns on the new `do` elaborator in Init, Lean, Std, Lake and
the testsuite.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 12:38:33 +00:00

40 lines
1.2 KiB
Text

set_option backward.do.legacy false
/-!
This is an example for monadic reasoning.
The eventual goal is to provide a nice user experience for proving `fib_impl n = fib_spec n`
and related goals.
Currently, this file just contains a proof that uses `simp` lemmas to convert the `do` notation
and for loop into a `List.foldl`, and then gives a "functional" proof.
(This is *not* the nice user experience we are aiming for!)
-/
def fib_spec : Nat → Nat
| 0 => 0
| 1 => 1
| n+2 => fib_spec n + fib_spec (n+1)
def fib_impl (n : Nat) := Id.run do
if n = 0 then return 0
let mut a := 0
let mut b := 0
b := b + 1
for _ in [1:n] do
let a' := a
a := b
b := a' + b
return b
theorem fib_correct {n} : fib_impl n = fib_spec n := by
-- The default simp set eliminates the binds generated by `do` notation,
-- and converts the `for` loop into a `List.foldl` over `List.range'`.
simp [fib_impl]
match n with
| 0 => simp [fib_spec]
| n+1 =>
suffices (List.range' 1 n).foldl (fun (a, b) _ ↦ (b, a + b)) (0, 1) =
(fib_spec n, fib_spec (n + 1)) by simp_all
induction n with
| zero => rfl
| succ n ih => simp [fib_spec, List.range'_1_concat, ih]