Theory Limit
theory Limit
imports LocalLexing
begin
definition setmonotone :: "('a set ⇒ 'a set) ⇒ bool"
where
"setmonotone f = (∀ X. X ⊆ f X)"
lemma setmonotone_funpower: "setmonotone f ⟹ setmonotone (funpower f n)"
by (induct n, auto simp add: setmonotone_def)
lemma subset_setmonotone: "setmonotone f ⟹ X ⊆ f X"
by (simp add: setmonotone_def)
lemma elem_setmonotone: "setmonotone f ⟹ x ∈ X ⟹ x ∈ f X"
by (auto simp add: setmonotone_def)
lemma elem_natUnion: "(∀ n. x ∈ f n) ⟹ x ∈ natUnion f"
by (auto simp add: natUnion_def)
lemma subset_natUnion: "(∀ n. X ⊆ f n) ⟹ X ⊆ natUnion f"
by (auto simp add: natUnion_def)
lemma setmonotone_limit:
assumes fmono: "setmonotone f"
shows "setmonotone (limit f)"
proof -
show "setmonotone (limit f)"
apply (auto simp add: setmonotone_def limit_def)
apply (rule elem_natUnion, auto)
apply (rule elem_setmonotone[OF setmonotone_funpower])
by (auto simp add: fmono)
qed
lemma[simp]: "funpower id n = id"
by (rule ext, induct n, simp_all)
lemma[simp]: "limit id = id"
by (rule ext, auto simp add: limit_def natUnion_def)
lemma natUnion_decompose[consumes 1, case_names Decompose]:
assumes p: "p ∈ natUnion S"
assumes decompose: "⋀ n p. p ∈ S n ⟹ P p"
shows "P p"
proof -
from p have "∃ n. p ∈ S n"
by (auto simp add: natUnion_def)
then obtain n where "p ∈ S n" by blast
from decompose[OF this] show ?thesis .
qed
lemma limit_induct[consumes 1, case_names Init Iterate]:
assumes p: "(p :: 'a) ∈ limit f X"
assumes init: "⋀ p. p ∈ X ⟹ P p"
assumes iterate: "⋀ p Y. (⋀ q . q ∈ Y ⟹ P q) ⟹ p ∈ f Y ⟹ P p"
shows "P p"
proof -
from p have p_in_natUnion: "p ∈ natUnion (λ n. funpower f n X)"
by (simp add: limit_def)
{
fix p :: 'a
fix n :: nat
have "p ∈ funpower f n X ⟹ P p"
proof (induct n arbitrary: p)
case 0 thus ?case using init[OF 0[simplified]] by simp
next
case (Suc n) show ?case
using iterate[OF Suc(1) Suc(2)[simplified], simplified] by simp
qed
}
with p_in_natUnion show ?thesis
by (induct rule: natUnion_decompose)
qed
definition chain :: "(nat ⇒ 'a set) ⇒ bool"
where
"chain C = (∀ i. C i ⊆ C (i + 1))"
definition continuous :: "('a set ⇒ 'b set) ⇒ bool"
where
"continuous f = (∀ C. chain C ⟶ (chain (f o C) ∧ f (natUnion C) = natUnion (f o C)))"
lemma continuous_apply:
"continuous f ⟹ chain C ⟹ f (natUnion C) = natUnion (f o C)"
by (simp add: continuous_def)
lemma continuous_imp_mono:
assumes continuous: "continuous f"
shows "mono f"
proof -
{
fix A :: "'a set"
fix B :: "'a set"
assume sub: "A ⊆ B"
let ?C = "λ (i::nat). if (i = 0) then A else B"
have "chain ?C" by (simp add: chain_def sub)
then have fC: "chain (f o ?C)" using continuous continuous_def by blast
then have "f (?C 0) ⊆ f (?C (0 + 1))"
proof -
have "⋀f n. ¬ chain f ∨ (f n::'b set) ⊆ f (Suc n)"
by (metis Suc_eq_plus1 chain_def)
then show ?thesis using fC by fastforce
qed
then have "f A ⊆ f B" by auto
}
then show "mono f" by (simp add: monoI)
qed
lemma mono_maps_chain_to_chain:
assumes f: "mono f"
assumes C: "chain C"
shows "chain (f o C)"
by (metis C comp_def f chain_def mono_def)
lemma natUnion_upperbound:
"(⋀ n. f n ⊆ G) ⟹ (natUnion f) ⊆ G"
by (auto simp add: natUnion_def)
lemma funpower_upperbound:
"(⋀ I. I ⊆ G ⟹ f I ⊆ G) ⟹ I ⊆ G ⟹ funpower f n I ⊆ G"
proof (induct n)
case 0 thus ?case by simp
next
case (Suc n) thus ?case by simp
qed
lemma limit_upperbound:
"(⋀ I. I ⊆ G ⟹ f I ⊆ G) ⟹ I ⊆ G ⟹ limit f I ⊆ G"
by (simp add: funpower_upperbound limit_def natUnion_upperbound)
lemma elem_limit_simp: "x ∈ limit f X = (∃ n. x ∈ funpower f n X)"
by (auto simp add: limit_def natUnion_def)
definition pointwise :: "('a set ⇒ 'b set) ⇒ bool" where
"pointwise f = (∀ X. f X = ⋃ { f {x} | x. x ∈ X})"
lemma pointwise_simp:
assumes f: "pointwise f"
shows "f X = ⋃ { f {x} | x. x ∈ X}"
proof -
from f have "∀ X. f X = ⋃ { f {x} | x. x ∈ X}"
by (rule iffD1[OF pointwise_def[where f=f]])
then show ?thesis by blast
qed
lemma natUnion_elem: "x ∈ f n ⟹ x ∈ natUnion f"
using natUnion_def by fastforce
lemma limit_elem: "x ∈ funpower f n X ⟹ x ∈ limit f X"
by (simp add: limit_def natUnion_elem)
lemma limit_step_pointwise:
assumes x: "x ∈ limit f X"
assumes f: "pointwise f"
assumes y: "y ∈ f {x}"
shows "y ∈ limit f X"
proof -
from x have "∃ n. x ∈ funpower f n X"
by (simp add: elem_limit_simp)
then obtain n where n: "x ∈ funpower f n X" by blast
have "y ∈ funpower f (Suc n) X"
apply simp
apply (subst pointwise_simp[OF f])
using y n by auto
then show "y ∈ limit f X" by (meson limit_elem)
qed
definition pointbase :: "('a set ⇒ 'b set) ⇒ 'a set ⇒ 'b set" where
"pointbase F I = ⋃ { F X | X. finite X ∧ X ⊆ I }"
definition pointbased :: "('a set ⇒ 'b set) ⇒ bool" where
"pointbased f = (∃ F. f = pointbase F)"
lemma pointwise_implies_pointbased:
assumes pointwise: "pointwise f"
shows "pointbased f"
proof -
let ?F = "λ X. f X"
{
fix I :: "'a set"
fix x :: "'b"
have lr: "x ∈ pointbase ?F I ⟹ x ∈ f I"
proof -
assume x: "x ∈ pointbase ?F I"
have "∃ X. x ∈ f X ∧ X ⊆ I"
proof -
have "x ∈ ⋃{f A |A. finite A ∧ A ⊆ I}"
by (metis pointbase_def x)
then show ?thesis
by blast
qed
then obtain X where X:"x ∈ f X ∧ X ⊆ I" by blast
have "∃ y. y ∈ I ∧ x ∈ f {y}"
using X apply (simp add: pointwise_simp[OF pointwise, where X=X])
by blast
then show "x ∈ f I"
apply (simp add: pointwise_simp[OF pointwise, where X=I])
by blast
qed
have rl: "x ∈ f I ⟹ x ∈ pointbase ?F I"
proof -
assume x: "x ∈ f I"
have "∃ y. y ∈ I ∧ x ∈ f {y}"
using x apply (simp add: pointwise_simp[OF pointwise, where X=I])
by blast
then obtain y where "y ∈ I ∧ x ∈ f {y}" by blast
then have "∃ X. x ∈ f X ∧ finite X ∧ X ⊆ I" by blast
then show "x ∈ pointbase f I"
apply (simp add: pointbase_def)
by blast
qed
note lr rl
}
then have "⋀ I. pointbase f I = f I" by blast
then have "pointbase f = f" by blast
then show ?thesis by (metis pointbased_def)
qed
lemma pointbase_is_mono:
"mono (pointbase f)"
proof -
{
fix A :: "'a set"
fix B :: "'a set"
assume subset: "A ⊆ B"
have "(pointbase f) A ⊆ (pointbase f) B"
apply (simp add: pointbase_def)
using subset by fastforce
}
then show ?thesis by (simp add: mono_def)
qed
lemma chain_implies_mono: "chain C ⟹ mono C"
by (simp add: chain_def mono_iff_le_Suc)
lemma chain_cover_witness: "finite X ⟹ chain C ⟹ X ⊆ natUnion C ⟹ ∃ n. X ⊆ C n"
proof (induct rule: finite.induct)
case emptyI thus ?case by blast
next
case (insertI X x)
then have "X ⊆ natUnion C" by simp
with insertI have "∃ n. X ⊆ C n" by blast
then obtain n where n: "X ⊆ C n" by blast
have x: "x ∈ natUnion C" using insertI.prems(2) by blast
then have "∃ m. x ∈ C m"
proof -
have "x ∈ ⋃{A. ∃n. A = C n}" by (metis x natUnion_def)
then show ?thesis by blast
qed
then obtain m where m: "x ∈ C m" by blast
have mono_C: "⋀ i j. i ≤ j ⟹ C i ⊆ C j"
using chain_implies_mono insertI(3) mono_def by blast
show ?case
apply (rule_tac x="max n m" in exI)
apply auto
apply (meson contra_subsetD m max.cobounded2 mono_C)
by (metis max_def mono_C n subsetCE)
qed
lemma pointbase_is_continuous:
"continuous (pointbase f)"
proof -
{
fix C :: "nat ⇒ 'a set"
assume C: "chain C"
have mono: "chain ((pointbase f) o C)"
by (simp add: C mono_maps_chain_to_chain pointbase_is_mono)
have subset1: "natUnion ((pointbase f) o C) ⊆ (pointbase f) (natUnion C)"
proof (auto)
fix y :: "'b"
assume "y ∈ natUnion ((pointbase f) o C)"
then show "y ∈ (pointbase f) (natUnion C)"
proof (induct rule: natUnion_decompose)
case (Decompose n p)
thus ?case by (metis comp_apply contra_subsetD mono_def natUnion_elem
pointbase_is_mono subsetI)
qed
qed
have subset2: "(pointbase f) (natUnion C) ⊆ natUnion ((pointbase f) o C)"
proof (auto)
fix y :: "'b"
assume y: "y ∈ (pointbase f) (natUnion C)"
have "∃ X. finite X ∧ X ⊆ natUnion C ∧ y ∈ f X"
proof -
have "y ∈ ⋃{f A |A. finite A ∧ A ⊆ natUnion C}"
by (metis y pointbase_def)
then show ?thesis by blast
qed
then obtain X where X: "finite X ∧ X ⊆ natUnion C ∧ y ∈ f X" by blast
then have "∃ n. X ⊆ C n" using chain_cover_witness C by blast
then obtain n where X_sub_C: "X ⊆ C n" by blast
show "y ∈ natUnion ((pointbase f) o C)"
apply (rule_tac natUnion_elem[where n=n])
proof -
have "y ∈ ⋃{f A |A. finite A ∧ A ⊆ C n}"
using X X_sub_C by blast
then show "y ∈ (pointbase f ∘ C) n" by (simp add: pointbase_def)
qed
qed
note mono subset1 subset2
}
then show ?thesis by (simp add: continuous_def subset_antisym)
qed
lemma pointbased_implies_continuous:
"pointbased f ⟹ continuous f"
using pointbase_is_continuous pointbased_def by force
lemma setmonotone_implies_chain_funpower:
assumes setmonotone: "setmonotone f"
shows "chain (λ n. funpower f n I)"
by (simp add: chain_def setmonotone subset_setmonotone)
lemma natUnion_subset: "(⋀ n. ∃ m. f n ⊆ g m) ⟹ natUnion f ⊆ natUnion g"
by (meson natUnion_elem natUnion_upperbound subset_iff)
lemma natUnion_eq[case_names Subset Superset]:
"(⋀ n. ∃ m. f n ⊆ g m) ⟹ (⋀ n. ∃ m. g n ⊆ f m) ⟹ natUnion f = natUnion g"
by (simp add: natUnion_subset subset_antisym)
lemma natUnion_shift[symmetric]:
assumes chain: "chain C"
shows "natUnion C = natUnion (λ n. C (n + m))"
proof (induct rule: natUnion_eq)
case (Subset n)
show ?case using chain chain_implies_mono le_add1 mono_def by blast
next
case (Superset n)
show ?case by blast
qed
definition regular :: "('a set ⇒ 'a set) ⇒ bool"
where
"regular f = (setmonotone f ∧ continuous f)"
lemma regular_fixpoint:
assumes regular: "regular f"
shows "f (limit f I) = limit f I"
proof -
have setmonotone: "setmonotone f" using regular regular_def by blast
have continuous: "continuous f" using regular regular_def by blast
let ?C = "λ n. funpower f n I"
have chain: "chain ?C"
by (simp add: setmonotone setmonotone_implies_chain_funpower)
have "f (limit f I) = f (natUnion ?C)"
using limit_def by metis
also have "f (natUnion ?C) = natUnion (f o ?C)"
by (metis continuous continuous_def chain)
also have "natUnion (f o ?C) = natUnion (λ n. f(funpower f n I))"
by (meson comp_apply)
also have "natUnion (λ n. f(funpower f n I)) = natUnion (λ n. ?C (n + 1))"
by simp
also have "natUnion (λ n. ?C(n + 1)) = natUnion ?C"
apply (subst natUnion_shift)
using chain by (blast+)
finally show ?thesis by (simp add: limit_def)
qed
lemma fix_is_fix_of_limit:
assumes fixpoint: "f I = I"
shows "limit f I = I"
proof -
have funpower: "⋀ n. funpower f n I = I"
proof -
fix n :: nat
from fixpoint show "funpower f n I = I"
by (induct n, auto)
qed
show ?thesis by (simp add: limit_def funpower natUnion_def)
qed
lemma limit_is_idempotent: "regular f ⟹ limit f (limit f I) = limit f I"
by (simp add: fix_is_fix_of_limit regular_fixpoint)
definition mk_regular1 :: "('b ⇒ 'a ⇒ bool) ⇒ ('b ⇒ 'a ⇒ 'a) ⇒ 'a set ⇒ 'a set" where
"mk_regular1 P F I = I ∪ { F q x | q x. x ∈ I ∧ P q x }"
definition mk_regular2 :: "('b ⇒ 'a ⇒ 'a ⇒ bool) ⇒ ('b ⇒ 'a ⇒ 'a ⇒ 'a) ⇒ 'a set ⇒ 'a set" where
"mk_regular2 P F I = I ∪ { F q x y | q x y. x ∈ I ∧ y ∈ I ∧ P q x y }"
lemma setmonotone_mk_regular1: "setmonotone (mk_regular1 P F)"
by (simp add: mk_regular1_def setmonotone_def)
lemma setmonotone_mk_regular2: "setmonotone (mk_regular2 P F)"
by (simp add: mk_regular2_def setmonotone_def)
lemma pointbased_mk_regular1: "pointbased (mk_regular1 P F)"
proof -
let ?f = "λ X. X ∪ { F q x | q x. x ∈ X ∧ P q x }"
{
fix I :: "'a set"
have 1: "pointbase ?f I ⊆ mk_regular1 P F I"
by (auto simp add: pointbase_def mk_regular1_def)
have 2: "mk_regular1 P F I ⊆ pointbase ?f I"
apply (simp add: pointbase_def mk_regular1_def)
apply blast
done
from 1 2 have "pointbase ?f I = mk_regular1 P F I" by blast
}
then show ?thesis
apply (subst pointbased_def)
apply (rule_tac x="?f" in exI)
by blast
qed
lemma pointbased_mk_regular2: "pointbased (mk_regular2 P F)"
proof -
let ?f = "λ X. X ∪ { F q x y | q x y. x ∈ X ∧ y ∈ X ∧ P q x y }"
{
fix I :: "'a set"
have 1: "pointbase ?f I ⊆ mk_regular2 P F I"
by (auto simp add: pointbase_def mk_regular2_def)
have 2: "mk_regular2 P F I ⊆ pointbase ?f I"
apply (auto simp add: pointbase_def mk_regular2_def)
apply blast
proof -
fix q x y
assume x: "x ∈ I"
assume y: "y ∈ I"
assume P: "P q x y"
let ?X = "{x, y}"
let ?A = "?X ∪ {F q x y |q x y. x ∈ ?X ∧ y ∈ ?X ∧ P q x y}"
show "∃A. (∃X. A = X ∪ {F q x y |q x y. x ∈ X ∧ y ∈ X ∧ P q x y} ∧
finite X ∧ X ⊆ I) ∧ F q x y ∈ A"
apply (rule_tac x="?A" in exI)
apply (rule conjI)
apply (rule_tac x="?X" in exI)
apply (auto simp add: x y)[1]
using x y P by blast
qed
from 1 2 have "pointbase ?f I = mk_regular2 P F I" by blast
}
then show ?thesis
apply (subst pointbased_def)
apply (rule_tac x="?f" in exI)
by blast
qed
lemma regular1:"regular (mk_regular1 P F)"
by (simp add: pointbased_implies_continuous pointbased_mk_regular1 regular_def
setmonotone_mk_regular1)
lemma regular2: "regular (mk_regular2 P F)"
by (simp add: pointbased_implies_continuous pointbased_mk_regular2 regular_def
setmonotone_mk_regular2)
lemma continuous_comp:
assumes f: "continuous f"
assumes g: "continuous g"
shows "continuous (g o f)"
by (metis (no_types, lifting) comp_assoc comp_def continuous_def f g)
lemma setmonotone_comp:
assumes f: "setmonotone f"
assumes g: "setmonotone g"
shows "setmonotone (g o f)"
by (metis (mono_tags, lifting) comp_def f g rev_subsetD setmonotone_def subsetI)
lemma regular_comp:
assumes f: "regular f"
assumes g: "regular g"
shows "regular (g o f)"
using continuous_comp f g regular_def setmonotone_comp by blast
lemma setmonotone_id[simp]: "setmonotone id"
by (simp add: id_def setmonotone_def)
lemma continuous_id[simp]: "continuous id"
by (simp add: continuous_def)
lemma regular_id[simp]: "regular id"
by (simp add: regular_def)
lemma regular_funpower: "regular f ⟹ regular (funpower f n)"
proof (induct n)
case 0 thus ?case by (simp add: id_def[symmetric])
next
case (Suc n)
have funpower: "funpower f (Suc n) = f o (funpower f n)"
apply (rule ext)
by simp
with Suc show ?case
by (auto simp only: funpower regular_comp)
qed
lemma mono_id[simp]: "mono id"
by (simp add: mono_def id_def)
lemma mono_funpower:
assumes mono: "mono f"
shows "mono (funpower f n)"
proof (induct n)
case 0 thus ?case by (simp add: id_def[symmetric])
next
case (Suc n)
show ?case by (simp add: Suc.hyps mono monoD monoI)
qed
lemma mono_limit:
assumes mono: "mono f"
shows "mono (limit f)"
proof(auto simp add: mono_def limit_def)
fix A :: "'a set"
fix B :: "'a set"
fix x
assume subset: "A ⊆ B"
assume "x ∈ natUnion (λn. funpower f n A)"
then have "∃ n. x ∈ funpower f n A" using elem_limit_simp limit_def by fastforce
then obtain n where n: "x ∈ funpower f n A" by blast
then have mono: "mono (funpower f n)" by (simp add: mono mono_funpower)
then have "x ∈ funpower f n B" by (meson contra_subsetD monoD n subset)
then show "x ∈ natUnion (λn. funpower f n B)" by (simp add: natUnion_elem)
qed
lemma continuous_funpower:
assumes continuous: "continuous f"
shows "continuous (funpower f n)"
proof (induct n)
case 0 thus ?case by (simp add: id_def[symmetric])
next
case (Suc n)
have mono: "mono (funpower f (Suc n))"
by (simp add: continuous continuous_imp_mono mono_funpower)
have chain: "∀ C. chain C ⟶ chain ((funpower f (Suc n)) o C)"
by (simp del: funpower.simps add: mono mono_maps_chain_to_chain)
have limit: "⋀ C. chain C ⟹ (funpower f (Suc n)) (natUnion C) =
natUnion ((funpower f (Suc n)) o C)"
apply simp
apply (subst continuous_apply[OF Suc])
apply simp
apply (subst continuous_apply[OF continuous])
apply (simp add: Suc.hyps continuous_imp_mono mono_maps_chain_to_chain)
apply (rule arg_cong[where f="natUnion"])
apply (rule ext)
by simp
from chain limit show ?case using continuous_def by blast
qed
lemma natUnion_swap:
"natUnion (λ i. natUnion (λ j. f i j)) = natUnion (λ j. natUnion (λ i. f i j))"
by (metis (no_types, lifting) natUnion_elem natUnion_upperbound subsetI subset_antisym)
lemma continuous_limit:
assumes continuous: "continuous f"
shows "continuous (limit f)"
proof -
have mono: "mono (limit f)"
by (simp add: continuous continuous_imp_mono mono_limit)
have chain: "⋀ C. chain C ⟹ chain ((limit f) o C)"
by (simp add: mono mono_maps_chain_to_chain)
have "⋀ C. chain C ⟹ (limit f) (natUnion C) = natUnion ((limit f) o C)"
proof -
fix C :: "nat ⇒ 'a set"
assume chain_C: "chain C"
have contpower: "⋀ n. continuous (funpower f n)"
by (simp add: continuous continuous_funpower)
have comp: "⋀ n F. F o C = (λ i. F (C i))"
by auto
have "(limit f) (natUnion C) = natUnion (λ n. funpower f n (natUnion C))"
by (simp add: limit_def)
also have "natUnion (λ n. funpower f n (natUnion C)) =
natUnion (λ n. natUnion ((funpower f n) o C))"
apply (subst continuous_apply[OF contpower])
apply (simp add: chain_C)+
done
also have "natUnion (λ n. natUnion ((funpower f n) o C)) =
natUnion (λ n. natUnion (λ i. funpower f n (C i)))"
apply (subst comp)
apply blast
done
also have "natUnion (λ n. natUnion (λ i. funpower f n (C i))) =
natUnion (λ i. natUnion (λ n. funpower f n (C i)))"
apply (subst natUnion_swap)
apply blast
done
also have "natUnion (λ i. natUnion (λ n. funpower f n (C i))) =
(natUnion (λ i. limit f (C i)))"
apply (simp add: limit_def)
done
also have "natUnion (λ i. limit f (C i)) = natUnion ((limit f) o C)"
apply (subst comp)
apply simp
done
finally show "(limit f) (natUnion C) = natUnion ((limit f) o C)" by blast
qed
with chain show ?thesis by (simp add: continuous_def)
qed
lemma regular_limit: "regular f ⟹ regular (limit f)"
by (simp add: continuous_limit regular_def setmonotone_limit)
lemma regular_implies_mono: "regular f ⟹ mono f"
by (simp add: continuous_imp_mono regular_def)
lemma regular_implies_setmonotone: "regular f ⟹ setmonotone f"
by (simp add: regular_def)
lemma regular_implies_continuous: "regular f ⟹ continuous f"
by (simp add: regular_def)
end