(* Title: HOLCF/Cont.thy ID: $Id: Cont.thy,v 1.38 2008/03/27 18:49:24 huffman Exp $ Author: Franz Regensburger Results about continuity and monotonicity. *) header {* Continuity and monotonicity *} theory Cont imports Pcpo begin text {* Now we change the default class! Form now on all untyped type variables are of default class po *} defaultsort po subsection {* Definitions *} definition monofun :: "('a => 'b) => bool" -- "monotonicity" where "monofun f = (∀x y. x \<sqsubseteq> y --> f x \<sqsubseteq> f y)" definition contlub :: "('a::cpo => 'b::cpo) => bool" -- "first cont. def" where "contlub f = (∀Y. chain Y --> f (\<Squnion>i. Y i) = (\<Squnion>i. f (Y i)))" definition cont :: "('a::cpo => 'b::cpo) => bool" -- "secnd cont. def" where "cont f = (∀Y. chain Y --> range (λi. f (Y i)) <<| f (\<Squnion>i. Y i))" lemma contlubI: "[|!!Y. chain Y ==> f (\<Squnion>i. Y i) = (\<Squnion>i. f (Y i))|] ==> contlub f" by (simp add: contlub_def) lemma contlubE: "[|contlub f; chain Y|] ==> f (\<Squnion>i. Y i) = (\<Squnion>i. f (Y i))" by (simp add: contlub_def) lemma contI: "[|!!Y. chain Y ==> range (λi. f (Y i)) <<| f (\<Squnion>i. Y i)|] ==> cont f" by (simp add: cont_def) lemma contE: "[|cont f; chain Y|] ==> range (λi. f (Y i)) <<| f (\<Squnion>i. Y i)" by (simp add: cont_def) lemma monofunI: "[|!!x y. x \<sqsubseteq> y ==> f x \<sqsubseteq> f y|] ==> monofun f" by (simp add: monofun_def) lemma monofunE: "[|monofun f; x \<sqsubseteq> y|] ==> f x \<sqsubseteq> f y" by (simp add: monofun_def) subsection {* @{prop "monofun f ∧ contlub f ≡ cont f"} *} text {* monotone functions map chains to chains *} lemma ch2ch_monofun: "[|monofun f; chain Y|] ==> chain (λi. f (Y i))" apply (rule chainI) apply (erule monofunE) apply (erule chainE) done text {* monotone functions map upper bound to upper bounds *} lemma ub2ub_monofun: "[|monofun f; range Y <| u|] ==> range (λi. f (Y i)) <| f u" apply (rule ub_rangeI) apply (erule monofunE) apply (erule ub_rangeD) done lemma ub2ub_monofun': "[|monofun f; S <| u|] ==> f ` S <| f u" apply (rule ub_imageI) apply (erule monofunE) apply (erule (1) is_ubD) done text {* monotone functions map directed sets to directed sets *} lemma dir2dir_monofun: assumes f: "monofun f" assumes S: "directed S" shows "directed (f ` S)" proof (rule directedI) from directedD1 [OF S] obtain x where "x ∈ S" .. hence "f x ∈ f ` S" by simp thus "∃x. x ∈ f ` S" .. next fix x assume "x ∈ f ` S" then obtain a where x: "x = f a" and a: "a ∈ S" .. fix y assume "y ∈ f ` S" then obtain b where y: "y = f b" and b: "b ∈ S" .. from directedD2 [OF S a b] obtain c where "c ∈ S" and "a \<sqsubseteq> c ∧ b \<sqsubseteq> c" .. hence "f c ∈ f ` S" and "x \<sqsubseteq> f c ∧ y \<sqsubseteq> f c" using monofunE [OF f] x y by simp_all thus "∃z∈f ` S. x \<sqsubseteq> z ∧ y \<sqsubseteq> z" .. qed text {* left to right: @{prop "monofun f ∧ contlub f ==> cont f"} *} lemma monocontlub2cont: "[|monofun f; contlub f|] ==> cont f" apply (rule contI) apply (rule thelubE) apply (erule (1) ch2ch_monofun) apply (erule (1) contlubE [symmetric]) done text {* first a lemma about binary chains *} lemma binchain_cont: "[|cont f; x \<sqsubseteq> y|] ==> range (λi::nat. f (if i = 0 then x else y)) <<| f y" apply (subgoal_tac "f (\<Squnion>i::nat. if i = 0 then x else y) = f y") apply (erule subst) apply (erule contE) apply (erule bin_chain) apply (rule_tac f=f in arg_cong) apply (erule lub_bin_chain [THEN thelubI]) done text {* right to left: @{prop "cont f ==> monofun f ∧ contlub f"} *} text {* part1: @{prop "cont f ==> monofun f"} *} lemma cont2mono: "cont f ==> monofun f" apply (rule monofunI) apply (drule (1) binchain_cont) apply (drule_tac i=0 in is_ub_lub) apply simp done lemmas ch2ch_cont = cont2mono [THEN ch2ch_monofun] text {* right to left: @{prop "cont f ==> monofun f ∧ contlub f"} *} text {* part2: @{prop "cont f ==> contlub f"} *} lemma cont2contlub: "cont f ==> contlub f" apply (rule contlubI) apply (rule thelubI [symmetric]) apply (erule (1) contE) done lemmas cont2contlubE = cont2contlub [THEN contlubE] lemma contI2: assumes mono: "monofun f" assumes less: "!!Y. [|chain Y; chain (λi. f (Y i))|] ==> f (lub (range Y)) \<sqsubseteq> (\<Squnion>i. f (Y i))" shows "cont f" apply (rule monocontlub2cont) apply (rule mono) apply (rule contlubI) apply (rule antisym_less) apply (rule less, assumption) apply (erule ch2ch_monofun [OF mono]) apply (rule is_lub_thelub) apply (erule ch2ch_monofun [OF mono]) apply (rule ub2ub_monofun [OF mono]) apply (rule is_lubD1) apply (erule cpo_lubI) done subsection {* Continuity of basic functions *} text {* The identity function is continuous *} lemma cont_id: "cont (λx. x)" apply (rule contI) apply (erule cpo_lubI) done text {* constant functions are continuous *} lemma cont_const: "cont (λx. c)" apply (rule contI) apply (rule lub_const) done text {* if-then-else is continuous *} lemma cont_if [simp]: "[|cont f; cont g|] ==> cont (λx. if b then f x else g x)" by (induct b) simp_all subsection {* Finite chains and flat pcpos *} text {* monotone functions map finite chains to finite chains *} lemma monofun_finch2finch: "[|monofun f; finite_chain Y|] ==> finite_chain (λn. f (Y n))" apply (unfold finite_chain_def) apply (simp add: ch2ch_monofun) apply (force simp add: max_in_chain_def) done text {* The same holds for continuous functions *} lemma cont_finch2finch: "[|cont f; finite_chain Y|] ==> finite_chain (λn. f (Y n))" by (rule cont2mono [THEN monofun_finch2finch]) lemma chfindom_monofun2cont: "monofun f ==> cont (f::'a::chfin => 'b::cpo)" apply (rule monocontlub2cont) apply assumption apply (rule contlubI) apply (frule chfin2finch) apply (clarsimp simp add: finite_chain_def) apply (subgoal_tac "max_in_chain i (λi. f (Y i))") apply (simp add: maxinch_is_thelub ch2ch_monofun) apply (force simp add: max_in_chain_def) done text {* some properties of flat *} lemma flatdom_strict2mono: "f ⊥ = ⊥ ==> monofun (f::'a::flat => 'b::pcpo)" apply (rule monofunI) apply (drule ax_flat) apply auto done lemma flatdom_strict2cont: "f ⊥ = ⊥ ==> cont (f::'a::flat => 'b::pcpo)" by (rule flatdom_strict2mono [THEN chfindom_monofun2cont]) text {* functions with discrete domain *} lemma cont_discrete_cpo [simp]: "cont (f::'a::discrete_cpo => 'b::cpo)" apply (rule contI) apply (drule discrete_chain_const, clarify) apply (simp add: lub_const) done end
lemma contlubI:
(!!Y. chain Y ==> f (LUB i. Y i) = (LUB i. f (Y i))) ==> contlub f
lemma contlubE:
[| contlub f; chain Y |] ==> f (LUB i. Y i) = (LUB i. f (Y i))
lemma contI:
(!!Y. chain Y ==> range (λi. f (Y i)) <<| f (LUB i. Y i)) ==> cont f
lemma contE:
[| cont f; chain Y |] ==> range (λi. f (Y i)) <<| f (LUB i. Y i)
lemma monofunI:
(!!x y. x << y ==> f x << f y) ==> monofun f
lemma monofunE:
[| monofun f; x << y |] ==> f x << f y
lemma ch2ch_monofun:
[| monofun f; chain Y |] ==> chain (λi. f (Y i))
lemma ub2ub_monofun:
[| monofun f; range Y <| u |] ==> range (λi. f (Y i)) <| f u
lemma ub2ub_monofun':
[| monofun f; S <| u |] ==> f ` S <| f u
lemma dir2dir_monofun:
[| monofun f; directed S |] ==> directed (f ` S)
lemma monocontlub2cont:
[| monofun f; contlub f |] ==> cont f
lemma binchain_cont:
[| cont f; x << y |] ==> range (λi. f (if i = 0 then x else y)) <<| f y
lemma cont2mono:
cont f ==> monofun f
lemma ch2ch_cont:
[| cont f; chain Y |] ==> chain (λi. f (Y i))
lemma cont2contlub:
cont f ==> contlub f
lemma cont2contlubE:
[| cont f; chain Y |] ==> f (LUB i. Y i) = (LUB i. f (Y i))
lemma contI2:
[| monofun f;
!!Y. [| chain Y; chain (λi. f (Y i)) |] ==> f (Lub Y) << (LUB i. f (Y i)) |]
==> cont f
lemma cont_id:
cont (λx. x)
lemma cont_const:
cont (λx. c)
lemma cont_if:
[| cont f; cont g |] ==> cont (λx. if b then f x else g x)
lemma monofun_finch2finch:
[| monofun f; finite_chain Y |] ==> finite_chain (λn. f (Y n))
lemma cont_finch2finch:
[| cont f; finite_chain Y |] ==> finite_chain (λn. f (Y n))
lemma chfindom_monofun2cont:
monofun f ==> cont f
lemma flatdom_strict2mono:
f UU = UU ==> monofun f
lemma flatdom_strict2cont:
f UU = UU ==> cont f
lemma cont_discrete_cpo:
cont f