The finite type with n
elements
fin n
is the type whose elements are natural numbers smaller than n
.
This file expands on the development in the core library.
Main definitions
Induction principles
fin_zero.elim
: Elimination principle for the empty setfin 0
, generalizesfin.elim0
.fin.succ_rec
: DefineC n i
by induction oni : fin n
interpreted as(0 : fin (n - i)).succ.succ…
. This function has two arguments:H0 n
defines0
-th elementC (n+1) 0
of an(n+1)
-tuple, andHs n i
defines(i+1)
-st element of(n+1)
-tuple based onn
,i
, andi
-th element ofn
-tuple.fin.succ_rec_on
: same asfin.succ_rec
buti : fin n
is the first argument;
Casts
cast_lt i h
: embedi
into afin
whereh
proves it belongs into;cast_le h
: embedfin n
intofin m
,h : n ≤ m
;cast eq
: embedfin n
intofin m
,eq : n = m
;cast_add m
: embedfin n
intofin (n+m)
;cast_succ
: embedfin n
intofin (n+1)
;succ_above p
: embedfin n
intofin (n + 1)
with a hole aroundp
;pred_above p i h
: embedi : fin (n+1)
intofin n
by ignoringp
;sub_nat i h
: subtractm
fromi ≥ m
, generalizesfin.pred
;add_nat i h
: addm
oni
on the right, generalizesfin.succ
;nat_add i h
addsn
oni
on the left;clamp n m
:min n m
as an element offin (m + 1)
;
Operation on tuples
We interpret maps Π i : fin n, α i
as tuples (α 0, …, α (n-1))
.
If α i
is a constant map, then tuples are isomorphic (but not definitionally equal)
to vector
s.
We define the following operations:
tail
: the tail of ann+1
tuple, i.e., its lastn
entries;cons
: adding an element at the beginning of ann
-tuple, to get ann+1
-tuple;init
: the beginning of ann+1
tuple, i.e., its firstn
entries;snoc
: adding an element at the end of ann
-tuple, to get ann+1
-tuple. The namesnoc
comes fromcons
(i.e., adding an element to the left of a tuple) read in reverse order.find p
: returns the first indexn
wherep n
is satisfied, andnone
if it is never satisfied.
Misc definitions
Elimination principle for the empty set fin 0
, dependent version.
Equations
- fin_zero_elim x = x.elim0
Equations
- fin.linear_order = {le := has_le.le fin.has_le, lt := has_lt.lt fin.has_lt, le_refl := _, le_trans := _, lt_iff_le_not_le := _, le_antisymm := _, le_total := _}
Equations
- fin.decidable_linear_order = {le := linear_order.le fin.linear_order, lt := linear_order.lt fin.linear_order, le_refl := _, le_trans := _, lt_iff_le_not_le := _, le_antisymm := _, le_total := _, decidable_le := fin.decidable_le n, decidable_eq := fin.decidable_eq n, decidable_lt := fin.decidable_lt n}
cast_le h i
embeds i
into a larger fin
type.
Equations
- fin.cast_le h a = a.cast_lt _
cast_add m i
embeds i : fin n
in fin (n+m)
.
Equations
- fin.cast_add m = fin.cast_le _
Define C n i
by induction on i : fin n
interpreted as (0 : fin (n - i)).succ.succ…
.
This function has two arguments: H0 n
defines 0
-th element C (n+1) 0
of an (n+1)
-tuple,
and Hs n i
defines (i+1)
-st element of (n+1)
-tuple based on n
, i
, and i
-th element
of n
-tuple.
Equations
- fin.succ_rec H0 Hs ⟨i.succ, h⟩ = Hs n ⟨i, _⟩ (fin.succ_rec H0 Hs ⟨i, _⟩)
- fin.succ_rec H0 Hs ⟨0, _x⟩ = H0 n
- fin.succ_rec H0 Hs i = i.elim0
Define C n i
by induction on i : fin n
interpreted as (0 : fin (n - i)).succ.succ…
.
This function has two arguments: H0 n
defines 0
-th element C (n+1) 0
of an (n+1)
-tuple,
and Hs n i
defines (i+1)
-st element of (n+1)
-tuple based on n
, i
, and i
-th element
of n
-tuple.
A version of fin.succ_rec
taking i : fin n
as the first argument.
Equations
- i.succ_rec_on H0 Hs = fin.succ_rec H0 Hs i
Tuples
We can think of the type Π(i : fin n), α i
as n
-tuples of elements of possibly varying type
α i
. A particular case is fin n → α
of elements with all the same type. Here are some relevant
operations, first about adding or removing elements at the beginning of a tuple.
There is exactly one tuple of size zero.
Equations
- fin.tuple0_unique α = {to_inhabited := {default := fin_zero_elim (λ (i : fin 0), α i)}, uniq := _}
Updating a tuple and adding an element at the beginning commute.
Updating a nonzero element and taking the tail commute.
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.
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.
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.
find p
returns the first index n
where p n
is satisfied, and none
if it is never
satisfied.
Equations
- fin.find p = (fin.find (λ (i : fin n), p (i.cast_lt _))).cases_on (ite (p (fin.last n)) (option.some (fin.last n)) option.none) (λ (i : fin n), option.some (i.cast_lt _))
- fin.find p = option.none
If find p = some i
, then p i
holds
find p
does not return none
if and only if p i
holds at some index i
.
find p
returns none
if and only if p i
never holds.
Embedding of fin n
into ℕ
.
Equations
- function.embedding.fin n = {to_fun := coe coe_to_lift, inj' := _}
function.embedding.fin
coerced to a function.