Zulip Chat Archive
Stream: general
Topic: Canonical inductive types with 0,1,2,3,4 terms
Johan Commelin (Jul 22 2020 at 10:22):
We have empty
and unit
, which seem quite unquestionable. For an inductive type with two elements, we have bool
, although it might be considered abuse to treat it as an "arbitrary" type with two elements. How about types with 3 or 4 elements?
Should we have inductive three | a | b | c
and inductive four | a | b | c | d
?
Kenny Lau (Jul 22 2020 at 10:24):
why not an inductive type with n
elements?
Kenny Lau (Jul 22 2020 at 10:24):
(fin2
, egō tē videō)
Kenny Lau (Jul 22 2020 at 10:25):
/-- An alternate definition of `fin n` defined as an inductive type
instead of a subtype of `nat`. This is useful for its induction
principle and different definitional equalities. -/
inductive fin2 : ℕ → Type
| fz {n} : fin2 (succ n)
| fs {n} : fin2 n → fin2 (succ n)
Kenny Lau (Jul 22 2020 at 10:25):
Kenny Lau (Jul 22 2020 at 10:33):
or, even better, just use the recursor for fin
Kenny Lau (Jul 22 2020 at 10:33):
who cares if it's inductive by definition
Kevin Buzzard (Jul 22 2020 at 10:42):
fin
and fin2
both satisfy the spec for fin
so speaking as a mathematician I would say I'd be happy with either of them, but to make my life easy can we just fix upon one?
Kevin Buzzard (Jul 22 2020 at 10:43):
This is another notation question. Will we be able to tell the equation compiler in Lean 4 "and let me use those cool bars, here's your recursor"?
Kevin Buzzard (Jul 22 2020 at 10:44):
I think the canonical type with no terms should be 37
Kevin Buzzard (Jul 22 2020 at 10:44):
there is a problem here right? All those pesky computer scientists think that the canonical type with 0 terms is pempty
, but with our new system it's also fin3 0
right?
Bryan Gin-ge Chen (Jul 22 2020 at 10:46):
I thought only mathematicians knew what "canonical" meant...
Johan Commelin (Jul 22 2020 at 10:51):
Kenny Lau said:
or, even better, just use the recursor for
fin
As far as I know that means you will get a really ugly match expression, if you want the map fin 4 → polynomial nat
that sends
0
to 0
,
1
to X^2 + 3
,
2
to X + 5
, and
3
to X^37 + 57 * X + 1
Johan Commelin (Jul 22 2020 at 10:52):
Maybe I can abuse that nat
is inductive by definition...
Kenny Lau (Jul 22 2020 at 10:52):
then make it more beautiful
Johan Commelin (Jul 22 2020 at 10:53):
Sure, but it requires writing dedicated code for fin 2
, fin 3
, fin 4
, right? There's not a generic thing I can do, I guess.
Reid Barton (Jul 22 2020 at 11:15):
data.matrix.notation
?
Kenny Lau (Jul 22 2020 at 11:21):
import data.fin
@[elab_as_eliminator]
def const_n_ary {C : Sort*} (x : C) (n : ℕ) : (nat.rec_on n C (λ n ih, C → ih) : Sort*) :=
nat.rec_on n x $ λ n ih _, ih
@[elab_as_eliminator]
def fin.magic (n : ℕ) {C : Sort*} : fin n → (nat.rec_on n C (λ n ih, C → ih) : Sort*) :=
nat.rec_on n fin.elim0 $ λ n ih i x, fin.cases (const_n_ary x n) ih i
#eval (fin.magic 4 0 (-1729) (-314) (2718) (37) : ℤ) -- -1729
#eval (fin.magic 4 1 (-1729) (-314) (2718) (37) : ℤ) -- -314
#eval (fin.magic 4 2 (-1729) (-314) (2718) (37) : ℤ) -- 2718
#eval (fin.magic 4 3 (-1729) (-314) (2718) (37) : ℤ) -- 37
Johan Commelin (Jul 22 2020 at 11:21):
Ooh, that's a nice idea!
Kenny Lau (Jul 22 2020 at 11:22):
oh did I just wait 30 minutes rewriting what is already in mathlib
Eric Wieser (Jul 30 2020 at 21:25):
I think my question relates to this thread, since it's about matching against fin N
...
Aside from the fact this construction is very contrived, is there any way I can golf out the repeated apply_instance?
def blade : fin 4 → Type
| ⟨0, _⟩ := ℝ -- scalar
| ⟨1, _⟩ := ℝ × ℝ × ℝ
| ⟨2, _⟩ := ℝ × ℝ × ℝ
| ⟨3, _⟩ := ℝ -- psuedo-scalar
| ⟨n + 4, _⟩ := by {exfalso, linarith}
instance : Π i, add_comm_group (blade i)
| ⟨0, _⟩ := by {unfold blade, apply_instance}
| ⟨1, _⟩ := by {unfold blade, apply_instance}
| ⟨2, _⟩ := by {unfold blade, apply_instance}
| ⟨3, _⟩ := by {unfold blade, apply_instance}
| ⟨n + 4, h⟩ := by {exfalso, linarith}
Kevin Buzzard (Jul 30 2020 at 23:19):
What happens if you try to derive add_comm_group in the definition of blade?
Eric Wieser (Jul 31 2020 at 00:04):
How do you mean?
Alex J. Best (Jul 31 2020 at 00:41):
I don't think it works in this case but you can do
@[derive add_comm_group]
def myint := int
to automate later doing
instance : add_comm_group myint := by unfold myint; apply_instance
Utensil Song (Jul 31 2020 at 13:11):
Kevin Buzzard said:
What happens if you try to derive add_comm_group in the definition of blade?
To literally answer the question, what happens is:
tactic.mk_instance failed to generate instance for
add_comm_group
(a.cases_on
(λ (a_val : ℕ) (a_is_lt : a_val < 4),
a_val.cases_on (λ (a_is_lt : 0 < 4), id_rhs Type ℝ)
(λ (a_val : ℕ) (a_is_lt : a_val.succ < 4),
a_val.cases_on (λ (a_is_lt : 1 < 4), id_rhs Type ℝ³)
(λ (a_val : ℕ) (a_is_lt : a_val.succ.succ < 4),
a_val.cases_on (λ (a_is_lt : 2 < 4), id_rhs Type ℝ³)
(λ (a_val : ℕ) (a_is_lt : a_val.succ.succ.succ < 4),
a_val.cases_on (λ (a_is_lt : 3 < 4), id_rhs Type ℝ)
(λ (a_val : ℕ) (a_is_lt : a_val.succ.succ.succ.succ < 4), id_rhs Type (false.rec Type _))
a_is_lt)
a_is_lt)
a_is_lt)
a_is_lt))
Utensil Song (Jul 31 2020 at 13:12):
Sorry I used
notation `ℝ³` := ℝ × ℝ × ℝ`
hence the difference of error message
Last updated: Dec 20 2023 at 11:08 UTC