src/HOLCF/Library/Strict_Fun.thy
changeset 39974 b525988432e9
parent 37110 7ffdbc24b27f
child 39986 38677db30cad
equal deleted inserted replaced
39973:c62b4ff97bfc 39974:b525988432e9
     1 (*  Title:      HOLCF/ex/Strict_Fun.thy
     1 (*  Title:      HOLCF/Library/Strict_Fun.thy
     2     Author:     Brian Huffman
     2     Author:     Brian Huffman
     3 *)
     3 *)
     4 
     4 
     5 header {* The Strict Function Type *}
     5 header {* The Strict Function Type *}
     6 
     6 
   141     unfolding sfun_map_def sfun.e_eq_iff [symmetric]
   141     unfolding sfun_map_def sfun.e_eq_iff [symmetric]
   142     by (simp add: strictify_cancel
   142     by (simp add: strictify_cancel
   143          deflation_strict `deflation d1` `deflation d2`)
   143          deflation_strict `deflation d1` `deflation d2`)
   144 qed
   144 qed
   145 
   145 
   146 subsection {* Strict function space is bifinite *}
   146 subsection {* Strict function space is an SFP domain *}
   147 
   147 
   148 instantiation sfun :: (bifinite, bifinite) bifinite
   148 definition
       
   149   sfun_approx :: "nat \<Rightarrow> (udom \<rightarrow>! udom) \<rightarrow> (udom \<rightarrow>! udom)"
       
   150 where
       
   151   "sfun_approx = (\<lambda>i. sfun_map\<cdot>(udom_approx i)\<cdot>(udom_approx i))"
       
   152 
       
   153 lemma sfun_approx: "approx_chain sfun_approx"
       
   154 proof (rule approx_chain.intro)
       
   155   show "chain (\<lambda>i. sfun_approx i)"
       
   156     unfolding sfun_approx_def by simp
       
   157   show "(\<Squnion>i. sfun_approx i) = ID"
       
   158     unfolding sfun_approx_def
       
   159     by (simp add: lub_distribs sfun_map_ID)
       
   160   show "\<And>i. finite_deflation (sfun_approx i)"
       
   161     unfolding sfun_approx_def
       
   162     by (intro finite_deflation_sfun_map finite_deflation_udom_approx)
       
   163 qed
       
   164 
       
   165 definition sfun_sfp :: "sfp \<rightarrow> sfp \<rightarrow> sfp"
       
   166 where "sfun_sfp = sfp_fun2 sfun_approx sfun_map"
       
   167 
       
   168 lemma cast_sfun_sfp:
       
   169   "cast\<cdot>(sfun_sfp\<cdot>A\<cdot>B) =
       
   170     udom_emb sfun_approx oo sfun_map\<cdot>(cast\<cdot>A)\<cdot>(cast\<cdot>B) oo udom_prj sfun_approx"
       
   171 unfolding sfun_sfp_def
       
   172 apply (rule cast_sfp_fun2 [OF sfun_approx])
       
   173 apply (erule (1) finite_deflation_sfun_map)
       
   174 done
       
   175 
       
   176 instantiation sfun :: (sfp, sfp) sfp
   149 begin
   177 begin
   150 
   178 
   151 definition
   179 definition
   152   "approx = (\<lambda>i. sfun_map\<cdot>(approx i)\<cdot>(approx i))"
   180   "emb = udom_emb sfun_approx oo sfun_map\<cdot>prj\<cdot>emb"
       
   181 
       
   182 definition
       
   183   "prj = sfun_map\<cdot>emb\<cdot>prj oo udom_prj sfun_approx"
       
   184 
       
   185 definition
       
   186   "sfp (t::('a \<rightarrow>! 'b) itself) = sfun_sfp\<cdot>SFP('a)\<cdot>SFP('b)"
   153 
   187 
   154 instance proof
   188 instance proof
   155   show "chain (approx :: nat \<Rightarrow> ('a \<rightarrow>! 'b) \<rightarrow> ('a \<rightarrow>! 'b))"
   189   show "ep_pair emb (prj :: udom \<rightarrow> 'a \<rightarrow>! 'b)"
   156     unfolding approx_sfun_def by simp
   190     unfolding emb_sfun_def prj_sfun_def
       
   191     using ep_pair_udom [OF sfun_approx]
       
   192     by (intro ep_pair_comp ep_pair_sfun_map ep_pair_emb_prj)
   157 next
   193 next
   158   fix x :: "'a \<rightarrow>! 'b"
   194   show "cast\<cdot>SFP('a \<rightarrow>! 'b) = emb oo (prj :: udom \<rightarrow> 'a \<rightarrow>! 'b)"
   159   show "(\<Squnion>i. approx i\<cdot>x) = x"
   195     unfolding emb_sfun_def prj_sfun_def sfp_sfun_def cast_sfun_sfp
   160     unfolding approx_sfun_def
   196     by (simp add: cast_SFP oo_def expand_cfun_eq sfun_map_map)
   161     by (simp add: lub_distribs sfun_map_ID [unfolded ID_def])
       
   162 next
       
   163   fix i :: nat and x :: "'a \<rightarrow>! 'b"
       
   164   show "approx i\<cdot>(approx i\<cdot>x) = approx i\<cdot>x"
       
   165     unfolding approx_sfun_def
       
   166     by (intro deflation.idem deflation_sfun_map deflation_approx)
       
   167 next
       
   168   fix i :: nat
       
   169   show "finite {x::'a \<rightarrow>! 'b. approx i\<cdot>x = x}"
       
   170     unfolding approx_sfun_def
       
   171     by (intro finite_deflation.finite_fixes
       
   172               finite_deflation_sfun_map
       
   173               finite_deflation_approx)
       
   174 qed
   197 qed
   175 
   198 
   176 end
   199 end
   177 
   200 
   178 subsection {* Strict function space is representable *}
   201 text {* SFP of type constructor = type combinator *}
   179 
   202 
   180 instantiation sfun :: (rep, rep) rep
   203 lemma SFP_sfun: "SFP('a::sfp \<rightarrow>! 'b::sfp) = sfun_sfp\<cdot>SFP('a)\<cdot>SFP('b)"
   181 begin
   204 by (rule sfp_sfun_def)
   182 
       
   183 definition
       
   184   "emb = udom_emb oo sfun_map\<cdot>prj\<cdot>emb"
       
   185 
       
   186 definition
       
   187   "prj = sfun_map\<cdot>emb\<cdot>prj oo udom_prj"
       
   188 
       
   189 instance
       
   190 apply (default, unfold emb_sfun_def prj_sfun_def)
       
   191 apply (rule ep_pair_comp)
       
   192 apply (rule ep_pair_sfun_map)
       
   193 apply (rule ep_pair_emb_prj)
       
   194 apply (rule ep_pair_emb_prj)
       
   195 apply (rule ep_pair_udom)
       
   196 done
       
   197 
       
   198 end
       
   199 
       
   200 text {*
       
   201   A deflation constructor lets us configure the domain package to work
       
   202   with the strict function space type constructor.
       
   203 *}
       
   204 
       
   205 definition
       
   206   sfun_defl :: "TypeRep \<rightarrow> TypeRep \<rightarrow> TypeRep"
       
   207 where
       
   208   "sfun_defl = TypeRep_fun2 sfun_map"
       
   209 
       
   210 lemma cast_sfun_defl:
       
   211   "cast\<cdot>(sfun_defl\<cdot>A\<cdot>B) = udom_emb oo sfun_map\<cdot>(cast\<cdot>A)\<cdot>(cast\<cdot>B) oo udom_prj"
       
   212 unfolding sfun_defl_def
       
   213 apply (rule cast_TypeRep_fun2)
       
   214 apply (erule (1) finite_deflation_sfun_map)
       
   215 done
       
   216 
       
   217 lemma REP_sfun: "REP('a::rep \<rightarrow>! 'b::rep) = sfun_defl\<cdot>REP('a)\<cdot>REP('b)"
       
   218 apply (rule cast_eq_imp_eq, rule ext_cfun)
       
   219 apply (simp add: cast_REP cast_sfun_defl)
       
   220 apply (simp only: prj_sfun_def emb_sfun_def)
       
   221 apply (simp add: sfun_map_def cfun_map_def strictify_cancel)
       
   222 done
       
   223 
   205 
   224 lemma isodefl_sfun:
   206 lemma isodefl_sfun:
   225   "isodefl d1 t1 \<Longrightarrow> isodefl d2 t2 \<Longrightarrow>
   207   "isodefl d1 t1 \<Longrightarrow> isodefl d2 t2 \<Longrightarrow>
   226     isodefl (sfun_map\<cdot>d1\<cdot>d2) (sfun_defl\<cdot>t1\<cdot>t2)"
   208     isodefl (sfun_map\<cdot>d1\<cdot>d2) (sfun_sfp\<cdot>t1\<cdot>t2)"
   227 apply (rule isodeflI)
   209 apply (rule isodeflI)
   228 apply (simp add: cast_sfun_defl cast_isodefl)
   210 apply (simp add: cast_sfun_sfp cast_isodefl)
   229 apply (simp add: emb_sfun_def prj_sfun_def)
   211 apply (simp add: emb_sfun_def prj_sfun_def)
   230 apply (simp add: sfun_map_map deflation_strict [OF isodefl_imp_deflation])
   212 apply (simp add: sfun_map_map deflation_strict [OF isodefl_imp_deflation])
   231 done
   213 done
   232 
   214 
   233 setup {*
   215 setup {*
   234   Domain_Isomorphism.add_type_constructor
   216   Domain_Isomorphism.add_type_constructor
   235     (@{type_name "sfun"}, @{term sfun_defl}, @{const_name sfun_map}, @{thm REP_sfun},
   217     (@{type_name "sfun"}, @{term sfun_sfp}, @{const_name sfun_map}, @{thm SFP_sfun},
   236        @{thm isodefl_sfun}, @{thm sfun_map_ID}, @{thm deflation_sfun_map})
   218        @{thm isodefl_sfun}, @{thm sfun_map_ID}, @{thm deflation_sfun_map})
   237 *}
   219 *}
   238 
   220 
   239 end
   221 end