Zulip Chat Archive

Stream: mathlib4

Topic: Question about FinEnum


Ian Jauslin (May 26 2023 at 18:23):

If I have a set A : Set Type u that is a finenum hA: FinEnum A, and I have an element of A: a : A, is it possible to access a+1 (the next item in the enumneration, wrapped periodically)?

Kyle Miller (May 26 2023 at 19:21):

I think you could do FinEnum.Equiv.symm (FinEnum.Equiv a + 1), since Fin has wraparound addition

Ian Jauslin (May 26 2023 at 19:43):

Thank you! I'm getting an error: failed to synthesize instance OfNat Does this mean I need to instantiate FinEnum somehow?

Kyle Miller (May 26 2023 at 19:48):

Oh, that's because it doesn't know that the cardinality of A isn't 0... Obviously it isn't because a witnesses that fact, but Lean doesn't know that 1 : Fin (FinEnum.card A) is ok

Kyle Miller (May 26 2023 at 19:55):

Here's a way to give it a hint:

import Mathlib.Data.FinEnum

def Fin.neZero_of (i : Fin n) : NeZero n := Nat.pos_iff_ne_zero.mp (Fin.pos i)⟩

def next [FinEnum α] (a : α) : α :=
  haveI := Fin.neZero_of (FinEnum.Equiv a)
  FinEnum.Equiv.symm (FinEnum.Equiv a + 1)

Kyle Miller (May 26 2023 at 19:56):

(haveI is a way to get Lean to subsitute in the expression where it's used, rather than the definition involving any extra let or fun)

Ian Jauslin (May 26 2023 at 20:18):

Thank you! Because A is Set Type u, I had to redefine next as

def next {A : Set α} (hA: FinEnum A) (a : A) : α :=
  haveI := Fin.neZero_of (hA.Equiv a)
  hA.Equiv.symm (hA.Equiv a + 1)

Does this make sense? Or is there an easier way to proceed that I am missing? (I am not sure at all that I am understanding FinEnum properly: I understood it as A is a set whose elements are of Type u, and A is a FinEnum.)

Kyle Miller (May 26 2023 at 20:24):

That's fine, it's that A coerced to a type is a FinEnum, though it's better to not name instance arguments.

def next {A : Set α} [FinEnum A] (a : A) : A :=
  haveI := Fin.neZero_of (FinEnum.Equiv a)
  FinEnum.Equiv.symm (FinEnum.Equiv a + 1)

It seems like if the expected type is α rather than (the coercion of) A then elaboration goes a little off the rails.

Kyle Miller (May 26 2023 at 20:25):

Here's a workaround if you do want to coerce the result from A to α

def next {A : Set α} [FinEnum A] (a : A) : α :=
  haveI := Fin.neZero_of (FinEnum.Equiv a)
  (FinEnum.Equiv.symm (FinEnum.Equiv a + 1) : A)

That's giving the elaborator a type hint so it can figure out which type FinEnum.Equiv is supposed to use.

Ian Jauslin (May 26 2023 at 20:30):

OK, that seems to work. Thank you so much!


Last updated: Dec 20 2023 at 11:08 UTC