# Theory Cofinality

section‹Cofinality\label{sec:cofinality}›

theory Cofinality
imports
ZF_Library
begin

subsection‹Basic results and definitions›

text‹A set \<^term>‹X› is ∗‹cofinal› in \<^term>‹A› (with respect to the relation
\<^term>‹r›) if every element of \<^term>‹A› is bounded
above'' by some element of \<^term>‹X›. Note that \<^term>‹X› does not need
to be a subset of \<^term>‹A›.›
definition
cofinal :: "[i,i,i] ⇒ o" where
"cofinal(X,A,r) ≡ ∀a∈A. ∃x∈X. ⟨a,x⟩∈r ∨ a = x"

(*
(* Alternative definitions *)
definition
cofinal_predic :: "[i,i,[i,i]⇒o] ⇒ o" where
"cofinal_predic(X,A,r) ≡ ∀a∈A. ∃x∈X. r(a,x) ∨ a = x"

definition
f_cofinal :: "[i⇒i,i,i,i] ⇒ o" where
"f_cofinal(f,C,A,r) ≡ ∀a∈A. ∃x∈C. ⟨a,f(x)⟩∈r ∨ a = f(x)"

(* The next definition doesn't work if 0 is the top element of A.
But it works for limit ordinals. *)
definition
cofinal_fun' :: "[i,i,i] ⇒ o" where
"cofinal_fun'(f,A,r) == f_cofinal(λx. fx,domain(f),A, r)"
*)

text‹A function is cofinal if it range is.›
definition
cofinal_fun :: "[i,i,i] ⇒ o" where
"cofinal_fun(f,A,r) ≡ ∀a∈A. ∃x∈domain(f). ⟨a,fx⟩∈r ∨ a = fx"

lemma cofinal_funI:
assumes "⋀a. a∈A ⟹ ∃x∈domain(f). ⟨a,fx⟩∈r ∨ a = fx"
shows "cofinal_fun(f,A,r)"
using assms unfolding cofinal_fun_def by simp

lemma cofinal_funD:
assumes "cofinal_fun(f,A,r)" "a∈A"
shows "∃x∈domain(f). ⟨a,fx⟩∈r ∨ a = fx"
using assms unfolding cofinal_fun_def by simp

lemma cofinal_in_cofinal:
assumes
"trans(r)" "cofinal(Y,X,r)" "cofinal(X,A,r)"
shows
"cofinal(Y,A,r)"
unfolding cofinal_def
proof
fix a
assume "a∈A"
moreover from ‹cofinal(X,A,r)›
have "b∈A⟹∃x∈X. ⟨b,x⟩∈r ∨ b=x" for b
unfolding cofinal_def by simp
ultimately
obtain y where "y∈X" "⟨a,y⟩∈r ∨ a=y" by auto
moreover from ‹cofinal(Y,X,r)›
have "c∈X⟹∃y∈Y. ⟨c,y⟩∈r ∨ c=y" for c
unfolding cofinal_def by simp
ultimately
obtain x where "x∈Y" "⟨y,x⟩∈r ∨ y=x" by auto
with ‹a∈A› ‹y∈X› ‹⟨a,y⟩∈r ∨ a=y› ‹trans(r)›
show "∃x∈Y. ⟨a,x⟩∈r ∨ a=x" unfolding trans_def by auto
qed

lemma codomain_is_cofinal:
assumes "cofinal_fun(f,A,r)" "f:C → D"
shows "cofinal(D,A,r)"
unfolding cofinal_def
proof
fix b
assume "b ∈ A"
moreover from assms
have "a∈A ⟹ ∃x∈domain(f). ⟨a, f  x⟩ ∈ r ∨ a = fx" for a
unfolding cofinal_fun_def by simp
ultimately
obtain x where "x∈domain(f)" "⟨b, f  x⟩ ∈ r ∨ b = fx"
by blast
moreover from ‹f:C → D›  ‹x∈domain(f)›
have "fx∈D"
using domain_of_fun apply_rangeI by simp
ultimately
show  "∃y∈D. ⟨b, y⟩ ∈ r ∨ b = y" by auto
qed

lemma cofinal_range_iff_cofinal_fun:
assumes "function(f)"
shows "cofinal(range(f),A,r) ⟷ cofinal_fun(f,A,r)"
unfolding cofinal_fun_def
proof (intro iffI ballI)
fix a
assume "a∈A" ‹cofinal(range(f),A,r)›
then
obtain y where "y∈range(f)" "⟨a,y⟩ ∈ r ∨ a = y"
unfolding cofinal_def by blast
moreover from this
obtain x where "⟨x,y⟩∈f"
unfolding range_def domain_def converse_def by blast
moreover
note ‹function(f)›
ultimately
have "⟨a, f  x⟩ ∈ r ∨ a = f  x"
using function_apply_equality by blast
with ‹⟨x,y⟩∈f›
show "∃x∈domain(f). ⟨a, f  x⟩ ∈ r ∨ a = f  x"  by blast
next
assume "∀a∈A. ∃x∈domain(f). ⟨a, f  x⟩ ∈ r ∨ a = f  x"
with assms
show "cofinal(range(f), A, r)"
using function_apply_Pair[of f] unfolding cofinal_def by fast
qed

lemma cofinal_comp:
assumes
"f∈ mono_map(C,s,D,r)" "cofinal_fun(f,D,r)" "h:B → C"  "cofinal_fun(h,C,s)"
"trans(r)"
shows "cofinal_fun(f O h,D,r)"
unfolding cofinal_fun_def
proof
fix a
from ‹f∈ mono_map(C,s,D,r)›
have "f:C → D"
using mono_map_is_fun by simp
with ‹h:B → C›
have "domain(f) = C" "domain(h) = B"
using domain_of_fun by simp_all
moreover
assume "a ∈ D"
moreover
note ‹cofinal_fun(f,D,r)›
ultimately
obtain c where "c∈C"  "⟨a, f  c⟩ ∈ r ∨ a = f  c"
unfolding cofinal_fun_def by blast
with ‹cofinal_fun(h,C,s)› ‹domain(h) = B›
obtain b where "b ∈ B"  "⟨c, h  b⟩ ∈ s ∨ c = h  b"
unfolding cofinal_fun_def by blast
moreover from this and ‹h:B → C›
have "hb ∈ C" by simp
moreover
note ‹f ∈ mono_map(C,s,D,r)›  ‹c∈C›
ultimately
have "⟨fc, f (h  b)⟩ ∈ r ∨ fc = f (h  b)"
unfolding mono_map_def by blast
with ‹⟨a, f  c⟩ ∈ r ∨ a = f  c› ‹trans(r)› ‹h:B → C› ‹b∈B›
have "⟨a, (f O h)  b⟩ ∈ r ∨ a = (f O h)  b"
using transD by auto
moreover from ‹h:B → C› ‹domain(f) = C› ‹domain(h) = B›
have "domain(f O h) = B"
using range_fun_subset_codomain by blast
moreover
note ‹b∈B›
ultimately
show "∃x∈domain(f O h). ⟨a, (f O h)  x⟩ ∈ r ∨ a = (f O h)  x"  by blast
qed

