Timings for GCHtoAC.v
From HoTT Require Import TruncType ExcludedMiddle abstract_algebra.
From HoTT Require Import Universes.Smallness.
From HoTT Require Import Spaces.Nat.Core Spaces.Card.
From HoTT Require Import Equiv.BiInv.
From HoTT Require Import HIT.unique_choice.
From HoTT.Sets Require Import Ordinals Hartogs Powers GCH AC.
(* The proof of Sierpinski's results that GCH implies AC given in this file consists of two ingredients:
1. Adding powers of infinite sets does not increase the cardinality (path_infinite_power).
2. A variant of Cantor's theorem saying that P(X) <= (X + Y) implies P(X) <= Y for large X (Cantor_injects_injects).
Those are used to obtain that cardinality-controlled functions are well-behaved in the presence of GCH (Sierpinski), from which we obtain by instantiation with the Hartogs number that every set embeds into an ordinal, which is enough to conclude GCH -> AC (GCH_AC) since the well-ordering theorem implies AC (WO_AC). *)
(** * Constructive equivalences *)
(* For the first ingredient, we establish a bunch of paths and conclude the desired result by equational reasoning. *)
Context {UA : Univalence}.
Lemma path_sum_prod X Y Z :
(X -> Z) * (Y -> Z) = ((X + Y) -> Z).
apply path_universe_uncurried.
apply equiv_sum_distributive.
Lemma path_sum_assoc X Y Z :
X + (Y + Z) = X + Y + Z.
apply path_universe_uncurried.
Lemma path_sum_bool X :
X + X = Bool * X.
apply path_universe_uncurried.
srapply equiv_adjointify.
exact (fun x => match x with inl x => (true, x) | inr x => (false, x) end).
exact (fun x => match x with (true, x) => inl x | (false, x) => inr x end).
intros [[]]; reflexivity.
Lemma path_unit_nat :
Unit + nat = nat.
apply path_universe_uncurried.
srapply equiv_adjointify.
exact (fun x => match x with inl _ => O | inr n => S n end).
exact (fun n => match n with O => inl tt | S n => inr n end).
Lemma path_unit_fun X :
X = (Unit -> X).
apply path_universe_uncurried.
(** * Equivalences relying on LEM **)
Context {EM : ExcludedMiddle}.
Lemma path_bool_prop :
HProp = Bool.
apply path_universe_uncurried.
srapply equiv_adjointify.
exact (fun P => if LEM P _ then true else false).
exact (fun b : Bool => if b then merely Unit else merely Empty).
intros []; destruct LEM as [H|H]; auto.
apply (@merely_destruct Empty); try done.
destruct LEM as [H|H]; apply equiv_path_iff_hprop.
apply (@merely_destruct Empty); try done.
Lemma path_bool_subsingleton :
(Unit -> HProp) = Bool.
rewrite <- path_unit_fun.
Lemma path_pred_sum X (p : X -> HProp) :
X = sig p + sig (fun x => ~ p x).
apply path_universe_uncurried.
srapply equiv_adjointify.
destruct (LEM (p x) _) as [H|H]; [left | right]; by exists x.
intros [[x _]|[x _]]; exact x.
intros [[x Hx]|[x Hx]]; destruct LEM as [H|H]; try contradiction.
enough (H = Hx) as -> by reflexivity.
enough (H = Hx) as -> by reflexivity.
Definition ran {X Y : Type} (f : X -> Y) :=
fun y => hexists (fun x => f x = y).
Lemma path_ran {X} {Y : HSet} (f : X -> Y) :
IsInjective f -> sig (ran f) = X.
apply path_universe_uncurried.
srapply equiv_adjointify.
destruct (iota (fun x => f x = y) _) as [x Hx]; try exact x.
destruct iota as [x' Hx].
(** * Equivalences on infinite sets *)
Lemma path_infinite_unit (X : HSet) :
infinite X -> Unit + X = X.
rewrite (@path_pred_sum X (ran f)).
Fact path_infinite_power (X : HSet) :
infinite X -> (X -> HProp) + (X -> HProp) = (X -> HProp).
rewrite <- path_bool_subsingleton.
by rewrite path_infinite_unit.
(** * Variants of Cantors's theorem *)
(* For the second ingredient, we give a preliminary version (Cantor_path_inject) to see the idea, as well as a stronger refinement (Cantor_injects_injects) which is then a mere reformulation. *)
Context {PR : PropResizing}.
Lemma Cantor X (f : X -> X -> Type) :
{ p | forall x, f x <> p }.
exists (fun x => ~ f x x).
enough (Hx : f x x <-> ~ f x x).
apply Hx; apply Hx; intros H'; by apply Hx.
Lemma hCantor {X} (f : X -> X -> HProp) :
{ p | forall x, f x <> p }.
exists (fun x => Build_HProp (f x x -> Empty)).
enough (Hx : f x x <-> ~ f x x).
apply Hx; apply Hx; intros H'; by apply Hx.
Definition clean_sum {X Y Z} (f : X -> Y + Z) :
(forall x y, f x <> inl y) -> forall x, { z | inr z = f x }.
enough (H : forall x a, a = f x -> {z : Z & inr z = f x}).
Fact Cantor_path_injection {X Y} :
(X -> HProp) = (X + Y) -> (X + X) = X -> Injection (X -> HProp) Y.
assert (H : X + Y = (X -> HProp) * (X -> HProp)).
by rewrite <- H1, path_sum_prod, H2.
apply equiv_path in H as [f [g Hfg Hgf _]].
pose (f' x := fst (f (inl x))).
destruct (hCantor f') as [p Hp].
assert (H' : forall q x, g' q <> inl x).
exists (fun x => proj1 (clean_sum _ H' x)).
assert (Hqq' : g' q = g' q').
destruct clean_sum as [z <-].
destruct clean_sum as [z' <-].
change (snd (p, q) = snd (p, q')).
rewrite <- (Hfg (p, q)), <- (Hfg (p, q')).
(* Version just requiring propositional injections *)
Lemma Cantor_rel X (R : X -> (X -> HProp) -> HProp) :
(forall x p p', R x p -> R x p' -> merely (p = p')) -> { p | forall x, ~ R x p }.
pose (pc x := Build_HProp (smalltype (forall p : X -> HProp, R x p -> ~ p x))).
enough (Hpc : pc x <-> ~ pc x).
apply Hpc; apply Hpc; intros H'; by apply Hpc.
apply equiv_smalltype in Hx.
eapply merely_destruct; try exact (HR _ _ _ Hp H).
Lemma InjectsInto_power_morph X Y :
InjectsInto X Y -> InjectsInto (X -> HProp) (Y -> HProp).
eapply merely_destruct; try exact HF.
exists (fun p => fun y => hexists (fun x => p x /\ y = f x)).
apply equiv_path_iff_hprop.
assert (Hp : (fun y : Y => hexists (fun x : X => p x * (y = f x))) (f x)).
eapply merely_destruct; try exact Hp.
by intros [x'[Hq <- % Hf]].
assert (Hq : (fun y : Y => hexists (fun x : X => q x * (y = f x))) (f x)).
eapply merely_destruct; try exact Hq.
by intros [x'[Hp <- % Hf]].
Fact Cantor_injects_injects {X Y : HSet} :
InjectsInto (X -> HProp) (X + Y) -> InjectsInto (X + X) X -> InjectsInto (X -> HProp) Y.
assert (HF : InjectsInto ((X -> HProp) * (X -> HProp)) (X + Y)).
eapply InjectsInto_trans; try exact H1.
eapply InjectsInto_trans; try apply InjectsInto_power_morph, H2.
eapply merely_destruct; try exact HF.
pose (R x p := hexists (fun q => f (p, q) = inl x)).
destruct (@Cantor_rel _ R) as [p Hp].
eapply merely_destruct; try exact H3.
eapply merely_destruct; try apply H4.
change p with (fst (p, q)).
rewrite (Hf (p, q) (p', q')); trivial.
assert (H' : forall q x, f' q <> inl x).
exists (fun x => proj1 (clean_sum _ H' x)).
assert (Hqq' : f' q = f' q').
destruct clean_sum as [z <-].
destruct clean_sum as [z' <-].
change q with (snd (p, q)).
(** * Sierpinski's Theorem *)
Context {UA : Univalence}.
Context {EM : ExcludedMiddle}.
Context {PR : PropResizing}.
Definition powfix X :=
forall n, (power_iterated X n + power_iterated X n) = (power_iterated X n).
Variable HN : HSet -> HSet.
Hypothesis HN_ninject : forall X, ~ InjectsInto (HN X) X.
Hypothesis HN_inject : forall X, InjectsInto (HN X) (power_iterated X HN_bound).
(* This section then concludes the intermediate result that abstractly, any function [HN] behaving like the Hartogs number is tamed in the presence of GCH. Morally we show that [X <= HN X] for all [X], we just ensure that [X] is large enough by considering P(N + X). *)
Lemma InjectsInto_sum X Y X' Y' :
InjectsInto X X' -> InjectsInto Y Y' -> InjectsInto (X + Y) (X' + Y').
eapply merely_destruct; try exact H1.
eapply merely_destruct; try exact H2.
exists (fun z => match z with inl x => inl (f x) | inr y => inr (g y) end).
apply path_sum_inl with Y'.
by apply inl_ne_inr in H.
by apply inr_ne_inl in H.
apply path_sum_inr with X'.
(* The main proof is by induction on the cardinality bound for [HN]. As the Hartogs number is bounded by P^3(X), we'd actually just need finitely many instances of GCH. *)
Lemma Sierpinski_step (X : HSet) n :
GCH -> infinite X -> powfix X -> InjectsInto (HN X) (power_iterated X n) -> InjectsInto X (HN X).
by apply HN_ninject in Hi.
destruct (gch (Build_HSet (power_iterated X n)) (Build_HSet (power_iterated X n + HN X))) as [H|H].
by apply infinite_power_iterated.
eapply InjectsInto_trans.
apply InjectsInto_sum; try apply Hi.
apply tr, Injection_power.
apply tr, Injection_refl.
eapply InjectsInto_trans; try apply H.
apply InjectsInto_trans with (power_iterated X (S n)); try apply tr, Injection_power_iterated.
apply (Cantor_injects_injects H).
apply tr, Injection_refl.
Theorem GCH_injects' (X : HSet) :
GCH -> infinite X -> InjectsInto X (HN (Build_HSet (X -> HProp))).
eapply InjectsInto_trans; try apply tr, Injection_power; try apply X.
apply (@Sierpinski_step (Build_HSet (X -> HProp)) HN_bound gch).
apply infinite_inject with X; trivial.
rewrite !power_iterated_shift.
eapply path_infinite_power.
by apply infinite_power_iterated.
Theorem GCH_injects (X : HSet) :
GCH -> InjectsInto X (HN (Build_HSet (Build_HSet (nat + X) -> HProp))).
eapply InjectsInto_trans with (nat + X).
apply GCH_injects'; trivial.
(* Main result: GCH implies AC *)
Theorem GCH_AC {UA : Univalence} {PR : PropResizing} {LEM : ExcludedMiddle} :
GCH -> Choice_type.
exists (hartogs_number (Build_HSet (Build_HSet (nat + X) -> HProp))).
unshelve eapply (@GCH_injects UA LEM PR hartogs_number _ 3 _ X gch).
eapply merely_destruct; try apply H.
apply hartogs_number_no_injection.
apply hartogs_number_injection.
(* Note that the assumption of LEM is actually not necessary due to GCH_LEM. *)