# Theory CCPO_Topology

```(*  Title:       CCPO_Topology.thy
Author:      Johannes Hölzl, TU Munich
*)

section ‹CCPO topologies›

theory CCPO_Topology
imports
"HOL-Analysis.Extended_Real_Limits"
"../Coinductive_Nat"
begin

lemma dropWhile_append:
"dropWhile P (xs @ ys) = (if ∀x∈set xs. P x then dropWhile P ys else dropWhile P xs @ ys)"
by auto

lemma dropWhile_False: "(⋀x. x ∈ set xs ⟹ P x) ⟹ dropWhile P xs = []"
by simp

abbreviation (in order) "chain ≡ Complete_Partial_Order.chain (≤)"

lemma (in linorder) chain_linorder: "chain C"

assumes "0 ≤ t"
shows "continuous_on {-∞::ereal <..} (λx. t + x)"
proof (subst continuous_on_open_vimage, (intro open_greaterThan allI impI)+)
fix B :: "ereal set" assume "open B"
show "open ((λx. t + x) -` B ∩ {- ∞<..})"
proof (cases t)
case (real t')
then have *: "(λx. t + x) -` B ∩ {- ∞<..} = (λx. 1 * x + (-t)) ` (B ∩ {-∞ <..})"
apply (simp add: set_eq_iff image_iff Bex_def)
apply (intro allI iffI)
apply (rule_tac x= "x + ereal t'" in exI)
apply (case_tac x)
apply (auto simp: ac_simps)
done
show ?thesis
unfolding *
apply (rule ereal_open_affinity_pos)
using ‹open B›
apply (auto simp: real)
done
qed (insert ‹0 ≤ t›, auto)
qed

"0 ≤ x ⟹ 0 ≤ y ⟹ (f ⤏ y) F ⟹ ((λz. x + f z :: ereal) ⤏ x + y) F"
apply (rule tendsto_compose[where f=f])
unfolding continuous_on_def
apply (auto simp add: at_within_open[where S="{- ∞ <..}"])
done

lemma tendsto_LimI: "(f ⤏ y) F ⟹ (f ⤏ Lim F f) F"
by (metis tendsto_Lim tendsto_bot)

subsection ‹The filter ‹at'››

abbreviation (in ccpo) "compact_element ≡ ccpo.compact Sup (≤)"

lemma tendsto_unique_eventually:
fixes x x' :: "'a :: t2_space"
shows "F ≠ bot ⟹ eventually (λx. f x = g x) F ⟹ (f ⤏ x) F ⟹ (g ⤏ x') F ⟹ x = x'"
by (metis tendsto_unique filterlim_cong)

lemma (in ccpo) ccpo_Sup_upper2: "chain C ⟹ x ∈ C ⟹ y ≤ x ⟹ y ≤ Sup C"
by (blast intro: ccpo_Sup_upper order_trans)

lemma tendsto_open_vimage: "(⋀B. open B ⟹ open (f -` B)) ⟹ f ─l→ f l"
using continuous_on_open_vimage[of UNIV f] continuous_on_def[of UNIV f] by simp

lemma open_vimageI: "(⋀x. f ─x→ f x) ⟹ open A ⟹ open (f -` A)"
using continuous_on_open_vimage[of UNIV f] continuous_on_def[of UNIV f] by simp

lemma principal_bot: "principal x = bot ⟷ x = {}"
by (auto simp: filter_eq_iff eventually_principal)

definition "at' x = (if open {x} then principal {x} else at x)"

lemma at'_bot: "at' x ≠ bot"
by (simp add: at'_def at_eq_bot_iff principal_bot)

lemma tendsto_id_at'[simp, intro]: "((λx. x) ⤏ x) (at' x)"
by (simp add: at'_def topological_tendstoI eventually_principal tendsto_ident_at)

lemma cont_at': "(f ⤏ f x) (at' x) ⟷ f ─x→ f x"
using at_eq_bot_iff[of x] by (auto split: if_split_asm intro!: topological_tendstoI simp: eventually_principal at'_def)

subsection ‹The type class ‹ccpo_topology››

text ‹Temporarily relax type constraints for @{term "open"}.›
(@{const_name "open"}, SOME @{typ "'a::open set ⇒ bool"})›

class ccpo_topology = "open" + ccpo +
assumes open_ccpo: "open A ⟷ (∀C. chain C ⟶ C ≠ {} ⟶ Sup C ∈ A ⟶ C ∩ A ≠ {})"
begin

lemma open_ccpoD:
assumes "open A" "chain C" "C ≠ {}" "Sup C ∈ A"
shows "∃c∈C. ∀c'∈C. c ≤ c' ⟶ c' ∈ A"
proof (rule ccontr)
assume "¬ ?thesis"
then have *: "⋀c. c ∈ C ⟹ ∃c'∈C. c ≤ c' ∧ c' ∉ A"
by auto
with ‹chain C› ‹C ≠ {}› have "chain (C - A)" "C - A ≠ {}"
by (auto intro: chain_Diff)
moreover have "Sup C = Sup (C - A)"
proof (safe intro!: order.antisym ccpo_Sup_least ‹chain C› chain_Diff)
fix c assume "c ∈ C"
with * obtain c' where "c' ∈ C" "c ≤ c'" "c' ∉ A"
by auto
with ‹c∈C› show "c ≤ ⨆(C - A)"
by (intro ccpo_Sup_upper2 ‹chain (C - A)›) auto
qed (auto intro: ‹chain C› ccpo_Sup_upper)
ultimately show False
using ‹open A› ‹Sup C ∈ A› by (auto simp: open_ccpo)
qed

lemma open_ccpo_Iic: "open {.. b}"
by (auto simp: open_ccpo) (metis Int_iff atMost_iff ccpo_Sup_upper empty_iff order_trans)

subclass topological_space
proof
show "open (UNIV::'a set)"
unfolding open_ccpo by auto
next
fix S T :: "'a set" assume "open S" "open T"
show "open (S ∩ T)"
unfolding open_ccpo
proof (intro allI impI)
fix C assume C: "chain C" "C ≠ {}" and "⨆C ∈ S ∩ T"
with open_ccpoD[OF ‹open S› C] open_ccpoD[OF ‹open T› C]
show "C ∩ (S ∩ T) ≠ {}"
unfolding chain_def by blast
qed
next
fix K :: "'a set set" assume *: "∀D∈K. open D"
show "open (⋃K)"
unfolding open_ccpo
proof (intro allI impI)
fix C assume "chain C" "C ≠ {}" "⨆C ∈ (⋃K)"
with * obtain D where "D ∈ K" "⨆C ∈ D" "C ∩ D ≠ {}"
by (auto simp: open_ccpo)
then show "C ∩ (⋃K) ≠ {}"
by auto
qed
qed

lemma closed_ccpo: "closed A ⟷ (∀C. chain C ⟶ C ≠ {} ⟶ C ⊆ A ⟶ Sup C ∈ A)"
unfolding closed_def open_ccpo by auto

lemma open_singletonI_compact: "compact_element x ⟹ open {x}"

lemma closed_Ici: "closed {.. b}"
by (auto simp: closed_ccpo intro: ccpo_Sup_least)

lemma closed_Iic: "closed {b ..}"
by (auto simp: closed_ccpo intro: ccpo_Sup_upper2)

text ‹
@{class ccpo_topology}s are also @{class t2_space}s.
This is necessary to have a unique continuous extension.
›

subclass t2_space
proof
fix x y :: 'a assume "x ≠ y"
show "∃U V. open U ∧ open V ∧ x ∈ U ∧ y ∈ V ∧ U ∩ V = {}"
proof cases
{ fix x y assume "x ≠ y" "x ≤ y"
then have "open {..x} ∧ open (- {..x}) ∧ x ∈ {..x} ∧ y ∈ - {..x} ∧ {..x} ∩ - {..x} = {}"
by (auto intro: open_ccpo_Iic closed_Ici) }
moreover assume "x ≤ y ∨ y ≤ x"
ultimately show ?thesis
using ‹x ≠ y› by (metis Int_commute)
next
assume "¬ (x ≤ y ∨ y ≤ x)"
then have "open ({..x} ∩ - {..y}) ∧ open ({..y} ∩ - {..x}) ∧
x ∈ {..x} ∩ - {..y} ∧ y ∈ {..y} ∩ - {..x} ∧ ({..x} ∩ - {..y}) ∩ ({..y} ∩ - {..x}) = {}"
by (auto intro: open_ccpo_Iic closed_Ici)
then show ?thesis by auto
qed
qed

end

lemma tendsto_le_ccpo:
fixes f g :: "'a ⇒ 'b::ccpo_topology"
assumes F: "¬ trivial_limit F"
assumes x: "(f ⤏ x) F" and y: "(g ⤏ y) F"
assumes ev: "eventually (λx. g x ≤ f x) F"
shows "y ≤ x"
proof (rule ccontr)
assume "¬ y ≤ x"

show False
proof cases
assume "x ≤ y"
with ‹¬ y ≤ x›
have "open {..x}" "open (- {..x})" "x ∈ {..x}" "y ∈ - {..x}" "{..x} ∩ - {..x} = {}"
by (auto intro: open_ccpo_Iic closed_Ici)
with topological_tendstoD[OF x, of "{..x}"] topological_tendstoD[OF y, of "- {..x}"]
have "eventually (λz. f z ≤ x) F" "eventually (λz. ¬ g z ≤ x) F"
by auto
with ev have "eventually (λx. False) F" by eventually_elim (auto intro: order_trans)
with F show False by (auto simp: eventually_False)
next
assume "¬ x ≤ y"
with ‹¬ y ≤ x› have "open ({..x} ∩ - {..y})" "open ({..y} ∩ - {..x})"
"x ∈ {..x} ∩ - {..y}" "y ∈ {..y} ∩ - {..x}" "({..x} ∩ - {..y}) ∩ ({..y} ∩ - {..x}) = {}"
by (auto intro: open_ccpo_Iic closed_Ici)
with topological_tendstoD[OF x, of "{..x} ∩ - {..y}"]
topological_tendstoD[OF y, of "{..y} ∩ - {..x}"]
have "eventually (λz. f z ≤ x ∧ ¬ f z ≤ y) F" "eventually (λz. g z ≤ y ∧ ¬ g z ≤ x) F"
by auto
with ev have "eventually (λx. False) F" by eventually_elim (auto intro: order_trans)
with F show False by (auto simp: eventually_False)
qed
qed

lemma tendsto_ccpoI:
fixes f :: "'a::ccpo_topology ⇒ 'b::ccpo_topology"
shows "(⋀C. chain C ⟹ C ≠ {} ⟹ chain (f ` C) ∧ f (Sup C) = Sup (f`C)) ⟹ f ─x→ f x"
by (intro tendsto_open_vimage) (auto simp: open_ccpo)

lemma tendsto_mcont:
assumes mcont: "mcont Sup (≤) Sup (≤) (f :: 'a :: ccpo_topology ⇒ 'b :: ccpo_topology)"
shows "f ─l→ f l"
proof (intro tendsto_ccpoI conjI)
fix C :: "'a set" assume C: "chain C" "C ≠ {}"
show "chain (f`C)"
using mcont
by (intro chain_imageI[where le_a="(≤)"] C) (simp add: mcont_def monotone_def)
show "f (⨆C) = ⨆(f ` C)"
using mcont C by (simp add: mcont_def cont_def)
qed

subsection ‹Instances for @{class ccpo_topology}s and continuity theorems›

instantiation set :: (type) ccpo_topology
begin

definition open_set :: "'a set set ⇒ bool" where
"open_set A ⟷ (∀C. chain C ⟶ C ≠ {} ⟶ Sup C ∈ A ⟶ C ∩ A ≠ {})"

instance

end

instantiation enat :: ccpo_topology
begin

instance
proof
fix A :: "enat set"
show "open A = (∀C. chain C ⟶ C ≠ {} ⟶ ⨆C ∈ A ⟶ C ∩ A ≠ {})"
proof (intro iffI allI impI)
fix C x assume "open A" "chain C" "C ≠ {}" "⨆C ∈ A"

show "C ∩ A ≠ {}"
proof cases
assume "⨆C = ∞"
with ‹⨆C ∈ A› ‹open A› obtain n where "{enat n <..} ⊆ A"
unfolding open_enat_iff by auto
with ‹⨆C = ∞› Sup_eq_top_iff[of C] show ?thesis
by (auto simp: top_enat_def)
next
assume "⨆C ≠ ∞"
then obtain n where "C ⊆ {.. enat n}"
unfolding Sup_eq_top_iff top_enat_def[symmetric] by (auto simp: not_less top_enat_def)
moreover have "finite {.. enat n}"
by (auto intro: finite_enat_bounded)
ultimately have "finite C"
by (auto intro: finite_subset)
from in_chain_finite[OF ‹chain C› ‹finite C› ‹C ≠ {}›] ‹⨆C ∈ A› show ?thesis
by auto
qed
next
assume C: "∀C. chain C ⟶ C ≠ {} ⟶ ⨆C ∈ A ⟶ C ∩ A ≠ {}"
show "open A"
unfolding open_enat_iff
proof safe
assume "∞ ∈ A"
{ fix C :: "enat set" assume "infinite C"
then have "⨆C = ∞"
by (auto simp: Sup_enat_def)
with ‹infinite C› C[THEN spec, of C] ‹∞ ∈ A› have "C ∩ A ≠ {}"
by auto }
note inf_C = this

show "∃x. {enat x<..} ⊆ A"
proof (rule ccontr)
assume "¬ (∃x. {enat x<..} ⊆ A)"
with ‹∞ ∈ A› have "⋀x. ∃y>x. enat y ∉ A"
by (simp add: subset_eq Bex_def) (metis enat.exhaust enat_ord_simps(2))
then have "infinite {n. enat n ∉ A}"
unfolding infinite_nat_iff_unbounded by auto
then have "infinite (enat ` {n. enat n ∉ A})"
by (auto dest!: finite_imageD)
from inf_C[OF this] show False
by auto
qed
qed
qed
qed

end

lemmas tendsto_inf2[THEN tendsto_compose, tendsto_intros] =
tendsto_mcont[OF mcont_inf2]

lemma isCont_inf2[THEN isCont_o2[rotated]]:
"isCont (λx. x ⊓ y) (z :: _ :: {ccpo_topology, complete_distrib_lattice})"