Theory Not_CH

theory Not_CH
  imports
    Cardinal_Preservation
begin

definition
  Add_subs :: "[i,i]  i" where
  "Add_subs(κ,α)  Fn(ω,κ×α,2)"

locale M_master= M_cohen +
  assumes
  domain_separation: "M(x)  separation(M, λz. x  domain(z))"
  and
  inj_dense_separation: "M(x)  M(w) 
    separation(M, λz. nω.    w, n, 1  z  x, n, 0  z)"
  and
  lam_apply_replacement: "M(A)  M(f) 
      strong_replacement(M, λx y. y = x, λnA. f ` x, n)"
  and
  UN_lepoll_assumptions:
  "M(A)  M(b)  M(f)  M(A')  separation(M, λy. xA'. y = x, μ i. xif_range_F_else_F((`)(A), b, f, i))"

begin

lemma (in M_FiniteFun) Fn_nat_closed :
  assumes "M(A)" "M(B)" shows "M(Fn(ω,A,B))"
  using assms Fn_nat_eq_FiniteFun
  by simp

lemma Aleph_rel2_closed [intro,simp]: "M(2M)"
  using nat_into_M[of 2] nat_into_Ord by simp

end (* M_master *)

locale M_master_sub= M_master + N:M_master N for N +
  assumes
    M_imp_N: "M(x)  N(x)" and
    Ord_iff: "Ord(x)  M(x)  N(x)"

sublocale M_master_sub  M_N_Perm
  using M_imp_N by unfold_locales

context M_master_sub
begin

lemma cardinal_rel_le_cardinal_rel : "M(X)  |X|N  |X|M"
  using M_imp_N N.lepoll_rel_cardinal_rel_le[OF lepoll_rel_transfer Card_rel_is_Ord]
      cardinal_rel_eqpoll_rel[THEN eqpoll_rel_sym, THEN eqpoll_rel_imp_lepoll_rel]
  by simp

lemma Aleph_rel_sub_closed : "Ord(α)  M(α)  N(αM)"
  using Aleph_rel2_closed Ord_iff[THEN iffD1,
      OF Card_rel_Aleph_rel[THEN Card_rel_is_Ord]]
  by simp

lemma Card_rel_imp_Card_rel : "M(κ)  CardN(κ)  CardM(κ)"
  using N.Card_rel_is_Ord[of κ] M_imp_N Ord_cardinal_rel_le[of κ]
    cardinal_rel_le_cardinal_rel[of κ] le_anti_sym
  unfolding Card_rel_def by auto

lemma csucc_rel_le_csucc_rel :
  assumes "Ord(κ)" "M(κ)"
  shows "(κ+)M  (κ+)N"
proof -
  note assms
  moreover from this
  have "N(L)  CardN(L)  κ < L  M(L)  CardM(L)  κ < L"
    (is "?P(L)  ?Q(L)") for L
    using M_imp_N Ord_iff[THEN iffD2, of L] N.Card_rel_is_Ord lt_Ord
      Card_rel_imp_Card_rel by auto
  moreover from assms
  have "N((κ+)N)" "CardN((κ+)N)" "κ < (κ+)N"
    using N.lt_csucc_rel[of κ] N.Card_rel_csucc_rel[of κ] M_imp_N by simp_all
  ultimately
  show ?thesis
    using M_imp_N Least_antitone[of _ ?P ?Q] unfolding csucc_rel_def by blast
qed

lemma Aleph_rel_le_Aleph_rel : "Ord(α)  M(α) αM αN"
proof (induct rule:trans_induct3)
  case 0
  then
  show ?case
    using Aleph_rel_zero N.Aleph_rel_zero by simp
