Zulip Chat Archive

Stream: lean4

Topic: n : Nat defeq to n+1


Kenny Lau (Aug 09 2025 at 18:28):

Is it possible to make an expression n with elaborated type Nat such that n is defeq to n+1?

Aaron Liu (Aug 09 2025 at 18:32):

only in an inconsistent context

Kenny Lau (Aug 09 2025 at 18:32):

yes, in an inconsistent context

Aaron Liu (Aug 09 2025 at 18:32):

I think it's probably possible

Robin Arnez (Aug 09 2025 at 18:34):

Well,

example (n : Nat) : haveI : Add Nat := fun a _ => a⟩;
    n = n + 1 :=
  rfl

but I don't think the same is possible if you said n.succ

Aaron Liu (Aug 09 2025 at 18:41):

theorem k (h : False) :  n, n = n + 1 :=
  ⟨@Acc.rec Nat (fun _ _ => False) (fun _ _ => Nat)
    (fun x hx ih => ih x h + 1) 0 h.elim, by
  conv => lhs; rhs; change Acc.intro 0 h.elim

/--
info: fun h =>
  Exists.intro (Acc.rec (fun x hx ih => Nat.succ (ih x h)) (False.rec (fun x => Acc (fun x x => False) 0) h))
    (Eq.refl
      (Acc.rec (fun x hx ih => Nat.succ (ih x h))
          (False.rec (fun x => ∀ (y : Nat), False → Acc (fun x x => False) y) h 0 h)).succ)
-/
#guard_msgs in
#reduce (proofs := true) (types := true) k

Aaron Liu (Aug 09 2025 at 18:41):

for some reason rfl didn't work

Aaron Liu (Aug 09 2025 at 18:41):

but these are all defeq transformations

Aaron Liu (Aug 09 2025 at 18:43):

you can even see #reduce gives you Eq.refl

Kyle Miller (Aug 09 2025 at 18:47):

It might be a little more compelling if it weren't in an Exists.

However, I'm getting a kernel type error with this:

noncomputable def bad_n (h : False) : Nat :=
  @Acc.rec Nat (fun _ _ => False) (fun _ _ => Nat)
    (fun x _ ih => ih x h.elim + 1) 0 (Acc.intro 0 h.elim)

example (h : False) :
    bad_n h = bad_n h + 1 := by
  delta bad_n
  conv => lhs; rhs; change Acc.intro 0 h.elim

Aaron Liu (Aug 09 2025 at 18:50):

theorem k (h : False) :
  @Acc.rec Nat (fun _ _ => False) (fun _ _ => Nat)
    (fun x hx ih => ih x h + 1) 0 h.elim =
  @Acc.rec Nat (fun _ _ => False) (fun _ _ => Nat)
    (fun x hx ih => ih x h + 1) 0 h.elim + 1 := by
  conv => lhs; rhs; change Acc.intro 0 h.elim

/--
info: fun h =>
  Eq.refl
    (Acc.rec (fun x hx ih => Nat.succ (ih x h))
        (False.rec (fun x => ∀ (y : Nat), False → Acc (fun x x => False) y) h 0 h)).succ
-/
#guard_msgs in
#reduce (proofs := true) (types := true) k

Aaron Liu (Aug 09 2025 at 18:50):

you have to be careful around the kernel here

Aaron Liu (Aug 09 2025 at 18:52):

since it can sometimes just decide not to iota reduce your Acc.rec

Kenny Lau (Aug 09 2025 at 20:15):

i mean, acc.rec is well-known to be evil

Parth Shastri (Aug 09 2025 at 22:00):

noncomputable def inf : Acc (fun _ _ => True) ()  Nat := Acc.rec fun _ _ ih => ih () ⟨⟩ + 1

example : inf h = inf h + 1 := @id (inf h = inf ⟨_, fun _ _ => h) rfl
-- example : inf h = inf h + 1 := rfl -- fails

-- https://arxiv.org/abs/1911.08174
def F : Prop :=  p, (p  p)  p
def δ (z : F) : F := fun p η => η (z (F  F) id z p η)
def ω (h :  p q : Prop, p = q) : F := fun p _ => h (F  F) p  δ
def Ω (h :  p q : Prop, p = q) : Acc (fun _ _ => True) () := δ (ω h) (Acc (fun _ _ => True) ()) (⟨_, fun _ _ => ·⟩)

example : inf (Ω h) = inf (Ω h) + 1 := rfl

Aaron Liu (Aug 09 2025 at 22:06):

oh you can make it run for a while

set_option maxRecDepth 10000 in
example : inf (Ω h) = inf (Ω h) + 1000 := rfl

Aaron Liu (Aug 09 2025 at 22:07):

oh you can make it run forever

set_option maxRecDepth 0 in
example {n : Nat} : inf (Ω h) = inf (Ω h) + n := rfl

Kenny Lau (Aug 09 2025 at 22:08):

wow, someone dug into the arXivs

Aaron Liu (Aug 09 2025 at 22:09):

I think I remember seeing something like this before

Aaron Liu (Aug 09 2025 at 22:20):

oh I found it: #general > Normalization fails in lean @ 💬

Wuyang (Aug 11 2025 at 18:42):

Interesting exploration of how inconsistent contexts and Acc.rec tricks can yield n = n + 1 in Lean. You may try searching on LeanFinder: www.leanfinder.org.

Wuyang (Aug 11 2025 at 18:42):

@leanfinder Lean proofs and examples showing n = n + 1 via inconsistent contexts, Acc.rec, and normalization quirks.

leanfinder (Aug 11 2025 at 18:42):

Here’s what I found:

The recursion principle Nat.rec evaluated at n+1n+1 satisfies Nat.rec h0 h (n+1)=h(n,Nat.rec h0 h n)\text{Nat.rec}\ h_0\ h\ (n+1) = h(n, \text{Nat.rec}\ h_0\ h\ n). This means that the value at n+1n+1 is obtained by applying the step function hh to nn and the recursively computed value at nn. " (score: 0.683)

The recursion principle Nat.rec evaluated at one satisfies Nat.rec h0 h 1=h(0,h0)\text{Nat.rec}\ h_0\ h\ 1 = h(0, h_0). This means that starting from the base case h0h_0, applying the inductive step function once results in h(0,h0)h(0, h_0). " (score: 0.677)


Last updated: Dec 20 2025 at 21:32 UTC