src/HOLCF/UpperPD.thy
author huffman
Tue Jul 01 00:58:19 2008 +0200 (2008-07-01)
changeset 27405 785f5dbec8f4
parent 27373 5794a0e3e26c
child 29138 661a8db7e647
child 29237 e90d9d51106b
permissions -rw-r--r--
rename approx_pd to pd_take
     1 (*  Title:      HOLCF/UpperPD.thy
     2     ID:         $Id$
     3     Author:     Brian Huffman
     4 *)
     5 
     6 header {* Upper powerdomain *}
     7 
     8 theory UpperPD
     9 imports CompactBasis
    10 begin
    11 
    12 subsection {* Basis preorder *}
    13 
    14 definition
    15   upper_le :: "'a pd_basis \<Rightarrow> 'a pd_basis \<Rightarrow> bool" (infix "\<le>\<sharp>" 50) where
    16   "upper_le = (\<lambda>u v. \<forall>y\<in>Rep_pd_basis v. \<exists>x\<in>Rep_pd_basis u. x \<sqsubseteq> y)"
    17 
    18 lemma upper_le_refl [simp]: "t \<le>\<sharp> t"
    19 unfolding upper_le_def by fast
    20 
    21 lemma upper_le_trans: "\<lbrakk>t \<le>\<sharp> u; u \<le>\<sharp> v\<rbrakk> \<Longrightarrow> t \<le>\<sharp> v"
    22 unfolding upper_le_def
    23 apply (rule ballI)
    24 apply (drule (1) bspec, erule bexE)
    25 apply (drule (1) bspec, erule bexE)
    26 apply (erule rev_bexI)
    27 apply (erule (1) trans_less)
    28 done
    29 
    30 interpretation upper_le: preorder [upper_le]
    31 by (rule preorder.intro, rule upper_le_refl, rule upper_le_trans)
    32 
    33 lemma upper_le_minimal [simp]: "PDUnit compact_bot \<le>\<sharp> t"
    34 unfolding upper_le_def Rep_PDUnit by simp
    35 
    36 lemma PDUnit_upper_mono: "x \<sqsubseteq> y \<Longrightarrow> PDUnit x \<le>\<sharp> PDUnit y"
    37 unfolding upper_le_def Rep_PDUnit by simp
    38 
    39 lemma PDPlus_upper_mono: "\<lbrakk>s \<le>\<sharp> t; u \<le>\<sharp> v\<rbrakk> \<Longrightarrow> PDPlus s u \<le>\<sharp> PDPlus t v"
    40 unfolding upper_le_def Rep_PDPlus by fast
    41 
    42 lemma PDPlus_upper_less: "PDPlus t u \<le>\<sharp> t"
    43 unfolding upper_le_def Rep_PDPlus by fast
    44 
    45 lemma upper_le_PDUnit_PDUnit_iff [simp]:
    46   "(PDUnit a \<le>\<sharp> PDUnit b) = a \<sqsubseteq> b"
    47 unfolding upper_le_def Rep_PDUnit by fast
    48 
    49 lemma upper_le_PDPlus_PDUnit_iff:
    50   "(PDPlus t u \<le>\<sharp> PDUnit a) = (t \<le>\<sharp> PDUnit a \<or> u \<le>\<sharp> PDUnit a)"
    51 unfolding upper_le_def Rep_PDPlus Rep_PDUnit by fast
    52 
    53 lemma upper_le_PDPlus_iff: "(t \<le>\<sharp> PDPlus u v) = (t \<le>\<sharp> u \<and> t \<le>\<sharp> v)"
    54 unfolding upper_le_def Rep_PDPlus by fast
    55 
    56 lemma upper_le_induct [induct set: upper_le]:
    57   assumes le: "t \<le>\<sharp> u"
    58   assumes 1: "\<And>a b. a \<sqsubseteq> b \<Longrightarrow> P (PDUnit a) (PDUnit b)"
    59   assumes 2: "\<And>t u a. P t (PDUnit a) \<Longrightarrow> P (PDPlus t u) (PDUnit a)"
    60   assumes 3: "\<And>t u v. \<lbrakk>P t u; P t v\<rbrakk> \<Longrightarrow> P t (PDPlus u v)"
    61   shows "P t u"
    62 using le apply (induct u arbitrary: t rule: pd_basis_induct)
    63 apply (erule rev_mp)
    64 apply (induct_tac t rule: pd_basis_induct)
    65 apply (simp add: 1)
    66 apply (simp add: upper_le_PDPlus_PDUnit_iff)
    67 apply (simp add: 2)
    68 apply (subst PDPlus_commute)
    69 apply (simp add: 2)
    70 apply (simp add: upper_le_PDPlus_iff 3)
    71 done
    72 
    73 lemma pd_take_upper_chain:
    74   "pd_take n t \<le>\<sharp> pd_take (Suc n) t"
    75 apply (induct t rule: pd_basis_induct)
    76 apply (simp add: compact_basis.take_chain)
    77 apply (simp add: PDPlus_upper_mono)
    78 done
    79 
    80 lemma pd_take_upper_le: "pd_take i t \<le>\<sharp> t"
    81 apply (induct t rule: pd_basis_induct)
    82 apply (simp add: compact_basis.take_less)
    83 apply (simp add: PDPlus_upper_mono)
    84 done
    85 
    86 lemma pd_take_upper_mono:
    87   "t \<le>\<sharp> u \<Longrightarrow> pd_take n t \<le>\<sharp> pd_take n u"
    88 apply (erule upper_le_induct)
    89 apply (simp add: compact_basis.take_mono)
    90 apply (simp add: upper_le_PDPlus_PDUnit_iff)
    91 apply (simp add: upper_le_PDPlus_iff)
    92 done
    93 
    94 
    95 subsection {* Type definition *}
    96 
    97 typedef (open) 'a upper_pd =
    98   "{S::'a pd_basis set. upper_le.ideal S}"
    99 by (fast intro: upper_le.ideal_principal)
   100 
   101 instantiation upper_pd :: (profinite) sq_ord
   102 begin
   103 
   104 definition
   105   "x \<sqsubseteq> y \<longleftrightarrow> Rep_upper_pd x \<subseteq> Rep_upper_pd y"
   106 
   107 instance ..
   108 end
   109 
   110 instance upper_pd :: (profinite) po
   111 by (rule upper_le.typedef_ideal_po
   112     [OF type_definition_upper_pd sq_le_upper_pd_def])
   113 
   114 instance upper_pd :: (profinite) cpo
   115 by (rule upper_le.typedef_ideal_cpo
   116     [OF type_definition_upper_pd sq_le_upper_pd_def])
   117 
   118 lemma Rep_upper_pd_lub:
   119   "chain Y \<Longrightarrow> Rep_upper_pd (\<Squnion>i. Y i) = (\<Union>i. Rep_upper_pd (Y i))"
   120 by (rule upper_le.typedef_ideal_rep_contlub
   121     [OF type_definition_upper_pd sq_le_upper_pd_def])
   122 
   123 lemma ideal_Rep_upper_pd: "upper_le.ideal (Rep_upper_pd xs)"
   124 by (rule Rep_upper_pd [unfolded mem_Collect_eq])
   125 
   126 definition
   127   upper_principal :: "'a pd_basis \<Rightarrow> 'a upper_pd" where
   128   "upper_principal t = Abs_upper_pd {u. u \<le>\<sharp> t}"
   129 
   130 lemma Rep_upper_principal:
   131   "Rep_upper_pd (upper_principal t) = {u. u \<le>\<sharp> t}"
   132 unfolding upper_principal_def
   133 by (simp add: Abs_upper_pd_inverse upper_le.ideal_principal)
   134 
   135 interpretation upper_pd:
   136   ideal_completion [upper_le pd_take upper_principal Rep_upper_pd]
   137 apply unfold_locales
   138 apply (rule pd_take_upper_le)
   139 apply (rule pd_take_idem)
   140 apply (erule pd_take_upper_mono)
   141 apply (rule pd_take_upper_chain)
   142 apply (rule finite_range_pd_take)
   143 apply (rule pd_take_covers)
   144 apply (rule ideal_Rep_upper_pd)
   145 apply (erule Rep_upper_pd_lub)
   146 apply (rule Rep_upper_principal)
   147 apply (simp only: sq_le_upper_pd_def)
   148 done
   149 
   150 text {* Upper powerdomain is pointed *}
   151 
   152 lemma upper_pd_minimal: "upper_principal (PDUnit compact_bot) \<sqsubseteq> ys"
   153 by (induct ys rule: upper_pd.principal_induct, simp, simp)
   154 
   155 instance upper_pd :: (bifinite) pcpo
   156 by intro_classes (fast intro: upper_pd_minimal)
   157 
   158 lemma inst_upper_pd_pcpo: "\<bottom> = upper_principal (PDUnit compact_bot)"
   159 by (rule upper_pd_minimal [THEN UU_I, symmetric])
   160 
   161 text {* Upper powerdomain is profinite *}
   162 
   163 instantiation upper_pd :: (profinite) profinite
   164 begin
   165 
   166 definition
   167   approx_upper_pd_def: "approx = upper_pd.completion_approx"
   168 
   169 instance
   170 apply (intro_classes, unfold approx_upper_pd_def)
   171 apply (rule upper_pd.chain_completion_approx)
   172 apply (rule upper_pd.lub_completion_approx)
   173 apply (rule upper_pd.completion_approx_idem)
   174 apply (rule upper_pd.finite_fixes_completion_approx)
   175 done
   176 
   177 end
   178 
   179 instance upper_pd :: (bifinite) bifinite ..
   180 
   181 lemma approx_upper_principal [simp]:
   182   "approx n\<cdot>(upper_principal t) = upper_principal (pd_take n t)"
   183 unfolding approx_upper_pd_def
   184 by (rule upper_pd.completion_approx_principal)
   185 
   186 lemma approx_eq_upper_principal:
   187   "\<exists>t\<in>Rep_upper_pd xs. approx n\<cdot>xs = upper_principal (pd_take n t)"
   188 unfolding approx_upper_pd_def
   189 by (rule upper_pd.completion_approx_eq_principal)
   190 
   191 
   192 subsection {* Monadic unit and plus *}
   193 
   194 definition
   195   upper_unit :: "'a \<rightarrow> 'a upper_pd" where
   196   "upper_unit = compact_basis.basis_fun (\<lambda>a. upper_principal (PDUnit a))"
   197 
   198 definition
   199   upper_plus :: "'a upper_pd \<rightarrow> 'a upper_pd \<rightarrow> 'a upper_pd" where
   200   "upper_plus = upper_pd.basis_fun (\<lambda>t. upper_pd.basis_fun (\<lambda>u.
   201       upper_principal (PDPlus t u)))"
   202 
   203 abbreviation
   204   upper_add :: "'a upper_pd \<Rightarrow> 'a upper_pd \<Rightarrow> 'a upper_pd"
   205     (infixl "+\<sharp>" 65) where
   206   "xs +\<sharp> ys == upper_plus\<cdot>xs\<cdot>ys"
   207 
   208 syntax
   209   "_upper_pd" :: "args \<Rightarrow> 'a upper_pd" ("{_}\<sharp>")
   210 
   211 translations
   212   "{x,xs}\<sharp>" == "{x}\<sharp> +\<sharp> {xs}\<sharp>"
   213   "{x}\<sharp>" == "CONST upper_unit\<cdot>x"
   214 
   215 lemma upper_unit_Rep_compact_basis [simp]:
   216   "{Rep_compact_basis a}\<sharp> = upper_principal (PDUnit a)"
   217 unfolding upper_unit_def
   218 by (simp add: compact_basis.basis_fun_principal PDUnit_upper_mono)
   219 
   220 lemma upper_plus_principal [simp]:
   221   "upper_principal t +\<sharp> upper_principal u = upper_principal (PDPlus t u)"
   222 unfolding upper_plus_def
   223 by (simp add: upper_pd.basis_fun_principal
   224     upper_pd.basis_fun_mono PDPlus_upper_mono)
   225 
   226 lemma approx_upper_unit [simp]:
   227   "approx n\<cdot>{x}\<sharp> = {approx n\<cdot>x}\<sharp>"
   228 apply (induct x rule: compact_basis.principal_induct, simp)
   229 apply (simp add: approx_Rep_compact_basis)
   230 done
   231 
   232 lemma approx_upper_plus [simp]:
   233   "approx n\<cdot>(xs +\<sharp> ys) = (approx n\<cdot>xs) +\<sharp> (approx n\<cdot>ys)"
   234 by (induct xs ys rule: upper_pd.principal_induct2, simp, simp, simp)
   235 
   236 lemma upper_plus_assoc: "(xs +\<sharp> ys) +\<sharp> zs = xs +\<sharp> (ys +\<sharp> zs)"
   237 apply (induct xs ys arbitrary: zs rule: upper_pd.principal_induct2, simp, simp)
   238 apply (rule_tac x=zs in upper_pd.principal_induct, simp)
   239 apply (simp add: PDPlus_assoc)
   240 done
   241 
   242 lemma upper_plus_commute: "xs +\<sharp> ys = ys +\<sharp> xs"
   243 apply (induct xs ys rule: upper_pd.principal_induct2, simp, simp)
   244 apply (simp add: PDPlus_commute)
   245 done
   246 
   247 lemma upper_plus_absorb: "xs +\<sharp> xs = xs"
   248 apply (induct xs rule: upper_pd.principal_induct, simp)
   249 apply (simp add: PDPlus_absorb)
   250 done
   251 
   252 interpretation aci_upper_plus: ab_semigroup_idem_mult ["op +\<sharp>"]
   253   by unfold_locales
   254     (rule upper_plus_assoc upper_plus_commute upper_plus_absorb)+
   255 
   256 lemma upper_plus_left_commute: "xs +\<sharp> (ys +\<sharp> zs) = ys +\<sharp> (xs +\<sharp> zs)"
   257 by (rule aci_upper_plus.mult_left_commute)
   258 
   259 lemma upper_plus_left_absorb: "xs +\<sharp> (xs +\<sharp> ys) = xs +\<sharp> ys"
   260 by (rule aci_upper_plus.mult_left_idem)
   261 
   262 lemmas upper_plus_aci = aci_upper_plus.mult_ac_idem
   263 
   264 lemma upper_plus_less1: "xs +\<sharp> ys \<sqsubseteq> xs"
   265 apply (induct xs ys rule: upper_pd.principal_induct2, simp, simp)
   266 apply (simp add: PDPlus_upper_less)
   267 done
   268 
   269 lemma upper_plus_less2: "xs +\<sharp> ys \<sqsubseteq> ys"
   270 by (subst upper_plus_commute, rule upper_plus_less1)
   271 
   272 lemma upper_plus_greatest: "\<lbrakk>xs \<sqsubseteq> ys; xs \<sqsubseteq> zs\<rbrakk> \<Longrightarrow> xs \<sqsubseteq> ys +\<sharp> zs"
   273 apply (subst upper_plus_absorb [of xs, symmetric])
   274 apply (erule (1) monofun_cfun [OF monofun_cfun_arg])
   275 done
   276 
   277 lemma upper_less_plus_iff:
   278   "xs \<sqsubseteq> ys +\<sharp> zs \<longleftrightarrow> xs \<sqsubseteq> ys \<and> xs \<sqsubseteq> zs"
   279 apply safe
   280 apply (erule trans_less [OF _ upper_plus_less1])
   281 apply (erule trans_less [OF _ upper_plus_less2])
   282 apply (erule (1) upper_plus_greatest)
   283 done
   284 
   285 lemma upper_plus_less_unit_iff:
   286   "xs +\<sharp> ys \<sqsubseteq> {z}\<sharp> \<longleftrightarrow> xs \<sqsubseteq> {z}\<sharp> \<or> ys \<sqsubseteq> {z}\<sharp>"
   287  apply (rule iffI)
   288   apply (subgoal_tac
   289     "adm (\<lambda>f. f\<cdot>xs \<sqsubseteq> f\<cdot>{z}\<sharp> \<or> f\<cdot>ys \<sqsubseteq> f\<cdot>{z}\<sharp>)")
   290    apply (drule admD, rule chain_approx)
   291     apply (drule_tac f="approx i" in monofun_cfun_arg)
   292     apply (cut_tac x="approx i\<cdot>xs" in upper_pd.compact_imp_principal, simp)
   293     apply (cut_tac x="approx i\<cdot>ys" in upper_pd.compact_imp_principal, simp)
   294     apply (cut_tac x="approx i\<cdot>z" in compact_basis.compact_imp_principal, simp)
   295     apply (clarify, simp add: upper_le_PDPlus_PDUnit_iff)
   296    apply simp
   297   apply simp
   298  apply (erule disjE)
   299   apply (erule trans_less [OF upper_plus_less1])
   300  apply (erule trans_less [OF upper_plus_less2])
   301 done
   302 
   303 lemma upper_unit_less_iff [simp]: "{x}\<sharp> \<sqsubseteq> {y}\<sharp> \<longleftrightarrow> x \<sqsubseteq> y"
   304  apply (rule iffI)
   305   apply (rule profinite_less_ext)
   306   apply (drule_tac f="approx i" in monofun_cfun_arg, simp)
   307   apply (cut_tac x="approx i\<cdot>x" in compact_basis.compact_imp_principal, simp)
   308   apply (cut_tac x="approx i\<cdot>y" in compact_basis.compact_imp_principal, simp)
   309   apply clarsimp
   310  apply (erule monofun_cfun_arg)
   311 done
   312 
   313 lemmas upper_pd_less_simps =
   314   upper_unit_less_iff
   315   upper_less_plus_iff
   316   upper_plus_less_unit_iff
   317 
   318 lemma upper_unit_eq_iff [simp]: "{x}\<sharp> = {y}\<sharp> \<longleftrightarrow> x = y"
   319 unfolding po_eq_conv by simp
   320 
   321 lemma upper_unit_strict [simp]: "{\<bottom>}\<sharp> = \<bottom>"
   322 unfolding inst_upper_pd_pcpo Rep_compact_bot [symmetric] by simp
   323 
   324 lemma upper_plus_strict1 [simp]: "\<bottom> +\<sharp> ys = \<bottom>"
   325 by (rule UU_I, rule upper_plus_less1)
   326 
   327 lemma upper_plus_strict2 [simp]: "xs +\<sharp> \<bottom> = \<bottom>"
   328 by (rule UU_I, rule upper_plus_less2)
   329 
   330 lemma upper_unit_strict_iff [simp]: "{x}\<sharp> = \<bottom> \<longleftrightarrow> x = \<bottom>"
   331 unfolding upper_unit_strict [symmetric] by (rule upper_unit_eq_iff)
   332 
   333 lemma upper_plus_strict_iff [simp]:
   334   "xs +\<sharp> ys = \<bottom> \<longleftrightarrow> xs = \<bottom> \<or> ys = \<bottom>"
   335 apply (rule iffI)
   336 apply (erule rev_mp)
   337 apply (rule upper_pd.principal_induct2 [where x=xs and y=ys], simp, simp)
   338 apply (simp add: inst_upper_pd_pcpo upper_pd.principal_eq_iff
   339                  upper_le_PDPlus_PDUnit_iff)
   340 apply auto
   341 done
   342 
   343 lemma compact_upper_unit_iff [simp]: "compact {x}\<sharp> \<longleftrightarrow> compact x"
   344 unfolding profinite_compact_iff by simp
   345 
   346 lemma compact_upper_plus [simp]:
   347   "\<lbrakk>compact xs; compact ys\<rbrakk> \<Longrightarrow> compact (xs +\<sharp> ys)"
   348 by (auto dest!: upper_pd.compact_imp_principal)
   349 
   350 
   351 subsection {* Induction rules *}
   352 
   353 lemma upper_pd_induct1:
   354   assumes P: "adm P"
   355   assumes unit: "\<And>x. P {x}\<sharp>"
   356   assumes insert: "\<And>x ys. \<lbrakk>P {x}\<sharp>; P ys\<rbrakk> \<Longrightarrow> P ({x}\<sharp> +\<sharp> ys)"
   357   shows "P (xs::'a upper_pd)"
   358 apply (induct xs rule: upper_pd.principal_induct, rule P)
   359 apply (induct_tac a rule: pd_basis_induct1)
   360 apply (simp only: upper_unit_Rep_compact_basis [symmetric])
   361 apply (rule unit)
   362 apply (simp only: upper_unit_Rep_compact_basis [symmetric]
   363                   upper_plus_principal [symmetric])
   364 apply (erule insert [OF unit])
   365 done
   366 
   367 lemma upper_pd_induct:
   368   assumes P: "adm P"
   369   assumes unit: "\<And>x. P {x}\<sharp>"
   370   assumes plus: "\<And>xs ys. \<lbrakk>P xs; P ys\<rbrakk> \<Longrightarrow> P (xs +\<sharp> ys)"
   371   shows "P (xs::'a upper_pd)"
   372 apply (induct xs rule: upper_pd.principal_induct, rule P)
   373 apply (induct_tac a rule: pd_basis_induct)
   374 apply (simp only: upper_unit_Rep_compact_basis [symmetric] unit)
   375 apply (simp only: upper_plus_principal [symmetric] plus)
   376 done
   377 
   378 
   379 subsection {* Monadic bind *}
   380 
   381 definition
   382   upper_bind_basis ::
   383   "'a pd_basis \<Rightarrow> ('a \<rightarrow> 'b upper_pd) \<rightarrow> 'b upper_pd" where
   384   "upper_bind_basis = fold_pd
   385     (\<lambda>a. \<Lambda> f. f\<cdot>(Rep_compact_basis a))
   386     (\<lambda>x y. \<Lambda> f. x\<cdot>f +\<sharp> y\<cdot>f)"
   387 
   388 lemma ACI_upper_bind:
   389   "ab_semigroup_idem_mult (\<lambda>x y. \<Lambda> f. x\<cdot>f +\<sharp> y\<cdot>f)"
   390 apply unfold_locales
   391 apply (simp add: upper_plus_assoc)
   392 apply (simp add: upper_plus_commute)
   393 apply (simp add: upper_plus_absorb eta_cfun)
   394 done
   395 
   396 lemma upper_bind_basis_simps [simp]:
   397   "upper_bind_basis (PDUnit a) =
   398     (\<Lambda> f. f\<cdot>(Rep_compact_basis a))"
   399   "upper_bind_basis (PDPlus t u) =
   400     (\<Lambda> f. upper_bind_basis t\<cdot>f +\<sharp> upper_bind_basis u\<cdot>f)"
   401 unfolding upper_bind_basis_def
   402 apply -
   403 apply (rule fold_pd_PDUnit [OF ACI_upper_bind])
   404 apply (rule fold_pd_PDPlus [OF ACI_upper_bind])
   405 done
   406 
   407 lemma upper_bind_basis_mono:
   408   "t \<le>\<sharp> u \<Longrightarrow> upper_bind_basis t \<sqsubseteq> upper_bind_basis u"
   409 unfolding expand_cfun_less
   410 apply (erule upper_le_induct, safe)
   411 apply (simp add: monofun_cfun)
   412 apply (simp add: trans_less [OF upper_plus_less1])
   413 apply (simp add: upper_less_plus_iff)
   414 done
   415 
   416 definition
   417   upper_bind :: "'a upper_pd \<rightarrow> ('a \<rightarrow> 'b upper_pd) \<rightarrow> 'b upper_pd" where
   418   "upper_bind = upper_pd.basis_fun upper_bind_basis"
   419 
   420 lemma upper_bind_principal [simp]:
   421   "upper_bind\<cdot>(upper_principal t) = upper_bind_basis t"
   422 unfolding upper_bind_def
   423 apply (rule upper_pd.basis_fun_principal)
   424 apply (erule upper_bind_basis_mono)
   425 done
   426 
   427 lemma upper_bind_unit [simp]:
   428   "upper_bind\<cdot>{x}\<sharp>\<cdot>f = f\<cdot>x"
   429 by (induct x rule: compact_basis.principal_induct, simp, simp)
   430 
   431 lemma upper_bind_plus [simp]:
   432   "upper_bind\<cdot>(xs +\<sharp> ys)\<cdot>f = upper_bind\<cdot>xs\<cdot>f +\<sharp> upper_bind\<cdot>ys\<cdot>f"
   433 by (induct xs ys rule: upper_pd.principal_induct2, simp, simp, simp)
   434 
   435 lemma upper_bind_strict [simp]: "upper_bind\<cdot>\<bottom>\<cdot>f = f\<cdot>\<bottom>"
   436 unfolding upper_unit_strict [symmetric] by (rule upper_bind_unit)
   437 
   438 
   439 subsection {* Map and join *}
   440 
   441 definition
   442   upper_map :: "('a \<rightarrow> 'b) \<rightarrow> 'a upper_pd \<rightarrow> 'b upper_pd" where
   443   "upper_map = (\<Lambda> f xs. upper_bind\<cdot>xs\<cdot>(\<Lambda> x. {f\<cdot>x}\<sharp>))"
   444 
   445 definition
   446   upper_join :: "'a upper_pd upper_pd \<rightarrow> 'a upper_pd" where
   447   "upper_join = (\<Lambda> xss. upper_bind\<cdot>xss\<cdot>(\<Lambda> xs. xs))"
   448 
   449 lemma upper_map_unit [simp]:
   450   "upper_map\<cdot>f\<cdot>{x}\<sharp> = {f\<cdot>x}\<sharp>"
   451 unfolding upper_map_def by simp
   452 
   453 lemma upper_map_plus [simp]:
   454   "upper_map\<cdot>f\<cdot>(xs +\<sharp> ys) = upper_map\<cdot>f\<cdot>xs +\<sharp> upper_map\<cdot>f\<cdot>ys"
   455 unfolding upper_map_def by simp
   456 
   457 lemma upper_join_unit [simp]:
   458   "upper_join\<cdot>{xs}\<sharp> = xs"
   459 unfolding upper_join_def by simp
   460 
   461 lemma upper_join_plus [simp]:
   462   "upper_join\<cdot>(xss +\<sharp> yss) = upper_join\<cdot>xss +\<sharp> upper_join\<cdot>yss"
   463 unfolding upper_join_def by simp
   464 
   465 lemma upper_map_ident: "upper_map\<cdot>(\<Lambda> x. x)\<cdot>xs = xs"
   466 by (induct xs rule: upper_pd_induct, simp_all)
   467 
   468 lemma upper_map_map:
   469   "upper_map\<cdot>f\<cdot>(upper_map\<cdot>g\<cdot>xs) = upper_map\<cdot>(\<Lambda> x. f\<cdot>(g\<cdot>x))\<cdot>xs"
   470 by (induct xs rule: upper_pd_induct, simp_all)
   471 
   472 lemma upper_join_map_unit:
   473   "upper_join\<cdot>(upper_map\<cdot>upper_unit\<cdot>xs) = xs"
   474 by (induct xs rule: upper_pd_induct, simp_all)
   475 
   476 lemma upper_join_map_join:
   477   "upper_join\<cdot>(upper_map\<cdot>upper_join\<cdot>xsss) = upper_join\<cdot>(upper_join\<cdot>xsss)"
   478 by (induct xsss rule: upper_pd_induct, simp_all)
   479 
   480 lemma upper_join_map_map:
   481   "upper_join\<cdot>(upper_map\<cdot>(upper_map\<cdot>f)\<cdot>xss) =
   482    upper_map\<cdot>f\<cdot>(upper_join\<cdot>xss)"
   483 by (induct xss rule: upper_pd_induct, simp_all)
   484 
   485 lemma upper_map_approx: "upper_map\<cdot>(approx n)\<cdot>xs = approx n\<cdot>xs"
   486 by (induct xs rule: upper_pd_induct, simp_all)
   487 
   488 end