lemma list_chain_induct [consumes 1, case_names Nil Cons]: assumes"chain S" assumes 1: "P (λi. [])" assumes 2: "∧A B. chain A ==> chain B ==> P B ==> P (λi. A i # B i)" shows"P S" using‹chain S› proof (induct "S 0" arbitrary: S) case Nil have"∀i. S 0 ⊑ S i"by (simp add: chain_mono [OF ‹chain S›]) with Nil have"∀i. S i = []"by simp thus ?caseby (simp add: 1) next case (Cons x xs) have"∀i. S 0 ⊑ S i"by (simp add: chain_mono [OF ‹chain S›]) hence *: "∀i. S i ≠ []"by (rule all_forward, insert Cons) auto have"chain (λi. hd (S i))"and"chain (λi. tl (S i))" using‹chain S›by simp_all moreoverhave"P (λi. tl (S i))" using‹chain S›and‹x # xs = S 0› [symmetric] by (simp add: Cons(1)) ultimatelyhave"P (λi. hd (S i) # tl (S i))" by (rule 2) thus"P S"by (simp add: *) qed
lemma list_chain_cases: assumes S: "chain S" obtains"S = (λi. [])" |
A B where"chain A"and"chain B"and"S = (λi. A i # B i)" using S by (induct rule: list_chain_induct) simp_all
subsection‹Lists are a complete partial order›
lemma is_lub_Cons: assumes A: "range A <<| x" assumes B: "range B <<| xs" shows"range (λi. A i # B i) <<| x # xs" using assms unfolding is_lub_def is_ub_def by (clarsimp, case_tac u, simp_all)
instance list :: (cpo) cpo proof fix S :: "nat ==> 'a list" assume"chain S" thenshow"∃x. range S <<| x" proof (induct rule: list_chain_induct) case Nil have"{[]} <<| []" by simp thenobtain x :: "'a list"where"{[]} <<| x" .. thenshow ?case by auto next case (Cons A B) thenshow ?case by (auto intro: is_lub_Cons cpo_lubI) qed qed
subsection‹Continuity of list operations›
lemma cont2cont_Cons [simp, cont2cont]: assumes f: "cont (λx. f x)" assumes g: "cont (λx. g x)" shows"cont (λx. f x # g x)" apply (rule contI) apply (rule is_lub_Cons) apply (erule contE [OF f]) apply (erule contE [OF g]) done
lemma lub_Cons: fixes A :: "nat ==> 'a::cpo" assumes A: "chain A"and B: "chain B" shows"(⊔i. A i # B i) = (⊔i. A i) # (⊔i. B i)" by (intro lub_eqI is_lub_Cons cpo_lubI A B)
lemma cont2cont_case_list: assumes f: "cont (λx. f x)" assumes g: "cont (λx. g x)" assumes h1: "∧y ys. cont (λx. h x y ys)" assumes h2: "∧x ys. cont (λy. h x y ys)" assumes h3: "∧x y. cont (λys. h x y ys)" shows"cont (λx. case f x of [] ==> g x | y # ys ==> h x y ys)" apply (rule cont_apply [OF f]) apply (rule contI) apply (erule list_chain_cases) apply (simp add: is_lub_const) apply (simp add: lub_Cons) apply (simp add: cont2contlubE [OF h2]) apply (simp add: cont2contlubE [OF h3]) apply (simp add: diag_lub ch2ch_cont [OF h2] ch2ch_cont [OF h3]) apply (rule cpo_lubI, rule chainI, rule below_trans) apply (erule cont2monofunE [OF h2 chainE]) apply (erule cont2monofunE [OF h3 chainE]) apply (case_tac y, simp_all add: g h1) done
lemma cont2cont_case_list' [simp, cont2cont]: assumes f: "cont (λx. f x)" assumes g: "cont (λx. g x)" assumes h: "cont (λp. h (fst p) (fst (snd p)) (snd (snd p)))" shows"cont (λx. case f x of [] ==> g x | y # ys ==> h x y ys)" using assms by (simp add: cont2cont_case_list prod_cont_iff)
text‹The simple version (due to Joachim Breitner) is needed if the element type of the list is not a cpo.›
lemma cont2cont_case_list_simple [simp, cont2cont]: assumes"cont (λx. f1 x)" assumes"∧y ys. cont (λx. f2 x y ys)" shows"cont (λx. case l of [] ==> f1 x | y # ys ==> f2 x y ys)" using assms by (cases l) auto
text‹Lemma for proving continuity of recursive list functions:›
lemma list_contI: fixes f :: "'a::cpo list ==> 'b::cpo" assumes f: "∧x xs. f (x # xs) = g x xs (f xs)" assumes g1: "∧xs y. cont (λx. g x xs y)" assumes g2: "∧x y. cont (λxs. g x xs y)" assumes g3: "∧x xs. cont (λy. g x xs y)" shows"cont f" proof (rule contI2) obtain h where h: "∧x xs y. g x xs y = h⋅x⋅xs⋅y" proof fix x xs y show"g x xs y = (Λ x xs y. g x xs y)⋅x⋅xs⋅y" by (simp add: cont2cont_LAM g1 g2 g3) qed show mono: "monofun f" apply (rule monofunI) apply (erule list_below_induct) apply simp apply (simp add: f h monofun_cfun) done fix Y :: "nat ==> 'a list" assume"chain Y"thus"f (⊔i. Y i) ⊑ (⊔i. f (Y i))" apply (induct rule: list_chain_induct) apply simp apply (simp add: lub_Cons f h) apply (simp add: lub_APP ch2ch_monofun [OF mono]) apply (simp add: monofun_cfun) done qed
text‹Continuity rule for map›
lemma cont2cont_map [simp, cont2cont]: assumes f: "cont (λ(x, y). f x y)" assumes g: "cont (λx. g x)" shows"cont (λx. map (λy. f x y) (g x))" using f apply (simp add: prod_cont_iff) apply (rule cont_apply [OF g]) apply (rule list_contI, rule list.map, simp, simp, simp) apply (induct_tac y, simp, simp) done
text‹There are probably lots of other list operations that also deserve to have continuity lemmas. I'll add more as they are needed.›
subsection‹Lists are a discrete cpo›
instance list :: (discrete_cpo) discrete_cpo proof fix xs ys :: "'a list" show"xs ⊑ ys ⟷ xs = ys" by (induct xs arbitrary: ys, case_tac [!] ys, simp_all) qed
instance list :: (chfin) chfin proof fix Y :: "nat ==> 'a list"assume"chain Y" moreoverhave"∧(xs::'a list). compact xs" by (induct_tac xs, simp_all) ultimatelyshow"∃i. max_in_chain i Y" by (rule compact_imp_max_in_chain) qed
subsection‹Using lists with fixrec›
definition
match_Nil :: "'a::cpo list → 'b match → 'b match" where "match_Nil = (Λ xs k. case xs of [] ==> k | y # ys ==> Fixrec.fail)"
definition
match_Cons :: "'a::cpo list → ('a → 'a list → 'b match) → 'b match" where "match_Cons = (Λ xs k. case xs of [] ==> Fixrec.fail | y # ys ==> k⋅y⋅ys)"
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.