Truncation Lemma


Require Export Embeddings Stage.

ZF-closed classes induce submodels of ZF


Section Sub.

  Variable set : ZFStruct.
  Variable p : set -> Prop.

  Hypothesis set_ZF : ZFS set.
  Hypothesis PC : closed_ZF p.
  Hypothesis PWF : p <=p WF.

  (* We first turn the class P into a Z-structure *)

  Definition P :=
    { x | p x }.

  Definition toP x PX :=
    exist p x PX.

  Fact PI x :
    forall (PX PX' : p x), PX = PX'.
  Proof.
    apply proof_irrelevance.
  Qed.

  Lemma P_eq x y (PX : p x) (PY : p y) :
    toP PX = toP PY <-> x = y.
  Proof.
    split; intros H.
    - change (proj1_sig (toP PX) = proj1_sig (toP PY)). now rewrite H.
    - subst. now rewrite (PI PX PY).
  Qed.

  Lemma P_proj X :
    toP (proj2_sig X) = X.
  Proof.
    destruct X. reflexivity.
  Qed.

  Definition PS : SetStruct.
    apply (@Build_SetStruct P).
    intros [x _] [y _]. exact (x el y).
  Defined.

  Definition emclass (q : P -> Prop) x :=
    exists (PX : p x), q (toP PX).

  Definition PZ : ZStruct.
    apply (@Build_ZStruct PS).
    - exists 0. apply PC.
    - intros [x X] [y Y]. exists (upair x y). now apply PC.
    - intros [x X]. exists (union x). now apply PC.
    - intros [x X]. exists (power x). now apply PC.
    - intros q [x X]. exists (sep (emclass q) x).
      apply PC; trivial. now intros a a' -> % ZFSExt.
  Defined.

  (* P is a model of Z *)

  Lemma P_Ext (x y : PS) :
    x == y <-> x = y.
  Proof.
    split; try now intros ->.
    destruct x as [x PX], y as [y PY]. intros [H1 H2].
    apply P_eq. apply ZFSExt; split; intros z H3.
    - apply (H1 (exist p z (U_trans PC PX H3)) H3).
    - apply (H2 (exist p z (U_trans PC PY H3)) H3).
  Qed.

  Lemma P_WF (x : PS) :
    WF x.
  Proof.
    destruct x as [x PX]. induction (PWF PX) as [x _ IH].
    constructor. intros [y PY] Y. now apply IH.
  Qed.

  Lemma fress F :
    fres equiv F.
  Proof.
    now intros a a' -> % ZFSExt.
  Qed.

  Lemma cress P :
    cres equiv P.
  Proof.
    now intros a a' -> % ZFSExt.
  Qed.

  Hint Resolve fress cress.

  Fact P_Z :
    Z PZ.
  Proof.
    split; try apply P_Ext.
    split; try apply P_WF. split.
    - now intros x x' y -> % P_Ext.
    - intros [x PX] H. apply (Eset (z:=x)), H.
    - intros [x PX] [y PY] [z PZ].
      now rewrite (Pair x y z), !P_Ext, !ZFSExt, !P_eq.
    - intros [x PX] [y PY]. rewrite (Union x y). split; intros H.
      + destruct H as [z[Z1 Z2]]. now exists (exist p z (U_trans PC PX Z1)).
      + destruct H as [[z PZ] Z]. now exists z.
    - intros [x PX] [y PY]. rewrite (Power x y). split; intros H.
      + intros [z PZ] Z. apply H, Z.
      + intros z Z. apply (H (exist p z (U_trans PC PY Z)) Z).
    - intros q [x PX] [y PY] _. split; intros H.
      + apply (Sep (P:=emclass q)) in H as [H1 [PY' H2]]; trivial.
        split; trivial. now rewrite (PI PY PY').
      + apply (Sep (P:=emclass q)); trivial. destruct H as [H1 H2].
        split; trivial. now exists PY.
  Qed.

  (* Next we turn P into a ZF'-structure *)

  Lemma ZFSDesc (P : set -> Prop) x :
     P x -> unique P -> P (delta P).
  Proof.
    intros H1 H2. apply ZFSDesc1.
    exists x. intros y. rewrite ZFSExt.
    split; intros H.
    - now apply H2.
    - now rewrite H.
  Qed.

  Definition embed F x y :=
    exists (PX : p x) (PY : p y), (toP PY) = F (toP PX).

  Lemma embed_unique F x :
    unique (embed F x).
  Proof.
    intros y y' [PX[PY H1]] [PX'[PY' H2]].
    rewrite (PI PX' PX) in H2. rewrite <- H2 in H1.
    now apply P_eq in H1.
  Qed.

  Lemma embed_delta F x :
     p x -> embed F x (delta (embed F x)).
  Proof.
    intros H.
    pose (z := proj1_sig (F (toP H))).
    pose (PZ := proj2_sig (F (toP H))).
    eapply ZFSDesc; try apply embed_unique.
    exists H, PZ. rewrite <- P_proj. reflexivity.
  Qed.

  Definition rep' F x :=
    frep (fun y => delta (embed F y)) (sep p x).

  Definition PZF' : ZFStruct'.
    apply (@Build_ZFStruct' PZ).
    intros F [x X]. exists (rep' F x).
    repeat apply PC; trivial.
    intros z [y[H -> % ZFSExt]] % ZFSFrep; trivial.
    apply Sep in H as [H1 H2]; trivial.
    now apply (@embed_delta F) in H2 as [PY[PZ_]].
  Defined.

  (* We prove that P is a model of ZF' *)

  Lemma ax_rep' F x z :
    z el rep' F x <-> exists y, y el x /\ embed F y z.
  Proof.
    unfold rep'. rewrite ZFSFrep; trivial.
    split; intros [y[Y1 Y2]]; exists y; split.
    - now apply Sep in Y1.
    - apply ZFSExt in Y2. subst z. apply Sep in Y1; trivial. now apply embed_delta.
    - destruct Y2 as [PY _]. apply Sep; trivial. now split.
    - apply ZFSExt. apply (embed_unique Y2).
      apply (ZFSDesc Y2), embed_unique.
  Qed.

  Fact P_ZF' :
    ZF' PZF'.
  Proof.
    split; try apply P_Ext.
    split; try apply P_Z.
    intros F [x PX] [z PZ] _. rewrite (ax_rep' F x z).
    split; intros H.
      - destruct H as [y[Y1 [PY[PZ' Y2]]]].
        exists (toP PY). split; trivial.
        now rewrite P_Ext, (PI PZ PZ').
      - destruct H as [[y PY][Y1 Y2 % P_Ext]].
        exists y. split; trivial. now exists PY, PZ.
  Qed.

  (* We finally define a description operator for P *)

  Definition issing (q : PS -> Prop) :=
    ex q /\ unique q.

  Lemma sing_eqcl q :
    iseqcl q -> issing q.
  Proof.
    intros [x X]. split.
    - exists x. now apply X, P_Ext.
    - intros y y'. rewrite !X, !P_Ext. congruence.
  Qed.

  Definition desc (q : P -> Prop) :=
    sep (fun _ => issing q) (delta (emclass q)).

  Fact sep_true (x : set) (Q : set -> Prop) :
    (forall x, Q x) -> sep Q x = x.
  Proof.
    intros H. apply ZFSExt; split.
    - intros y [Y1 Y2] % Sep; trivial.
    - intros y Y. apply Sep; auto.
  Qed.

  Fact sep_false (x : set) (Q : set -> Prop) :
    (forall x, ~ Q x) -> sep Q x = 0.
  Proof.
    intros H. apply ZFSExt; split.
    - intros y [Y1 Y2] % Sep; trivial. contradiction (H y).
    - now intros y Y % Eset.
  Qed.

  Fact desc_issing q :
    issing q -> desc q = delta (emclass q).
  Proof.
    intros H. unfold desc.
    now rewrite sep_true.
  Qed.

  Fact desc_nissing q :
    ~ issing q -> desc q = 0.
  Proof.
    intros H. unfold desc.
    now rewrite sep_false.
  Qed.

  Lemma emc_issing q :
    issing q -> exists x, emclass q x /\ unique (emclass q).
  Proof.
    intros [[x X] H]. exists (proj1_sig x). split.
    - exists (proj2_sig x). now rewrite P_proj.
    - intros a b [A1 A2] [B1 B2].
      apply (@P_eq a b A1 B1). now apply H.
  Qed.

  Lemma desc_p q :
    p (desc q).
  Proof.
    destruct (classic (issing q)) as [H|H].
    - rewrite desc_issing; trivial.
      destruct (emc_issing H) as [x[X1 X2]].
      rewrite (X2 (delta (emclass q)) x); trivial.
      + now destruct X1.
      + now apply (ZFSDesc X1).
    - rewrite desc_nissing; trivial. apply PC.
  Qed.

  Definition descp q :=
    toP (desc_p q).

  Definition IM :=
    @Build_ZFStruct PZF' descp.

  (* The main result is that P is a model of ZF *)

  Lemma issing_ext q q' :
    issing q -> (forall x : IM, q x <-> q' x) -> issing q'.
  Proof.
    intros [[x X] U] H. split.
    - exists x. now apply H.
    - intros y y'. rewrite <- !H. apply U.
  Qed.

  Lemma delta_equal (Q : set -> Prop) x :
    Q x -> unique Q -> delta Q = x.
  Proof.
    intros H1 H2. apply H2; trivial.
    now apply (ZFSDesc H1).
  Qed.

  Theorem IM_ZF :
    ZF IM.
  Proof.
    split; try apply P_Ext.
    split; try apply P_ZF'.
    - intros q QE % sing_eqcl. simpl.
      cut (emclass q (delta (emclass q))).
      + intros [H1 H2]. unfold descp.
        destruct (P_eq H1 (desc_p q)) as [_ <-]; trivial.
        symmetry. now apply desc_issing.
      + destruct (emc_issing QE) as [x[X1 X2]].
        now apply (ZFSDesc X1).
    - intros q q' E. apply P_eq.
      destruct (classic (issing q)) as [H|H];
      destruct (classic (issing q')) as [H'|H'].
      + rewrite (desc_issing H), (desc_issing H').
        apply emc_issing in H as [y[Y1 Y2]].
        apply emc_issing in H' as [y'[Y1' Y2']].
        rewrite (delta_equal Y1), (delta_equal Y1'); trivial.
        apply Y2; trivial. destruct Y1' as [PY Y].
        exists PY. now apply E.
      + contradict H'. now apply (issing_ext H).
      + contradict H. apply (issing_ext H'). intros x. now rewrite E.
      + now rewrite (desc_nissing H), (desc_nissing H').
  Qed.

End Sub.

Hint Resolve cress fress.

Models of strength n admit inner models of ZFn


Section IMISO.

  Context { M : ZFStruct }.
  Context { MZF : ZF M }.

  Variable p : M -> Prop.
  Hypothesis PC : closed_ZF p.

  Lemma ZF_ZFS :
    ZFS M.
  Proof.
    split; try apply HiZF.
    - apply ZFExt.
    - apply Desc1.
    - apply Desc2.
  Qed.

  Definition MP :=
    IM ZF_ZFS PC.

  Definition exmp x (PX : p x) : MP :=
    exist _ x PX.

  Instance MPZF :
    ZF MP.
  Proof.
    apply IM_ZF. apply WF_sub.
  Qed.

  Definition pi (x : MP) : M :=
    proj1_sig x.

  Lemma pi_mor (x y : MP) :
    x el y <-> pi x el pi y.
  Proof.
    now destruct x, y; simpl.
  Qed.

  Lemma pi_sur (x : MP) (y' : M) :
    y' el pi x -> exists y, y el x /\ pi y == y'.
  Proof.
    destruct x as [x' X]. intros H; simpl in H.
    assert (Y : p y') by now apply (U_trans PC X).
    exists (toP Y). simpl. split; trivial. reflexivity.
  Qed.

  Lemma IM_universe u (PU : p u) :
    universe u <-> universe (exmp PU).
  Proof.
    rewrite (h_universe (h:=pi)).
    - simpl. reflexivity.
    - apply pi_mor.
    - apply pi_sur.
  Qed.

  Lemma IM_strength x n (PX : p x) :
     strength n x <-> strength n (exmp PX).
  Proof.
    rewrite (h_strength (h:=pi)).
    - simpl. reflexivity.
    - apply pi_mor.
    - apply pi_sur.
  Qed.

End IMISO.

Lemma shrink n :
  (exists M, ZFge n M) -> (exists M, ZFn n M).
Proof.
  intros [M[MZF[X XN]]].
  destruct (classic (exists X', strength (S n) X')) as [[X'[U'[U1' U2']]]|H].
  - apply universe_least in U2' as [U[[U1 U2] U3]].
    clear U1' U' X'. exists (IM ZF_ZFS U1). split.
    + split; try apply IM_ZF, WF_sub.
      apply (uni_strength U1) in U2 as [U'[H1 H2]].
      exists (exmp U1 H1). now apply IM_strength.
    + intros [[X' H] [U'[H1 H2]] % IM_strength].
      apply (WF_no_loop (x:=U')). apply U3; trivial.
      now apply (universe_trans U1 H).
  - exists M. split; trivial. split; trivial. now exists X.
Qed.