lemma is_lub_bin: "x \ y \ {x, y} <<| y" by (simp add: is_lub_def)
lemma lub_bin: "x \ y \ lub {x, y} = y" by (rule is_lub_bin [THEN lub_eqI])
lemma is_lub_maximal: "S <| x \ x \ S \ S <<| x" by (erule is_lubI, erule (1) is_ubD)
lemma lub_maximal: "S <| x \ x \ S \ lub S = x" by (rule is_lub_maximal [THEN lub_eqI])
subsection \<open>Countable chains\<close>
definition chain :: "(nat \ 'a) \ bool" where\<comment> \<open>Here we use countable chains and I prefer to code them as functions!\<close> "chain Y = (\i. Y i \ Y (Suc i))"
lemma chainI: "(\i. Y i \ Y (Suc i)) \ chain Y" unfolding chain_def by fast
lemma chainE: "chain Y \ Y i \ Y (Suc i)" unfolding chain_def by fast
text\<open>chains are monotone functions\<close>
lemma chain_mono_less: "chain Y \ i < j \ Y i \ Y j" by (erule less_Suc_induct, erule chainE, erule below_trans)
lemma chain_mono: "chain Y \ i \ j \ Y i \ Y j" by (cases "i = j") (simp_all add: chain_mono_less)
lemma chain_shift: "chain Y \ chain (\i. Y (i + j))" by (rule chainI, simp, erule chainE)
text\<open>technical lemmas about (least) upper bounds of chains\<close>
lemma is_lub_rangeD1: "range S <<| x \ S i \ x" by (rule is_lubD1 [THEN ub_rangeD])
lemma is_ub_range_shift: "chain S \ range (\i. S (i + j)) <| x = range S <| x" apply (rule iffI) apply (rule ub_rangeI) apply (rule_tac y="S (i + j)"in below_trans) apply (erule chain_mono) apply (rule le_add1) apply (erule ub_rangeD) apply (rule ub_rangeI) apply (erule ub_rangeD) done
lemma is_lub_range_shift: "chain S \ range (\i. S (i + j)) <<| x = range S <<| x" by (simp add: is_lub_def is_ub_range_shift)
text\<open>the lub of a constant chain is the constant\<close>
lemma chain_const [simp]: "chain (\i. c)" by (simp add: chainI)
lemma is_lub_const: "range (\x. c) <<| c" by (blast dest: ub_rangeD intro: is_lubI ub_rangeI)
lemma lub_const [simp]: "(\i. c) = c" by (rule is_lub_const [THEN lub_eqI])
subsection \<open>Finite chains\<close>
definition max_in_chain :: "nat \ (nat \ 'a) \ bool" where\<comment> \<open>finite chains, needed for monotony of continuous functions\<close> "max_in_chain i C \ (\j. i \ j \ C i = C j)"
definition finite_chain :: "(nat \ 'a) \ bool" where"finite_chain C = (chain C \ (\i. max_in_chain i C))"
text\<open>results about finite chains\<close>
lemma max_in_chainI: "(\j. i \ j \ Y i = Y j) \ max_in_chain i Y" unfolding max_in_chain_def by fast
lemma max_in_chainD: "max_in_chain i Y \ i \ j \ Y i = Y j" unfolding max_in_chain_def by fast
lemma finite_chainI: "chain C \ max_in_chain i C \ finite_chain C" unfolding finite_chain_def by fast
lemma finite_chainE: "\finite_chain C; \i. \chain C; max_in_chain i C\ \ R\ \ R" unfolding finite_chain_def by fast
lemma lub_finch1: "chain C \ max_in_chain i C \ range C <<| C i" apply (rule is_lubI) apply (rule ub_rangeI, rename_tac j) apply (rule_tac x=i and y=j in linorder_le_cases) apply (drule (1) max_in_chainD, simp) apply (erule (1) chain_mono) apply (erule ub_rangeD) done
lemma lub_finch2: "finite_chain C \ range C <<| C (LEAST i. max_in_chain i C)" apply (erule finite_chainE) apply (erule LeastI2 [where Q="\i. range C <<| C i"]) apply (erule (1) lub_finch1) done
lemma finch_imp_finite_range: "finite_chain Y \ finite (range Y)" apply (erule finite_chainE) apply (rule_tac B="Y ` {..i}"in finite_subset) apply (rule subsetI) apply (erule rangeE, rename_tac j) apply (rule_tac x=i and y=j in linorder_le_cases) apply (subgoal_tac "Y j = Y i", simp) apply (simp add: max_in_chain_def) apply simp apply simp done
lemma finite_range_has_max: fixes f :: "nat \ 'a" and r :: "'a \ 'a \ bool" assumes mono: "\i j. i \ j \ r (f i) (f j)" assumes finite_range: "finite (range f)" shows"\k. \i. r (f i) (f k)" proof (intro exI allI) fix i :: nat let ?j = "LEAST k. f k = f i" let ?k = "Max ((\x. LEAST k. f k = x) ` range f)" have"?j \ ?k" proof (rule Max_ge) show"finite ((\x. LEAST k. f k = x) ` range f)" using finite_range by (rule finite_imageI) show"?j \ (\x. LEAST k. f k = x) ` range f" by (intro imageI rangeI) qed hence"r (f ?j) (f ?k)" by (rule mono) alsohave"f ?j = f i" by (rule LeastI, rule refl) finallyshow"r (f i) (f ?k)" . qed
lemma bin_chain: "x \ y \ chain (\i. if i=0 then x else y)" by (rule chainI) simp
lemma bin_chainmax: "x \ y \ max_in_chain (Suc 0) (\i. if i=0 then x else y)" by (simp add: max_in_chain_def)
lemma is_lub_bin_chain: "x \ y \ range (\i::nat. if i=0 then x else y) <<| y" apply (frule bin_chain) apply (drule bin_chainmax) apply (drule (1) lub_finch1) apply simp done
text\<open>the maximal element in a chain is its lub\<close>
lemma lub_chain_maxelem: "Y i = c \ \i. Y i \ c \ lub (range Y) = c" by (blast dest: ub_rangeD intro: lub_eqI is_lubI ub_rangeI)
end
section \<open>Classes cpo and pcpo\<close>
subsection \<open>Complete partial orders\<close>
text\<open>The class cpo of chain complete partial orders\<close>
class cpo = po + assumes cpo: "chain S \ \x. range S <<| x"
default_sort cpo
context cpo begin
text\<open>in cpo's everthing equal to THE lub has lub properties for every chain\<close>
lemma cpo_lubI: "chain S \ range S <<| (\i. S i)" by (fast dest: cpo elim: is_lub_lub)
lemma thelubE: "\chain S; (\i. S i) = l\ \ range S <<| l" by (blast dest: cpo intro: is_lub_lub)
text\<open>Properties of the lub\<close>
lemma is_ub_thelub: "chain S \ S x \ (\i. S i)" by (blast dest: cpo intro: is_lub_lub [THEN is_lub_rangeD1])
lemma is_lub_thelub: "\chain S; range S <| x\ \ (\i. S i) \ x" by (blast dest: cpo intro: is_lub_lub [THEN is_lubD2])
lemma lub_below_iff: "chain S \ (\i. S i) \ x \ (\i. S i \ x)" by (simp add: is_lub_below_iff [OF cpo_lubI] is_ub_def)
lemma lub_below: "\chain S; \i. S i \ x\ \ (\i. S i) \ x" by (simp add: lub_below_iff)
lemma below_lub: "\chain S; x \ S i\ \ x \ (\i. S i)" by (erule below_trans, erule is_ub_thelub)
lemma lub_range_mono: "\range X \ range Y; chain Y; chain X\ \ (\i. X i) \ (\i. Y i)" apply (erule lub_below) apply (subgoal_tac "\j. X i = Y j") apply clarsimp apply (erule is_ub_thelub) apply auto done
lemma lub_range_shift: "chain Y \ (\i. Y (i + j)) = (\i. Y i)" apply (rule below_antisym) apply (rule lub_range_mono) apply fast apply assumption apply (erule chain_shift) apply (rule lub_below) apply assumption apply (rule_tac i="i"in below_lub) apply (erule chain_shift) apply (erule chain_mono) apply (rule le_add1) done
lemma maxinch_is_thelub: "chain Y \ max_in_chain i Y = ((\i. Y i) = Y i)" apply (rule iffI) apply (fast intro!: lub_eqI lub_finch1) apply (unfold max_in_chain_def) apply (safe intro!: below_antisym) apply (fast elim!: chain_mono) apply (drule sym) apply (force elim!: is_ub_thelub) done
text\<open>the \<open>\<sqsubseteq>\<close> relation between two chains is preserved by their lubs\<close>
lemma lub_mono: "\chain X; chain Y; \i. X i \ Y i\ \ (\i. X i) \ (\i. Y i)" by (fast elim: lub_below below_lub)
text\<open>the = relation between two chains is preserved by their lubs\<close>
lemma lub_eq: "(\i. X i = Y i) \ (\i. X i) = (\i. Y i)" by simp
lemma ch2ch_lub: assumes 1: "\j. chain (\i. Y i j)" assumes 2: "\i. chain (\j. Y i j)" shows"chain (\i. \j. Y i j)" apply (rule chainI) apply (rule lub_mono [OF 2 2]) apply (rule chainE [OF 1]) done
lemma diag_lub: assumes 1: "\j. chain (\i. Y i j)" assumes 2: "\i. chain (\j. Y i j)" shows"(\i. \j. Y i j) = (\i. Y i i)" proof (rule below_antisym) have 3: "chain (\i. Y i i)" apply (rule chainI) apply (rule below_trans) apply (rule chainE [OF 1]) apply (rule chainE [OF 2]) done have 4: "chain (\i. \j. Y i j)" by (rule ch2ch_lub [OF 1 2]) show"(\i. \j. Y i j) \ (\i. Y i i)" apply (rule lub_below [OF 4]) apply (rule lub_below [OF 2]) apply (rule below_lub [OF 3]) apply (rule below_trans) apply (rule chain_mono [OF 1 max.cobounded1]) apply (rule chain_mono [OF 2 max.cobounded2]) done show"(\i. Y i i) \ (\i. \j. Y i j)" apply (rule lub_mono [OF 3 4]) apply (rule is_ub_thelub [OF 2]) done qed
lemma ex_lub: assumes 1: "\j. chain (\i. Y i j)" assumes 2: "\i. chain (\j. Y i j)" shows"(\i. \j. Y i j) = (\j. \i. Y i j)" by (simp add: diag_lub 1 2)
end
subsection \<open>Pointed cpos\<close>
text\<open>The class pcpo of pointed cpos\<close>
class pcpo = cpo + assumes least: "\x. \y. x \ y" begin
definition bottom :: "'a" (\<open>\<bottom>\<close>) where"bottom = (THE x. \y. x \ y)"
lemma chfin2finch: "chain Y \ finite_chain Y" by (simp add: chfin finite_chain_def)
end
class flat = pcpo + assumes ax_flat: "x \ y \ x = \ \ x = y" begin
subclass chfin proof fix Y assume *: "chain Y" show"\n. max_in_chain n Y" apply (unfold max_in_chain_def) apply (cases "\i. Y i = \") apply simp apply simp apply (erule exE) apply (rule_tac x="i"in exI) apply clarify using * apply (blast dest: chain_mono ax_flat) done qed
lemma flat_below_iff: "x \ y \ x = \ \ x = y" by (safe dest!: ax_flat)
lemma flat_eq: "a \ \ \ a \ b = (a = b)" by (safe dest!: ax_flat)
end
subsection \<open>Discrete cpos\<close>
class discrete_cpo = below + assumes discrete_cpo [simp]: "x \ y \ x = y" begin
subclass po by standard simp_all
text\<open>In a discrete cpo, every chain is constant\<close>
lemma discrete_chain_const: assumes S: "chain S" shows"\x. S = (\i. x)" proof (intro exI ext) fix i :: nat from S le0 have"S 0 \ S i" by (rule chain_mono) thenhave"S 0 = S i"by simp thenshow"S i = S 0"by (rule sym) qed
subclass chfin proof fix S :: "nat \ 'a" assume S: "chain S" thenhave"\x. S = (\i. x)" by (rule discrete_chain_const) thenhave"max_in_chain 0 S" by (auto simp: max_in_chain_def) thenshow"\i. max_in_chain i S" .. qed
end
section \<open>Continuity and monotonicity\<close>
subsection \<open>Definitions\<close>
definition monofun :: "('a::po \ 'b::po) \ bool" \ \monotonicity\ where"monofun f \ (\x y. x \ y \ f x \ f y)"
definition cont :: "('a \ 'b) \ bool" where"cont f = (\Y. chain Y \ range (\i. f (Y i)) <<| f (\i. Y i))"
lemma contI: "(\Y. chain Y \ range (\i. f (Y i)) <<| f (\i. Y i)) \ cont f" by (simp add: cont_def)
lemma contE: "cont f \ chain Y \ range (\i. f (Y i)) <<| f (\i. Y i)" by (simp add: cont_def)
lemma monofunI: "(\x y. x \ y \ f x \ f y) \ monofun f" by (simp add: monofun_def)
lemma monofunE: "monofun f \ x \ y \ f x \ f y" by (simp add: monofun_def)
subsection \<open>Equivalence of alternate definition\<close>
text\<open>monotone functions map chains to chains\<close>
lemma ch2ch_monofun: "monofun f \ chain Y \ chain (\i. f (Y i))" apply (rule chainI) apply (erule monofunE) apply (erule chainE) done
text\<open>monotone functions map upper bound to upper bounds\<close>
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
text\<open>a lemma about binary chains\<close>
lemma binchain_cont: "cont f \ x \ y \ range (\i::nat. f (if i = 0 then x else y)) <<| f y" apply (subgoal_tac "f (\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 is_lub_bin_chain [THEN lub_eqI]) done
lemma cont2cont_lub [simp]: assumes chain: "\x. chain (\i. F i x)" and cont: "\i. cont (\x. F i x)" shows"cont (\x. \i. F i x)" apply (rule contI2) apply (simp add: monofunI cont2monofunE [OF cont] lub_mono chain) apply (simp add: cont2contlubE [OF cont]) apply (simp add: diag_lub ch2ch_cont [OF cont] chain) done
text\<open>if-then-else is continuous\<close>
lemma cont_if [simp, cont2cont]: "cont f \ cont g \ cont (\x. if b then f x else g x)" by (induct b) simp_all
subsection \<open>Finite chains and flat pcpos\<close>
text\<open>Monotone functions map finite chains to finite chains.\<close>
lemma monofun_finch2finch: "monofun f \ finite_chain Y \ finite_chain (\n. f (Y n))" by (force simp add: finite_chain_def ch2ch_monofun max_in_chain_def)
text\<open>The same holds for continuous functions.\<close>
lemma cont_finch2finch: "cont f \ finite_chain Y \ finite_chain (\n. f (Y n))" by (rule cont2mono [THEN monofun_finch2finch])
text\<open>All monotone functions with chain-finite domain are continuous.\<close>
lemma chfindom_monofun2cont: "monofun f \ cont f" for f :: "'a::chfin \ 'b" apply (erule contI2) 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\<open>All strict functions with flat domain are continuous.\<close>
lemma flatdom_strict2mono: "f \ = \ \ monofun f" for f :: "'a::flat \ 'b::pcpo" apply (rule monofunI) apply (drule ax_flat) apply auto done
lemma flatdom_strict2cont: "f \ = \ \ cont f" for f :: "'a::flat \ 'b::pcpo" by (rule flatdom_strict2mono [THEN chfindom_monofun2cont])
text\<open>All functions with discrete domain are continuous.\<close>
section \<open>Admissibility and compactness\<close>
subsection \<open>Definitions\<close>
context cpo begin
definition adm :: "('a \ bool) \ bool" where"adm P \ (\Y. chain Y \ (\i. P (Y i)) \ P (\i. Y i))"
lemma admI: "(\Y. \chain Y; \i. P (Y i)\ \ P (\i. Y i)) \ adm P" unfolding adm_def by fast
lemma admD: "adm P \ chain Y \ (\i. P (Y i)) \ P (\i. Y i)" unfolding adm_def by fast
lemma admD2: "adm (\x. \ P x) \ chain Y \ P (\i. Y i) \ \i. P (Y i)" unfolding adm_def by fast
lemma triv_admI: "\x. P x \ adm P" by (rule admI) (erule spec)
end
subsection \<open>Admissibility on chain-finite types\<close>
text\<open>For chain-finite (easy) types every formula is admissible.\<close>
lemma adm_chfin [simp]: "adm P"for P :: "'a::chfin \ bool" by (rule admI, frule chfin, auto simp add: maxinch_is_thelub)
subsection \<open>Admissibility of special formulae and propagation\<close>
context cpo begin
lemma adm_const [simp]: "adm (\x. t)" by (rule admI, simp)
lemma adm_conj [simp]: "adm (\x. P x) \ adm (\x. Q x) \ adm (\x. P x \ Q x)" by (fast intro: admI elim: admD)
lemma adm_all [simp]: "(\y. adm (\x. P x y)) \ adm (\x. \y. P x y)" by (fast intro: admI elim: admD)
lemma adm_ball [simp]: "(\y. y \ A \ adm (\x. P x y)) \ adm (\x. \y\A. P x y)" by (fast intro: admI elim: admD)
text\<open>Admissibility for disjunction is hard to prove. It requires 2 lemmas.\<close>
lemma adm_disj_lemma1: assumes adm: "adm P" assumes chain: "chain Y" assumes P: "\i. \j\i. P (Y j)" shows"P (\i. Y i)" proof -
define f where"f i = (LEAST j. i \ j \ P (Y j))" for i have chain': "chain (\i. Y (f i))" unfolding f_def apply (rule chainI) apply (rule chain_mono [OF chain]) apply (rule Least_le) apply (rule LeastI2_ex) apply (simp_all add: P) done have f1: "\i. i \ f i" and f2: "\i. P (Y (f i))" using LeastI_ex [OF P [rule_format]] by (simp_all add: f_def) have lub_eq: "(\i. Y i) = (\i. Y (f i))" apply (rule below_antisym) apply (rule lub_mono [OF chain chain']) apply (rule chain_mono [OF chain f1]) apply (rule lub_range_mono [OF _ chain chain']) apply clarsimp done show"P (\i. Y i)" unfolding lub_eq using adm chain' f2 by (rule admD) qed
lemma adm_disj_lemma2: "\n::nat. P n \ Q n \ (\i. \j\i. P j) \ (\i. \j\i. Q j)" apply (erule contrapos_pp) apply (clarsimp, rename_tac a b) apply (rule_tac x="max a b"in exI) apply simp done
section \<open>Class instances for the full function space\<close>
subsection \<open>Full function space is a partial order\<close>
instantiation"fun" :: (type, below) below begin
definition below_fun_def: "(\) \ (\f g. \x. f x \ g x)"
instance .. end
instance"fun" :: (type, po) po proof fix f g h :: "'a \ 'b" show"f \ f" by (simp add: below_fun_def) show"f \ g \ g \ f \ f = g" by (simp add: below_fun_def fun_eq_iff below_antisym) show"f \ g \ g \ h \ f \ h" unfolding below_fun_def by (fast elim: below_trans) qed
lemma fun_below_iff: "f \ g \ (\x. f x \ g x)" by (simp add: below_fun_def)
lemma fun_belowI: "(\x. f x \ g x) \ f \ g" by (simp add: below_fun_def)
lemma fun_belowD: "f \ g \ f x \ g x" by (simp add: below_fun_def)
subsection \<open>Full function space is chain complete\<close>
text\<open>Properties of chains of functions.\<close>
lemma fun_chain_iff: "chain S \ (\x. chain (\i. S i x))" by (auto simp: chain_def fun_below_iff)
lemma ch2ch_fun: "chain S \ chain (\i. S i x)" by (simp add: chain_def below_fun_def)
lemma ch2ch_lambda: "(\x. chain (\i. S i x)) \ chain S" by (simp add: chain_def below_fun_def)
text\<open>Type \<^typ>\<open>'a::type \<Rightarrow> 'b::cpo\<close> is chain complete\<close>
lemma is_lub_lambda: "(\x. range (\i. Y i x) <<| f x) \ range Y <<| f" by (simp add: is_lub_def is_ub_def below_fun_def)
lemma is_lub_fun: "chain S \ range S <<| (\x. \i. S i x)" for S :: "nat \ 'a::type \ 'b" apply (rule is_lub_lambda) apply (rule cpo_lubI) apply (erule ch2ch_fun) done
lemma lub_fun: "chain S \ (\i. S i) = (\x. \i. S i x)" for S :: "nat \ 'a::type \ 'b" by (rule is_lub_fun [THEN lub_eqI])
text\<open>Function application preserves monotonicity and continuity.\<close>
lemma mono2mono_fun: "monofun f \ monofun (\x. f x y)" by (simp add: monofun_def fun_below_iff)
lemma cont2cont_fun: "cont f \ cont (\x. f x y)" apply (rule contI2) apply (erule cont2mono [THEN mono2mono_fun]) apply (simp add: cont2contlubE lub_fun ch2ch_cont) done
lemma cont_fun: "cont (\f. f x)" using cont_id by (rule cont2cont_fun)
simproc_setup apply_cont (\<open>cont (\<lambda>f. E f)\<close>) = \<open>
fn _ => fn ctxt => fn lhs =>
(caseThm.term_of lhs of \<^Const_>\<open>cont _ _ for \<open>Abs (_, _, expr)\<close>\<close> => ifcase strip_comb expr of (f, args) =>
f = Bound 0 andalso not (exists Term.is_dependent args) (* since \<open>\<lambda>f. E f\<close> is too permissive, we ensure here that the term
is of the form \<open>\<lambda>f. f \<dots>\<close>, with \<open>f\<close> no longer appearing in \<open>\<dots>\<close> *) then let
val tac = Metis_Tactic.metis_tac ["no_types"] "combs" ctxt @{thms cont2cont_fun cont_id}
val thm =
Goal.prove_internal ctxt [] \<^instantiate>\<open>lhs in cprop \<open>lhs = True\<close>\<close>
(fn _ => tac 1) in SOME (mk_meta_eq thm) end
else NONE
| _ => NONE) \<close>
lemma"cont (\f. f x)" and "cont (\f. f x y)" and "cont (\f. f x y z)" by simp_all
text\<open>
Lambda abstraction preserves monotonicity and continuity.
(Note\<open>(\<lambda>x. \<lambda>y. f x y) = f\<close>.) \<close>
lemma mono2mono_lambda: "(\y. monofun (\x. f x y)) \ monofun f" by (simp add: monofun_def fun_below_iff)
lemma cont2cont_lambda [simp]: assumes f: "\y. cont (\x. f x y)" shows"cont f" by (rule contI, rule is_lub_lambda, rule contE [OF f])
text\<open>What D.A.Schmidt calls continuity of abstraction; never used here\<close>
lemma contlub_lambda: "(\x. chain (\i. S i x)) \ (\x. \i. S i x) = (\i. (\x. S i x))" for S :: "nat \ 'a::type \ 'b" by (simp add: lub_fun ch2ch_lambda)
section \<open>The cpo of cartesian products\<close>
instance prod :: (po, po) po proof fix x y z :: "'a \ 'b" show"x \ x" by (simp add: below_prod_def) show"x \ y \ y \ x \ x = y" unfolding below_prod_def prod_eq_iff by (fast intro: below_antisym) show"x \ y \ y \ z \ x \ z" unfolding below_prod_def by (fast intro: below_trans) qed
subsection \<open>Monotonicity of \emph{Pair}, \emph{fst}, \emph{snd}\<close>
lemma prod_belowI: "fst p \ fst q \ snd p \ snd q \ p \ q" by (simp add: below_prod_def)
lemma Pair_below_iff [simp]: "(a, b) \ (c, d) \ a \ c \ b \ d" by (simp add: below_prod_def)
text\<open>Pair \<open>(_,_)\<close> is monotone in both arguments\<close>
lemma monofun_pair1: "monofun (\x. (x, y))" by (simp add: monofun_def)
lemma monofun_pair2: "monofun (\y. (x, y))" by (simp add: monofun_def)
lemma prod_chain_cases: assumes chain: "chain Y" obtains A B where"chain A"and"chain B"and"Y = (\i. (A i, B i))" proof from chain show"chain (\i. fst (Y i))" by (rule ch2ch_fst) from chain show"chain (\i. snd (Y i))" by (rule ch2ch_snd) show"Y = (\i. (fst (Y i), snd (Y i)))" by simp qed
subsection \<open>Product type is a cpo\<close>
lemma is_lub_Pair: "range A <<| x \ range B <<| y \ range (\i. (A i, B i)) <<| (x, y)" by (simp add: is_lub_def is_ub_def below_prod_def)
lemma lub_Pair: "chain A \ chain B \ (\i. (A i, B i)) = (\i. A i, \i. B i)" for A :: "nat \ 'a" and B :: "nat \ 'b" by (fast intro: lub_eqI is_lub_Pair elim: thelubE)
lemma is_lub_prod: fixes S :: "nat \ ('a \ 'b)" assumes"chain S" shows"range S <<| (\i. fst (S i), \i. snd (S i))" using assms by (auto elim: prod_chain_cases simp: is_lub_Pair cpo_lubI)
lemma lub_prod: "chain S \ (\i. S i) = (\i. fst (S i), \i. snd (S i))" for S :: "nat \ 'a \ 'b" by (rule is_lub_prod [THEN lub_eqI])
instance prod :: (cpo, cpo) cpo proof fix S :: "nat \ ('a \ 'b)" assume"chain S" thenhave"range S <<| (\i. fst (S i), \i. snd (S i))" by (rule is_lub_prod) thenshow"\x. range S <<| x" .. qed
instance prod :: (discrete_cpo, discrete_cpo) discrete_cpo proof show"x \ y \ x = y" for x y :: "'a \ 'b" by (simp add: below_prod_def prod_eq_iff) qed
subsection \<open>Product type is pointed\<close>
lemma minimal_prod: "(\, \) \ p" by (simp add: below_prod_def)
lemma cont2cont_case_prod: assumes f1: "\a b. cont (\x. f x a b)" assumes f2: "\x b. cont (\a. f x a b)" assumes f3: "\x a. cont (\b. f x a b)" assumes g: "cont (\x. g x)" shows"cont (\x. case g x of (a, b) \ f x a b)" unfolding split_def apply (rule cont_apply [OF g]) apply (rule cont_apply [OF cont_fst f2]) apply (rule cont_apply [OF cont_snd f3]) apply (rule cont_const) apply (rule f1) done
lemma prod_contI: assumes f1: "\y. cont (\x. f (x, y))" assumes f2: "\x. cont (\y. f (x, y))" shows"cont f" proof - have"cont (\(x, y). f (x, y))" by (intro cont2cont_case_prod f1 f2 cont2cont) thenshow"cont f" by (simp only: case_prod_eta) qed
lemma cont2cont_case_prod' [simp, cont2cont]: assumes f: "cont (\p. f (fst p) (fst (snd p)) (snd (snd p)))" assumes g: "cont (\x. g x)" shows"cont (\x. case_prod (f x) (g x))" using assms by (simp add: cont2cont_case_prod prod_cont_iff)
text\<open>The simple version (due to Joachim Breitner) is needed if
either element type of the pair is not a cpo.\<close>
lemma cont2cont_split_simple [simp, cont2cont]: assumes"\a b. cont (\x. f x a b)" shows"cont (\x. case p of (a, b) \ f x a b)" using assms by (cases p) auto
text\<open>Admissibility of predicates on product types.\<close>
lemma adm_case_prod [simp]: assumes"adm (\x. P x (fst (f x)) (snd (f x)))" shows"adm (\x. case f x of (a, b) \ P x a b)" unfolding case_prod_beta using assms .
subsection \<open>Compactness and chain-finiteness\<close>
lemma fst_below_iff: "fst x \ y \ x \ (y, snd x)" for x :: "'a \ 'b" by (simp add: below_prod_def)
lemma snd_below_iff: "snd x \ y \ x \ (fst x, y)" for x :: "'a \ 'b" by (simp add: below_prod_def)
lemma compact_fst: "compact x \ compact (fst x)" by (rule compactI) (simp add: fst_below_iff)
lemma compact_snd: "compact x \ compact (snd x)" by (rule compactI) (simp add: snd_below_iff)
lemma compact_Pair: "compact x \ compact y \ compact (x, y)" by (rule compactI) (simp add: below_prod_def)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.