definition
cf_fun :: "[i,i] ⇒ o" where
"cf_fun(f,α) ≡ cofinal_fun(f,α,Memrel(α))"

lemma cf_funI[intro!]: "cofinal_fun(f,α,Memrel(α)) ⟹ cf_fun(f,α)"
unfolding cf_fun_def by simp

lemma cf_funD[dest!]: "cf_fun(f,α) ⟹ cofinal_fun(f,α,Memrel(α))"
unfolding cf_fun_def by simp

lemma cf_fun_comp:
assumes
"Ord(α)" "f∈ mono_map(C,s,α,Memrel(α))" "cf_fun(f,α)"
"h:B → C" "cofinal_fun(h,C,s)"
shows "cf_fun(f O h,α)"
using assms cofinal_comp[OF _ _ _ _ trans_Memrel] by auto

definition
cf :: "i⇒i" where
"cf(γ) ≡ μ β.  ∃A. A⊆γ ∧ cofinal(A,γ,Memrel(γ)) ∧ β = ordertype(A,Memrel(γ))"

lemma Ord_cf [TC]: "Ord(cf(β))"
unfolding cf_def using Ord_Least by simp

lemma gamma_cofinal_gamma:
assumes "Ord(γ)"
shows "cofinal(γ,γ,Memrel(γ))"
unfolding cofinal_def by auto

lemma cf_is_ordertype:
assumes "Ord(γ)"
shows "∃A. A⊆γ ∧ cofinal(A,γ,Memrel(γ)) ∧ cf(γ) = ordertype(A,Memrel(γ))"
(is "?P(cf(γ))")
using gamma_cofinal_gamma LeastI[of ?P γ] ordertype_Memrel[symmetric] assms
unfolding cf_def by blast

lemma cf_fun_succ':
assumes "Ord(β)" "Ord(α)" "f:α→succ(β)"
shows "(∃x∈α. fx=β) ⟷ cf_fun(f,succ(β))"
proof (intro iffI)
assume "(∃x∈α. fx=β)"
with assms
show "cf_fun(f,succ(β))"
using domain_of_fun[OF ‹f:α→succ(β)›]
unfolding cf_fun_def cofinal_fun_def by auto
next
assume "cf_fun(f,succ(β))"
with assms
obtain x where "x∈α" "⟨β,fx⟩ ∈ Memrel(succ(β)) ∨ β = f  x"
using domain_of_fun[OF ‹f:α→succ(β)›]
unfolding cf_fun_def cofinal_fun_def by auto
moreover from ‹Ord(β)›
have "⟨β,y⟩ ∉ Memrel(succ(β))" for y
using foundation unfolding Memrel_def by blast
ultimately
show "∃x∈α. f  x = β" by blast
qed

lemma cf_fun_succ:
"Ord(β) ⟹ f:1→succ(β) ⟹ f0=β ⟹ cf_fun(f,succ(β))"
using cf_fun_succ' by blast

lemma ordertype_0_not_cofinal_succ:
assumes "ordertype(A,Memrel(succ(i))) = 0"  "A⊆succ(i)" "Ord(i)"
shows "¬cofinal(A,succ(i),Memrel(succ(i)))"
proof
have 1:"ordertype(A,Memrel(succ(i))) = ordertype(0,Memrel(0))"
using ‹ordertype(A,Memrel(succ(i))) = 0› ordertype_0 by simp
from  ‹A⊆succ(i)› ‹Ord(i)›
have "∃f. f ∈ ⟨A, Memrel(succ(i))⟩ ≅ ⟨0, Memrel(0)⟩"
using   well_ord_Memrel well_ord_subset
ordertype_eq_imp_ord_iso[OF 1] Ord_0  by blast
then
have "A=0"
using  ord_iso_is_bij bij_imp_eqpoll eqpoll_0_is_0 by blast
moreover
assume "cofinal(A, succ(i), Memrel(succ(i)))"
moreover
note ‹Ord(i)›
ultimately
show "False"
using not_mem_empty unfolding cofinal_def by auto
qed

text‹I thank Edwin Pacheco Rodríguez for the following lemma.›
lemma cf_succ:
assumes "Ord(α)"
shows "cf(succ(α)) = 1"
proof -
define f where "f ≡ {⟨0,α⟩}"
then
have  "f : 1→succ(α)" "f0 = α"
using fun_extend3[of 0 0 "succ(α)" 0 α] singleton_0 by auto
with assms
have "cf_fun(f,succ(α))"
using cf_fun_succ unfolding cofinal_fun_def by simp
from ‹f:1→succ(α)›
have "0∈domain(f)" using domain_of_fun by simp
define A where "A={f0}"
with ‹cf_fun(f,succ(α))› ‹0∈domain(f)› ‹f0=α›
have "cofinal(A,succ(α),Memrel(succ(α)))"
unfolding cofinal_def cofinal_fun_def by simp
moreover from  ‹f0=α› ‹A={f0}›
have "A ⊆ succ(α)" unfolding succ_def  by auto
moreover from ‹Ord(α)› ‹A⊆ succ(α)›
have "well_ord(A,Memrel(succ(α)))"
using Ord_succ well_ord_Memrel  well_ord_subset relation_Memrel by blast
moreover from ‹Ord(α)›
have "¬(∃A. A ⊆ succ(α) ∧ cofinal(A, succ(α), Memrel(succ(α))) ∧ 0 = ordertype(A, Memrel(succ(α))))"
(is "¬?P(0)")
using ordertype_0_not_cofinal_succ  unfolding cf_def  by auto
moreover
have "1 = ordertype(A,Memrel(succ(α)))"
proof -
from ‹A={f0}›
have "A≈1" using singleton_eqpoll_1 by simp
with ‹well_ord(A,Memrel(succ(α)))›
show ?thesis using nat_1I ordertype_eq_n by simp
qed
ultimately
show "cf(succ(α)) = 1" using Ord_1  Least_equality[of ?P 1]
unfolding cf_def by blast
qed

