Zulip Chat Archive
Stream: lean4
Topic: Custom default recursors?
François G. Dorais (May 07 2022 at 20:20):
When declaring an inductive type the recursor generated by Lean doesn't use common notation. Indeed, these always come after the inductive definition. For example, with Nat
, the induction tactic does this:
example (n : Nat) : n + 1 - 1 = n := by
induction n with
| zero => sorry -- goal: Nat.zero + 1 - 1 = Nat.zero
| succ n ih => sorry -- goal: Nat.succ n + 1 - 1 = Nat.succ n
In such cases, I add a custom recursor like this:
protected def Nat.recAux.{u} {motive : Nat → Sort u} (zero : motive 0) (succ : (n : Nat) → motive n → motive (n+1)) : (t : Nat) → motive t
| 0 => zero
| n+1 => succ n (Nat.recAux zero succ n)
example (n : Nat) : n + 1 - 1 = n := by
induction n using Nat.recAux with
| zero => sorry -- goal: 0 + 1 - 1 = 0
| succ n ih => sorry -- goal: n + 1 + 1 - 1 = n + 1
Once recAux
and friends are available, there is not much further uses for the original rec
. It would be nice to be able to customize the default recursor to so we can use recAux
without specifying induction ... using ...
. (The original recursor would still be available by using
the original recursor.) The main drawback is that the exact form of rec
can be deduced from the inductive definition but this is not true for custom default recursors.
It would also be nice to be able to specify default recursors to use for double induction. For example, I often use this diagonal recursor:
protected def Nat.recDiag.{u} {motive : Nat → Nat → Sort u}
(zero_zero : motive 0 0)
(succ_zero : (x : Nat) → motive x 0 → motive (x + 1) 0)
(zero_succ : (y : Nat) → motive 0 y → motive 0 (y + 1))
(succ_succ : (x y : Nat) → motive x y → motive (x + 1) (y + 1)) :
(x y : Nat) → motive x y := sorry
It doesn't necessarily make sense to make this a global default for double induction, but it would be useful as a local default in some cases.
All these examples are about Nat
but there are other use cases.
So, I ask:
- Is this something that other people would use?
- Would this be easy or hard to implement?
Eric Wieser (May 07 2022 at 20:26):
Another place this comes up is for cases when a definition is changed to something equivalent but with a different built in recursor (eg consider someone changing int
to be the quotient definition that Kevin talks about); it would be nice to be able to provide a custom recursor equivalent to the old one, and make it the default so that downstream inductions don't break
Last updated: Dec 20 2023 at 11:08 UTC