Zulip Chat Archive

Stream: lean4

Topic: Kernel reduction of Nat.succ is more strict that expected


Joachim Breitner (Sep 06 2024 at 09:46):

I noticed this behavior which surprised me: The kernel reduction of Nat.succ e will try to reduce e even if it’s not actually required by its context, this sets its behavior apart from other constructors like List.cons:

import Lean

def foo : Nat  Nat
  | 0 => 0
  | n+1 => foo n/2
termination_by n => n

elab "#kernel_reduce" t:term : command => Lean.Elab.Command.runTermElabM fun _ => do
  let e  Lean.Elab.Term.elabTermAndSynthesize t none
  let e'  Lean.ofExceptKernelException <| Lean.Kernel.whnf ( Lean.getEnv) ( Lean.getLCtx) e
  Lean.logInfo m!"{e'}"

def slow : Bool := foo 1000000 = 0

/-- error: (kernel) deep recursion detected -/
#guard_msgs in
#kernel_reduce slow

/-- info: [if slow = true then 1 else 2] -/
#guard_msgs in
#kernel_reduce List.cons (if slow then 1 else 2) []

/-- error: (kernel) deep recursion detected -/
#guard_msgs in
#kernel_reduce Nat.succ (if slow then 1 else 2)

This is not really an issue, but part of how the kernel efficiently works with natural numbers, so I’ll just record this fact here for posterity.


Last updated: May 02 2025 at 03:31 UTC