lemma cf_zero [simp]:
"cf(0) = 0"
unfolding cf_def cofinal_def using
ordertype_0 subset_empty_iff Least_le[of _ 0] by auto

lemma surj_is_cofinal: "f ∈ surj(δ,γ) ⟹ cf_fun(f,γ)"
unfolding surj_def cofinal_fun_def cf_fun_def
using domain_of_fun by force

lemma cf_zero_iff: "Ord(α) ⟹ cf(α) = 0 ⟷ α = 0"
proof (intro iffI)
assume "α = 0" "Ord(α)"
then
show "cf(α) = 0" using cf_zero by simp
next
assume "cf(α) = 0" "Ord(α)"
moreover from this
obtain A where "A⊆α" "cf(α) = ordertype(A,Memrel(α))"
"cofinal(A,α,Memrel(α))"
using cf_is_ordertype by blast
ultimately
have "cofinal(0,α,Memrel(α))"
using ordertype_zero_imp_zero[of A "Memrel(α)"] by simp
then
show "α=0"
unfolding cofinal_def by blast
qed

― ‹TODO: define Succ (predicate for successor ordinals)›
lemma cf_eq_one_iff:
assumes "Ord(γ)"
shows "cf(γ) = 1 ⟷ (∃α. Ord(α) ∧ γ  = succ(α))"
proof (intro iffI)
assume "∃α. Ord(α) ∧ γ  = succ(α)"
then
show "cf(γ) = 1" using cf_succ by auto
next
assume "cf(γ) = 1"
moreover from assms
obtain A where "A ⊆ γ" "cf(γ) = ordertype(A,Memrel(γ))"
"cofinal(A,γ,Memrel(γ))"
using cf_is_ordertype by blast
ultimately
have "ordertype(A,Memrel(γ)) = 1" by simp
moreover
define f where "f≡converse(ordermap(A,Memrel(γ)))"
moreover from this ‹ordertype(A,Memrel(γ)) = 1› ‹A ⊆ γ› assms
have "f ∈ surj(1,A)"
using well_ord_subset[OF well_ord_Memrel, THEN ordermap_bij,
THEN bij_converse_bij, of γ A] bij_is_surj
by simp
with ‹cofinal(A,γ,Memrel(γ))›
have "∀a∈γ. ⟨a, f0⟩ ∈ Memrel(γ) ∨ a = f0"
unfolding cofinal_def surj_def
by auto
with assms ‹A ⊆ γ› ‹f ∈ surj(1,A)›
show "∃α. Ord(α) ∧ γ  = succ(α)"
using Ord_has_max_imp_succ[of γ "f0"]
surj_is_fun[of f 1 A] apply_type[of f 1 "λ_.A" 0]
unfolding lt_def
by (auto intro:Ord_in_Ord)
qed

lemma ordertype_in_cf_imp_not_cofinal:
assumes
"ordertype(A,Memrel(γ)) ∈ cf(γ)"
"A ⊆ γ"
shows
"¬ cofinal(A,γ,Memrel(γ))"
proof
note ‹A ⊆ γ›
moreover
assume "cofinal(A,γ,Memrel(γ))"
ultimately
have "∃B. B ⊆ γ ∧ cofinal(B, γ, Memrel(γ)) ∧  ordertype(A,Memrel(γ)) = ordertype(B, Memrel(γ))"
(is "?P(ordertype(A,_))")
by blast
moreover from assms
have "ordertype(A,Memrel(γ)) < cf(γ)"
using Ord_cf ltI by blast
ultimately
show "False"
unfolding cf_def using less_LeastE[of ?P  "ordertype(A,Memrel(γ))"]
by auto
qed

lemma cofinal_mono_map_cf:
assumes "Ord(γ)"
shows "∃j ∈ mono_map(cf(γ), Memrel(cf(γ)), γ, Memrel(γ)) . cf_fun(j,γ)"
proof -
note assms
moreover from this
obtain A where "A ⊆ γ" "cf(γ) = ordertype(A,Memrel(γ))"
"cofinal(A,γ,Memrel(γ))"
using cf_is_ordertype by blast
moreover
define j where "j ≡ converse(ordermap(A,Memrel(γ)))"
moreover from calculation
have "j :cf(γ) →⇩< γ"
using ordertype_ord_iso[THEN ord_iso_sym,
THEN ord_iso_is_mono_map, THEN mono_map_mono,
of A "Memrel(γ)" γ] well_ord_Memrel[THEN well_ord_subset]
by simp
moreover from calculation
have "j ∈ surj(cf(γ),A)"
using well_ord_Memrel[THEN well_ord_subset, THEN ordertype_ord_iso,
THEN ord_iso_sym, of γ A, THEN ord_iso_is_bij,
THEN bij_is_surj]
by simp
with ‹cofinal(A,γ,Memrel(γ))›
have "cf_fun(j,γ)"
using cofinal_range_iff_cofinal_fun[of j γ "Memrel(γ)"]
surj_range[of j "cf(γ)" A] surj_is_fun fun_is_function
by fastforce
with ‹j ∈ mono_map(_,_,_,_)›
show ?thesis by auto
qed

subsection‹The factorization lemma›

text‹In this subsection we prove a factorization lemma for cofinal functions
into ordinals, which shows that any cofinal function between ordinals can be
decomposed'' in such a way that a commutative triangle of strictly increasing
maps arises.

The factorization lemma has a kind of
fundamental character, in that the rest of the basic results on cofinality
(for, instance, idempotence) follow easily from it, in a more algebraic way.

This is a consequence that the proof encapsulates uses of transfinite
recursion in the basic theory of cofinality; indeed, only one use is needed.
In the setting of Isabelle/ZF, this is convenient since the machinery of
recursion is pretty clumsy. On the downside, this way of presenting things
results in a longer proof of the factorization lemma. This approach was
taken by the author in the notes \<^cite>‹"apunte_st"› for an introductory course
in Set Theory.

To organize the use of the hypotheses of the factorization lemma,
we set up a locale containing all the relevant ingredients.
›
locale cofinal_factor =
fixes j δ ξ γ f
assumes j_mono: "j :ξ →⇩< γ"
and     ords: "Ord(δ)" "Ord(ξ)" "Limit(γ)"
and   f_type: "f: δ → γ"
begin

text‹Here, \<^term>‹f› is cofinal function from \<^term>‹δ› to \<^term>‹γ›, and the
ordinal \<^term>‹ξ› is meant to be the cofinality of \<^term>‹γ›. Hence, there exists
an increasing map \<^term>‹j› from  \<^term>‹ξ› to  \<^term>‹γ› by the last lemma.

