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:
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:
-
lemma rec_add_one {C : ℕ → Sort*} (h0 : C 0) (h : ∀ n, C n → C (n + 1)) (n : ℕ) : Nat.rec h0 h (n + 1) = h n (Nat.rec h0 h n) := rfl "For any type family and given:
-
A base case
- An inductive step function
The recursion principle Nat.rec evaluated at satisfies . This means that the value at is obtained by applying the step function to and the recursively computed value at . " (score: 0.683)
-
theorem rec_eq_recC : @Acc.rec = @Acc.recC := by funext α r motive intro a t induction t with | intro x h ih => dsimp only [recC_intro intro h] congr; funext y hr; exact ih _ hr "The theorem states that the recursive function \texttt{Acc.rec} is equal to \texttt{Acc.recC}. This is shown by using function extensionality and induction on the accessibility predicate. Specifically, for a type , a relation , and a motive, the functions are equal for any accessible element and its proof . The proof proceeds by induction on , showing that the two functions produce the same result by congruence and function extensionality." (score: 0.683)
-
theorem ndrec_eq_ndrecC : @Acc.ndrec = @Acc.ndrecC := by funext α r motive intro a t rw [Acc.ndrec, rec_eq_recC, Acc.ndrecC] "The recursion principle
Acc.ndrecis equal to the computable versionAcc.ndrecCfor accessible elements." (score: 0.679) -
theorem Nat.rec_add_one {C : ℕ → Sort*} (h0 : C 0) (h : ∀ n, C n → C (n + 1)) (n : ℕ) : Nat.rec h0 h (n + 1) = h n (Nat.rec h0 h n) := rfl "For any type family , given a base case and a step function , the recursive computation of at satisfies ." (score: 0.678)
-
@[simp] lemma rec_one {C : ℕ → Sort*} (h0 : C 0) (h : ∀ n, C n → C (n + 1)) : Nat.rec (motive := C) h0 h 1 = h 0 h0 := rfl "For any type family and given:
-
A base case
- An inductive step function
The recursion principle Nat.rec evaluated at one satisfies . This means that starting from the base case , applying the inductive step function once results in . " (score: 0.677)
-
theorem ndrecOn_eq_ndrecOnC : @Acc.ndrecOn = @Acc.ndrecOnC := by funext α r motive intro a t rw [Acc.ndrecOn, rec_eq_recC, Acc.ndrecOnC] "The recursion principle
Acc.ndrecOnis equal to the computable versionAcc.ndrecOnC. This equality holds for any type , relation , and motive." (score: 0.675) -
lemma leRecOn_self {C : ℕ → Sort*} {n} {next : ∀ {k}, C k → C (k + 1)} (x : C n) : (leRecOn n.le_refl next x : C n) = x := leRec_self _ _ "For any type family , natural number , and step function , applying the recursion principle with initial value when yields:
where the result is of type . This establishes the base case for recursion." (score: 0.673) -
lemma not_succ_lt_self : ¬ succ n < n := Nat.not_lt_of_ge n.le_succ "For any natural number , the successor of is not less than , i.e., . This follows from the fact that ." (score: 0.672)
- theorem Nat.rec_one {C : ℕ → Sort*} (h0 : C 0) (h : ∀ n, C n → C (n + 1)) : Nat.rec (motive := C) h0 h 1 = h 0 h0 := rfl "For any type family , base case , and inductive step function , the recursion principle applied to satisfies ." (score: 0.671)
- theorem PFunctor.M.agree'_refl {n : ℕ} (x : M F) : Agree' n x x := by induction' n with _ n_ih generalizing x <;> induction x using PFunctor.M.casesOn' <;> constructor <;> try rfl intros apply n_ih "For any natural number and any element of the M-type (the final coalgebra of a polynomial functor ), the depth- agreement relation holds. That is, any tree is identical to itself up to any depth ." (score: 0.669)
Last updated: Dec 20 2025 at 21:32 UTC