Zulip Chat Archive

Stream: new members

Topic: Converting ordered tuple to fin n → α


Martin C. Martin (May 14 2023 at 20:46):

Given def tuple (n : ℕ) := fin n → Type u, how do ai convert e.g. (5, 23, 99) to a tuple 3?

Yakov Pechersky (May 14 2023 at 20:47):

![5, 23, 99]

Martin C. Martin (May 14 2023 at 20:56):

That's not working for me. I'm in Lean 3, is that a Lean 4 construct?

Martin C. Martin (May 14 2023 at 20:57):

I get that ! expects a bool.

Kevin Buzzard (May 14 2023 at 20:59):

It's Lean 3 and it needs an import. Something like data.vector.notation or something?

Kevin Buzzard (May 14 2023 at 21:01):

import data.matrix.notation

#check ![1,2,3] -- works

Eric Wieser (May 14 2023 at 21:12):

Lean 4 has it too, with the same import

Martin C. Martin (May 15 2023 at 13:15):

Thanks, that works! My definition of tuple should be:

def tuple {α : Type*} (n : ) := fin n  α

Martin C. Martin (May 15 2023 at 13:17):

.

Eric Wieser (May 15 2023 at 13:47):

You'll have an easier time if you put @[reducible] on that

Martin C. Martin (May 16 2023 at 19:17):

How do I expand the notation? For example:

import data.matrix.notation

example : ![3, 5]  ![5, 3] :=
begin
  intro h,
  rw matrix.cons_val_zero at h,
  sorry
end

Martin C. Martin (May 16 2023 at 19:18):

(The rw fails saying there's no instance of matrix.vec_cons in h.)

Eric Wieser (May 16 2023 at 19:24):

That's not what the error says, it says it can't find matrix.vec_cons ?m_3 ?m_4 0

Eric Wieser (May 16 2023 at 19:25):

Which is true, h is of the form matrix.vec_cons ?m_3 ?m_4 = _ without a 0 anywhere

Eric Wieser (May 16 2023 at 19:25):

rw function.ne_iff, makes good progress on the original goal

Martin C. Martin (May 16 2023 at 19:31):

Ah, thanks!

Eric Wieser (May 16 2023 at 19:32):

And dec_trivial can just solve the original goal immediately

Martin C. Martin (May 16 2023 at 19:43):

I hadn't heard of dec_trivial before. Thanks.

Martin C. Martin (May 17 2023 at 11:13):

The type of (3, 5) is ℕ × ℕ. The type of (3, 5, 23) is ℕ × ℕ × ℕ. Is there an existing type for ℕ^n?

Eric Wieser (May 17 2023 at 11:15):

I assume you're not looking for fin n → ℕ, since that's in the title of the thread already

Eric Wieser (May 17 2023 at 11:16):

What type do you want for ℕ^0?

Martin C. Martin (May 17 2023 at 11:16):

I'm wondering what it would take to create a function from ℕ^n to fin n → ℕ.

Martin C. Martin (May 17 2023 at 11:18):

So I could say (3, 5).tup instead of ![3, 5]. The custom function from ℕ^n would probably be worse, but I just want to understand what's involved.

Eric Wieser (May 17 2023 at 11:20):

You can write your own:

@[reducible] def nprod (α : Type*) :   Type*
| 0 := unit
| 1 := α
| (n + 2) := α × nprod (n + 1)

example : ( ×  × ) = nprod  3 := rfl

but I wouldn't recommend it

Eric Wieser (May 17 2023 at 11:20):

Because now you have to deal with three different cases depending on the length of n, rather than just one or two

Martin C. Martin (May 17 2023 at 11:22):

Ok, thanks. I figured if the type didn't already exist, which it seems it doesn't, then that's probably because there are better ways to accomplish the same goal. :)

Eric Wieser (May 17 2023 at 11:23):

This seems to work slightly better as a definition:

def nprod (α : Type*) (n : ) : Type* :=
begin
  cases n,
  { exact unit },
  induction n with n ih,
  { exact α },
  { exact α × ih },
end

#check ((1, 2, 3) : nprod  3)

Eric Wieser (May 17 2023 at 11:26):

And then you can write what you asked for as

def nprod.to_fin {α : Type*} : Π {n}, nprod α n  (fin n  α)
| 0 x := ![]
| 1 x := ![x]
| (n + 2) (x, xs) := matrix.vec_cons x (@nprod.to_fin (n + 1) xs)

#eval nprod.to_fin (show nprod  3, from (1, 2, 3))

Eric Wieser (May 17 2023 at 11:31):

Here's one more way

class has_to_tuple (α : Type*) (n : out_param ) (β : out_param Type*) :=
( to_fun : α  fin n  β)

instance has_to_tuple.base (α : Type*) : has_to_tuple α 1 α :=
{ to_fun := λ a, ![a] }

instance has_to_tuple.prod (α β : Type*) (n : ) [has_to_tuple β n α] : has_to_tuple (α × β) (n + 1) α :=
{ to_fun := λ a, matrix.vec_cons a.1 (has_to_tuple.to_fun a.2) }

#eval has_to_tuple.to_fun (1, 2, 3)  -- ![1, 2, 3]

If you never want to refer to nprod for a variable n, then this should be enough

Martin C. Martin (May 17 2023 at 11:33):

Oh interesting, I haven't used the class stuff much, and hadn't thought of it as an alternative to definition by cases. Cheers.

Eric Wieser (May 17 2023 at 11:34):

Classes are the tool you need if the thing you want to case on is the type itself


Last updated: Dec 20 2023 at 11:08 UTC