The main goal is to construct an increasing function \<^term>‹g:ξ→δ› such that
the composition \<^term>‹f O g› is still cofinal but also increasing.›

definition
factor_body :: "[i,i,i] ⇒ o" where
"factor_body(β,h,x) ≡ (x∈δ ∧ jβ ≤ fx ∧ (∀α<β . f(hα) < fx)) ∨ x=δ"

definition
factor_rec :: "[i,i] ⇒ i" where
"factor_rec(β,h) ≡  μ x. factor_body(β,h,x)"

text‹\<^term>‹factor_rec› is the inductive step for the definition by transfinite
recursion of the ∗‹factor› function (called \<^term>‹g› above), which in
turn is obtained by minimizing the predicate \<^term>‹factor_body›. Next we show
that this predicate is monotonous.›

lemma factor_body_mono:
assumes
"β∈ξ" "α<β"
"factor_body(β,λx∈β. G(x),x)"
shows
"factor_body(α,λx∈α. G(x),x)"
proof -
from ‹α<β›
have "α∈β" using ltD by simp
moreover
note ‹β∈ξ›
moreover from calculation
have "α∈ξ" using ords ltD Ord_cf Ord_trans by blast
ultimately
have "jα ∈ jβ" using j_mono mono_map_increasing by blast
moreover from ‹β∈ξ›
have "jβ∈γ"
using j_mono domain_of_fun apply_rangeI mono_map_is_fun by force
moreover from this
have "Ord(jβ)"
using Ord_in_Ord ords Limit_is_Ord by auto
ultimately
have "jα ≤ jβ"  unfolding lt_def by blast
then
have "jβ ≤ fθ ⟹ jα ≤ fθ" for θ using le_trans by blast
moreover
have "f((λw∈α. G(w))y) < fz" if "z∈δ" "∀x<β. f((λw∈β. G(w))x) < fz" "y<α" for y z
proof -
note ‹y<α›
also
note ‹α<β›
finally
have "y<β" by simp
with ‹∀x<β. f((λw∈β. G(w))x) < fz›
have "f  ((λw∈β. G(w))  y) < f  z" by simp
moreover from ‹y<α› ‹y<β›
have "(λw∈β. G(w))  y = (λw∈α. G(w))  y"
using beta_if  by (auto dest:ltD)
ultimately show ?thesis by simp
qed
moreover
note ‹factor_body(β,λx∈β. G(x),x)›
ultimately
show ?thesis
unfolding factor_body_def by blast
qed

lemma factor_body_simp[simp]: "factor_body(α,g,δ)"
unfolding factor_body_def by simp

lemma factor_rec_mono:
assumes
"β∈ξ" "α<β"
shows
"factor_rec(α,λx∈α. G(x)) ≤ factor_rec(β,λx∈β. G(x))"
unfolding factor_rec_def
using assms ords factor_body_mono Least_antitone by simp

text‹We now define the factor as higher-order function.
Later it will be restricted to a set to obtain a bona fide function of
type @{typ i}.›
definition
factor :: "i ⇒ i" where
"factor(β) ≡ transrec(β,factor_rec)"

lemma factor_unfold:
"factor(α) = factor_rec(α,λx∈α. factor(x))"
using def_transrec[OF factor_def] .

lemma factor_mono:
assumes "β∈ξ" "α<β" "factor(α)≠δ" "factor(β)≠δ"
shows "factor(α) ≤ factor(β)"
proof -
have "factor(α) = factor_rec(α, λx∈α. factor(x))"
using factor_unfold .
also from assms and factor_rec_mono
have "... ≤ factor_rec(β, λx∈β. factor(x))"
by simp
also
have "factor_rec(β, λx∈β. factor(x)) = factor(β)"
using def_transrec[OF factor_def, symmetric] .
finally show ?thesis .
qed

text‹The factor satisfies the predicate body of the minimization.›

lemma factor_body_factor:
"factor_body(α,λx∈α. factor(x),factor(α))"
using ords factor_unfold[of α]
LeastI[of "factor_body(_,_)" δ]
unfolding factor_rec_def by simp

lemma factor_type [TC]: "Ord(factor(α))"
using ords factor_unfold[of α]
unfolding factor_rec_def by simp

text‹The value \<^term>‹δ› in \<^term>‹factor_body› (and therefore, in
\<^term>‹factor›) is meant to be a default value''. Whenever it is not
attained, the factor function behaves as expected: It is increasing
and its composition with \<^term>‹f› also is.›

lemma f_factor_increasing:
assumes "β∈ξ" "α<β" "factor(β)≠δ"
shows "ffactor(α) < ffactor(β)"
proof -
from assms
have "f  ((λx∈β. factor(x))  α) < f  factor(β)"
using factor_unfold[of β] ords LeastI[of "factor_body(β,λx∈β. factor(x))"]
unfolding factor_rec_def factor_body_def
by (auto simp del:beta_if)
with ‹α<β›
show ?thesis using ltD by auto
qed

lemma factor_increasing:
assumes "β∈ξ" "α<β" "factor(α)≠δ" "factor(β)≠δ"
shows "factor(α)<factor(β)"
using assms f_factor_increasing factor_mono by (force intro:le_neq_imp_lt)

lemma factor_in_delta:
assumes "factor(β) ≠ δ"
shows "factor(β) ∈ δ"
using assms factor_body_factor ords
unfolding factor_body_def by auto

text‹Finally, we define the (set) factor function as the restriction of
factor to the ordinal  \<^term>‹ξ›.›

definition
fun_factor :: "i" where
"fun_factor ≡ λβ∈ξ. factor(β)"

lemma fun_factor_is_mono_map:
assumes "⋀β. β ∈ ξ ⟹ factor(β) ≠ δ"
shows "fun_factor ∈ mono_map(ξ, Memrel(ξ), δ, Memrel(δ))"
unfolding mono_map_def
proof (intro CollectI ballI impI)
text‹Proof that \<^term>‹fun_factor› respects membership:›
fix α β
assume "α∈ξ" "β∈ξ"
moreover
note assms
moreover from calculation
have "factor(α)≠δ" "factor(β)≠δ" "Ord(β)"
using factor_in_delta Ord_in_Ord ords by auto
moreover
assume "⟨α, β⟩ ∈ Memrel(ξ)"
ultimately
show "⟨fun_factor  α, fun_factor  β⟩ ∈ Memrel(δ)"
unfolding fun_factor_def
using ltI factor_increasing[THEN ltD] factor_in_delta
by simp
next
text‹Proof that it has the appropriate type:›
from assms
show "fun_factor : ξ → δ"
unfolding fun_factor_def
using ltI lam_type factor_in_delta by simp
qed

