src/HOL/HOLCF/Library/List_Predomain.thy
changeset 41292 2b7bc8d9fd6e
parent 41112 866148b76247
child 41320 4953e21ac76c
equal deleted inserted replaced
41291:752d81c2ce25 41292:2b7bc8d9fd6e
     3 *)
     3 *)
     4 
     4 
     5 header {* Predomain class instance for HOL list type *}
     5 header {* Predomain class instance for HOL list type *}
     6 
     6 
     7 theory List_Predomain
     7 theory List_Predomain
     8 imports List_Cpo
     8 imports List_Cpo Sum_Cpo
     9 begin
     9 begin
    10 
    10 
    11 subsection {* Strict list type *}
    11 subsection {* Strict list type *}
    12 
    12 
    13 domain 'a slist = SNil | SCons "'a" "'a slist"
    13 domain 'a slist = SNil | SCons "'a" "'a slist"
       
    14 
       
    15 text {* Polymorphic map function for strict lists. *}
       
    16 
       
    17 text {* FIXME: The domain package should generate this! *}
       
    18 
       
    19 fixrec slist_map' :: "('a \<rightarrow> 'b) \<rightarrow> 'a slist \<rightarrow> 'b slist"
       
    20   where "slist_map'\<cdot>f\<cdot>SNil = SNil"
       
    21   | "\<lbrakk>x \<noteq> \<bottom>; xs \<noteq> \<bottom>\<rbrakk> \<Longrightarrow>
       
    22       slist_map'\<cdot>f\<cdot>(SCons\<cdot>x\<cdot>xs) = SCons\<cdot>(f\<cdot>x)\<cdot>(slist_map'\<cdot>f\<cdot>xs)"
       
    23 
       
    24 lemma slist_map'_strict [simp]: "slist_map'\<cdot>f\<cdot>\<bottom> = \<bottom>"
       
    25 by fixrec_simp
       
    26 
       
    27 lemma slist_map_conv [simp]: "slist_map = slist_map'"
       
    28 apply (rule cfun_eqI, rule cfun_eqI, rename_tac f xs)
       
    29 apply (induct_tac xs, simp_all)
       
    30 apply (subst slist_map_unfold, simp)
       
    31 apply (subst slist_map_unfold, simp add: SNil_def)
       
    32 apply (subst slist_map_unfold, simp add: SCons_def)
       
    33 done
       
    34 
       
    35 lemma slist_map'_slist_map':
       
    36   "f\<cdot>\<bottom> = \<bottom> \<Longrightarrow> slist_map'\<cdot>f\<cdot>(slist_map'\<cdot>g\<cdot>xs) = slist_map'\<cdot>(\<Lambda> x. f\<cdot>(g\<cdot>x))\<cdot>xs"
       
    37 apply (induct xs, simp, simp)
       
    38 apply (case_tac "g\<cdot>a = \<bottom>", simp, simp)
       
    39 apply (case_tac "slist_map'\<cdot>g\<cdot>xs = \<bottom>", simp, simp)
       
    40 done
       
    41 
       
    42 lemma slist_map'_oo:
       
    43   "f\<cdot>\<bottom> = \<bottom> \<Longrightarrow> slist_map'\<cdot>(f oo g) = slist_map'\<cdot>f oo slist_map'\<cdot>g"
       
    44 by (simp add: cfcomp1 slist_map'_slist_map' eta_cfun)
       
    45 
       
    46 lemma slist_map'_ID: "slist_map'\<cdot>ID = ID"
       
    47 by (rule cfun_eqI, induct_tac x, simp_all)
       
    48 
       
    49 lemma ep_pair_slist_map':
       
    50   "ep_pair e p \<Longrightarrow> ep_pair (slist_map'\<cdot>e) (slist_map'\<cdot>p)"
       
    51 apply (rule ep_pair.intro)
       
    52 apply (subst slist_map'_slist_map')
       
    53 apply (erule pcpo_ep_pair.p_strict [unfolded pcpo_ep_pair_def])
       
    54 apply (simp add: ep_pair.e_inverse ID_def [symmetric] slist_map'_ID)
       
    55 apply (subst slist_map'_slist_map')
       
    56 apply (erule pcpo_ep_pair.e_strict [unfolded pcpo_ep_pair_def])
       
    57 apply (rule below_eq_trans [OF _ ID1])
       
    58 apply (subst slist_map'_ID [symmetric])
       
    59 apply (intro monofun_cfun below_refl)
       
    60 apply (simp add: cfun_below_iff ep_pair.e_p_below)
       
    61 done
    14 
    62 
    15 text {*
    63 text {*
    16   Types @{typ "'a list u"}. and @{typ "'a u slist"} are isomorphic.
    64   Types @{typ "'a list u"}. and @{typ "'a u slist"} are isomorphic.
    17 *}
    65 *}
    18 
    66 
    46 apply (case_tac "decode_list_u\<cdot>y", simp, simp)
    94 apply (case_tac "decode_list_u\<cdot>y", simp, simp)
    47 done
    95 done
    48 
    96 
    49 subsection {* Lists are a predomain *}
    97 subsection {* Lists are a predomain *}
    50 
    98 
       
    99 definition udefl :: "udom defl \<rightarrow> udom u defl"
       
   100   where "udefl = defl_fun1 (strictify\<cdot>up) (fup\<cdot>ID) ID"
       
   101 
       
   102 lemma cast_udefl:
       
   103   "cast\<cdot>(udefl\<cdot>t) = strictify\<cdot>up oo cast\<cdot>t oo fup\<cdot>ID"
       
   104 unfolding udefl_def by (simp add: cast_defl_fun1 ep_pair_strictify_up)
       
   105 
       
   106 definition list_liftdefl :: "udom u defl \<rightarrow> udom u defl"
       
   107   where "list_liftdefl = (\<Lambda> a. udefl\<cdot>(slist_defl\<cdot>(u_defl\<cdot>a)))"
       
   108 
       
   109 lemma cast_slist_defl: "cast\<cdot>(slist_defl\<cdot>a) = emb oo slist_map\<cdot>(cast\<cdot>a) oo prj"
       
   110 using isodefl_slist [where fa="cast\<cdot>a" and da="a"]
       
   111 unfolding isodefl_def by simp
       
   112 
       
   113 lemma u_emb_bottom: "u_emb\<cdot>\<bottom> = \<bottom>"
       
   114 by (rule pcpo_ep_pair.e_strict [unfolded pcpo_ep_pair_def, OF ep_pair_u])
       
   115 
    51 instantiation list :: (predomain) predomain
   116 instantiation list :: (predomain) predomain
    52 begin
   117 begin
    53 
   118 
    54 definition
   119 definition
    55   "liftemb = emb oo encode_list_u"
   120   "liftemb = (strictify\<cdot>up oo emb oo slist_map'\<cdot>u_emb) oo slist_map'\<cdot>liftemb oo encode_list_u"
    56 
   121 
    57 definition
   122 definition
    58   "liftprj = decode_list_u oo prj"
   123   "liftprj = (decode_list_u oo slist_map'\<cdot>liftprj) oo (slist_map'\<cdot>u_prj oo prj) oo fup\<cdot>ID"
    59 
   124 
    60 definition
   125 definition
    61   "liftdefl (t::('a list) itself) = DEFL(('a\<^sub>\<bottom>) slist)"
   126   "liftdefl (t::('a list) itself) = list_liftdefl\<cdot>LIFTDEFL('a)"
    62 
   127 
    63 instance proof
   128 instance proof
    64   have "ep_pair encode_list_u decode_list_u"
   129   show "ep_pair liftemb (liftprj :: udom u \<rightarrow> ('a list) u)"
    65     by (rule ep_pair.intro, simp_all)
       
    66   thus "ep_pair liftemb (liftprj :: udom \<rightarrow> ('a list) u)"
       
    67     unfolding liftemb_list_def liftprj_list_def
   130     unfolding liftemb_list_def liftprj_list_def
    68     using ep_pair_emb_prj by (rule ep_pair_comp)
   131     by (intro ep_pair_comp ep_pair_slist_map' ep_pair_strictify_up
    69   show "cast\<cdot>LIFTDEFL('a list) = liftemb oo (liftprj :: udom \<rightarrow> ('a list) u)"
   132       ep_pair_emb_prj predomain_ep ep_pair_u, simp add: ep_pair.intro)
       
   133   show "cast\<cdot>LIFTDEFL('a list) = liftemb oo (liftprj :: udom u \<rightarrow> ('a list) u)"
    70     unfolding liftemb_list_def liftprj_list_def liftdefl_list_def
   134     unfolding liftemb_list_def liftprj_list_def liftdefl_list_def
    71     by (simp add: cfcomp1 cast_DEFL)
   135     apply (simp add: list_liftdefl_def cast_udefl cast_slist_defl cast_u_defl cast_liftdefl)
       
   136     apply (simp add: slist_map'_oo u_emb_bottom cfun_eq_iff)
       
   137     done
    72 qed
   138 qed
    73 
   139 
    74 end
   140 end
    75 
   141 
    76 lemma liftdefl_list [domain_defl_simps]:
   142 lemma liftdefl_list [domain_defl_simps]:
    77   "LIFTDEFL('a::predomain list) = slist_defl\<cdot>LIFTDEFL('a)"
   143   "LIFTDEFL('a::predomain list) = list_liftdefl\<cdot>LIFTDEFL('a)"
    78 unfolding liftdefl_list_def by (simp add: domain_defl_simps)
   144 by (rule liftdefl_list_def)
    79 
   145 
    80 subsection {* Continuous map operation for lists *}
   146 subsection {* Continuous map operation for lists *}
    81 
   147 
    82 definition
   148 definition
    83   list_map :: "('a::predomain \<rightarrow> 'b::predomain) \<rightarrow> 'a list \<rightarrow> 'b list"
   149   list_map :: "('a::predomain \<rightarrow> 'b::predomain) \<rightarrow> 'a list \<rightarrow> 'b list"
   103 subsection {* Configuring list type to work with domain package *}
   169 subsection {* Configuring list type to work with domain package *}
   104 
   170 
   105 lemma encode_list_u_map:
   171 lemma encode_list_u_map:
   106   "encode_list_u\<cdot>(u_map\<cdot>(list_map\<cdot>f)\<cdot>(decode_list_u\<cdot>xs))
   172   "encode_list_u\<cdot>(u_map\<cdot>(list_map\<cdot>f)\<cdot>(decode_list_u\<cdot>xs))
   107     = slist_map\<cdot>(u_map\<cdot>f)\<cdot>xs"
   173     = slist_map\<cdot>(u_map\<cdot>f)\<cdot>xs"
   108 apply (induct xs)
   174 apply (induct xs, simp, simp)
   109 apply (simp, subst slist_map_unfold, simp)
       
   110 apply (simp, subst slist_map_unfold, simp add: SNil_def)
       
   111 apply (case_tac a, simp, rename_tac b)
   175 apply (case_tac a, simp, rename_tac b)
   112 apply (case_tac "decode_list_u\<cdot>xs")
   176 apply (case_tac "decode_list_u\<cdot>xs")
   113 apply (drule_tac f="encode_list_u" in cfun_arg_cong, simp)
   177 apply (drule_tac f="encode_list_u" in cfun_arg_cong, simp, simp)
   114 by (simp, subst slist_map_unfold, simp add: SCons_def)
   178 done
   115 
   179 
   116 lemma isodefl_list_u [domain_isodefl]:
   180 lemma isodefl_list_u [domain_isodefl]:
   117   fixes d :: "'a::predomain \<rightarrow> 'a"
   181   fixes d :: "'a::predomain \<rightarrow> 'a"
   118   assumes "isodefl (u_map\<cdot>d) t"
   182   assumes "isodefl' d t"
   119   shows "isodefl (u_map\<cdot>(list_map\<cdot>d)) (slist_defl\<cdot>t)"
   183   shows "isodefl' (list_map\<cdot>d) (list_liftdefl\<cdot>t)"
   120 using assms [THEN isodefl_slist] unfolding isodefl_def
   184 using assms unfolding isodefl'_def liftemb_list_def liftprj_list_def
   121 unfolding emb_u_def prj_u_def liftemb_list_def liftprj_list_def
   185 apply (simp add: list_liftdefl_def cast_udefl cast_slist_defl cast_u_defl)
   122 by (simp add: cfcomp1 encode_list_u_map)
   186 apply (simp add: cfcomp1 encode_list_u_map)
       
   187 apply (simp add: slist_map'_slist_map' u_emb_bottom)
       
   188 done
   123 
   189 
   124 setup {*
   190 setup {*
   125   Domain_Take_Proofs.add_rec_type (@{type_name "list"}, [true])
   191   Domain_Take_Proofs.add_rec_type (@{type_name "list"}, [true])
   126 *}
   192 *}
   127 
   193