src/HOLCF/Product_Cpo.thy
changeset 40771 1c6f7d4b110e
parent 40619 84edf7177d73
equal deleted inserted replaced
40770:6023808b38d4 40771:1c6f7d4b110e
   109 
   109 
   110 subsection {* Product type is a cpo *}
   110 subsection {* Product type is a cpo *}
   111 
   111 
   112 lemma is_lub_Pair:
   112 lemma is_lub_Pair:
   113   "\<lbrakk>range A <<| x; range B <<| y\<rbrakk> \<Longrightarrow> range (\<lambda>i. (A i, B i)) <<| (x, y)"
   113   "\<lbrakk>range A <<| x; range B <<| y\<rbrakk> \<Longrightarrow> range (\<lambda>i. (A i, B i)) <<| (x, y)"
   114 apply (rule is_lubI [OF ub_rangeI])
   114 unfolding is_lub_def is_ub_def ball_simps below_prod_def by simp
   115 apply (simp add: is_ub_lub)
   115 
   116 apply (frule ub2ub_monofun [OF monofun_fst])
   116 lemma lub_Pair:
   117 apply (drule ub2ub_monofun [OF monofun_snd])
       
   118 apply (simp add: below_prod_def is_lub_lub)
       
   119 done
       
   120 
       
   121 lemma thelub_Pair:
       
   122   "\<lbrakk>chain (A::nat \<Rightarrow> 'a::cpo); chain (B::nat \<Rightarrow> 'b::cpo)\<rbrakk>
   117   "\<lbrakk>chain (A::nat \<Rightarrow> 'a::cpo); chain (B::nat \<Rightarrow> 'b::cpo)\<rbrakk>
   123     \<Longrightarrow> (\<Squnion>i. (A i, B i)) = (\<Squnion>i. A i, \<Squnion>i. B i)"
   118     \<Longrightarrow> (\<Squnion>i. (A i, B i)) = (\<Squnion>i. A i, \<Squnion>i. B i)"
   124 by (fast intro: thelubI is_lub_Pair elim: thelubE)
   119 by (fast intro: lub_eqI is_lub_Pair elim: thelubE)
   125 
   120 
   126 lemma lub_cprod:
   121 lemma is_lub_prod:
   127   fixes S :: "nat \<Rightarrow> ('a::cpo \<times> 'b::cpo)"
   122   fixes S :: "nat \<Rightarrow> ('a::cpo \<times> 'b::cpo)"
   128   assumes S: "chain S"
   123   assumes S: "chain S"
   129   shows "range S <<| (\<Squnion>i. fst (S i), \<Squnion>i. snd (S i))"
   124   shows "range S <<| (\<Squnion>i. fst (S i), \<Squnion>i. snd (S i))"
   130 proof -
   125 using S by (auto elim: prod_chain_cases simp add: is_lub_Pair cpo_lubI)
   131   from `chain S` have "chain (\<lambda>i. fst (S i))"
   126 
   132     by (rule ch2ch_fst)
   127 lemma lub_prod:
   133   hence 1: "range (\<lambda>i. fst (S i)) <<| (\<Squnion>i. fst (S i))"
       
   134     by (rule cpo_lubI)
       
   135   from `chain S` have "chain (\<lambda>i. snd (S i))"
       
   136     by (rule ch2ch_snd)
       
   137   hence 2: "range (\<lambda>i. snd (S i)) <<| (\<Squnion>i. snd (S i))"
       
   138     by (rule cpo_lubI)
       
   139   show "range S <<| (\<Squnion>i. fst (S i), \<Squnion>i. snd (S i))"
       
   140     using is_lub_Pair [OF 1 2] by simp
       
   141 qed
       
   142 
       
   143 lemma thelub_cprod:
       
   144   "chain (S::nat \<Rightarrow> 'a::cpo \<times> 'b::cpo)
   128   "chain (S::nat \<Rightarrow> 'a::cpo \<times> 'b::cpo)
   145     \<Longrightarrow> (\<Squnion>i. S i) = (\<Squnion>i. fst (S i), \<Squnion>i. snd (S i))"
   129     \<Longrightarrow> (\<Squnion>i. S i) = (\<Squnion>i. fst (S i), \<Squnion>i. snd (S i))"
   146 by (rule lub_cprod [THEN thelubI])
   130 by (rule is_lub_prod [THEN lub_eqI])
   147 
   131 
   148 instance prod :: (cpo, cpo) cpo
   132 instance prod :: (cpo, cpo) cpo
   149 proof
   133 proof
   150   fix S :: "nat \<Rightarrow> ('a \<times> 'b)"
   134   fix S :: "nat \<Rightarrow> ('a \<times> 'b)"
   151   assume "chain S"
   135   assume "chain S"
   152   hence "range S <<| (\<Squnion>i. fst (S i), \<Squnion>i. snd (S i))"
   136   hence "range S <<| (\<Squnion>i. fst (S i), \<Squnion>i. snd (S i))"
   153     by (rule lub_cprod)
   137     by (rule is_lub_prod)
   154   thus "\<exists>x. range S <<| x" ..
   138   thus "\<exists>x. range S <<| x" ..
   155 qed
   139 qed
   156 
   140 
   157 instance prod :: (discrete_cpo, discrete_cpo) discrete_cpo
   141 instance prod :: (discrete_cpo, discrete_cpo) discrete_cpo
   158 proof
   142 proof
   162     by simp
   146     by simp
   163 qed
   147 qed
   164 
   148 
   165 subsection {* Product type is pointed *}
   149 subsection {* Product type is pointed *}
   166 
   150 
   167 lemma minimal_cprod: "(\<bottom>, \<bottom>) \<sqsubseteq> p"
   151 lemma minimal_prod: "(\<bottom>, \<bottom>) \<sqsubseteq> p"
   168 by (simp add: below_prod_def)
   152 by (simp add: below_prod_def)
   169 
   153 
   170 instance prod :: (pcpo, pcpo) pcpo
   154 instance prod :: (pcpo, pcpo) pcpo
   171 by intro_classes (fast intro: minimal_cprod)
   155 by intro_classes (fast intro: minimal_prod)
   172 
   156 
   173 lemma inst_cprod_pcpo: "\<bottom> = (\<bottom>, \<bottom>)"
   157 lemma inst_prod_pcpo: "\<bottom> = (\<bottom>, \<bottom>)"
   174 by (rule minimal_cprod [THEN UU_I, symmetric])
   158 by (rule minimal_prod [THEN UU_I, symmetric])
   175 
   159 
   176 lemma Pair_bottom_iff [simp]: "(x, y) = \<bottom> \<longleftrightarrow> x = \<bottom> \<and> y = \<bottom>"
   160 lemma Pair_bottom_iff [simp]: "(x, y) = \<bottom> \<longleftrightarrow> x = \<bottom> \<and> y = \<bottom>"
   177 unfolding inst_cprod_pcpo by simp
   161 unfolding inst_prod_pcpo by simp
   178 
   162 
   179 lemma fst_strict [simp]: "fst \<bottom> = \<bottom>"
   163 lemma fst_strict [simp]: "fst \<bottom> = \<bottom>"
   180 unfolding inst_cprod_pcpo by (rule fst_conv)
   164 unfolding inst_prod_pcpo by (rule fst_conv)
   181 
   165 
   182 lemma snd_strict [simp]: "snd \<bottom> = \<bottom>"
   166 lemma snd_strict [simp]: "snd \<bottom> = \<bottom>"
   183 unfolding inst_cprod_pcpo by (rule snd_conv)
   167 unfolding inst_prod_pcpo by (rule snd_conv)
   184 
   168 
   185 lemma Pair_strict [simp]: "(\<bottom>, \<bottom>) = \<bottom>"
   169 lemma Pair_strict [simp]: "(\<bottom>, \<bottom>) = \<bottom>"
   186 by simp
   170 by simp
   187 
   171 
   188 lemma split_strict [simp]: "split f \<bottom> = f \<bottom> \<bottom>"
   172 lemma split_strict [simp]: "split f \<bottom> = f \<bottom> \<bottom>"
   192 
   176 
   193 lemma cont_pair1: "cont (\<lambda>x. (x, y))"
   177 lemma cont_pair1: "cont (\<lambda>x. (x, y))"
   194 apply (rule contI)
   178 apply (rule contI)
   195 apply (rule is_lub_Pair)
   179 apply (rule is_lub_Pair)
   196 apply (erule cpo_lubI)
   180 apply (erule cpo_lubI)
   197 apply (rule lub_const)
   181 apply (rule is_lub_const)
   198 done
   182 done
   199 
   183 
   200 lemma cont_pair2: "cont (\<lambda>y. (x, y))"
   184 lemma cont_pair2: "cont (\<lambda>y. (x, y))"
   201 apply (rule contI)
   185 apply (rule contI)
   202 apply (rule is_lub_Pair)
   186 apply (rule is_lub_Pair)
   203 apply (rule lub_const)
   187 apply (rule is_lub_const)
   204 apply (erule cpo_lubI)
   188 apply (erule cpo_lubI)
   205 done
   189 done
   206 
   190 
   207 lemma cont_fst: "cont fst"
   191 lemma cont_fst: "cont fst"
   208 apply (rule contI)
   192 apply (rule contI)
   209 apply (simp add: thelub_cprod)
   193 apply (simp add: lub_prod)
   210 apply (erule cpo_lubI [OF ch2ch_fst])
   194 apply (erule cpo_lubI [OF ch2ch_fst])
   211 done
   195 done
   212 
   196 
   213 lemma cont_snd: "cont snd"
   197 lemma cont_snd: "cont snd"
   214 apply (rule contI)
   198 apply (rule contI)
   215 apply (simp add: thelub_cprod)
   199 apply (simp add: lub_prod)
   216 apply (erule cpo_lubI [OF ch2ch_snd])
   200 apply (erule cpo_lubI [OF ch2ch_snd])
   217 done
   201 done
   218 
   202 
   219 lemma cont2cont_Pair [simp, cont2cont]:
   203 lemma cont2cont_Pair [simp, cont2cont]:
   220   assumes f: "cont (\<lambda>x. f x)"
   204   assumes f: "cont (\<lambda>x. f x)"