lemma f_fun_factor_is_mono_map:
assumes "⋀β. β ∈ ξ ⟹ factor(β) ≠ δ"
shows "f O fun_factor ∈ mono_map(ξ, Memrel(ξ), γ, Memrel(γ))"
unfolding mono_map_def
using f_type
proof (intro CollectI ballI impI comp_fun[of _ _ δ])
from assms
show "fun_factor : ξ → δ"
using fun_factor_is_mono_map mono_map_is_fun by simp
text‹Proof that \<^term>‹f O fun_factor› respects membership›
fix α β
assume "⟨α, β⟩ ∈ Memrel(ξ)"
then
have "α<β"
using Ord_in_Ord[of "ξ"] ltI ords by blast
assume "α∈ξ" "β∈ξ"
moreover from this and assms
have "factor(α)≠δ" "factor(β)≠δ" by auto
moreover
have "Ord(γ)" "γ≠0" using ords Limit_is_Ord by auto
moreover
note ‹α<β› ‹fun_factor : ξ → δ›
ultimately
show "⟨(f O fun_factor)  α, (f O fun_factor)  β⟩ ∈ Memrel(γ)"
using ltD[of "f  factor(α)" "f  factor(β)"]
f_factor_increasing apply_in_codomain_Ord f_type
unfolding fun_factor_def by auto
qed

end ― ‹\<^locale>‹cofinal_factor››

text‹We state next the factorization lemma.›

lemma cofinal_fun_factorization:
notes le_imp_subset [dest] lt_trans2 [trans]
assumes
"Ord(δ)" "Limit(γ)" "f: δ → γ" "cf_fun(f,γ)"
shows
"∃g ∈ cf(γ) →⇩< δ.  f O g : cf(γ) →⇩< γ ∧
cofinal_fun(f O g,γ,Memrel(γ))"
proof -
from ‹Limit(γ)›
have "Ord(γ)" using Limit_is_Ord by simp
then
obtain j where "j :cf(γ) →⇩< γ" "cf_fun(j,γ)"
using cofinal_mono_map_cf by blast
then
have "domain(j) = cf(γ)"
using domain_of_fun mono_map_is_fun by force
from ‹j ∈ _› assms
interpret cofinal_factor j δ "cf(γ)"
by (unfold_locales) (simp_all)
text‹The core of the argument is to show that the factor function
indeed maps into \<^term>‹δ›, therefore its values satisfy the first
disjunct of \<^term>‹factor_body›. This holds in turn because no
restriction of the factor composed with \<^term>‹f› to a proper initial
segment of \<^term>‹cf(γ)› can be cofinal in \<^term>‹γ› by definition of
cofinality. Hence there must be a witness that satisfies the first
disjunct.›
have factor_not_delta: "factor(β)≠δ" if "β ∈ cf(γ)" for β
text‹For this, we induct on \<^term>‹β› ranging over \<^term>‹cf(γ)›.›
proof (induct β rule:Ord_induct[OF _ Ord_cf[of γ]])
case 1 with that show ?case .
next
case (2 β)
then
have IH: "z∈β ⟹ factor(z)≠δ" for z by simp
define h where "h ≡ λx∈β. ffactor(x)"
from IH
have "z∈β ⟹ factor(z) ∈ δ" for z
using factor_in_delta by blast
with ‹f:δ→γ›
have "h : β → γ" unfolding h_def using apply_funtype lam_type by auto
then
have "h : β →⇩< γ"
unfolding mono_map_def
proof (intro CollectI ballI impI)
fix x y
assume "x∈β" "y∈β"
moreover from this and IH
have "factor(y) ≠ δ" by simp
moreover from calculation and ‹h ∈ β → γ›
have "hx ∈ γ" "hy ∈ γ" by simp_all
moreover from ‹β∈cf(γ)› and ‹y∈β›
have "y ∈ cf(γ)"
using Ord_trans Ord_cf by blast
moreover from this
have "Ord(y)"
using Ord_cf Ord_in_Ord by blast
moreover
assume "⟨x,y⟩ ∈ Memrel(β)"
moreover from calculation
have "x<y" by (blast intro:ltI)
ultimately
show "⟨h  x, h  y⟩ ∈ Memrel(γ)"
unfolding h_def using f_factor_increasing ltD by (auto)
qed
with ‹β∈cf(γ)› ‹Ord(γ)›
have "ordertype(hβ,Memrel(γ)) = β" (* Maybe should use range(h) *)
using mono_map_ordertype_image[of β] Ord_cf Ord_in_Ord by blast
also
note ‹β ∈cf(γ)›
finally
have "ordertype(hβ,Memrel(γ)) ∈ cf(γ)" by simp
moreover from ‹h ∈ β → γ›
have "hβ ⊆ γ"
using mono_map_is_fun Image_sub_codomain by blast
ultimately
have "¬ cofinal(hβ,γ,Memrel(γ))"
using ordertype_in_cf_imp_not_cofinal by simp
then
obtain α_0 where "α_0∈γ" "∀x∈h  β. ¬ ⟨α_0, x⟩ ∈ Memrel(γ) ∧ α_0 ≠ x"
unfolding cofinal_def by auto
with ‹Ord(γ)› ‹hβ ⊆ γ›
have "∀x∈h  β. x ∈ α_0"
using well_ord_Memrel[of γ] well_ord_is_linear[of γ "Memrel(γ)"]
unfolding linear_def by blast
from ‹α_0 ∈ γ› ‹j ∈ mono_map(_,_,γ,_)› ‹Ord(γ)›
have "jβ ∈ γ"
using mono_map_is_fun apply_in_codomain_Ord by force
with ‹α_0 ∈ γ› ‹Ord(γ)›
have "α_0 ∪ jβ ∈ γ"
using Un_least_mem_iff Ord_in_Ord by auto
with ‹cf_fun(f,γ)›
obtain θ where "θ∈domain(f)" "⟨α_0 ∪ jβ, f  θ⟩ ∈ Memrel(γ) ∨  α_0 ∪ jβ = f  θ"
moreover from this and ‹f:δ→γ›
have "θ ∈ δ" using domain_of_fun by auto
moreover
note ‹Ord(γ)›
moreover from this and ‹f:δ→γ›  ‹α_0 ∈ γ›
have "Ord(fθ)"
using apply_in_codomain_Ord Ord_in_Ord by blast
moreover from calculation and ‹α_0 ∈ γ› and ‹Ord(δ)› and ‹jβ ∈ γ›
have "Ord(α_0)" "Ord(jβ)" "Ord(θ)"
using Ord_in_Ord by auto
moreover from ‹∀x∈h  β. x ∈ α_0› ‹Ord(α_0)› ‹h:β→γ›
have "x∈β ⟹ hx < α_0" for x
using fun_is_function[of h β "λ_. γ"]
Image_subset_Ord_imp_lt domain_of_fun[of h β "λ_. γ"]
by blast
moreover
have "x∈β ⟹ hx < fθ" for x
proof -
fix x
assume "x∈β"
with ‹∀x∈h  β. x ∈ α_0› ‹Ord(α_0)› ‹h:β→γ›
have "hx < α_0"
using fun_is_function[of h β "λ_. γ"]
Image_subset_Ord_imp_lt domain_of_fun[of h β "λ_. γ"]
by blast
also from ‹⟨α_0 ∪ _, f  θ⟩ ∈ Memrel(γ) ∨ α_0 ∪ _= f  θ›
‹Ord(fθ)› ‹Ord(α_0)› ‹Ord(jβ)›
have "α_0 ≤ fθ"
using Un_leD1[OF leI [OF ltI]] Un_leD1[OF le_eqI] by blast
finally
show "hx < fθ" .
qed
ultimately
have "factor_body(β,λx∈β. factor(x),θ)"
unfolding h_def factor_body_def using ltD
by (auto dest:Un_memD2 Un_leD2[OF le_eqI])
with ‹Ord(θ)›
have "factor(β) ≤ θ"
using factor_unfold[of β] Least_le unfolding factor_rec_def by auto
with ‹θ∈δ› ‹Ord(δ)›
have "factor(β) ∈ δ"
using leI[of θ] ltI[of θ]  by (auto dest:ltD)
then
show ?case by (auto elim:mem_irrefl)
qed
moreover
have "cofinal_fun(f O fun_factor, γ, Memrel(γ))"
proof (intro cofinal_funI)
fix a
assume "a ∈ γ"
with ‹cf_fun(j,γ)› ‹domain(j) = cf(γ)›
obtain x where "x∈cf(γ)" "a ∈ jx ∨ a = jx"
with factor_not_delta
have "x ∈ domain(f O fun_factor)"
using f_fun_factor_is_mono_map mono_map_is_fun domain_of_fun by force
moreover
have "a ∈ (f O fun_factor) x ∨ a = (f O fun_factor) x"
proof -
from ‹x∈cf(γ)› factor_not_delta
have "j  x ≤ f  factor(x)"
using mem_not_refl factor_body_factor factor_in_delta
unfolding factor_body_def by auto
with ‹a ∈ jx ∨ a = jx›
have "a ∈ f  factor(x) ∨ a = f  factor(x)"
using ltD by blast
with ‹x∈cf(γ)›
show ?thesis using lam_funtype[of "cf(γ)" factor]
unfolding fun_factor_def by auto
qed
moreover
note ‹a ∈ γ›
moreover from calculation and ‹Ord(γ)› and factor_not_delta
have "(f O fun_factor) x ∈ γ"
using Limit_nonzero apply_in_codomain_Ord mono_map_is_fun[of "f O fun_factor"]
f_fun_factor_is_mono_map by blast
ultimately
show "∃x ∈ domain(f O fun_factor). ⟨a, (f O fun_factor)  x⟩ ∈ Memrel(γ)
∨ a = (f O fun_factor) x"
by blast
qed
ultimately
show ?thesis
using fun_factor_is_mono_map f_fun_factor_is_mono_map by blast
qed

