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 iby induction oni : fin ninterpreted as(0 : fin (n - i)).succ.succ…. This function has two arguments:H0 ndefines0-th elementC (n+1) 0of an(n+1)-tuple, andHs n idefines(i+1)-st element of(n+1)-tuple based onn,i, andi-th element ofn-tuple.fin.succ_rec_on: same asfin.succ_recbuti : fin nis the first argument;fin.induction: DefineC iby induction oni : fin (n + 1), separating into thenat-like base cases ofC 0andC (i.succ).fin.induction_on: same asfin.inductionbut withi : fin (n + 1)as the first argument.fin.cases: definef : Π i : fin n.succ, C iby separately handling the casesi = 0andi = 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 iby going down;fin.last_cases: definef : Π i, fin (n + 1), C iby separately handling the casesi = fin.last nandi = 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 iandfin.nat_add m i;fin.succ_above_cases: giveni : fin (n + 1), define a function onfin (n + 1)by separately handling the casesj = iandj = fin.succ_above i k, same asfin.insert_nthbut 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.succas anorder_embedding;fin.cast_le h: embedfin nintofin m,h : n ≤ m;fin.cast eq: order isomorphism betweenfin nand fin mprovided thatn = m, see alsoequiv.fin_congr`;fin.cast_add m: embedfin nintofin (n+m);fin.cast_succ: embedfin nintofin (n+1);fin.succ_above p: embedfin nintofin (n + 1)with a hole aroundp;fin.add_nat m i: addmonion the right, generalizesfin.succ;fin.nat_add n iaddsnonion the left;
Other casts #
fin.of_nat': given a positive numbern(deduced from[ne_zero n]),fin.of_nat' iisi % ninterpreted as an element offin n;fin.cast_lt i h: embediinto afinwherehproves it belongs into;fin.pred_above (p : fin n) i: embedi : fin (n+1)intofin nby 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: subtractmfromi ≥ m, generalizesfin.pred;fin.clamp n m:min n mas 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)