next
  case (succ x)
  then
  have "ℵxM xN" "Ord(x)" "M(x)" by simp_all
  moreover from this
  have "(xM+)M  (xN+)M"
    using M_imp_N Ord_iff[THEN iffD2, OF N.Card_rel_is_Ord]
    by (intro csucc_rel_le_mono) simp_all
  moreover from calculation
  have "(xN+)M  (xN+)N"
    using M_imp_N N.Card_rel_is_Ord Ord_iff[THEN iffD2, OF N.Card_rel_is_Ord]
    by (intro csucc_rel_le_csucc_rel) auto
  ultimately
  show ?case
    using M_imp_N Aleph_rel_succ N.Aleph_rel_succ csucc_rel_le_csucc_rel
      le_trans by auto
next
  case (limit x)
  then
  show ?case
    using M_imp_N Aleph_rel_limit N.Aleph_rel_limit
     by simp (blast dest: transM intro!:le_implies_UN_le_UN)
qed

end (* M_master_sub *)

lemmas (in M_ZFC_trans) sep_instances =
 separation_toplevel1_body separation_toplevel2_body separation_toplevel3_body
 separation_toplevel4_body separation_toplevel5_body separation_toplevel6_body
 separation_toplevel7_body separation_toplevel8_body separation_toplevel9_body
 separation_toplevel10_body separation_toplevel11_body separation_Ord
 separation_toplevel12_body separation_insnd_ballPair
 separation_restrict_eq_dom_eq separation_restrict_eq_dom_eq_pair
 separation_ifrangeF_body separation_ifrangeF_body2 separation_ifrangeF_body3
 separation_ifrangeF_body4 separation_ifrangeF_body5 separation_ifrangeF_body6
 separation_ifrangeF_body7