text‹As a final observation in this part, we note that if the original
cofinal map was increasing, then the factor function is also cofinal.›
lemma factor_is_cofinal:
assumes
"Ord(δ)" "Ord(γ)"
"f :δ →⇩< γ"  "f O g ∈ mono_map(α,r,γ,Memrel(γ))"
"cofinal_fun(f O g,γ,Memrel(γ))" "g: α → δ"
shows
"cf_fun(g,δ)"
unfolding cf_fun_def cofinal_fun_def
proof
fix a
assume "a ∈ δ"
with ‹f ∈ mono_map(δ,_,γ,_)›
have "fa ∈ γ"
using mono_map_is_fun by force
with ‹cofinal_fun(f O g,γ,_)›
obtain y where "y∈α"  "⟨fa, (f O g)  y⟩ ∈ Memrel(γ) ∨ fa = (f O g)  y"
unfolding cofinal_fun_def using domain_of_fun[OF ‹g:α → δ›] by blast
with ‹g:α → δ›
have "⟨fa, f  (g  y)⟩ ∈ Memrel(γ) ∨ fa = f  (g  y)" "gy ∈ δ"
using comp_fun_apply[of g α δ y f] by auto
with assms(1-3) and ‹a∈δ›
have "⟨a, g  y⟩ ∈ Memrel(δ) ∨ a = g  y"
using Memrel_mono_map_reflects Memrel_mono_map_is_inj[of δ f γ γ]
inj_apply_equality[of f δ γ]  by blast
with ‹y∈α›
show "∃x∈domain(g). ⟨a, g  x⟩ ∈ Memrel(δ) ∨ a = g  x"
using domain_of_fun[OF ‹g:α → δ›] by blast
qed

subsection‹Classical results on cofinalities›

text‹Now the rest of the results follow in a more algebraic way. The
next proof one invokes a case analysis on whether the argument is zero,
a successor ordinal or a limit one; the last case being the most
relevant one and is immediate from the factorization lemma.›

lemma cf_le_domain_cofinal_fun:
assumes
"Ord(γ)" "Ord(δ)" "f:δ → γ" "cf_fun(f,γ)"
shows
"cf(γ)≤δ"
using assms
proof (cases rule:Ord_cases)
case 0
with ‹Ord(δ)›
show ?thesis using Ord_0_le by simp
next
case (succ γ)
with assms
obtain x where "x∈δ" "fx=γ" using cf_fun_succ' by blast
then
have "δ≠0" by blast
let ?f="{⟨0,fx⟩}"
from ‹fx=γ›
have "?f:1→succ(γ)"
using singleton_0 singleton_fun[of 0 γ] singleton_subsetI fun_weaken_type by simp
with ‹Ord(γ)›  ‹fx=γ›
have "cf(succ(γ)) = 1" using cf_succ by simp
with ‹δ≠0› succ
show ?thesis using Ord_0_lt_iff succ_leI ‹Ord(δ)› by simp
next
case (limit)
with assms
obtain g where "g :cf(γ) →⇩< δ"
using cofinal_fun_factorization by blast
with assms
show ?thesis using mono_map_imp_le by simp
qed

