Library Continuum.Sierpinskis_Theorem

Require Export Continuum.Hartogs_Number.

Require Import Coq.Logic.Classical.

Require Import Coq.Program.Program.
Require Import Coq.Init.Nat.

Definition Infinite (A : S) :=
  Numeral A.

Definition Generalized_Continuum_Hypothesis :=
   x y : S,
    Infinite x
    x y 𝒫 x
    x = y y = 𝒫 x.

Definition Well_Ordering_Theorem :=
   x : S, inhabited (Well_Order_On x).

Definition Axiom_Of_Choice' :=
   (I : S) (F : I S),
    inhabited ( i, inhabited (F i) F i).

Definition Axiom_Of_Choice :=
   (I : S) (F : I S),
    ( i, inhabited (F i))
    inhabited ( i, F i).

Goal Axiom_Of_Choice Axiom_Of_Choice'.
  intros ac I F.
  unshelve eset (H := ac `{i in I | inhabited (F i)}
                         (fun iF (element i))
                         _). {
    cbn. intros i. apply (comprehension_condition i).
  } destruct H as [f].
  apply inhabits.

  intros i Hi.
  assert (i `{ i in I | inhabited (F i)}). {
    rewrite in_comprehension_iff_typed. assumption.
  }
  specialize (f (element i)).
  cbn in f. rewrite strip_element in f. exact f.
Qed.

Theorem Well_Ordering_to_Choice :
  Well_Ordering_Theorem Axiom_Of_Choice.
Proof.
  intros well_ordering I F H.

  destruct (well_ordering ( i I, F i)) as [R].
  apply inhabits.

  assert ( i, F i 𝒫 (⋃ i I, F i)) by automation.
  exact (fun ileast_element (element (F i)) (H i)).
Qed.

Lemma lemma1 (A B : S) :
  A A A
  A B 𝒫 A
  𝒫 A B.
Proof.
  intros H1 H2.

  assert (f : A B 𝒫 A × 𝒫 A). {

    transitivity (𝒫 A). {
      exact H2.
    }

    transitivity (𝒫 (A A)). {
      rewrite H1. reflexivity.
    }

    rewrite power_set_of_disjoint_union. reflexivity.

  } destruct f as [f].
  clear H1 H2.

  assert (H : A1 : 𝒫 A, A2 : 𝒫 A, (f⁻¹ `(A1, A2)).(Is_From_Right)). {

    set (g := π1 f inj1 _ _ : A 𝒫 A).
    assert (H : ¬ g.(Is_Surjective)). {
      intros H. apply (cantors_theorem A).
      exact (inhabits (build_surjection g H)).
    }

    change (¬ A1, a, A1 = g a) in H.

    apply not_all_ex_not in H. destruct H as [A1 H]. A1.

    intros A2.
    enough (¬ (f⁻¹ `(A1, A2)).(Is_From_Left)). {
      destruct (from_left_or_right (f⁻¹ `(A1, A2))); tauto.
    }
    unfold Is_From_Left. unfold g in H; cbn in g.

    intros [a contra]. apply H. a.
    unfold compose. rewrite <- contra.
    rewrite cancel_inverse_right. rewrite left_projection_beta.
    reflexivity.
  }
  destruct H as [A1 H].

  unshelve eset (g (A2 : 𝒫 A) := extract_from_right (f⁻¹ `(A1, A2)) : B). {

    apply H.
  }

  simple refine (inhabits (build_injection g _)).
  intros A2 A2' H1. unfold g in H1.
  apply extract_from_right_is_injective in H1.
  apply bijection_is_injective in H1.
  apply pair_is_injective_right in H1.
  exact H1.

Qed.

Lemma lemma2 (x y : S) :
  Generalized_Continuum_Hypothesis
  Infinite x
  x x x
  𝒫 x 𝒫 x 𝒫 x
  y 𝒫 x
  y x 𝒫 x y.
Proof.
  intros gch. intros H1 H2 H3 H4.

  assert (x x y 𝒫 x). {
    split.
    - apply disjoint_union_is_increasing_on_left.
    - rewrite (power_set_is_increasing x) at 1.
      rewrite H4. rewrite H3. reflexivity.
  }

  assert (cases : x = x y
                  x y = 𝒫 x). {

    apply gch; assumption.
  } destruct cases as [-> | H5].

  - left. apply disjoint_union_is_increasing_on_right.

  - right. apply lemma1.
    + assumption.
    + rewrite H5. reflexivity.

Qed.

Theorem sierpinskis_theorem :
  Generalized_Continuum_Hypothesis Axiom_Of_Choice.
Proof.
  intros gch. apply Well_Ordering_to_Choice. intros x.

  enough (H : O : Ordinal, x O). {
    destruct H as [O [f]].
    apply inhabits.

    apply (transport_well_order (injection_as_bijection_into_image f)⁻¹).
    exact (restrict_well_order (ordinal_order O) (image_of f)).
  }



  set (x0 := x Numeral).
  set (x' n := iter (1 + n) 𝒫 x0).

   (hartogs_number (x' 0)).

  transitivity (x' 0). {
    cbn. unfold x0.
    rewrite <- power_set_is_increasing.
    rewrite <- disjoint_union_is_increasing_on_left.
    reflexivity.
  }

  assert (H1 : n, x' n x' n x' n). {
    intros n. change (x' n) with (𝒫 (iter n 𝒫 x0)).
    symmetry. apply power_set_equiv_power_set_plus_power_set.
    induction n.
    - cbn. unfold x0. apply disjoint_union_is_increasing_on_right.
    - change (iter (Datatypes.S n) 𝒫 x0) with (𝒫 (iter n 𝒫 x0)).
      rewrite power_set_is_increasing at 1. rewrite IHn at 1. reflexivity.
  }



  assert (H2 : (hartogs_number (x' 0) : S) x' 6) by
    apply hartogs_number_has_upper_bound.
  revert H2. generalize 6. intros n H2. induction n.
  - apply hartogs_number_is_not_smaller in H2. contradiction.
  - assert (cases : (hartogs_number (x' 0) : S) x' n
                    x' (1 + n) hartogs_number (x' 0)). {
      apply lemma2; auto.
      - unfold Infinite. clear. induction n.
        + cbn. unfold x0. rewrite <- power_set_is_increasing.
          apply disjoint_union_is_increasing_on_right.
        + change (Numeral 𝒫 (x' n)).
          rewrite IHn. apply power_set_is_increasing.
      - apply H1.
    } destruct cases as [ | <-].
    + apply IHn. assumption.
    + unfold x'. generalize (1 + n) x0; clear. intros n x0; induction n.
      × reflexivity.
      × rewrite IHn. rewrite power_set_is_increasing. reflexivity.

Qed.