Zulip Chat Archive

Stream: new members

Topic: Fin cast and succ


Malvin Gattinger (Oct 20 2023 at 07:35):

I thought this one should be (true and) easy, but I am stuck.

import Mathlib.Data.Fin.Basic

theorem fin_succ_succ (i : Fin n) : (i + 1 + 1 = i.succ.succ) :=
  by
  apply Fin.eq_of_veq
  simp
  -- why do I now have three cast arrows in the left side?
  sorry

Probably I should not use Fin.eq_of_veq at all? Am I misunderstanding Fin? I am assuming that the = I want to show is within Fin (n+2) right?

Ruben Van de Velde (Oct 20 2023 at 07:45):

It would be easier to investigate if you added the imports needed to make this a #mwe

Malvin Gattinger (Oct 20 2023 at 07:47):

Oh, sorry. I wrongly thought Fin would be available by default.

Eric Wieser (Oct 20 2023 at 07:54):

What's the goal state after the by? I suspect there are coercions in weird places

Joël Riou (Oct 20 2023 at 07:55):

The statement is true, but it seems quite confusing to me. Lean knows that this has to be an equality in Fin (n+2) only by considering the RHS: if you do let j := i + 1 + 1, Lean will not accept this term! The correct way to take the successor of something in Fin is to use the syntax i.succ.
Otherwise, if you really want to prove this, the definition of + in Fin.add is by taking the sum in the natural numbers and then taking the reminder of a division: proving the equality can be quite painful, but simp and linarith can handle it:

theorem fin_succ_succ {n : } (i : Fin n) : i + 1 + 1 = i.succ.succ := by
  ext
  dsimp only [HAdd.hAdd, Add.add, Fin.add]
  simp
  have := i.is_lt
  linarith

Malvin Gattinger (Oct 20 2023 at 08:01):

Right, my mistake was to use i + 1 instead of i.succ in the larger theorem for which I then reached this as a subgoal. Using i.succ instead makes the whole problem go away :tada: Thanks everyone!

Notification Bot (Oct 20 2023 at 08:01):

Malvin Gattinger has marked this topic as resolved.

Notification Bot (Oct 20 2023 at 08:20):

Malvin Gattinger has marked this topic as unresolved.

Malvin Gattinger (Oct 20 2023 at 08:20):

I have another +1 vs succ problem when using vectors. Would you also find this statement confusing, and can I do something else to avoid the coercions? (When does one say coercion and when cast, btw?)

import Mathlib.Data.Vector.Basic

theorem vec_succ (i : Fin n) (ys : Vector α n.succ) : (a :: ys).get (i.succ) = ys.get i :=
  by
  -- Vector.get (a ::ᵥ ys) ↑↑(Fin.succ i) = Vector.get ys ↑↑i
  simp
  -- Vector.get (a ::ᵥ ys) (↑↑i + 1) = Vector.get ys (Fin.castSucc i)
  sorry

Eric Wieser (Oct 20 2023 at 08:29):

That looks very weird; shouldn't the n.succ just be n?

Malvin Gattinger (Oct 20 2023 at 09:55):

Indeed with n instead of n.succ it goes through just with simp, but with a one-item-longer vector it should still be true?

Eric Wieser (Oct 20 2023 at 09:57):

With the one-time longer vector it's a very weird statement

Eric Wieser (Oct 20 2023 at 09:58):

The +1 in your second goal comment is in Fin n which has modular arithmetic

Eric Wieser (Oct 20 2023 at 09:59):

The ↑↑ in your first goal statement is effectively i.succ.val % (n + 2)


Last updated: Dec 20 2023 at 11:08 UTC