lemma cf_ordertype_cofinal:
assumes
"Limit(γ)" "A⊆γ" "cofinal(A,γ,Memrel(γ))"
shows
"cf(γ) = cf(ordertype(A,Memrel(γ)))"
proof (intro le_anti_sym)
text‹We show the result by proving the two inequalities.›
from ‹Limit(γ)›
have "Ord(γ)"
using Limit_is_Ord by simp
with ‹A ⊆ γ›
have "well_ord(A,Memrel(γ))"
using well_ord_Memrel well_ord_subset by blast
then
obtain f α where "f:⟨α, Memrel(α)⟩ ≅ ⟨A,Memrel(γ)⟩" "Ord(α)" "α = ordertype(A,Memrel(γ))"
using ordertype_ord_iso Ord_ordertype ord_iso_sym by blast
moreover from this
have "f: α → A"
using ord_iso_is_mono_map mono_map_is_fun[of f _ "Memrel(α)"] by blast
moreover from this
have "function(f)"
using fun_is_function by simp
moreover from ‹f:⟨α, Memrel(α)⟩ ≅ ⟨A,Memrel(γ)⟩›
have "range(f) = A"
using ord_iso_is_bij bij_is_surj surj_range by blast
moreover note ‹cofinal(A,γ,_)›
ultimately
have "cf_fun(f,γ)"
using cofinal_range_iff_cofinal_fun by blast
moreover from ‹Ord(α)›
obtain h where "h :cf(α) →⇩< α" "cf_fun(h,α)"
using cofinal_mono_map_cf by blast
moreover from ‹Ord(γ)›
have "trans(Memrel(γ))"
using trans_Memrel by simp
moreover
note ‹A⊆γ›
ultimately
have "cofinal_fun(f O h,γ,Memrel(γ))"
using cofinal_comp ord_iso_is_mono_map[OF ‹f:⟨α,_⟩ ≅ ⟨A,_⟩›] mono_map_is_fun
mono_map_mono by blast
moreover from ‹f:α→A› ‹A⊆γ› ‹h∈mono_map(cf(α),_,α,_)›
have "f O h : cf(α) → γ"
using Pi_mono[of A γ] comp_fun  mono_map_is_fun by blast
moreover
note ‹Ord(γ)› ‹Ord(α)› ‹α = ordertype(A,Memrel(γ))›
ultimately
show "cf(γ) ≤ cf(ordertype(A,Memrel(γ)))"
using cf_le_domain_cofinal_fun[of _ _ "f O h"]
text‹That finishes the first inequality. Now we go the other side.›
from ‹f:⟨α, _⟩ ≅ ⟨A,_⟩› ‹A⊆γ›
have "f :α →⇩< γ"
using mono_map_mono[OF ord_iso_is_mono_map] by simp
then
have "f: α → γ"
using mono_map_is_fun by simp
with ‹cf_fun(f,γ)› ‹Limit(γ)› ‹Ord(α)›
obtain g where "g :cf(γ) →⇩< α"
"f O g :cf(γ) →⇩< γ"
"cofinal_fun(f O g,γ,Memrel(γ))"
using cofinal_fun_factorization by blast
moreover from this
have "g:cf(γ)→α"
using mono_map_is_fun by simp
moreover
note ‹Ord(α)›
moreover from calculation and ‹f :α →⇩< γ› ‹Ord(γ)›
have "cf_fun(g,α)"
using factor_is_cofinal by blast
moreover
note ‹α = ordertype(A,Memrel(γ))›
ultimately
show "cf(ordertype(A,Memrel(γ))) ≤ cf(γ)"
using cf_le_domain_cofinal_fun[OF _ Ord_cf mono_map_is_fun] by simp
qed

lemma cf_idemp:
assumes "Limit(γ)"
shows "cf(γ) = cf(cf(γ))"
proof -
from assms
obtain A where "A⊆γ" "cofinal(A,γ,Memrel(γ))" "cf(γ) = ordertype(A,Memrel(γ))"
using Limit_is_Ord cf_is_ordertype by blast
with assms
have "cf(γ) = cf(ordertype(A,Memrel(γ)))" using cf_ordertype_cofinal by simp
also
have "... = cf(cf(γ))"
using ‹cf(γ) = ordertype(A,Memrel(γ))› by simp
finally
show "cf(γ) = cf(cf(γ))"  .
qed

lemma cf_le_cardinal:
assumes "Limit(γ)"
shows "cf(γ) ≤ |γ|"
proof -
from assms
have ‹Ord(γ)› using Limit_is_Ord by simp
then
obtain f where "f ∈ surj(|γ|,γ)"
using Ord_cardinal_eqpoll unfolding eqpoll_def bij_def by blast
with ‹Ord(γ)›
show ?thesis
using Card_is_Ord[OF Card_cardinal] surj_is_cofinal
cf_le_domain_cofinal_fun[of γ] surj_is_fun by blast
qed

lemma regular_is_Card:
notes le_imp_subset [dest]
assumes "Limit(γ)" "γ = cf(γ)"
shows "Card(γ)"
proof -
from assms
have "|γ| ⊆ γ"
using Limit_is_Ord Ord_cardinal_le by blast
also from ‹γ = cf(γ)›
have "γ ⊆ cf(γ)" by simp
finally
have "|γ| ⊆ cf(γ)" .
with assms
show ?thesis unfolding Card_def using cf_le_cardinal by force
qed

lemma Limit_cf: assumes "Limit(κ)" shows "Limit(cf(κ))"
using Ord_cf[of κ, THEN Ord_cases]
― ‹\<^term>‹cf(κ)› being $0$ or successor leads to contradiction›
proof (cases)
case 1
with ‹Limit(κ)›
show ?thesis using cf_zero_iff Limit_is_Ord by simp
next
case (2 α)
moreover
note ‹Limit(κ)›
moreover from calculation
have "cf(κ) = 1"
using cf_idemp cf_succ by fastforce
ultimately
show ?thesis
using succ_LimitE cf_eq_one_iff Limit_is_Ord
by auto
qed

lemma InfCard_cf: "Limit(κ) ⟹ InfCard(cf(κ))"
using regular_is_Card cf_idemp Limit_cf nat_le_Limit Limit_cf
unfolding InfCard_def by simp

