The finite type with n
elements #
THIS FILE IS SYNCHRONIZED WITH MATHLIB4. Any changes to this file require a corresponding PR to mathlib4.
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;fin.induction
: DefineC i
by induction oni : fin (n + 1)
, separating into thenat
-like base cases ofC 0
andC (i.succ)
.fin.induction_on
: same asfin.induction
but withi : fin (n + 1)
as the first argument.fin.cases
: definef : Π i : fin n.succ, C i
by separately handling the casesi = 0
andi = fin.succ j
,j : fin n
, defined usingfin.induction
.fin.reverse_induction
: reverse induction oni : fin (n + 1)
; givenC (fin.last n)
and∀ i : fin n, C (fin.succ i) → C (fin.cast_succ i)
, constructs all valuesC i
by going down;fin.last_cases
: definef : Π i, fin (n + 1), C i
by separately handling the casesi = fin.last n
andi = fin.cast_succ j
, a special case offin.reverse_induction
;fin.add_cases
: define a function onfin (m + n)
by separately handling the casesfin.cast_add n i
andfin.nat_add m i
;fin.succ_above_cases
: giveni : fin (n + 1)
, define a function onfin (n + 1)
by separately handling the casesj = i
andj = fin.succ_above i k
, same asfin.insert_nth
but marked as eliminator and works forSort*
.
Order embeddings and an order isomorphism #
fin.order_iso_subtype
: coercion to{ i // i < n }
as anorder_iso
;fin.coe_embedding
: coercion to natural numbers as anembedding
;fin.coe_order_embedding
: coercion to natural numbers as anorder_embedding
;fin.succ_embedding
:fin.succ
as anorder_embedding
;fin.cast_le h
: embedfin n
intofin m
,h : n ≤ m
;fin.cast eq
: order isomorphism betweenfin n
and fin mprovided that
n = m, see also
equiv.fin_congr`;fin.cast_add m
: embedfin n
intofin (n+m)
;fin.cast_succ
: embedfin n
intofin (n+1)
;fin.succ_above p
: embedfin n
intofin (n + 1)
with a hole aroundp
;fin.add_nat m i
: addm
oni
on the right, generalizesfin.succ
;fin.nat_add n i
addsn
oni
on the left;
Other casts #
fin.of_nat'
: given a positive numbern
(deduced from[ne_zero n]
),fin.of_nat' i
isi % n
interpreted as an element offin n
;fin.cast_lt i h
: embedi
into afin
whereh
proves it belongs into;fin.pred_above (p : fin n) i
: embedi : fin (n+1)
intofin n
by subtracting one ifp < i
;fin.cast_pred
: embedfin (n + 2)
intofin (n + 1)
by mappingfin.last (n + 1)
tofin.last n
;fin.sub_nat i h
: subtractm
fromi ≥ m
, generalizesfin.pred
;fin.clamp n m
:min n m
as an element offin (m + 1)
;fin.div_nat i
: dividesi : fin (m * n)
byn
;fin.mod_nat i
: takes the mod ofi : fin (m * n)
byn
;
Misc definitions #
Elimination principle for the empty set fin 0
, dependent version.
Equations
- fin_zero_elim x = x.elim0
coercions and constructions #
order #
Equations
- fin.linear_order = linear_order.lift fin.val fin.val_injective fin.linear_order._proof_3 fin.linear_order._proof_4
Equations
The equivalence fin n ≃ { i // i < n }
is an order isomorphism.
Equations
- fin.order_iso_subtype = fin.equiv_subtype.to_order_iso fin.order_iso_subtype._proof_1 fin.order_iso_subtype._proof_2
The inclusion map fin n → ℕ
is an embedding.
Equations
- fin.coe_embedding = {to_fun := coe coe_to_lift, inj' := _}
The inclusion map fin n → ℕ
is an order embedding.
Equations
- fin.coe_order_embedding n = {to_embedding := fin.coe_embedding n, map_rel_iff' := _}
The ordering on fin n
is a well order.
Use the ordering on fin n
for checking recursive definitions.
For example, the following definition is not accepted by the termination checker,
unless we declare the has_well_founded
instance:
def factorial {n : ℕ} : fin n → ℕ
| ⟨0, _⟩ := 1
| ⟨i + 1, hi⟩ := (i + 1) * factorial ⟨i, i.lt_succ_self.trans hi⟩
Equations
fin.rev n
as an order-reversing isomorphism.
Equations
Equations
Equations
- fin.order_iso_unique = unique.mk' (fin n ≃o fin n)
Two strictly monotone functions from fin n
are equal provided that their ranges
are equal.
addition, numerals, and coercion from nat #
Equations
- fin.add_comm_semigroup n = {add := has_add.add fin.has_add, add_assoc := _, add_comm := _}
Equations
- fin.add_comm_monoid n = {add := has_add.add fin.has_add, add_assoc := _, zero := 0, zero_add := _, add_zero := _, nsmul := add_monoid.nsmul._default 0 has_add.add fin.zero_add fin.add_zero, nsmul_zero' := _, nsmul_succ' := _, add_comm := _}
Equations
- fin.add_monoid_with_one = {nat_cast := fin.of_nat' _inst_1, add := add_comm_monoid.add (fin.add_comm_monoid n), add_assoc := _, zero := add_comm_monoid.zero (fin.add_comm_monoid n), zero_add := _, add_zero := _, nsmul := add_comm_monoid.nsmul (fin.add_comm_monoid n), nsmul_zero' := _, nsmul_succ' := _, one := 1, nat_cast_zero := _, nat_cast_succ := _}
succ and casts into larger fin types #
fin.succ
as an order_embedding
Equations
Version of succ_zero_eq_one
to be used by dsimp
Version of succ_one_eq_two
to be used by dsimp
cast_le h i
embeds i
into a larger fin
type.
Equations
- fin.cast_le h = order_embedding.of_strict_mono (λ (a : fin n), a.cast_lt _) fin.cast_le._proof_2
While in many cases fin.cast
is better than equiv.cast
/cast
, sometimes we want to apply
a generic theorem about cast
.
cast_add m i
embeds i : fin n
in fin (n+m)
. See also fin.nat_add
and fin.add_nat
.
Equations
- fin.cast_add m = fin.cast_le _
For rewriting in the reverse direction, see fin.cast_cast_add_left
.
cast_succ i
is positive when i
is positive
For rewriting in the reverse direction, see fin.cast_add_nat_left
.
nat_add n i
adds n
to i
"on the left".
Equations
- fin.nat_add n = order_embedding.of_strict_mono (λ (i : fin m), ⟨n + ↑i, _⟩) _
For rewriting in the reverse direction, see fin.cast_nat_add_right
.
pred #
recursion and induction principles #
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
Define C i
by induction on i : fin (n + 1)
via induction on the underlying nat
value.
This function has two arguments: h0
handles the base case on C 0
,
and hs
defines the inductive step using C i.cast_succ
.
Define C i
by induction on i : fin (n + 1)
via induction on the underlying nat
value.
This function has two arguments: h0
handles the base case on C 0
,
and hs
defines the inductive step using C i.cast_succ
.
A version of fin.induction
taking i : fin (n + 1)
as the first argument.
Equations
- i.induction_on h0 hs = fin.induction h0 hs i
Define f : Π i : fin n.succ, C i
by separately handling the cases i = 0
and
i = j.succ
, j : fin n
.
Equations
- fin.cases H0 Hs = fin.induction H0 (λ (i : fin n) (_x : C (⇑fin.cast_succ i)), Hs i)
Define C i
by reverse induction on i : fin (n + 1)
via induction on the underlying nat
value.
This function has two arguments: hlast
handles the base case on C (fin.last n)
,
and hs
defines the inductive step using C i.succ
, inducting downwards.
Define f : Π i : fin n.succ, C i
by separately handling the cases i = fin.last n
and
i = j.cast_succ
, j : fin n
.
Equations
- fin.last_cases hlast hcast i = fin.reverse_induction hlast (λ (i : fin n) (_x : C i.succ), hcast i) i
Define f : Π i : fin (m + n), C i
by separately handling the cases i = cast_add n i
,
j : fin m
and i = nat_add m j
, j : fin n
.
Abelian group structure on fin n
.
Equations
- fin.add_comm_group n = {add := add_comm_monoid.add (fin.add_comm_monoid n), add_assoc := _, zero := add_comm_monoid.zero (fin.add_comm_monoid n), zero_add := _, add_zero := _, nsmul := add_comm_monoid.nsmul (fin.add_comm_monoid n), nsmul_zero' := _, nsmul_succ' := _, neg := has_neg.neg (fin.has_neg n), sub := fin.sub n, sub_eq_add_neg := _, zsmul := add_group.zsmul._default add_comm_monoid.add _ add_comm_monoid.zero _ _ add_comm_monoid.nsmul _ _ has_neg.neg, zsmul_zero' := _, zsmul_succ' := _, zsmul_neg' := _, add_left_neg := _, add_comm := _}
Note this is more general than fin.add_comm_group
as it applies (vacuously) to fin 0
too.
Equations
- fin.has_involutive_neg n = {neg := has_neg.neg (fin.has_neg n), neg_neg := _}
Note this is more general than fin.add_comm_group
as it applies (vacuously) to fin 0
too.
Note this is more general than fin.add_comm_group
as it applies (vacuously) to fin 0
too.
Equations
- fin.add_left_cancel_semigroup n = {add := add_comm_semigroup.add (fin.add_comm_semigroup n), add_assoc := _, add_left_cancel := _}
Note this is more general than fin.add_comm_group
as it applies (vacuously) to fin 0
too.
Equations
- fin.add_right_cancel_semigroup n = {add := add_comm_semigroup.add (fin.add_comm_semigroup n), add_assoc := _, add_right_cancel := _}
succ_above p i
embeds fin n
into fin (n + 1)
with a hole around p
.
Equations
- p.succ_above = order_embedding.of_strict_mono (λ (i : fin n), ite (⇑fin.cast_succ i < p) (⇑fin.cast_succ i) i.succ) _
Embedding i : fin n
into fin (n + 1)
with a hole around p : fin (n + 1)
embeds i
by cast_succ
when the resulting i.cast_succ < p
.
Embedding i : fin n
into fin (n + 1)
is always about some hole p
.
Embedding i : fin n
into fin (n + 1)
using a pivot p
that is greater
results in a value that is less than p
.
Embedding i : fin n
into fin (n + 1)
using a pivot p
that is lesser
results in a value that is greater than p
.
The range of p.succ_above
is everything except p
.
Given a fixed pivot x : fin (n + 1)
, x.succ_above
is injective
Given a fixed pivot x : fin (n + 1)
, x.succ_above
is injective
succ_above
is injective at the pivot
succ_above
is injective at the pivot
By moving succ
to the outside of this expression, we create opportunities for further
simplification using succ_above_zero
or succ_succ_above_zero
.
pred_above p i
embeds i : fin (n+1)
into fin n
by subtracting one if p < i
.
Equations
- p.pred_above i = dite (⇑fin.cast_succ p < i) (λ (h : ⇑fin.cast_succ p < i), i.pred _) (λ (h : ¬⇑fin.cast_succ p < i), i.cast_lt _)
Sending fin (n+1)
to fin n
by subtracting one from anything above p
then back to fin (n+1)
with a gap around p
is the identity away from p
.
Sending fin n
into fin (n + 1)
with a gap at p
then back to fin n
by subtracting one from anything above p
is the identity.
succ
commutes with pred_above
.
min n m
as an element of fin (m + 1)
Equations
- fin.clamp n m = fin.of_nat (linear_order.min n m)