Timings for Card.v
(** Representation of cardinals, see Chapter 10 of the HoTT book. *)
Require Import HoTT.Universes.TruncType.
Require Import HoTT.Classes.interfaces.abstract_algebra.
(** This speeds things up considerably *)
Local Opaque equiv_isequiv istrunc_isequiv_istrunc.
(** ** Definitions and operations *)
Definition Card := Trunc 0 HSet.
Definition card A `{IsHSet A} : Card
:= tr (Build_HSet A).
Definition sum_card (a b : Card) : Card.
exact (tr (Build_HSet (a + b))).
Definition prod_card (a b : Card) : Card.
exact (tr (Build_HSet (a * b))).
Definition exp_card `{Funext} (b a : Card) : Card.
exact (tr (Build_HSet (b -> a))).
Definition leq_card `{Univalence} : Card -> Card -> HProp.
refine (Trunc_rec (fun a => _)).
refine (Trunc_rec (fun b => _)).
exact (hexists (fun (i : a -> b) => IsInjective i)).
#[export] Instance plus_card : Plus Card := sum_card.
#[export] Instance mult_card : Mult Card := prod_card.
#[export] Instance zero_card : Zero Card := tr (Build_HSet Empty).
#[export] Instance one_card : One Card := tr (Build_HSet Unit).
#[export] Instance le_card : Le Card := leq_card.
(* Reduce an algebraic equation to an equivalence *)
Local Ltac reduce :=
repeat (intros ?); strip_truncations; cbn; f_ap; apply path_hset.
(* Simplify an equation by unfolding all the definitions apart from
the actual operations. *)
(* Note that this is an expensive thing to do, and will be very slow unless we tell it not to unfold the following. *)
Local Ltac simpl_ops :=
cbv-[plus_card mult_card zero_card one_card exp_card].
(** We only make the instances of upper classes global, since the
other instances will be project anyway. *)
(** *** [Card] is a semi-ring *)
Instance associative_sum : Associative plus_card.
Instance rightid_sum : RightIdentity plus_card zero_card.
Instance commutative_sum : Commutative plus_card.
Instance associative_prod : Associative mult_card.
Instance rightid_prod : RightIdentity mult_card one_card.
Instance commutative_prod : Commutative mult_card.
Instance leftdistributive_card : LeftDistribute mult_card plus_card.
Instance leftabsorb_card : LeftAbsorb mult_card zero_card.
#[export] Instance issemiring_card : IsSemiCRing Card.
repeat split; try exact _.
rewrite (commutativity zero_card _).
rewrite (commutativity one_card _).
(** *** Properties of exponentiation *)
Lemma exp_zero_card (a : Card) : exp_card 0 a = 1.
Lemma exp_card_one (a : Card) : exp_card a 1 = 1.
Lemma exp_one_card (a : Card) : exp_card 1 a = a.
Lemma exp_card_sum_mult (a b c : Card) :
exp_card (b + c) a = (exp_card b a) * (exp_card c a).
apply equiv_sum_distributive.
Lemma exp_mult_card_exp (a b c : Card) :
exp_card (b * c) a = exp_card c (exp_card b a).
rewrite (@commutativity _ _ (.*.) _ b c).
Lemma exp_card_mult_mult (a b c : Card) :
exp_card c (a * b) = (exp_card c a) * (exp_card c b).
(** *** Properties of ≤ *)
Instance reflexive_card : Reflexive leq_card.
exact (fun _ _ => idmap).
Instance transitive_card : Transitive leq_card.
destruct Hab as [iab Hab].
destruct Hbc as [ibc Hbc].
#[export] Instance preorder_card : PreOrder le_card.
(** * Cardinality comparisons *)
(* We also work with cardinality comparisons directly to avoid unnecessary type truncations via cardinals. *)
Definition Injection X Y :=
{ f : X -> Y | IsInjective f }.
Instance Injection_refl :
Reflexive Injection.
Lemma Injection_trans X Y Z :
Injection X Y -> Injection Y Z -> Injection X Z.
exists (fun x => g (f x)).
Definition InjectsInto X Y :=
merely (Injection X Y).
Instance InjectsInto_refl :
Reflexive InjectsInto.
Lemma InjectsInto_trans X Y Z :
InjectsInto X Y -> InjectsInto Y Z -> InjectsInto X Z.
eapply merely_destruct; try exact H1.
eapply merely_destruct; try exact H2.
exists (fun x => g (f x)).
(** * Infinity *)
(* We call a set infinite if nat embeds into it. *)
Definition infinite X :=
Injection nat X.