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 end. 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: Sendi : Fin ntoi : Fin (n + 1)ifi < p,i + 1 : Fin (n + 1)ifp ≤ i.
Fin.succAboveCases: Induction/recursion principle forFin: To prove a property/define a function for allFin (n + 1), it is enough to prove/define it forpand forp.succAbove ifor alli : Fin n.Fin.insertNth: Turn a tuplef : Fin n → αand an entrya : αinto a tupleFin.insertNth f a : Fin (n + 1) → αby addingain positionp. In general, tuples can be dependent functions, in which casef : ∀ i : Fin n, α (p.succAbove i)anda : α p. This is a special case ofFin.succAboveCases.Fin.removeNth: Turn a tuplef : Fin (n + 1) → αinto a tupleFin.removeNth p f : Fin n → αby forgetting thep-th value. In general, tuples can be dependent functions, in which caseFin.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 h: returns the first indexi : Fin nwherep iis satisfied given the hypothesis thath : ∃ i, p i.Fin.append a b: append two tuples.Fin.repeat n a: repeat a tuplentimes.
The tail of an n+1 tuple, i.e., its last n entries.
Instances For
Updating a tuple and adding an element at the beginning commute.
As a binary function, Fin.cons is injective.
Adding an element at the beginning of a tuple and then updating it amounts to adding it directly.
Concatenating the first element of a tuple with its tail gives back the original tuple
Equivalence between tuples of length n + 1 and pairs of an element and a tuple of length n
given by separating out the first element of the tuple.
Instances For
Recurse on an n+1-tuple by splitting it into a single element and an n-tuple.
Instances For
Recurse on a tuple by splitting into Fin.elim0 and Fin.cons.
Instances For
Updating the first element of a tuple does not change the tail.
Updating a nonzero element and taking the tail commute.
Append a tuple of length m to a tuple of length n to get a tuple of length m + n.
This is a non-dependent version of Fin.add_cases.
Instances For
Variant of append_left using Fin.castLE instead of Fin.castAdd.
Appending a one-tuple to the left is the same as Fin.cons.
Fin.cons is the same as appending a one-tuple to the left.
Splitting a dependent finite sequence v into an initial part and a final part, and then concatenating these components, produces an identical sequence.
Repeat a m times. For example Fin.repeat 2 ![0, 3, 7] = ![0, 3, 7, 0, 3, 7].
Instances For
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.
Adding an element at the end of an n-tuple, to get an n+1-tuple. The name snoc comes from
cons (i.e., adding an element to the left of a tuple) read in reverse order.
Instances For
Updating a tuple and adding an element at the end commute.
Adding an element at the beginning of a tuple and then updating it amounts to adding it directly.
As a binary function, Fin.snoc is injective.
Concatenating the first element of a tuple with its tail gives back the original tuple
Updating the last element of a tuple does not change the beginning.
Updating an element and taking the beginning commute.
tail and init commute. We state this lemma in a non-dependent setting, as otherwise it
would involve a cast to convince Lean that the two types are equal, making it harder to use.
cons and snoc commute. We state this lemma in a non-dependent setting, as otherwise it
would involve a cast to convince Lean that the two types are equal, making it harder to use.
Appending a one-tuple to the right is the same as Fin.snoc.
Fin.snoc is the same as appending a one-tuple
Equivalence between tuples of length n + 1 and pairs of an element and a tuple of length n
given by separating out the last element of the tuple.
Instances For
Recurse on an n+1-tuple by splitting it its initial n-tuple and its last element.
Instances For
Recurse on a tuple by splitting into Fin.elim0 and Fin.snoc.
Instances For
Define a function on Fin (n + 1) from a value on i : Fin (n + 1) and values on each
Fin.succAbove i j, j : Fin n. This version is elaborated as eliminator and works for
propositions, see also Fin.insertNth for a version without an @[elab_as_elim]
attribute.
Instances For
Alias of Fin.forall_fin_succ.
Alias of Fin.exists_fin_succ.
A finite sequence of properties P holds for {0, ..., m + n - 1} iff it holds separately for both {0, ..., m - 1} and {m, ..., m + n - 1}.
A property holds for all dependent finite sequence of length m + n iff it holds for the concatenation of all pairs of length m sequences and length n sequences.
Analogue of Fin.eq_zero_or_eq_succ for succAbove.
Remove the p-th entry of a tuple.
Instances For
Insert an element into a tuple at a given position. For i = 0 see Fin.cons,
for i = Fin.last n see Fin.snoc. See also Fin.succAboveCases for a version elaborated
as an eliminator.
Instances For
As a binary function, Fin.insertNth is injective.
Equivalence between tuples of length n + 1 and pairs of an element and a tuple of length n
given by separating out the p-th element of the tuple.
This is Fin.insertNth as an Equiv.
Instances For
Note this lemma can only be written about non-dependent tuples as insertNth (last n) = snoc is
not a definitional equality.
A HEq version of Fin.removeNth_removeNth_eq_swap.
Given an (n + 2)-tuple m and two indexes i : Fin (n + 1) and j : Fin (n + 2),
one can remove jth element from m, then remove ith element from the result,
or one can remove (j.succAbove i)th element from m,
then remove (i.predAbove j)th element from the result.
These two operations correspond to removing the same two elements in a different order,
so they result in the same n-tuple.
Fin.find p h returns the smallest index k : Fin n where p k is satisfied,
given that it is satisfied for some k.
Instances For
Fin.find p h satisfies p.
For m : Fin n, if m satisfies p, then Fin.find p h ≤ m.
If a predicate q holds at some x and implies p up to that x, then
the earliest xq such that q xq is at least the smallest xp where p xp.
The stronger version of Fin.find_mono, since this one needs
implication only up to Fin.find _ while the other requires q implying p everywhere.
A weak version of Fin.find_mono_of_le, requiring q implies p everywhere.
If a predicate p holds at some x and agrees with q up to that x, then
their Fin.find agree. The stronger version of Fin.find_congr', since this one needs
agreement only up to Fin.find _ while the other requires p = q.
Usage of this lemma will likely be via obtain ⟨x, hx⟩ := hp; apply Fin.find_congr hx to unify q,
or provide it explicitly with rw [Fin.find_congr (q := q) hx].
A weak version of Fin.find_congr, requiring p = q everywhere.
Sends (g₀, ..., gₙ) to (g₀, ..., op gⱼ gⱼ₊₁, ..., gₙ).
Instances For
To show two sigma pairs of tuples agree, it to show the second elements are related via
Fin.cast.
Fin.sigma_eq_of_eq_comp_cast as an iff.
Π i : Fin 2, α i is equivalent to α 0 × α 1. See also finTwoArrowEquiv for a
non-dependent version and prodEquivPiFinTwo for a version with inputs α β : Type u.