lemma cf_le_cf_fun:
notes [dest] = Limit_is_Ord
assumes "cf(κ) ≤ ν" "Limit(κ)"
shows "∃f.  f:ν → κ  ∧  cf_fun(f, κ)"
proof -
note assms
moreover from this
obtain h where h_cofinal_mono: "cf_fun(h,κ)"
"h :cf(κ) →⇩< κ"
"h : cf(κ) → κ"
using cofinal_mono_map_cf mono_map_is_fun by force
moreover from calculation
obtain g where "g ∈ inj(cf(κ), ν)"
using le_imp_lepoll by blast
from this and calculation(2,3,5)
obtain f where "f ∈ surj(ν, cf(κ))" "f: ν → cf(κ)"
using inj_imp_surj[OF _ Limit_has_0[THEN ltD]]
surj_is_fun Limit_cf by blast
moreover from this
have "cf_fun(f,cf(κ))"
using surj_is_cofinal by simp
moreover
note h_cofinal_mono ‹Limit(κ)›
moreover from calculation
have "cf_fun(h O f,κ)"
using cf_fun_comp by blast
moreover from calculation
have "h O f ∈ ν -> κ"
using comp_fun by simp
ultimately
show ?thesis by blast
qed

lemma Limit_cofinal_fun_lt:
notes [dest] = Limit_is_Ord
assumes "Limit(κ)" "f: ν → κ" "cf_fun(f,κ)" "n∈κ"
shows "∃α∈ν. n < fα"
proof -
from ‹Limit(κ)› ‹n∈κ›
have "succ(n) ∈ κ"
using Limit_has_succ[OF _ ltI, THEN ltD] by auto
moreover
note ‹f: ν → _›
moreover from this
have "domain(f) = ν"
using domain_of_fun by simp
moreover
note ‹cf_fun(f,κ)›
ultimately
obtain α where "α ∈ ν" "succ(n) ∈ fα ∨ succ(n) = f α"
using cf_funD[THEN cofinal_funD] by blast
moreover from this
consider (1) "succ(n) ∈ fα" | (2) "succ(n) = f α"
by blast
then
have "n < fα"
proof (cases)
case 1
moreover
have "n ∈ succ(n)" by simp
moreover
note ‹Limit(κ)› ‹f: ν → _› ‹α ∈ ν›
moreover from this
have "Ord(f  α)"
using apply_type[of f ν "λ_. κ", THEN [2] Ord_in_Ord]
by blast
ultimately
show ?thesis
using Ord_trans[of n "succ(n)" "f  α"] ltI  by blast
next
case 2
have "n ∈ f  α" by (simp add:2[symmetric])
with ‹Limit(κ)› ‹f: ν → _› ‹α ∈ ν›
show ?thesis
using ltI
apply_type[of f ν "λ_. κ", THEN [2] Ord_in_Ord]
by blast
qed
ultimately
show ?thesis by blast
qed

context
includes Ord_dests Aleph_dests Aleph_intros Aleph_mem_dests mono_map_rules
begin

text‹We end this section by calculating the cofinality of Alephs, for
the zero and limit case. The successor case depends on $\AC$.›

lemma cf_nat: "cf(ω) = ω"
using Limit_nat[THEN InfCard_cf] cf_le_cardinal[of ω]
Card_nat[THEN Card_cardinal_eq] le_anti_sym
unfolding InfCard_def by auto

lemma cf_Aleph_zero: "cf(ℵ⇘0⇙) = ℵ⇘0⇙"
using cf_nat unfolding Aleph_def by simp

lemma cf_Aleph_Limit:
assumes "Limit(γ)"
shows "cf(ℵ⇘γ⇙) = cf(γ)"
proof -
note ‹Limit(γ)›
moreover from this
have "(λx∈γ. ℵ⇘x⇙) : γ → ℵ⇘γ⇙" (is "?f : _ → _")
using lam_funtype[of _ Aleph] fun_weaken_type[of _ _ _ "ℵ⇘γ⇙"] by blast
moreover from ‹Limit(γ)›
have "x ∈ y ⟹ ℵ⇘x⇙ ∈ ℵ⇘y⇙" if "x ∈ γ" "y ∈ γ" for x y
using that Ord_in_Ord[of γ] Ord_trans[of _ _ γ] by blast
ultimately
have "?f ∈ mono_map(γ,Memrel(γ),ℵ⇘γ⇙, Memrel(ℵ⇘γ⇙))"
by auto
with  ‹Limit(γ)›
have "?f ∈ ⟨γ, Memrel(γ)⟩ ≅ ⟨?fγ, Memrel(ℵ⇘γ⇙)⟩"
using mono_map_imp_ord_iso_Memrel[of γ "ℵ⇘γ⇙" ?f]
Card_Aleph (* Already an intro rule, but need it explicitly *)
by blast
then
have "converse(?f) ∈ ⟨?fγ, Memrel(ℵ⇘γ⇙)⟩ ≅ ⟨γ, Memrel(γ)⟩"
using ord_iso_sym by simp
with ‹Limit(γ)›
have "ordertype(?fγ, Memrel(ℵ⇘γ⇙)) = γ"
using ordertype_eq[OF _ well_ord_Memrel]
ordertype_Memrel by auto
moreover from ‹Limit(γ)›
have "cofinal(?fγ, ℵ⇘γ⇙, Memrel(ℵ⇘γ⇙))"
unfolding cofinal_def
proof (standard, intro ballI)
fix a
assume "a∈ℵ⇘γ⇙" "ℵ⇘γ⇙ = (⋃i<γ. ℵ⇘i⇙)"
moreover from this
obtain i where "i<γ" "a∈ℵ⇘i⇙"
by auto
moreover from this and ‹Limit(γ)›
have "Ord(i)" using ltD Ord_in_Ord by blast
moreover from ‹Limit(γ)› and calculation
have "succ(i) ∈ γ" using ltD by auto
moreover from this and ‹Ord(i)›
have "ℵ⇘i⇙ < ℵ⇘succ(i)⇙"
by (auto)
ultimately
have "⟨a,ℵ⇘i⇙⟩ ∈ Memrel(ℵ⇘γ⇙)"
using ltD by (auto dest:Aleph_increasing)
moreover from ‹i<γ›
have "ℵ⇘i⇙ ∈ ?fγ"
using ltD apply_in_image[OF ‹?f : _ → _›] by auto
ultimately
show "∃x∈?f  γ. ⟨a, x⟩ ∈ Memrel(ℵ⇘γ⇙) ∨ a = x" by blast
qed
moreover
note ‹?f: γ → ℵ⇘γ⇙› ‹Limit(γ)›
ultimately
show "cf(ℵ⇘γ⇙) =  cf(γ)"
using cf_ordertype_cofinal[OF Limit_Aleph Image_sub_codomain, of γ ?f γ γ ]
Limit_is_Ord by simp
qed

end ― ‹includes›

end`