Zulip Chat Archive
Stream: lean4
Topic: Bug in `fun_induction` tactic
Frédéric Dupuis (Aug 10 2025 at 03:05):
I found a strange bug in the fun_induction tactic:
def ack : Nat → Nat → Nat
| 0, y => y+1
| x+1, 0 => ack x 1
| x+1, y+1 => ack x (ack (x+1) y)
def ack' : Nat → Nat → Nat
| 0, y => y+1
| x+1, 0 => ack' x 1
| x+1, y+1 => ack' x (ack' (x+1) y)
theorem ack'_eq_ack_works (i x : Nat) : ack' i x = ack i x := by
fun_induction ack with
| case1 => sorry
| case2 => sorry
| case3 => sorry
theorem ack'_eq_ack_fails : ack' = ack := by
ext i x
fun_induction ack with -- Could not find a suitable call of 'ack' in the goal
| case1 => sorry
| case2 => sorry
| case3 => sorry
In the second example, fun_induction fails despite the fact that the goal is identical to the first example. Perhaps @Joachim Breitner could have a quick look?
Kyle Miller (Aug 10 2025 at 03:08):
Adding dsimp only right before fun_induction makes it go through. Maybe it's a metavariable instantiation issue?
Edit: Yes, there are metavariables:
import Lean
def ack : Nat → Nat → Nat
| 0, y => y+1
| x+1, 0 => ack x 1
| x+1, y+1 => ack x (ack (x+1) y)
def ack' : Nat → Nat → Nat
| 0, y => y+1
| x+1, 0 => ack' x 1
| x+1, y+1 => ack' x (ack' (x+1) y)
open Lean Elab Tactic in
elab "show_goal" : tactic => do
withMainContext do
logInfo m!"{(← getMainDecl).type}"
set_option pp.all true
set_option pp.instantiateMVars false
example : ack' = ack := by
ext i x
show_goal -- @Eq.{?u.53900} (?β x) (?f x) (?g x)
dsimp only
show_goal -- @Eq.{?u.53900} Nat (ack' i x) (ack i x)
fun_induction ack with
| case1 => sorry
| case2 => sorry
| case3 => sorry
Joachim Breitner (Aug 11 2025 at 10:30):
Thanks for the report and analysis. Note that fun_induction ack i x works, so the component that is broken is the “guess the function paramters” part. Reported at https://github.com/leanprover/lean4/issues/9844
Last updated: Dec 20 2025 at 21:32 UTC