Finite types #
This file defines a typeclass to state that a type is finite.
Main declarations #
Fintype α
: Typeclass saying that a type is finite. It takes as fields aFinset
and a proof that all terms of typeα
are in it.Finset.univ
: The finset of all elements of a fintype.
See Data.Fintype.Card
for the cardinality of a fintype,
the equivalence with Fin (Fintype.card α)
, and pigeonhole principles.
Instances #
Instances for Fintype
for
{x // p x}
are in this file asFintype.subtype
Option α
are inData.Fintype.Option
α × β
are inData.Fintype.Prod
α ⊕ β
are inData.Fintype.Sum
Σ (a : α), β a
are inData.Fintype.Sigma
These files also contain appropriate Infinite
instances for these types.
Infinite
instances for ℕ
, ℤ
, Multiset α
, and List α
are in Data.Fintype.Lattice
.
Types which have a surjection from/an injection to a Fintype
are themselves fintypes.
See Fintype.ofInjective
and Fintype.ofSurjective
.
Fintype α
means that α
is finite, i.e. there are only
finitely many distinct elements of type α
. The evidence of this
is a finset elems
(a list up to permutation without duplicates),
together with a proof that everything of type α
is in the list.
- elems : Finset α
- complete : ∀ (x : α), x ∈ Fintype.elems
A proof that
elems
contains every element of the type
Instances
Equations
- Finset.boundedOrder = let __src := inferInstanceAs (OrderBot (Finset α)); BoundedOrder.mk
Equations
- Finset.booleanAlgebra = GeneralizedBooleanAlgebra.toBooleanAlgebra
Note this is a special case of (Finset.image_preimage f univ _).symm
.
Equations
- Fintype.decidablePiFintype f g = decidable_of_iff (∀ a ∈ Fintype.elems, f a = g a) ⋯
Equations
- Fintype.decidableForallFintype = decidable_of_iff (∀ a ∈ Finset.univ, p a) ⋯
Equations
- Fintype.decidableExistsFintype = decidable_of_iff (∃ a ∈ Finset.univ, p a) ⋯
Equations
- Fintype.decidableMemRangeFintype f x = Fintype.decidableExistsFintype
Equations
- Fintype.decidableSubsingleton = decidable_of_iff (∀ a ∈ s, ∀ b ∈ s, a = b) ⋯
Equations
- Fintype.decidableEqEquivFintype a b = decidable_of_iff (a.toFun = b.toFun) ⋯
Equations
- Fintype.decidableEqEmbeddingFintype a b = decidable_of_iff (⇑a = ⇑b) ⋯
Equations
- Fintype.decidableEqZeroHomFintype a b = decidable_of_iff (⇑a = ⇑b) ⋯
Equations
- Fintype.decidableEqOneHomFintype a b = decidable_of_iff (⇑a = ⇑b) ⋯
Equations
- Fintype.decidableEqAddHomFintype a b = decidable_of_iff (⇑a = ⇑b) ⋯
Equations
- Fintype.decidableEqMulHomFintype a b = decidable_of_iff (⇑a = ⇑b) ⋯
Equations
- Fintype.decidableEqAddMonoidHomFintype a b = decidable_of_iff (⇑a = ⇑b) ⋯
Equations
- Fintype.decidableEqMonoidHomFintype a b = decidable_of_iff (⇑a = ⇑b) ⋯
Equations
- Fintype.decidableEqMonoidWithZeroHomFintype a b = decidable_of_iff (⇑a = ⇑b) ⋯
Equations
- Fintype.decidableEqRingHomFintype a b = decidable_of_iff (⇑a = ⇑b) ⋯
Equations
- Fintype.decidableInjectiveFintype x = id inferInstance
Equations
- Fintype.decidableSurjectiveFintype x = id inferInstance
Equations
- Fintype.decidableBijectiveFintype x = id inferInstance
Equations
- Fintype.decidableRightInverseFintype f g = let_fun this := inferInstance; this
Equations
- Fintype.decidableLeftInverseFintype f g = let_fun this := inferInstance; this
Construct a proof of Fintype α
from a universal multiset
Equations
- Fintype.ofMultiset s H = { elems := Multiset.toFinset s, complete := ⋯ }
Instances For
Construct a proof of Fintype α
from a universal list
Equations
- Fintype.ofList l H = { elems := List.toFinset l, complete := ⋯ }
Instances For
Given a predicate that can be represented by a finset, the subtype associated to the predicate is a fintype.
Equations
- Fintype.subtype s H = { elems := { val := Multiset.pmap Subtype.mk s.val ⋯, nodup := ⋯ }, complete := ⋯ }
Instances For
Construct a fintype from a finset with the same elements.
Equations
- Fintype.ofFinset s H = Fintype.subtype s H
Instances For
If f : α → β
is a bijection and α
is a fintype, then β
is also a fintype.
Equations
- Fintype.ofBijective f H = { elems := Finset.map { toFun := f, inj' := ⋯ } Finset.univ, complete := ⋯ }
Instances For
If f : α → β
is a surjection and α
is a fintype, then β
is also a fintype.
Equations
- Fintype.ofSurjective f H = { elems := Finset.image f Finset.univ, complete := ⋯ }
Instances For
Equations
- Finset.decidableCodisjoint = decidable_of_iff (∀ ⦃a : α⦄, a ∉ s → a ∈ t) ⋯
Equations
- Finset.decidableIsCompl = decidable_of_iff' (Disjoint s t ∧ Codisjoint s t) ⋯
The inverse of an hf : injective
function f : α → β
, of the type ↥(Set.range f) → α
.
This is the computable version of Function.invFun
that requires Fintype α
and DecidableEq β
,
or the function version of applying (Equiv.ofInjective f hf).symm
.
This function should not usually be used for actual computation because for most cases,
an explicit inverse can be stated that has better computational properties.
This function computes by checking all terms a : α
to find the f a = b
, so it is O(N) where
N = Fintype.card α
.
Equations
- Function.Injective.invOfMemRange hf b = Finset.choose (fun (a : α) => f a = ↑b) Finset.univ ⋯
Instances For
The inverse of an embedding f : α ↪ β
, of the type ↥(Set.range f) → α
.
This is the computable version of Function.invFun
that requires Fintype α
and DecidableEq β
,
or the function version of applying (Equiv.ofInjective f f.injective).symm
.
This function should not usually be used for actual computation because for most cases,
an explicit inverse can be stated that has better computational properties.
This function computes by checking all terms a : α
to find the f a = b
, so it is O(N) where
N = Fintype.card α
.
Equations
Instances For
Given an injective function to a fintype, the domain is also a fintype. This is noncomputable because injectivity alone cannot be used to construct preimages.
Equations
- Fintype.ofInjective f H = if hα : Nonempty α then Fintype.ofSurjective (Function.invFun f) ⋯ else { elems := ∅, complete := ⋯ }
Instances For
If f : α ≃ β
and α
is a fintype, then β
is also a fintype.
Equations
- Fintype.ofEquiv α f = Fintype.ofBijective ⇑f ⋯
Instances For
Any subsingleton type with a witness is a fintype (with one term).
Equations
- Fintype.ofSubsingleton a = { elems := {a}, complete := ⋯ }
Instances For
An empty type is a fintype. Not registered as an instance, to make sure that there aren't two
conflicting Fintype ι
instances around when casing over whether a fintype ι
is empty or not.
Instances For
Note: this lemma is specifically about Fintype.ofIsEmpty
. For a statement about
arbitrary Fintype
instances, use Finset.univ_eq_empty
.
Equations
- Fintype.instFintypeEmpty = Fintype.ofIsEmpty
Equations
- Fintype.instFintypePEmpty = Fintype.ofIsEmpty
Construct a finset enumerating a set s
, given a Fintype
instance.
Equations
- Set.toFinset s = Finset.map (Function.Embedding.subtype fun (x : α) => x ∈ s) Finset.univ
Instances For
Many Fintype
instances for sets are defined using an extensionally equal Finset
.
Rewriting s.toFinset
with Set.toFinset_ofFinset
replaces the term with such a Finset
.
Membership of a set with a Fintype
instance is decidable.
Using this as an instance leads to potential loops with Subtype.fintype
under certain decidability
assumptions, so it should only be declared a local instance.
Equations
- Set.decidableMemOfFintype s a = decidable_of_iff (a ∈ Set.toFinset s) ⋯
Instances For
Alias of the reverse direction of Set.toFinset_subset_toFinset
.
Alias of the reverse direction of Set.toFinset_ssubset_toFinset
.
Equations
- Fin.fintype n = { elems := { val := ↑(List.finRange n), nodup := ⋯ }, complete := ⋯ }
Embed Fin n
into Fin (n + 1)
by appending a new Fin.last n
to the univ
Embed Fin n
into Fin (n + 1)
by inserting
around a specified pivot p : Fin (n + 1)
into the univ
Equations
- Unique.fintype = Fintype.ofSubsingleton default
Short-circuit instance to decrease search for Unique.fintype
,
since that relies on a subsingleton elimination for Unique
.
Equations
- Fintype.subtypeEq y = Fintype.subtype {y} ⋯
Short-circuit instance to decrease search for Unique.fintype
,
since that relies on a subsingleton elimination for Unique
.
Equations
- Fintype.subtypeEq' y = Fintype.subtype {y} ⋯
Equations
Equations
- Bool.fintype = { elems := { val := {true, false}, nodup := Bool.fintype.proof_1 }, complete := Bool.fintype.proof_2 }
Equations
- Additive.fintype = Fintype.ofEquiv α Additive.ofMul
Equations
- Multiplicative.fintype = Fintype.ofEquiv α Multiplicative.ofAdd
Given that α × β
is a fintype, α
is also a fintype.
Equations
- Fintype.prodLeft = { elems := Finset.image Prod.fst Finset.univ, complete := ⋯ }
Instances For
Given that α × β
is a fintype, β
is also a fintype.
Equations
- Fintype.prodRight = { elems := Finset.image Prod.snd Finset.univ, complete := ⋯ }
Instances For
Equations
- ULift.fintype α = Fintype.ofEquiv α Equiv.ulift.symm
Equations
- PLift.fintype α = Fintype.ofEquiv α Equiv.plift.symm
Equations
- OrderDual.fintype α = inst
Equations
- Finset.fintypeCoeSort s = { elems := Finset.attach s, complete := ⋯ }
Equations
Equations
Equations
- Finset.Subtype.fintype s = { elems := Finset.attach s, complete := ⋯ }
Equations
Equations
- PLift.fintypeProp p = { elems := if h : p then {{ down := h }} else ∅, complete := ⋯ }
Equations
- Prop.fintype = { elems := { val := {True, False}, nodup := Prop.fintype.proof_1 }, complete := Prop.fintype.proof_2 }
Equations
- Subtype.fintype p = Fintype.subtype (Finset.filter p Finset.univ) ⋯
A set on a fintype, when coerced to a type, is a fintype.
Equations
- setFintype s = Subtype.fintype fun (x : α) => x ∈ s
Instances For
In a GroupWithZero
α
, the unit group αˣ
is equivalent to the subtype of nonzero
elements.
Equations
- unitsEquivNeZero α = { toFun := fun (a : αˣ) => { val := ↑a, property := ⋯ }, invFun := fun (a : { a : α // a ≠ 0 }) => Units.mk0 ↑a ⋯, left_inv := ⋯, right_inv := ⋯ }
Instances For
Given Fintype α
, finsetEquivSet
is the equiv between Finset α
and Set α
. (All
sets on a finite type are finite.)
Equations
- Fintype.finsetEquivSet = { toFun := Finset.toSet, invFun := fun (s : Set α) => Set.toFinset s, left_inv := ⋯, right_inv := ⋯ }
Instances For
Given a fintype α
, finsetOrderIsoSet
is the order isomorphism between Finset α
and Set α
(all sets on a finite type are finite).
Equations
- Fintype.finsetOrderIsoSet = { toEquiv := Fintype.finsetEquivSet, map_rel_iff' := ⋯ }
Instances For
Equations
- Quotient.fintype s = Fintype.ofSurjective Quotient.mk'' ⋯
Given a fintype α
and a predicate p
, associate to a proof that there is a unique element of
α
satisfying p
this unique element, as an element of the corresponding subtype.
Equations
- Fintype.chooseX p hp = { val := Finset.choose p Finset.univ ⋯, property := ⋯ }
Instances For
Given a fintype α
and a predicate p
, associate to a proof that there is a unique element of
α
satisfying p
this unique element, as an element of α
.
Equations
- Fintype.choose p hp = ↑(Fintype.chooseX p hp)
Instances For
bijInv f
is the unique inverse to a bijection f
. This acts
as a computable alternative to Function.invFun
.
Equations
- Fintype.bijInv f_bij b = Fintype.choose (fun (a : α) => f a = b) ⋯
Instances For
A Nonempty
Fintype
constructively contains an element.
Equations
- truncOfNonemptyFintype α = truncOfMultisetExistsMem Finset.univ.val ⋯
Instances For
By iterating over the elements of a fintype, we can lift an existential statement ∃ a, P a
to Trunc (Σ' a, P a)
, containing data.
Equations
- truncSigmaOfExists h = truncOfNonemptyFintype ((a : α) ×' P a)
Instances For
For functions on finite sets, they are bijections iff they map universes into universes.
Auxiliary definition to show exists_seq_of_forall_finset_exists
.
Equations
- seqOfForallFinsetExistsAux P r h x = Classical.choose ⋯
Instances For
Induction principle to build a sequence, by adding one point at a time satisfying a given relation with respect to all the previously chosen points.
More precisely, Assume that, for any finite set s
, one can find another point satisfying
some relation r
with respect to all the points in s
. Then one may construct a
function f : ℕ → α
such that r (f m) (f n)
holds whenever m < n
.
We also ensure that all constructed points satisfy a given predicate P
.
Induction principle to build a sequence, by adding one point at a time satisfying a given symmetric relation with respect to all the previously chosen points.
More precisely, Assume that, for any finite set s
, one can find another point satisfying
some relation r
with respect to all the points in s
. Then one may construct a
function f : ℕ → α
such that r (f m) (f n)
holds whenever m ≠ n
.
We also ensure that all constructed points satisfy a given predicate P
.