Zulip Chat Archive
Stream: lean4
Topic: weird nat unification behaviour
Edward van de Meent (Jun 03 2025 at 09:31):
i came across the following:
inductive foo : Nat → Type _ where
| zero : foo 0
| succ n : foo n → foo (n + 1)
example (x : foo 5) : x = x := by
cases x with
| succ _ a =>
/-
a : foo (0 + 4)
⊢ foo.succ (0 + 4) a = foo.succ (0 + 4) a
-/
cases a with
| succ _ b =>
/-
b : foo (0 + 3)
⊢ foo.succ (0 + 4) (foo.succ (0 + 3) b) = foo.succ (0 + 4) (foo.succ (0 + 3) b)
-/
sorry
for whatever reason, lean uses 0+n here rather than just n. is there a reason for this?
I did a simple test unifying 5 with Nat.succ ?m and it doesn't display this behaviour:
import Lean.Expr
import Lean.Meta
open Lean Meta
run_meta do
let four? ← mkFreshExprMVar (.some (.const ``Nat []))
four?.mvarId!.setUserName `four
let five? ← mkAppM ``Nat.succ #[four?]
let five : Expr := .lit (.natVal 5)
logInfo m!"five?:{five?}, five:{five}" -- five?:Nat.succ ?four, five:5
let b ← isDefEq five? five
logInfo m!"isDefEq:{b}" -- isDefEq:true
let four ← instantiateMVars four?
logInfo m!"four:{four}" -- four:4
i have two questions:
- What is the mechanism that causes this to happen?
- Is this behaviour chosen on purpose, and if so, why?
Jovan Gerbscheid (Jun 03 2025 at 11:53):
That's very strange. It's specifically the cases tactic doing this. It behaves normally with match.
Last updated: Dec 20 2025 at 21:32 UTC