(* FIXME: the second instance has been proved in Lambda Replacement, it shouldn't be here. *)
lemmas (in M_ZF_trans) repl_instances = lam_replacement_inj_rel
  lam_replacement_cardinal[unfolded lam_replacement_def] replacement_trans_apply_image
  replacement_abs_apply_pair

sublocale M_ZFC_trans  M_master "##M"
  by unfold_locales (simp_all add:repl_instances sep_instances del:setclass_iff)

context M_ctm_AC
begin

― ‹FIXME: using notation as if term‹Add_subs› were used›
lemma ccc_Add_subs_Aleph_2 : "cccM(Fn(ω,2M × ω,2),Fnle(ω,2M × ω,2))"
proof -
  interpret M_add_reals "##M" "ℵ2M × ω"
    by unfold_locales blast
  show ?thesis
    using ccc_rel_Fn_nat by fast
qed

end (* M_ctm *)

sublocale G_generic_AC  M_master_sub "##M" "##(M[G])"
  using M_subset_MG[OF one_in_G] generic Ord_MG_iff
  by unfold_locales auto

lemma (in M_trans) mem_F_bound4 :
  fixes F A
  defines "F  (`)"
  shows "xF(A,c)  c  (range(f)  domain(A))"
  using apply_0 unfolding F_def
  by (cases "M(c)", auto simp:F_def)

lemma (in M_trans) mem_F_bound5 :
  fixes F A
  defines "F  λ_ x. A`x "
  shows "xF(A,c)  c  (range(f)  domain(A))"
  using apply_0 unfolding F_def
  by (cases "M(c)", auto simp:F_def drSR_Y_def dC_F_def)

context G_generic_AC begin

context
  includes G_generic_lemmas
begin

lemma G_in_MG : "G  M[G]"
  using G_in_Gen_Ext[ OF _ one_in_G, OF _ generic]
  by blast

lemma ccc_preserves_Aleph_succ :
  assumes "cccM(P,leq)" "Ord(z)" "z  M"
  shows "CardM[G](ℵsucc(z)M)"
proof (rule ccontr)
  assume "¬ CardM[G](ℵsucc(z)M)"
  moreover
  note z  M
  moreover from this and ‹Ord(z)
  have "Ord(succ(z)M)"
    using Card_rel_Aleph_rel[of "succ(z)", THEN Card_rel_is_Ord]
    by fastforce
  ultimately
  obtain α f where "α <succ(z)M" "f  surjM[G](α,succ(z)M)"
    using ext.lt_surj_rel_empty_imp_Card_rel M_subset_MG[OF one_in_G, OF generic]
      Aleph_rel_closed[of "succ(z)"] ‹Ord(z) by simp blast
  moreover from this and zM ‹Ord(z)
  have "α  M" "f  M[G]"
    using Aleph_rel_closed[of "succ(z)"] ext.trans_surj_rel_closed
    by (auto dest:transM ext.transM dest!:ltD)
  moreover
  note ‹cccM(P,leq) zM
  ultimately
  obtain F where "F:αPow(succ(z)M)" "βα. f`β  F`β" "βα. |F`β|M  ω"
    "F  M"
    using ccc_fun_approximation_lemma[of α "ℵsucc(z)M" f]
      ext.mem_surj_abs[of f α "ℵsucc(z)M"] ‹Ord(z)
      Aleph_rel_closed[of "succ(z)"] surj_is_fun[of f α "ℵsucc(z)M"] by auto
  then
  have "β  α  |F`β|M 0M" for β
    using Aleph_rel_zero by simp
  interpret M_replacement_lepoll "##M" "(`)"
    using UN_lepoll_assumptions lam_replacement_apply lam_replacement_inj_rel
      mem_F_bound4 apply_0
    unfolding lepoll_assumptions_defs
  proof (unfold_locales, 
      rule_tac [3] lam_Least_assumption_general[where U=domain, OF _ mem_F_bound4], simp_all) 
    fix A i x
    assume "A  M" "x  M" "x  A ` i"
    then
    show "i  M"
      using apply_0[of i A] transM[of _ "domain(A)", simplified]
      by force
  qed
  from α  M F:αPow(succ(z)M) FM
  interpret M_cardinal_UN_lepoll "##M" "λβ. F`β" α
    using Aleph_rel_closed[of 0] UN_lepoll_assumptions lepoll_assumptions
      lam_replacement_apply lam_replacement_inj_rel
  proof (unfold_locales, auto dest:transM simp del:if_range_F_else_F_def)
    show "w  F ` x  x  M" for w x
    proof -
      fix w x
      assume "w  F`x"
      then
      have "x  domain(F)"
        using apply_0 by auto
      with F:αPow(succ(z)M)
      have "x  α"
        using domain_of_fun by simp
      with α  M
      show "x  M" by (auto dest:transM)
    qed
   show "w  F ` x  x  M" for w x ― ‹FIXME: why two times?›
    proof -
      fix w x
      assume "w  F`x"
      then
      have "x  domain(F)"
        using apply_0 by auto
      with F:αPow(succ(z)M)
      have "x  α"
        using domain_of_fun by simp
      with α  M
      show "x  M" by (auto dest:transM)
    qed
  next
    fix f b
    assume "bM" "fM"
    with FM
    show "lam_replacement(##M, λx. μ i. x  if_range_F_else_F((`)(F), b, f, i))"
      using UN_lepoll_assumptions mem_F_bound5
      by (rule_tac lam_Least_assumption_general[where U="domain", OF _ mem_F_bound5])
        simp_all
  qed
  from α <succ(z)M α  M assms
  have "αMzM"
    using
      Aleph_rel_zero
      cardinal_rel_lt_csucc_rel_iff[of "ℵzM" α]
      le_Card_rel_iff[of "ℵzM" α]
      Aleph_rel_succ[of z] Card_rel_lt_iff[of α "ℵsucc(z)M"]
      lt_Ord[of α "ℵsucc(z)M"]
      csucc_rel_closed[of "ℵzM"] Card_rel_csucc_rel[of "ℵzM"]
      Aleph_rel_closed[of z]
      Card_rel_Aleph_rel[THEN Card_rel_is_Ord, OF _ _ Aleph_rel_closed]
    by simp
  with α <succ(z)M βα. |F`β|M  ω α  M assms
  have "|βα. F`β|M zM"
    using InfCard_rel_Aleph_rel[of z] Aleph_rel_zero
      subset_imp_lepoll_rel[THEN lepoll_rel_imp_cardinal_rel_le,
        of "βα. F`β" "ℵzM"]
      Aleph_rel_closed[of z] Aleph_rel_succ
      Aleph_rel_increasing[THEN leI, THEN [2] le_trans, of _ 0 z]
      Ord_0_lt_iff[THEN iffD1, of z]
    by (cases "0<z"; rule_tac leqpoll_rel_imp_cardinal_rel_UN_le) (auto, force)
  moreover
  note zM ‹Ord(z)
  moreover from βα. f`β  F`β f  surjM[G](α,succ(z)M)
    α  M f  M[G] and this
  have "ℵsucc(z)M  (βα. F`β)"
    using Aleph_rel_closed[of "succ(z)"] ext.mem_surj_abs
    by (force simp add:surj_def)
  moreover from F  M α  M
  have "(xα. F ` x)  M"
    using j.B_replacement― ‹NOTE: it didn't require @{thm j.UN_closed} before!›
    by (intro Union_closed[simplified] RepFun_closed[simplified])
      (auto dest:transM)
  ultimately
  have "ℵsucc(z)M zM"
    using subset_imp_le_cardinal_rel[of "ℵsucc(z)M" "βα. F`β"]
      Aleph_rel_closed[of "succ(z)"] le_trans
    by auto
  with assms
  show "False"
    using Aleph_rel_increasing not_le_iff_lt[of "ℵsucc(z)M" "ℵzM"]
      Card_rel_Aleph_rel[THEN Card_rel_is_Ord, OF _ _ Aleph_rel_closed]
    by auto
qed

end (* G_generic_lemmas *)

end (* G_generic *)

context M_ctm
begin

abbreviation
  Add :: "i" where
  "Add  Fn(ω,2M × ω, 2)"

end (* M_ctm *)

locale add_generic= G_generic_AC "Fn(ω,2##M × ω, 2)" "Fnle(ω,2##M × ω, 2)" 0

sublocale add_generic  cohen_data ω "ℵ2M × ω" 2 by unfold_locales auto

context add_generic
begin

notation Leq (infixl "" 50)
notation Incompatible (infixl "" 50)
notation GenExt_at_P ("_[_]" [71,1])

lemma Add_subs_preserves_Aleph_succ : "Ord(z)  zM  CardM[G](ℵsucc(z)M)"
  using ccc_preserves_Aleph_succ ccc_Add_subs_Aleph_2
  by auto

lemma Aleph_rel_nats_MG_eq_Aleph_rel_nats_M :
  includes G_generic_lemmas
  assumes "z  ω"
  shows "ℵzM[G] =zM"
  using assms
proof (induct)
  case 0
  have "ℵ0M[G] = ω"
    using ext.Aleph_rel_zero .
  also
  have "ω =0M"
    using Aleph_rel_zero by simp
  finally
  show ?case .
next
  case (succ z)
  then
  have "ℵsucc(z)M succ(z)M[G]"
    using Aleph_rel_le_Aleph_rel nat_into_M by simp
  moreover from z  ω
  have "ℵzM  M[G]" "ℵsucc(z)M  M[G]"
    using Aleph_rel_closed nat_into_M by simp_all
  moreover from this and ‹ℵzM[G] =zM z  ω
  have "ℵsucc(z)M[G] succ(z)M"
    using ext.Aleph_rel_succ nat_into_M
      Add_subs_preserves_Aleph_succ[THEN ext.csucc_rel_le, of z]
      Aleph_rel_increasing[of z "succ(z)"]
    by simp
  ultimately
  show ?case using le_anti_sym by blast
qed

abbreviation
  f_G :: "i" (fG) where
  "fG  G"

abbreviation
  dom_dense :: "ii" where
  "dom_dense(x)  { pAdd . x  domain(p) }"

― ‹FIXME write general versions of this for term‹Fn(ω,I,J)
    in a context with a generic filter for it›
lemma dense_dom_dense : "x 2M × ω  dense(dom_dense(x))"
proof
  fix p
  assume "x 2M × ω" "p  Add"
  show "ddom_dense(x). d  p"
  proof (cases "x  domain(p)")
    case True
    with x 2M × ω p  Add›
    show ?thesis using refl_leq by auto
  next
    case False
    note p  Add›
    moreover from this and False and x 2M × ω
    have "cons(x,0, p)  Add"
      using FiniteFun.consI[of x "ℵ2M × ω" 0 2 p]
        Fn_nat_eq_FiniteFun by auto
    moreover from p  Add›
    have "xdomain(cons(x,0, p))" by simp
    ultimately
    show ?thesis
      by (fastforce del:FnD)
  qed
qed

(*
NOTE Class model version?
lemma dom_dense_closed[intro,simp]: "x ∈ ℵ2M × ω ⟹ M(dom_dense(x))" *)
lemma dom_dense_closed [intro,simp]: "x 2M × ω  dom_dense(x)  M"
  using Fn_nat_closed Aleph_rel2_closed domain_separation[of x] nat_into_M
  by (rule_tac separation_closed[simplified], blast dest:transM) simp

lemma domain_f_G : assumes "x 2M" "y  ω"
  shows "x, y  domain(fG)"
proof -
  from assms
  have "dense(dom_dense(x, y))" using dense_dom_dense by simp
  with assms
  obtain p where "pdom_dense(x, y)" "pG"
    using generic[THEN M_generic_denseD, of "dom_dense(x, y)"]
    by auto
  then
  show "x, y  domain(fG)" by blast
qed

― ‹MOVE THIS to 🗏‹Cohen_Posets.thy›
lemma Fn_nat_subset_Pow : "Fn(ω,I,J)  Pow(I×J)"
  using subset_trans[OF FiniteFun.dom_subset Fin.dom_subset]
    Fn_nat_eq_FiniteFun by simp

lemma f_G_funtype :
  includes G_generic_lemmas
  shows "fG :2M × ω  2"
  using generic domain_f_G
  unfolding Pi_def
proof (auto)
  show "x  B  B  G  x  (2M × ω) × 2" for B x
    using Fn_nat_subset_Pow by blast
  show "function(fG)"
    using Un_filter_is_function generic
    unfolding M_generic_def by fast
qed

abbreviation
  inj_dense :: "iii" where
  "inj_dense(w,x) 
    { pAdd . (nω. <<w,n>,1>  p  <<x,n>,0>  p) }"

― ‹FIXME write general versions of this for term‹Fn(ω,I,J)
    in a context with a generic filter for it›
lemma dense_inj_dense :
  assumes "w 2M" "x 2M" "w  x"
  shows "dense(inj_dense(w,x))"
proof
  fix p
  assume "p  Add"
  then
  obtain n where "<w,n>  domain(p)" "<x,n>  domain(p)" "n  ω"
  proof -
    {
      assume "<w,n>  domain(p)  <x,n>  domain(p)" if "n  ω" for n
      then
      have "ω  range(domain(p))" by blast
      then
      have "¬ Finite(p)"
        using Finite_range Finite_domain subset_Finite nat_not_Finite
        by auto
      with p  Add›
      have False
        using Fn_nat_eq_FiniteFun FiniteFun.dom_subset[of "ℵ2M × ω" 2]
          Fin_into_Finite by auto
    }
    with that― ‹the shape of the goal puts assumptions in this variable›
    show ?thesis by auto
  qed
  moreover
  note p  Add› assms
  moreover from calculation
  have "cons(x,n,0, p)  Add"
    using FiniteFun.consI[of "x,n" "ℵ2M × ω" 0 2 p]
      Fn_nat_eq_FiniteFun by auto
  ultimately
  have "cons(w,n,1, cons(x,n,0, p) )  Add"
    using FiniteFun.consI[of "w,n" "ℵ2M × ω" 1 2 "cons(x,n,0, p)"]
      Fn_nat_eq_FiniteFun by auto
  with n  ω
  show "dinj_dense(w,x). d  p"
    using p  Add› by (intro bexI) auto
qed

lemma inj_dense_closed [intro,simp]:
  "w 2M  x 2M  inj_dense(w,x)  M"
  using Fn_nat_closed Aleph_rel2_closed domain_separation[of x] nat_into_M
    inj_dense_separation transM[OF _ Aleph_rel2_closed]
  by (rule_tac separation_closed[simplified]; simp_all)

lemma Aleph_rel2_new_reals :
  assumes "w 2M" "x 2M" "w  x"
  shows "(λnω. fG ` w, n)  (λnω. fG ` x, n)"
proof -
  from assms
  have "dense(inj_dense(w,x))" using dense_inj_dense by simp
  with assms
  obtain p where "pinj_dense(w,x)" "pG"
    using generic[THEN M_generic_denseD, of "inj_dense(w,x)"]
    by blast
  then
  obtain n where "n  ω" "w, n, 1  p" "x, n, 0  p"
    by blast
  moreover from this and pG
  have "w, n, 1  fG" "x, n, 0  fG" by auto
  moreover from calculation
  have "fG ` w, n = 1" "fG ` x, n = 0"
    using f_G_funtype apply_equality
    by auto
  ultimately
  have "(λnω. fG ` w, n) ` n  (λnω. fG ` x, n) ` n"
    by simp
  then
  show ?thesis by fastforce
qed

definition
  h_G :: "i" (hG) where
  "hG  λα2M. λnω. fG`<α,n>"

lemma h_G_in_MG [simp]:
  includes G_generic_lemmas
  shows "hG  M[G]"
  using Aleph_rel2_closed
    ext.lam_apply_replacement ext.apply_replacement2
    ext.Union_closed[simplified, OF G_in_MG]
    ― ‹The "simplified" here is because of
        the term‹setclass› ocurrences›
    ext.nat_in_M Aleph_rel2_closed ext.nat_into_M
  unfolding h_G_def
  by (rule_tac ext.lam_closed[simplified] | auto dest:transM)+

lemma h_G_inj_Aleph_rel2_reals : "hG  injM[G](ℵ2M, ωM[G] 2)"
  using Aleph_rel_sub_closed
proof (intro ext.mem_inj_abs[THEN iffD2])
  show "hG  inj(2M, ωM[G] 2)"
    unfolding inj_def
  proof (intro ballI CollectI impI)
    show "hG 2M  ωM[G] 2"
      using f_G_funtype G_in_MG ext.nat_into_M unfolding h_G_def
      apply (intro lam_type ext.mem_function_space_rel_abs[THEN iffD2], simp_all)
      apply (rule_tac ext.lam_closed[simplified], simp_all)
       apply (rule ext.apply_replacement2)
         apply (auto dest:ext.transM[OF _ Aleph_rel_sub_closed])
      done
    fix w x
    assume "w 2M" "x 2M" "hG ` w = hG ` x"
    then
    show "w = x"
      unfolding h_G_def using Aleph_rel2_new_reals by auto
  qed
qed simp_all

lemma Aleph2_extension_le_continuum_rel :
  includes G_generic_lemmas
  shows "ℵ2M[G]  2↑ℵ0M[G],M[G]"
proof -
  have "ℵ2M  M[G]" "Ord(2M)"
    using Card_rel_Aleph_rel[THEN Card_rel_is_Ord, of 2]
      Aleph_rel2_closed
    by auto
  moreover from this
  have "ℵ2MM[G] ωM[G] 2"
    using ext.def_lepoll_rel[of "ℵ2M" "ωM[G] 2",
        OF _ ext.function_space_rel_closed]
      h_G_inj_Aleph_rel2_reals h_G_in_MG ext.nat_into_M ext.M_nat
    by auto
  moreover from calculation
  have "ℵ2MM[G] |ωM[G] 2|M[G]"
    using ext.lepoll_rel_imp_lepoll_rel_cardinal_rel by simp
  ultimately
  have "|2M|M[G]  2↑ℵ0M[G],M[G]"
    using ext.lepoll_rel_imp_cardinal_rel_le[of "ℵ2M" "ωM[G] 2",
        OF _ _ ext.function_space_rel_closed] ext.nat_into_M ext.M_nat
      ext.Aleph_rel_zero Aleph_rel_nats_MG_eq_Aleph_rel_nats_M
    unfolding cexp_rel_def by simp
  then
  show "ℵ2M[G]  2↑ℵ0M[G],M[G]"
    using Aleph_rel_nats_MG_eq_Aleph_rel_nats_M
      ext.Card_rel_Aleph_rel[of 2, THEN ext.Card_rel_cardinal_rel_eq]
      ext.Aleph_rel2_closed
    by simp
qed

lemma Aleph_rel_lt_continuum_rel : "ℵ1M[G] < 2↑ℵ0M[G],M[G]"
  using Aleph2_extension_le_continuum_rel
    ext.Aleph_rel_increasing[of 1 2] le_trans by auto

corollary not_CH: "ℵ1M[G]  2↑ℵ0M[G],M[G]"
  using Aleph_rel_lt_continuum_rel by auto

end (* add_generic *)

definition
  ContHyp :: "o" where
  "ContHyp 1 = 2↑ℵ0"

relativize functional "ContHyp" "ContHyp_rel"
notation ContHyp_rel (CH⇗_)
relationalize "ContHyp_rel" "is_ContHyp"

context M_master
begin

is_iff_rel for "ContHyp"
  using is_cexp_iff is_Aleph_iff[of 0] is_Aleph_iff[of 1] unfolding is_ContHyp_def ContHyp_rel_def
  by auto (rule_tac x=0 in rexI, auto)

end (* M_master *)

synthesize "is_ContHyp" from_definition assuming "nonempty"
arity_theorem for "is_ContHyp_fm"

notation is_ContHyp_fm (⋅CH⋅)

theorem ctm_of_not_CH :
  assumes
    "M  ω" "Transset(M)" "M  ZFC"
  shows
    "N.
      M  N  N  ω  Transset(N)  N  ZFC  {⋅¬⋅CH⋅} 
      (α. Ord(α)  (α  M  α  N))"
proof -
  from M  ZFC›
  interpret M_ZFC M
    using M_ZFC_iff_M_satT
    by simp
  from ‹Transset(M)
  interpret M_ZF_trans M
    using M_ZF_iff_M_satT
    by unfold_locales
  from M  ω
  obtain enum where "enum  bij(ω,M)"
    using eqpoll_sym unfolding eqpoll_def by blast
  then
  interpret M_ctm_AC M enum by unfold_locales
  interpret forcing_data "Fn(ω,2M × ω,2)" "Fnle(ω,2M × ω,2)" 0 M enum
  proof -
    interpret cohen_data ω "ℵ2M × ω" 2 by unfold_locales auto
    show "forcing_data(Fn(ω,2M × ω, 2), Fnle(ω,2M × ω, 2), 0, M, enum)"
      using nat_into_M[of 2] M_nat
        Fn_nat_closed[OF cartprod_closed, OF Aleph_rel_closed, of 2 ω 2]
        Fnle_nat_closed[OF cartprod_closed, OF Aleph_rel_closed, of 2 ω 2]
      by (unfold_locales, simp_all)
  qed
  obtain G where "M_generic(G)"
    using generic_filter_existence[OF one_in_P]
    by auto
  moreover from this
  interpret add_generic M enum G by unfold_locales
  have "¬ (1M[G] = 2↑ℵ0M[G],M[G])"
    using not_CH .
  then
  have "M[G], []  ⋅¬⋅CH⋅"
    using ext.is_ContHyp_iff
    by (simp add:ContHyp_rel_def)
  then
  have "M[G]  ZFC  {⋅¬⋅CH⋅}"
    using M_ZFC_iff_M_satT[of "M[G]"] ext.M_ZFC_axioms by auto
  moreover
  have "Transset(M[G])" using Transset_MG .
  moreover
  have "M  M[G]" using M_subset_MG[OF one_in_G] generic by simp
  ultimately
  show ?thesis
    using Ord_MG_iff MG_eqpoll_nat
    by (rule_tac x="M[G]" in exI, simp)
qed

end