(* Title: HOL/HOLCF/Cpo.thy Author: Franz Regensburger Author: Tobias Nipkow Author: Brian Huffman Foundations of HOLCF: complete partial orders etc. *)
theory Cpo imports Main begin
section‹Partial orders›
declare [[typedef_overloaded]]
subsection‹Type class for partial orders›
class below = fixes below :: "'a ==> 'a ==> bool" begin
notation (ASCII)
below (infix‹🚫› 50)
notation
below (infix‹⊑› 50)
abbreviation not_below :: "'a ==> 'a ==> bool" (infix‹🪙› 50) where"not_below x y ≡¬ below x y"
notation (ASCII)
not_below (infix‹~🚫› 50)
lemma below_eq_trans: "a ⊑ b ==> b = c ==> a ⊑ c" by (rule subst)
lemma eq_below_trans: "a = b ==> b ⊑ c ==> a ⊑ c" by (rule ssubst)
end
class po = below + assumes below_refl [iff]: "x ⊑ x" assumes below_trans: "x ⊑ y ==> y ⊑ z ==> x ⊑ z" assumes below_antisym: "x ⊑ y ==> y ⊑ x ==> x = y" begin
lemma eq_imp_below: "x = y ==> x ⊑ y" by simp
lemma box_below: "a ⊑ b ==> c ⊑ a ==> b ⊑ d ==> c ⊑ d" by (rule below_trans [OF below_trans])
lemma po_eq_conv: "x = y ⟷ x ⊑ y ∧ y ⊑ x" by (fast intro!: below_antisym)
lemma rev_below_trans: "y ⊑ z ==> x ⊑ y ==> x ⊑ z" by (rule below_trans)
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‹Countable chains›
definition chain :: "(nat ==> 'a) ==> bool" where🍋‹Here we use countable chains and I prefer to code them as functions!› "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‹chains are monotone functions›
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‹technical lemmas about (least) upper bounds of chains›
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‹the lub of a constant chain is the constant›
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‹Finite chains›
definition max_in_chain :: "nat ==> (nat ==> 'a) ==> bool" where🍋‹finite chains, needed for monotony of continuous functions› "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‹results about finite chains›
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‹the maximal element in a chain is its lub›
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‹Classes cpo and pcpo›
subsection‹Complete partial orders›
text‹The class cpo of chain complete partial orders›
class cpo = po + assumes cpo: "chain S ==>∃x. range S <<| x"
default_sort cpo
context cpo begin
text‹in cpo's everthing equal to THE lub has lub properties for every chain›
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‹Properties of the lub›
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‹the ‹⊑›relation between two chains is preserved by their lubs›
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‹the = relation between two chains is preserved by their lubs›
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‹Pointed cpos›
text‹The class pcpo of pointed cpos›
class pcpo = cpo + assumes least: "∃x. ∀y. x ⊑ y" begin
definition bottom :: "'a" (‹⊥›) 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‹Discrete cpos›
class discrete_cpo = below + assumes discrete_cpo [simp]: "x ⊑ y ⟷ x = y" begin
subclass po by standard simp_all
text‹In a discrete cpo, every chain is constant›
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‹Continuity and monotonicity›
subsection‹Definitions›
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‹Equivalence of alternate definition›
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
text‹a lemma about binary chains›
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 cont_const [simp, cont2cont]: "cont (λx. c)" using is_lub_const by (rule contI)
text‹application of functions is continuous›
lemma cont_apply: fixes f :: "'a ==> 'b ==> 'c"and t :: "'a ==> 'b" assumes 1: "cont (λx. t x)" assumes 2: "∧x. cont (λy. f x y)" assumes 3: "∧y. cont (λx. f x y)" shows"cont (λx. (f x) (t x))" proof (rule contI2 [OF monofunI]) fix x y :: "'a" assume"x ⊑ y" thenshow"f x (t x) ⊑ f y (t y)" by (auto intro: cont2monofunE [OF 1]
cont2monofunE [OF 2]
cont2monofunE [OF 3]
below_trans) next fix Y :: "nat ==> 'a" assume"chain Y" thenshow"f (⊔i. Y i) (t (⊔i. Y i)) ⊑ (⊔i. f (Y i) (t (Y i)))" by (simp only: cont2contlubE [OF 1] ch2ch_cont [OF 1]
cont2contlubE [OF 2] ch2ch_cont [OF 2]
cont2contlubE [OF 3] ch2ch_cont [OF 3]
diag_lub below_refl) qed
lemma cont_compose: "cont c ==> cont (λx. f x) ==> cont (λx. c (f x))" by (rule cont_apply [OF _ _ cont_const])
text‹Least upper bounds preserve continuity›
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‹if-then-else is continuous›
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‹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))" by (force simp add: finite_chain_def ch2ch_monofun max_in_chain_def)
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])
text‹All monotone functions with chain-finite domain are continuous.›
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‹All strict functions with flat domain are continuous.›
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‹All functions with discrete domain are continuous.›
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‹Admissibility on chain-finite types›
text‹For chain-finite (easy) types every formula is admissible.›
lemma adm_chfin [simp]: "adm P"for P :: "'a::chfin ==> bool" by (rule admI, frule chfin, auto simp add: maxinch_is_thelub)
subsection‹Admissibility of special formulae and propagation›
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‹Admissibility for disjunction is hard to prove. It requires 2 lemmas.›
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‹Class instances for the full function space›
subsection‹Full function space is a partial order›
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‹Full function space is chain complete›
text‹Properties of chains of functions.›
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)
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‹Function application preserves monotonicity and continuity.›
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 (‹cont (λf. E f)›) = ‹ fn _ => fn ctxt => fn lhs => (case Thm.term_of lhs of 🍋‹cont _ _ for ‹Abs (_, _, expr)›\› => if case strip_comb expr of (f, args) => f = Bound 0 andalso not (exists Term.is_dependent args) (* since ‹λf. E f›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 [] 🍋‹lhs in cprop ‹lhs = True›\›
(fn _ => tac 1) in SOME (mk_meta_eq thm) end
else NONE
| _ => NONE) ›
lemma"cont (λf. f x)"and"cont (λf. f x y)"and"cont (λf. f x y z)" by simp_all
text‹ Lambda abstraction preserves monotonicity and continuity. (Note ‹(λx. λy. f x y) = f›.) ›
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‹What D.A.Schmidt calls continuity of abstraction; never used here›
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)
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‹Monotonicity of \emph{Pair}, \emph{fst}, \emph{snd}›
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‹Pair ‹(_,_)›is monotone in both arguments›
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‹Product type is a cpo›
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‹Product type is pointed›
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‹The simple version (due to Joachim Breitner) is needed if either element type of the pair is not a cpo.›
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‹Admissibility of predicates on product types.›
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‹Compactness and chain-finiteness›
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 und die Messung sind noch experimentell.