# HG changeset patch # User huffman # Date 1283610394 25200 # Node ID d80990d8b90998cde3bbfcd2e879e367032f5f4b # Parent 12dac4b58df8f1b979c6c155c1514211282c711a add List_Cpo.thy to HOLCF/Library diff -r 12dac4b58df8 -r d80990d8b909 src/HOLCF/IsaMakefile --- a/src/HOLCF/IsaMakefile Sat Sep 04 00:59:03 2010 +0200 +++ b/src/HOLCF/IsaMakefile Sat Sep 04 07:26:34 2010 -0700 @@ -103,6 +103,7 @@ HOLCF-Library: HOLCF $(LOG)/HOLCF-Library.gz $(LOG)/HOLCF-Library.gz: $(OUT)/HOLCF \ + Library/List_Cpo.thy \ Library/Stream.thy \ Library/Strict_Fun.thy \ Library/Sum_Cpo.thy \ diff -r 12dac4b58df8 -r d80990d8b909 src/HOLCF/Library/HOLCF_Library.thy --- a/src/HOLCF/Library/HOLCF_Library.thy Sat Sep 04 00:59:03 2010 +0200 +++ b/src/HOLCF/Library/HOLCF_Library.thy Sat Sep 04 07:26:34 2010 -0700 @@ -1,5 +1,6 @@ theory HOLCF_Library imports + List_Cpo Stream Strict_Fun Sum_Cpo diff -r 12dac4b58df8 -r d80990d8b909 src/HOLCF/Library/List_Cpo.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOLCF/Library/List_Cpo.thy Sat Sep 04 07:26:34 2010 -0700 @@ -0,0 +1,210 @@ +(* Title: HOLCF/Library/List_Cpo.thy + Author: Brian Huffman +*) + +header {* Lists as a complete partial order *} + +theory List_Cpo +imports HOLCF +begin + +subsection {* Lists are a partial order *} + +instantiation list :: (po) po +begin + +definition + "xs \ ys \ list_all2 (op \) xs ys" + +instance proof + fix xs :: "'a list" + from below_refl show "xs \ xs" + unfolding below_list_def + by (rule list_all2_refl) +next + fix xs ys zs :: "'a list" + assume "xs \ ys" and "ys \ zs" + with below_trans show "xs \ zs" + unfolding below_list_def + by (rule list_all2_trans) +next + fix xs ys zs :: "'a list" + assume "xs \ ys" and "ys \ xs" + with below_antisym show "xs = ys" + unfolding below_list_def + by (rule list_all2_antisym) +qed + +end + +lemma below_list_simps [simp]: + "[] \ []" + "x # xs \ y # ys \ x \ y \ xs \ ys" + "\ [] \ y # ys" + "\ x # xs \ []" +by (simp_all add: below_list_def) + +lemma Nil_below_iff [simp]: "[] \ xs \ xs = []" +by (cases xs, simp_all) + +lemma below_Nil_iff [simp]: "xs \ [] \ xs = []" +by (cases xs, simp_all) + +text "Thanks to Joachim Breitner" + +lemma list_Cons_below: + assumes "a # as \ xs" + obtains b and bs where "a \ b" and "as \ bs" and "xs = b # bs" + using assms by (cases xs, auto) + +lemma list_below_Cons: + assumes "xs \ b # bs" + obtains a and as where "a \ b" and "as \ bs" and "xs = a # as" + using assms by (cases xs, auto) + +lemma hd_mono: "xs \ ys \ hd xs \ hd ys" +by (cases xs, simp, cases ys, simp, simp) + +lemma tl_mono: "xs \ ys \ tl xs \ tl ys" +by (cases xs, simp, cases ys, simp, simp) + +lemma ch2ch_hd [simp]: "chain (\i. S i) \ chain (\i. hd (S i))" +by (rule chainI, rule hd_mono, erule chainE) + +lemma ch2ch_tl [simp]: "chain (\i. S i) \ chain (\i. tl (S i))" +by (rule chainI, rule tl_mono, erule chainE) + +lemma below_same_length: "xs \ ys \ length xs = length ys" +unfolding below_list_def by (rule list_all2_lengthD) + +lemma list_chain_cases: + assumes S: "chain S" + obtains "\i. S i = []" | + A B where "chain A" and "chain B" and "\i. S i = A i # B i" +proof (cases "S 0") + case Nil + have "\i. S 0 \ S i" by (simp add: chain_mono [OF S]) + with Nil have "\i. S i = []" by simp + thus ?thesis .. +next + case (Cons x xs) + have "\i. S 0 \ S i" by (simp add: chain_mono [OF S]) + hence *: "\i. S i \ []" by (rule all_forward) (auto simp add: Cons) + let ?A = "\i. hd (S i)" + let ?B = "\i. tl (S i)" + from S have "chain ?A" and "chain ?B" by simp_all + moreover have "\i. S i = ?A i # ?B i" by (simp add: *) + ultimately show ?thesis .. +qed + +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 Ball_def [symmetric] +by (clarsimp, case_tac u, simp_all) + +lemma list_cpo_lemma: + fixes S :: "nat \ 'a::cpo list" + assumes "chain S" and "\i. length (S i) = n" + shows "\x. range S <<| x" +using assms + apply (induct n arbitrary: S) + apply (subgoal_tac "S = (\i. [])") + apply (fast intro: lub_const) + apply (simp add: expand_fun_eq) + apply (drule_tac x="\i. tl (S i)" in meta_spec, clarsimp) + apply (rule_tac x="(\i. hd (S i)) # x" in exI) + apply (subgoal_tac "range (\i. hd (S i) # tl (S i)) = range S") + apply (erule subst) + apply (rule is_lub_Cons) + apply (rule thelubE [OF _ refl]) + apply (erule ch2ch_hd) + apply assumption + apply (rule_tac f="\S. range S" in arg_cong) + apply (rule ext) + apply (rule hd_Cons_tl) + apply (drule_tac x=i in spec, auto) +done + +instance list :: (cpo) cpo +proof + fix S :: "nat \ 'a list" + assume "chain S" + hence "\i. S 0 \ S i" by (simp add: chain_mono) + hence "\i. length (S i) = length (S 0)" + by (fast intro: below_same_length [symmetric]) + with `chain S` show "\x. range S <<| x" + by (rule list_cpo_lemma) +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 thelubI is_lub_Cons cpo_lubI A B) + +lemma cont2cont_list_case: + 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: 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_list_case' [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)" +proof - + have "\y ys. cont (\x. h x (fst (y, ys)) (snd (y, ys)))" + by (rule h [THEN cont_fst_snd_D1]) + hence h1: "\y ys. cont (\x. h x y ys)" by simp + note h2 = h [THEN cont_fst_snd_D2, THEN cont_fst_snd_D1] + note h3 = h [THEN cont_fst_snd_D2, THEN cont_fst_snd_D2] + from f g h1 h2 h3 show ?thesis by (rule cont2cont_list_case) +qed + +text {* The simple version (due to Joachim Breitner) is needed if the + element type of the list is not a cpo. *} + +lemma cont2cont_list_case_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 {* There are probably lots of other list operations that also +deserve to have continuity lemmas. I'll add more as they are +needed. *} + +end