Module docstring
{"# Operation on tuples
We interpret maps ∀ i : Fin n, α i as n-tuples of elements of possibly varying type α i,
(α 0, …, α (n-1)). A particular case is Fin n → α of elements with all the same type.
In this case when α i is a constant map, then tuples are isomorphic (but not definitionally equal)
to Vectors.
Main declarations
There are three (main) ways to consider Fin n as a subtype of Fin (n + 1), hence three (main)
ways to move between tuples of length n and of length n + 1 by adding/removing an entry.
Adding at the start
Fin.succ: Sendi : Fin ntoi + 1 : Fin (n + 1). This is defined in Core.Fin.cases: Induction/recursion principle forFin: To prove a property/define a function for allFin (n + 1), it is enough to prove/define it for0and fori.succfor alli : Fin n. This is defined in Core.Fin.cons: Turn a tuplef : Fin n → αand an entrya : αinto a tupleFin.cons a f : Fin (n + 1) → αby addingaat the start. In general, tuples can be dependent functions, in which casef : ∀ i : Fin n, α i.succanda : α 0. This is a special case ofFin.cases.Fin.tail: Turn a tuplef : Fin (n + 1) → αinto a tupleFin.tail f : Fin n → αby forgetting the start. In general, tuples can be dependent functions, in which caseFin.tail f : ∀ i : Fin n, α i.succ.
Adding at the end
Fin.castSucc: Sendi : Fin ntoi : Fin (n + 1). This is defined in Core.Fin.lastCases: Induction/recursion principle forFin: To prove a property/define a function for allFin (n + 1), it is enough to prove/define it forlast nand fori.castSuccfor alli : Fin n. This is defined in Core.Fin.snoc: Turn a tuplef : Fin n → αand an entrya : αinto a tupleFin.snoc f a : Fin (n + 1) → αby addingaat the end. In general, tuples can be dependent functions, in which casef : ∀ i : Fin n, α i.castSuccanda : α (last n). This is a special case ofFin.lastCases.Fin.init: Turn a tuplef : Fin (n + 1) → αinto a tupleFin.init f : Fin n → αby forgetting the start. In general, tuples can be dependent functions, in which caseFin.init f : ∀ i : Fin n, α i.castSucc.
Adding in the middle
For a pivot p : Fin (n + 1),
* Fin.succAbove: Send i : Fin n to
* i : Fin (n + 1) if i < p,
* i + 1 : Fin (n + 1) if p ≤ i.
* Fin.succAboveCases: Induction/recursion principle for Fin: To prove a property/define a
function for all Fin (n + 1), it is enough to prove/define it for p and for p.succAbove i
for all i : Fin n.
* Fin.insertNth: Turn a tuple f : Fin n → α and an entry a : α into a tuple
Fin.insertNth f a : Fin (n + 1) → α by adding a in position p. In general, tuples can be
dependent functions, in which case f : ∀ i : Fin n, α (p.succAbove i) and a : α p. This is a
special case of Fin.succAboveCases.
* Fin.removeNth: Turn a tuple f : Fin (n + 1) → α into a tuple Fin.removeNth p f : Fin n → α
by forgetting the p-th value. In general, tuples can be dependent functions,
in which case Fin.removeNth f : ∀ i : Fin n, α (succAbove p i).
p = 0 means we add at the start. p = last n means we add at the end.
Miscellaneous
Fin.find p: returns the first indexnwherep nis satisfied, andnoneif it is never satisfied.Fin.append a b: append two tuples.Fin.repeat n a: repeat a tuplentimes.
","In the previous section, we have discussed inserting or removing elements on the left of a
tuple. In this section, we do the same on the right. A difference is that Fin (n+1) is constructed
inductively from Fin n starting from the left, not from the right. This implies that Lean needs
more help to realize that elements belong to the right types, i.e., we need to insert casts at
several places. "}