src/HOL/HOLCF/Library/Sum_Cpo.thy
changeset 40774 0437dbc127b3
parent 40771 1c6f7d4b110e
child 40830 158d18502378
equal deleted inserted replaced
40773:6c12f5e24e34 40774:0437dbc127b3
       
     1 (*  Title:      HOLCF/Sum_Cpo.thy
       
     2     Author:     Brian Huffman
       
     3 *)
       
     4 
       
     5 header {* The cpo of disjoint sums *}
       
     6 
       
     7 theory Sum_Cpo
       
     8 imports HOLCF
       
     9 begin
       
    10 
       
    11 subsection {* Ordering on sum type *}
       
    12 
       
    13 instantiation sum :: (below, below) below
       
    14 begin
       
    15 
       
    16 definition below_sum_def:
       
    17   "x \<sqsubseteq> y \<equiv> case x of
       
    18          Inl a \<Rightarrow> (case y of Inl b \<Rightarrow> a \<sqsubseteq> b | Inr b \<Rightarrow> False) |
       
    19          Inr a \<Rightarrow> (case y of Inl b \<Rightarrow> False | Inr b \<Rightarrow> a \<sqsubseteq> b)"
       
    20 
       
    21 instance ..
       
    22 end
       
    23 
       
    24 lemma Inl_below_Inl [simp]: "Inl x \<sqsubseteq> Inl y \<longleftrightarrow> x \<sqsubseteq> y"
       
    25 unfolding below_sum_def by simp
       
    26 
       
    27 lemma Inr_below_Inr [simp]: "Inr x \<sqsubseteq> Inr y \<longleftrightarrow> x \<sqsubseteq> y"
       
    28 unfolding below_sum_def by simp
       
    29 
       
    30 lemma Inl_below_Inr [simp]: "\<not> Inl x \<sqsubseteq> Inr y"
       
    31 unfolding below_sum_def by simp
       
    32 
       
    33 lemma Inr_below_Inl [simp]: "\<not> Inr x \<sqsubseteq> Inl y"
       
    34 unfolding below_sum_def by simp
       
    35 
       
    36 lemma Inl_mono: "x \<sqsubseteq> y \<Longrightarrow> Inl x \<sqsubseteq> Inl y"
       
    37 by simp
       
    38 
       
    39 lemma Inr_mono: "x \<sqsubseteq> y \<Longrightarrow> Inr x \<sqsubseteq> Inr y"
       
    40 by simp
       
    41 
       
    42 lemma Inl_belowE: "\<lbrakk>Inl a \<sqsubseteq> x; \<And>b. \<lbrakk>x = Inl b; a \<sqsubseteq> b\<rbrakk> \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
       
    43 by (cases x, simp_all)
       
    44 
       
    45 lemma Inr_belowE: "\<lbrakk>Inr a \<sqsubseteq> x; \<And>b. \<lbrakk>x = Inr b; a \<sqsubseteq> b\<rbrakk> \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
       
    46 by (cases x, simp_all)
       
    47 
       
    48 lemmas sum_below_elims = Inl_belowE Inr_belowE
       
    49 
       
    50 lemma sum_below_cases:
       
    51   "\<lbrakk>x \<sqsubseteq> y;
       
    52     \<And>a b. \<lbrakk>x = Inl a; y = Inl b; a \<sqsubseteq> b\<rbrakk> \<Longrightarrow> R;
       
    53     \<And>a b. \<lbrakk>x = Inr a; y = Inr b; a \<sqsubseteq> b\<rbrakk> \<Longrightarrow> R\<rbrakk>
       
    54       \<Longrightarrow> R"
       
    55 by (cases x, safe elim!: sum_below_elims, auto)
       
    56 
       
    57 subsection {* Sum type is a complete partial order *}
       
    58 
       
    59 instance sum :: (po, po) po
       
    60 proof
       
    61   fix x :: "'a + 'b"
       
    62   show "x \<sqsubseteq> x"
       
    63     by (induct x, simp_all)
       
    64 next
       
    65   fix x y :: "'a + 'b"
       
    66   assume "x \<sqsubseteq> y" and "y \<sqsubseteq> x" thus "x = y"
       
    67     by (induct x, auto elim!: sum_below_elims intro: below_antisym)
       
    68 next
       
    69   fix x y z :: "'a + 'b"
       
    70   assume "x \<sqsubseteq> y" and "y \<sqsubseteq> z" thus "x \<sqsubseteq> z"
       
    71     by (induct x, auto elim!: sum_below_elims intro: below_trans)
       
    72 qed
       
    73 
       
    74 lemma monofun_inv_Inl: "monofun (\<lambda>p. THE a. p = Inl a)"
       
    75 by (rule monofunI, erule sum_below_cases, simp_all)
       
    76 
       
    77 lemma monofun_inv_Inr: "monofun (\<lambda>p. THE b. p = Inr b)"
       
    78 by (rule monofunI, erule sum_below_cases, simp_all)
       
    79 
       
    80 lemma sum_chain_cases:
       
    81   assumes Y: "chain Y"
       
    82   assumes A: "\<And>A. \<lbrakk>chain A; Y = (\<lambda>i. Inl (A i))\<rbrakk> \<Longrightarrow> R"
       
    83   assumes B: "\<And>B. \<lbrakk>chain B; Y = (\<lambda>i. Inr (B i))\<rbrakk> \<Longrightarrow> R"
       
    84   shows "R"
       
    85  apply (cases "Y 0")
       
    86   apply (rule A)
       
    87    apply (rule ch2ch_monofun [OF monofun_inv_Inl Y])
       
    88   apply (rule ext)
       
    89   apply (cut_tac j=i in chain_mono [OF Y le0], simp)
       
    90   apply (erule Inl_belowE, simp)
       
    91  apply (rule B)
       
    92   apply (rule ch2ch_monofun [OF monofun_inv_Inr Y])
       
    93  apply (rule ext)
       
    94  apply (cut_tac j=i in chain_mono [OF Y le0], simp)
       
    95  apply (erule Inr_belowE, simp)
       
    96 done
       
    97 
       
    98 lemma is_lub_Inl: "range S <<| x \<Longrightarrow> range (\<lambda>i. Inl (S i)) <<| Inl x"
       
    99  apply (rule is_lubI)
       
   100   apply (rule ub_rangeI)
       
   101   apply (simp add: is_lub_rangeD1)
       
   102  apply (frule ub_rangeD [where i=arbitrary])
       
   103  apply (erule Inl_belowE, simp)
       
   104  apply (erule is_lubD2)
       
   105  apply (rule ub_rangeI)
       
   106  apply (drule ub_rangeD, simp)
       
   107 done
       
   108 
       
   109 lemma is_lub_Inr: "range S <<| x \<Longrightarrow> range (\<lambda>i. Inr (S i)) <<| Inr x"
       
   110  apply (rule is_lubI)
       
   111   apply (rule ub_rangeI)
       
   112   apply (simp add: is_lub_rangeD1)
       
   113  apply (frule ub_rangeD [where i=arbitrary])
       
   114  apply (erule Inr_belowE, simp)
       
   115  apply (erule is_lubD2)
       
   116  apply (rule ub_rangeI)
       
   117  apply (drule ub_rangeD, simp)
       
   118 done
       
   119 
       
   120 instance sum :: (cpo, cpo) cpo
       
   121  apply intro_classes
       
   122  apply (erule sum_chain_cases, safe)
       
   123   apply (rule exI)
       
   124   apply (rule is_lub_Inl)
       
   125   apply (erule cpo_lubI)
       
   126  apply (rule exI)
       
   127  apply (rule is_lub_Inr)
       
   128  apply (erule cpo_lubI)
       
   129 done
       
   130 
       
   131 subsection {* Continuity of \emph{Inl}, \emph{Inr}, and case function *}
       
   132 
       
   133 lemma cont_Inl: "cont Inl"
       
   134 by (intro contI is_lub_Inl cpo_lubI)
       
   135 
       
   136 lemma cont_Inr: "cont Inr"
       
   137 by (intro contI is_lub_Inr cpo_lubI)
       
   138 
       
   139 lemmas cont2cont_Inl [simp, cont2cont] = cont_compose [OF cont_Inl]
       
   140 lemmas cont2cont_Inr [simp, cont2cont] = cont_compose [OF cont_Inr]
       
   141 
       
   142 lemmas ch2ch_Inl [simp] = ch2ch_cont [OF cont_Inl]
       
   143 lemmas ch2ch_Inr [simp] = ch2ch_cont [OF cont_Inr]
       
   144 
       
   145 lemmas lub_Inl = cont2contlubE [OF cont_Inl, symmetric]
       
   146 lemmas lub_Inr = cont2contlubE [OF cont_Inr, symmetric]
       
   147 
       
   148 lemma cont_sum_case1:
       
   149   assumes f: "\<And>a. cont (\<lambda>x. f x a)"
       
   150   assumes g: "\<And>b. cont (\<lambda>x. g x b)"
       
   151   shows "cont (\<lambda>x. case y of Inl a \<Rightarrow> f x a | Inr b \<Rightarrow> g x b)"
       
   152 by (induct y, simp add: f, simp add: g)
       
   153 
       
   154 lemma cont_sum_case2: "\<lbrakk>cont f; cont g\<rbrakk> \<Longrightarrow> cont (sum_case f g)"
       
   155 apply (rule contI)
       
   156 apply (erule sum_chain_cases)
       
   157 apply (simp add: cont2contlubE [OF cont_Inl, symmetric] contE)
       
   158 apply (simp add: cont2contlubE [OF cont_Inr, symmetric] contE)
       
   159 done
       
   160 
       
   161 lemma cont2cont_sum_case:
       
   162   assumes f1: "\<And>a. cont (\<lambda>x. f x a)" and f2: "\<And>x. cont (\<lambda>a. f x a)"
       
   163   assumes g1: "\<And>b. cont (\<lambda>x. g x b)" and g2: "\<And>x. cont (\<lambda>b. g x b)"
       
   164   assumes h: "cont (\<lambda>x. h x)"
       
   165   shows "cont (\<lambda>x. case h x of Inl a \<Rightarrow> f x a | Inr b \<Rightarrow> g x b)"
       
   166 apply (rule cont_apply [OF h])
       
   167 apply (rule cont_sum_case2 [OF f2 g2])
       
   168 apply (rule cont_sum_case1 [OF f1 g1])
       
   169 done
       
   170 
       
   171 lemma cont2cont_sum_case' [simp, cont2cont]:
       
   172   assumes f: "cont (\<lambda>p. f (fst p) (snd p))"
       
   173   assumes g: "cont (\<lambda>p. g (fst p) (snd p))"
       
   174   assumes h: "cont (\<lambda>x. h x)"
       
   175   shows "cont (\<lambda>x. case h x of Inl a \<Rightarrow> f x a | Inr b \<Rightarrow> g x b)"
       
   176 using assms by (simp add: cont2cont_sum_case prod_cont_iff)
       
   177 
       
   178 subsection {* Compactness and chain-finiteness *}
       
   179 
       
   180 lemma compact_Inl: "compact a \<Longrightarrow> compact (Inl a)"
       
   181 apply (rule compactI2)
       
   182 apply (erule sum_chain_cases, safe)
       
   183 apply (simp add: lub_Inl)
       
   184 apply (erule (2) compactD2)
       
   185 apply (simp add: lub_Inr)
       
   186 done
       
   187 
       
   188 lemma compact_Inr: "compact a \<Longrightarrow> compact (Inr a)"
       
   189 apply (rule compactI2)
       
   190 apply (erule sum_chain_cases, safe)
       
   191 apply (simp add: lub_Inl)
       
   192 apply (simp add: lub_Inr)
       
   193 apply (erule (2) compactD2)
       
   194 done
       
   195 
       
   196 lemma compact_Inl_rev: "compact (Inl a) \<Longrightarrow> compact a"
       
   197 unfolding compact_def
       
   198 by (drule adm_subst [OF cont_Inl], simp)
       
   199 
       
   200 lemma compact_Inr_rev: "compact (Inr a) \<Longrightarrow> compact a"
       
   201 unfolding compact_def
       
   202 by (drule adm_subst [OF cont_Inr], simp)
       
   203 
       
   204 lemma compact_Inl_iff [simp]: "compact (Inl a) = compact a"
       
   205 by (safe elim!: compact_Inl compact_Inl_rev)
       
   206 
       
   207 lemma compact_Inr_iff [simp]: "compact (Inr a) = compact a"
       
   208 by (safe elim!: compact_Inr compact_Inr_rev)
       
   209 
       
   210 instance sum :: (chfin, chfin) chfin
       
   211 apply intro_classes
       
   212 apply (erule compact_imp_max_in_chain)
       
   213 apply (case_tac "\<Squnion>i. Y i", simp_all)
       
   214 done
       
   215 
       
   216 instance sum :: (discrete_cpo, discrete_cpo) discrete_cpo
       
   217 by intro_classes (simp add: below_sum_def split: sum.split)
       
   218 
       
   219 subsection {* Using sum types with fixrec *}
       
   220 
       
   221 definition
       
   222   "match_Inl = (\<Lambda> x k. case x of Inl a \<Rightarrow> k\<cdot>a | Inr b \<Rightarrow> Fixrec.fail)"
       
   223 
       
   224 definition
       
   225   "match_Inr = (\<Lambda> x k. case x of Inl a \<Rightarrow> Fixrec.fail | Inr b \<Rightarrow> k\<cdot>b)"
       
   226 
       
   227 lemma match_Inl_simps [simp]:
       
   228   "match_Inl\<cdot>(Inl a)\<cdot>k = k\<cdot>a"
       
   229   "match_Inl\<cdot>(Inr b)\<cdot>k = Fixrec.fail"
       
   230 unfolding match_Inl_def by simp_all
       
   231 
       
   232 lemma match_Inr_simps [simp]:
       
   233   "match_Inr\<cdot>(Inl a)\<cdot>k = Fixrec.fail"
       
   234   "match_Inr\<cdot>(Inr b)\<cdot>k = k\<cdot>b"
       
   235 unfolding match_Inr_def by simp_all
       
   236 
       
   237 setup {*
       
   238   Fixrec.add_matchers
       
   239     [ (@{const_name Inl}, @{const_name match_Inl}),
       
   240       (@{const_name Inr}, @{const_name match_Inr}) ]
       
   241 *}
       
   242 
       
   243 subsection {* Disjoint sum is a predomain *}
       
   244 
       
   245 definition
       
   246   "encode_sum_u =
       
   247     (\<Lambda>(up\<cdot>x). case x of Inl a \<Rightarrow> sinl\<cdot>(up\<cdot>a) | Inr b \<Rightarrow> sinr\<cdot>(up\<cdot>b))"
       
   248 
       
   249 definition
       
   250   "decode_sum_u = sscase\<cdot>(\<Lambda>(up\<cdot>a). up\<cdot>(Inl a))\<cdot>(\<Lambda>(up\<cdot>b). up\<cdot>(Inr b))"
       
   251 
       
   252 lemma decode_encode_sum_u [simp]: "decode_sum_u\<cdot>(encode_sum_u\<cdot>x) = x"
       
   253 unfolding decode_sum_u_def encode_sum_u_def
       
   254 by (case_tac x, simp, rename_tac y, case_tac y, simp_all)
       
   255 
       
   256 lemma encode_decode_sum_u [simp]: "encode_sum_u\<cdot>(decode_sum_u\<cdot>x) = x"
       
   257 unfolding decode_sum_u_def encode_sum_u_def
       
   258 apply (case_tac x, simp)
       
   259 apply (rename_tac a, case_tac a, simp, simp)
       
   260 apply (rename_tac b, case_tac b, simp, simp)
       
   261 done
       
   262 
       
   263 instantiation sum :: (predomain, predomain) predomain
       
   264 begin
       
   265 
       
   266 definition
       
   267   "liftemb = (udom_emb ssum_approx oo ssum_map\<cdot>emb\<cdot>emb) oo encode_sum_u"
       
   268 
       
   269 definition
       
   270   "liftprj =
       
   271     decode_sum_u oo (ssum_map\<cdot>prj\<cdot>prj oo udom_prj ssum_approx)"
       
   272 
       
   273 definition
       
   274   "liftdefl (t::('a + 'b) itself) = ssum_defl\<cdot>DEFL('a u)\<cdot>DEFL('b u)"
       
   275 
       
   276 instance proof
       
   277   show "ep_pair liftemb (liftprj :: udom \<rightarrow> ('a + 'b) u)"
       
   278     unfolding liftemb_sum_def liftprj_sum_def
       
   279     apply (rule ep_pair_comp)
       
   280     apply (rule ep_pair.intro, simp, simp)
       
   281     apply (rule ep_pair_comp)
       
   282     apply (intro ep_pair_ssum_map ep_pair_emb_prj)
       
   283     apply (rule ep_pair_udom [OF ssum_approx])
       
   284     done
       
   285   show "cast\<cdot>LIFTDEFL('a + 'b) = liftemb oo (liftprj :: udom \<rightarrow> ('a + 'b) u)"
       
   286     unfolding liftemb_sum_def liftprj_sum_def liftdefl_sum_def
       
   287     by (simp add: cast_ssum_defl cast_DEFL cfcomp1 ssum_map_map)
       
   288 qed
       
   289 
       
   290 end
       
   291 
       
   292 end