new theory of powerdomains
authorhuffman
Mon, 14 Jan 2008 19:26:41 +0100
changeset 25904 8161f137b0e9
parent 25903 5e59af604d4f
child 25905 098469c6c351
new theory of powerdomains
src/HOLCF/CompactBasis.thy
src/HOLCF/ConvexPD.thy
src/HOLCF/HOLCF.thy
src/HOLCF/LowerPD.thy
src/HOLCF/UpperPD.thy
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOLCF/CompactBasis.thy	Mon Jan 14 19:26:41 2008 +0100
@@ -0,0 +1,686 @@
+(*  Title:      HOLCF/CompactBasis.thy
+    ID:         $Id$
+    Author:     Brian Huffman
+*)
+
+header {* Compact bases of domains *}
+
+theory CompactBasis
+imports Bifinite SetPcpo
+begin
+
+subsection {* Ideals over a preorder *}
+
+locale preorder =
+  fixes r :: "'a::type \<Rightarrow> 'a \<Rightarrow> bool"
+  assumes refl: "r x x"
+  assumes trans: "\<lbrakk>r x y; r y z\<rbrakk> \<Longrightarrow> r x z"
+begin
+
+definition
+  ideal :: "'a set \<Rightarrow> bool" where
+  "ideal A = ((\<exists>x. x \<in> A) \<and> (\<forall>x\<in>A. \<forall>y\<in>A. \<exists>z\<in>A. r x z \<and> r y z) \<and>
+    (\<forall>x y. r x y \<longrightarrow> y \<in> A \<longrightarrow> x \<in> A))"
+
+lemma idealI:
+  assumes "\<exists>x. x \<in> A"
+  assumes "\<And>x y. \<lbrakk>x \<in> A; y \<in> A\<rbrakk> \<Longrightarrow> \<exists>z\<in>A. r x z \<and> r y z"
+  assumes "\<And>x y. \<lbrakk>r x y; y \<in> A\<rbrakk> \<Longrightarrow> x \<in> A"
+  shows "ideal A"
+unfolding ideal_def using prems by fast
+
+lemma idealD1:
+  "ideal A \<Longrightarrow> \<exists>x. x \<in> A"
+unfolding ideal_def by fast
+
+lemma idealD2:
+  "\<lbrakk>ideal A; x \<in> A; y \<in> A\<rbrakk> \<Longrightarrow> \<exists>z\<in>A. r x z \<and> r y z"
+unfolding ideal_def by fast
+
+lemma idealD3:
+  "\<lbrakk>ideal A; r x y; y \<in> A\<rbrakk> \<Longrightarrow> x \<in> A"
+unfolding ideal_def by fast
+
+lemma ideal_directed_finite:
+  assumes A: "ideal A"
+  shows "\<lbrakk>finite U; U \<subseteq> A\<rbrakk> \<Longrightarrow> \<exists>z\<in>A. \<forall>x\<in>U. r x z"
+apply (induct U set: finite)
+apply (simp add: idealD1 [OF A])
+apply (simp, clarify, rename_tac y)
+apply (drule (1) idealD2 [OF A])
+apply (clarify, erule_tac x=z in rev_bexI)
+apply (fast intro: trans)
+done
+
+lemma ideal_principal: "ideal {x. r x z}"
+apply (rule idealI)
+apply (rule_tac x=z in exI)
+apply (fast intro: refl)
+apply (rule_tac x=z in bexI, fast)
+apply (fast intro: refl)
+apply (fast intro: trans)
+done
+
+lemma directed_image_ideal:
+  assumes A: "ideal A"
+  assumes f: "\<And>x y. r x y \<Longrightarrow> f x \<sqsubseteq> f y"
+  shows "directed (f ` A)"
+apply (rule directedI)
+apply (cut_tac idealD1 [OF A], fast)
+apply (clarify, rename_tac a b)
+apply (drule (1) idealD2 [OF A])
+apply (clarify, rename_tac c)
+apply (rule_tac x="f c" in rev_bexI)
+apply (erule imageI)
+apply (simp add: f)
+done
+
+lemma adm_ideal: "adm (\<lambda>A. ideal A)"
+unfolding ideal_def by (intro adm_lemmas adm_set_lemmas)
+
+end
+
+subsection {* Defining functions in terms of basis elements *}
+
+lemma (in preorder) lub_image_principal:
+  assumes f: "\<And>x y. r x y \<Longrightarrow> f x \<sqsubseteq> f y"
+  shows "(\<Squnion>x\<in>{x. r x y}. f x) = f y"
+apply (rule thelubI)
+apply (rule is_lub_maximal)
+apply (rule ub_imageI)
+apply (simp add: f)
+apply (rule imageI)
+apply (simp add: refl)
+done
+
+lemma finite_directed_has_lub: "\<lbrakk>finite S; directed S\<rbrakk> \<Longrightarrow> \<exists>u. S <<| u"
+apply (drule (1) directed_finiteD, rule subset_refl)
+apply (erule bexE)
+apply (rule_tac x=z in exI)
+apply (erule (1) is_lub_maximal)
+done
+
+lemma is_ub_thelub0: "\<lbrakk>\<exists>u. S <<| u; x \<in> S\<rbrakk> \<Longrightarrow> x \<sqsubseteq> lub S"
+apply (erule exE, drule lubI)
+apply (drule is_lubD1)
+apply (erule (1) is_ubD)
+done
+
+lemma is_lub_thelub0: "\<lbrakk>\<exists>u. S <<| u; S <| x\<rbrakk> \<Longrightarrow> lub S \<sqsubseteq> x"
+by (erule exE, drule lubI, erule is_lub_lub)
+
+locale bifinite_basis = preorder +
+  fixes principal :: "'a::type \<Rightarrow> 'b::cpo"
+  fixes approxes :: "'b::cpo \<Rightarrow> 'a::type set"
+  assumes ideal_approxes: "\<And>x. preorder.ideal r (approxes x)"
+  assumes cont_approxes: "cont approxes"
+  assumes approxes_principal: "\<And>a. approxes (principal a) = {b. r b a}"
+  assumes subset_approxesD: "\<And>x y. approxes x \<subseteq> approxes y \<Longrightarrow> x \<sqsubseteq> y"
+
+  fixes take :: "nat \<Rightarrow> 'a::type \<Rightarrow> 'a"
+  assumes take_less: "r (take n a) a"
+  assumes take_take: "take n (take n a) = take n a"
+  assumes take_mono: "r a b \<Longrightarrow> r (take n a) (take n b)"
+  assumes take_chain: "r (take n a) (take (Suc n) a)"
+  assumes finite_range_take: "finite (range (take n))"
+  assumes take_covers: "\<exists>n. take n a = a"
+begin
+
+lemma finite_take_approxes: "finite (take n ` approxes x)"
+by (rule finite_subset [OF image_mono [OF subset_UNIV] finite_range_take])
+
+lemma basis_fun_lemma0:
+  fixes f :: "'a::type \<Rightarrow> 'c::cpo"
+  assumes f_mono: "\<And>a b. r a b \<Longrightarrow> f a \<sqsubseteq> f b"
+  shows "\<exists>u. f ` take i ` approxes x <<| u"
+apply (rule finite_directed_has_lub)
+apply (rule finite_imageI)
+apply (rule finite_take_approxes)
+apply (subst image_image)
+apply (rule directed_image_ideal)
+apply (rule ideal_approxes)
+apply (rule f_mono)
+apply (erule take_mono)
+done
+
+lemma basis_fun_lemma1:
+  fixes f :: "'a::type \<Rightarrow> 'c::cpo"
+  assumes f_mono: "\<And>a b. r a b \<Longrightarrow> f a \<sqsubseteq> f b"
+  shows "chain (\<lambda>i. lub (f ` take i ` approxes x))"
+ apply (rule chainI)
+ apply (rule is_lub_thelub0)
+  apply (rule basis_fun_lemma0, erule f_mono)
+ apply (rule is_ubI, clarsimp, rename_tac a)
+ apply (rule trans_less [OF f_mono [OF take_chain]])
+ apply (rule is_ub_thelub0)
+  apply (rule basis_fun_lemma0, erule f_mono)
+ apply simp
+done
+
+lemma basis_fun_lemma2:
+  fixes f :: "'a::type \<Rightarrow> 'c::cpo"
+  assumes f_mono: "\<And>a b. r a b \<Longrightarrow> f a \<sqsubseteq> f b"
+  shows "f ` approxes x <<| (\<Squnion>i. lub (f ` take i ` approxes x))"
+ apply (rule is_lubI)
+ apply (rule ub_imageI, rename_tac a)
+  apply (cut_tac a=a in take_covers, erule exE, rename_tac i)
+  apply (erule subst)
+  apply (rule rev_trans_less)
+   apply (rule_tac x=i in is_ub_thelub)
+   apply (rule basis_fun_lemma1, erule f_mono)
+  apply (rule is_ub_thelub0)
+   apply (rule basis_fun_lemma0, erule f_mono)
+  apply simp
+ apply (rule is_lub_thelub [OF _ ub_rangeI])
+  apply (rule basis_fun_lemma1, erule f_mono)
+ apply (rule is_lub_thelub0)
+  apply (rule basis_fun_lemma0, erule f_mono)
+ apply (rule is_ubI, clarsimp, rename_tac a)
+ apply (rule trans_less [OF f_mono [OF take_less]])
+ apply (erule (1) ub_imageD)
+done
+
+lemma basis_fun_lemma:
+  fixes f :: "'a::type \<Rightarrow> 'c::cpo"
+  assumes f_mono: "\<And>a b. r a b \<Longrightarrow> f a \<sqsubseteq> f b"
+  shows "\<exists>u. f ` approxes x <<| u"
+by (rule exI, rule basis_fun_lemma2, erule f_mono)
+
+lemma approxes_mono: "x \<sqsubseteq> y \<Longrightarrow> approxes x \<subseteq> approxes y"
+apply (drule cont_approxes [THEN cont2mono, THEN monofunE])
+apply (simp add: set_cpo_simps)
+done
+
+lemma approxes_contlub:
+  "chain Y \<Longrightarrow> approxes (\<Squnion>i. Y i) = (\<Union>i. approxes (Y i))"
+by (simp add: cont2contlubE [OF cont_approxes] set_cpo_simps)
+
+lemma less_def: "(x \<sqsubseteq> y) = (approxes x \<subseteq> approxes y)"
+by (rule iffI [OF approxes_mono subset_approxesD])
+
+lemma approxes_eq: "approxes x = {a. principal a \<sqsubseteq> x}"
+unfolding less_def approxes_principal
+apply safe
+apply (erule (1) idealD3 [OF ideal_approxes])
+apply (erule subsetD, simp add: refl)
+done
+
+lemma mem_approxes_iff: "(a \<in> approxes x) = (principal a \<sqsubseteq> x)"
+by (simp add: approxes_eq)
+
+lemma principal_less_iff: "(principal a \<sqsubseteq> x) = (a \<in> approxes x)"
+by (simp add: approxes_eq)
+
+lemma approxesD: "a \<in> approxes x \<Longrightarrow> principal a \<sqsubseteq> x"
+by (simp add: approxes_eq)
+
+lemma principal_mono: "r a b \<Longrightarrow> principal a \<sqsubseteq> principal b"
+by (rule approxesD, simp add: approxes_principal)
+
+lemma lessI: "(\<And>a. principal a \<sqsubseteq> x \<Longrightarrow> principal a \<sqsubseteq> u) \<Longrightarrow> x \<sqsubseteq> u"
+unfolding principal_less_iff
+by (simp add: less_def subset_def)
+
+lemma lub_principal_approxes: "principal ` approxes x <<| x"
+apply (rule is_lubI)
+apply (rule ub_imageI)
+apply (erule approxesD)
+apply (subst less_def)
+apply (rule subsetI)
+apply (drule (1) ub_imageD)
+apply (simp add: approxes_eq)
+done
+
+definition
+  basis_fun :: "('a::type \<Rightarrow> 'c::cpo) \<Rightarrow> 'b \<rightarrow> 'c" where
+  "basis_fun = (\<lambda>f. (\<Lambda> x. lub (f ` approxes x)))"
+
+lemma basis_fun_beta:
+  fixes f :: "'a::type \<Rightarrow> 'c::cpo"
+  assumes f_mono: "\<And>a b. r a b \<Longrightarrow> f a \<sqsubseteq> f b"
+  shows "basis_fun f\<cdot>x = lub (f ` approxes x)"
+unfolding basis_fun_def
+proof (rule beta_cfun)
+  have lub: "\<And>x. \<exists>u. f ` approxes x <<| u"
+    using f_mono by (rule basis_fun_lemma)
+  show cont: "cont (\<lambda>x. lub (f ` approxes x))"
+    apply (rule contI2)
+     apply (rule monofunI)
+     apply (rule is_lub_thelub0 [OF lub ub_imageI])
+     apply (rule is_ub_thelub0 [OF lub imageI])
+     apply (erule (1) subsetD [OF approxes_mono])
+    apply (rule is_lub_thelub0 [OF lub ub_imageI])
+    apply (simp add: approxes_contlub, clarify)
+    apply (erule rev_trans_less [OF is_ub_thelub])
+    apply (erule is_ub_thelub0 [OF lub imageI])
+    done
+qed
+
+lemma basis_fun_principal:
+  fixes f :: "'a::type \<Rightarrow> 'c::cpo"
+  assumes f_mono: "\<And>a b. r a b \<Longrightarrow> f a \<sqsubseteq> f b"
+  shows "basis_fun f\<cdot>(principal a) = f a"
+apply (subst basis_fun_beta, erule f_mono)
+apply (subst approxes_principal)
+apply (rule lub_image_principal, erule f_mono)
+done
+
+lemma basis_fun_mono:
+  assumes f_mono: "\<And>a b. r a b \<Longrightarrow> f a \<sqsubseteq> f b"
+  assumes g_mono: "\<And>a b. r a b \<Longrightarrow> g a \<sqsubseteq> g b"
+  assumes less: "\<And>a. f a \<sqsubseteq> g a"
+  shows "basis_fun f \<sqsubseteq> basis_fun g"
+ apply (rule less_cfun_ext)
+ apply (simp only: basis_fun_beta f_mono g_mono)
+ apply (rule is_lub_thelub0)
+  apply (rule basis_fun_lemma, erule f_mono)
+ apply (rule ub_imageI, rename_tac a)
+ apply (rule trans_less [OF less])
+ apply (rule is_ub_thelub0)
+  apply (rule basis_fun_lemma, erule g_mono)
+ apply (erule imageI)
+done
+
+lemma compact_principal: "compact (principal a)"
+by (rule compactI2, simp add: principal_less_iff approxes_contlub)
+
+lemma chain_basis_fun_take:
+  "chain (\<lambda>i. basis_fun (\<lambda>a. principal (take i a)))"
+apply (rule chainI)
+apply (rule basis_fun_mono)
+apply (erule principal_mono [OF take_mono])
+apply (erule principal_mono [OF take_mono])
+apply (rule principal_mono [OF take_chain])
+done
+
+lemma lub_basis_fun_take:
+  "(\<Squnion>i. basis_fun (\<lambda>a. principal (take i a))\<cdot>x) = x"
+ apply (simp add: basis_fun_beta principal_mono take_mono)
+ apply (subst image_image [where f=principal, symmetric])
+ apply (rule unique_lub [OF _ lub_principal_approxes])
+ apply (rule basis_fun_lemma2, erule principal_mono)
+done
+
+lemma finite_directed_contains_lub:
+  "\<lbrakk>finite S; directed S\<rbrakk> \<Longrightarrow> \<exists>u\<in>S. S <<| u"
+apply (drule (1) directed_finiteD, rule subset_refl)
+apply (erule bexE)
+apply (rule rev_bexI, assumption)
+apply (erule (1) is_lub_maximal)
+done
+
+lemma lub_finite_directed_in_self:
+  "\<lbrakk>finite S; directed S\<rbrakk> \<Longrightarrow> lub S \<in> S"
+apply (drule (1) directed_finiteD, rule subset_refl)
+apply (erule bexE)
+apply (drule (1) is_lub_maximal)
+apply (drule thelubI)
+apply simp
+done
+
+lemma basis_fun_take_eq_principal:
+  "\<exists>a\<in>approxes x.
+    basis_fun (\<lambda>a. principal (take i a))\<cdot>x = principal (take i a)"
+ apply (simp add: basis_fun_beta principal_mono take_mono)
+ apply (subst image_image [where f=principal, symmetric])
+ apply (subgoal_tac "finite (principal ` take i ` approxes x)")
+  apply (subgoal_tac "directed (principal ` take i ` approxes x)")
+   apply (drule (1) lub_finite_directed_in_self, fast)
+  apply (subst image_image)
+  apply (rule directed_image_ideal)
+   apply (rule ideal_approxes)
+  apply (erule principal_mono [OF take_mono])
+ apply (rule finite_imageI)
+ apply (rule finite_take_approxes)
+done
+
+lemma principal_induct:
+  assumes adm: "adm P"
+  assumes P: "\<And>a. P (principal a)"
+  shows "P x"
+ apply (subgoal_tac "P (\<Squnion>i. basis_fun (\<lambda>a. principal (take i a))\<cdot>x)")
+ apply (simp add: lub_basis_fun_take)
+ apply (rule admD [rule_format, OF adm])
+  apply (simp add: chain_basis_fun_take)
+ apply (cut_tac x=x and i=i in basis_fun_take_eq_principal)
+ apply (clarify, simp add: P)
+done
+
+lemma finite_fixes_basis_fun_take:
+  "finite {x. basis_fun (\<lambda>a. principal (take i a))\<cdot>x = x}" (is "finite ?S")
+apply (subgoal_tac "?S \<subseteq> principal ` range (take i)")
+apply (erule finite_subset)
+apply (rule finite_imageI)
+apply (rule finite_range_take)
+apply (clarify, erule subst)
+apply (cut_tac x=x and i=i in basis_fun_take_eq_principal)
+apply fast
+done
+
+end
+
+
+subsection {* Compact bases of bifinite domains *}
+
+defaultsort bifinite
+
+typedef (open) 'a compact_basis = "{x::'a::bifinite. compact x}"
+by (fast intro: compact_approx)
+
+lemma compact_Rep_compact_basis [simp]: "compact (Rep_compact_basis a)"
+by (rule Rep_compact_basis [simplified])
+
+lemma Rep_Abs_compact_basis_approx [simp]:
+  "Rep_compact_basis (Abs_compact_basis (approx n\<cdot>x)) = approx n\<cdot>x"
+by (rule Abs_compact_basis_inverse, simp)
+
+lemma compact_imp_Rep_compact_basis:
+  "compact x \<Longrightarrow> \<exists>y. x = Rep_compact_basis y"
+by (rule exI, rule Abs_compact_basis_inverse [symmetric], simp)
+
+definition
+  compact_le :: "'a compact_basis \<Rightarrow> 'a compact_basis \<Rightarrow> bool" where
+  "compact_le = (\<lambda>x y. Rep_compact_basis x \<sqsubseteq> Rep_compact_basis y)"
+
+lemma compact_le_refl: "compact_le x x"
+unfolding compact_le_def by (rule refl_less)
+
+lemma compact_le_trans: "\<lbrakk>compact_le x y; compact_le y z\<rbrakk> \<Longrightarrow> compact_le x z"
+unfolding compact_le_def by (rule trans_less)
+
+lemma compact_le_antisym: "\<lbrakk>compact_le x y; compact_le y x\<rbrakk> \<Longrightarrow> x = y"
+unfolding compact_le_def
+apply (rule Rep_compact_basis_inject [THEN iffD1])
+apply (erule (1) antisym_less)
+done
+
+interpretation compact_le: preorder [compact_le]
+by (rule preorder.intro, rule compact_le_refl, rule compact_le_trans)
+
+text {* minimal compact element *}
+
+definition
+  compact_bot :: "'a compact_basis" where
+  "compact_bot = Abs_compact_basis \<bottom>"
+
+lemma Rep_compact_bot: "Rep_compact_basis compact_bot = \<bottom>"
+unfolding compact_bot_def by (simp add: Abs_compact_basis_inverse)
+
+lemma compact_minimal [simp]: "compact_le compact_bot a"
+unfolding compact_le_def Rep_compact_bot by simp
+
+text {* compacts *}
+
+definition
+  compacts :: "'a \<Rightarrow> 'a compact_basis set" where
+  "compacts = (\<lambda>x. {a. Rep_compact_basis a \<sqsubseteq> x})"
+
+lemma ideal_compacts: "compact_le.ideal (compacts w)"
+unfolding compacts_def
+ apply (rule compact_le.idealI)
+   apply (rule_tac x="Abs_compact_basis (approx 0\<cdot>w)" in exI)
+   apply (simp add: approx_less)
+  apply simp
+  apply (cut_tac a=x in compact_Rep_compact_basis)
+  apply (cut_tac a=y in compact_Rep_compact_basis)
+  apply (drule bifinite_compact_eq_approx)
+  apply (drule bifinite_compact_eq_approx)
+  apply (clarify, rename_tac i j)
+  apply (rule_tac x="Abs_compact_basis (approx (max i j)\<cdot>w)" in exI)
+  apply (simp add: approx_less compact_le_def)
+  apply (erule subst, erule subst)
+  apply (simp add: monofun_cfun chain_mono3 [OF chain_approx])
+ apply (simp add: compact_le_def)
+ apply (erule (1) trans_less)
+done
+
+lemma compacts_Rep_compact_basis:
+  "compacts (Rep_compact_basis b) = {a. compact_le a b}"
+unfolding compacts_def compact_le_def ..
+
+lemma cont_compacts: "cont compacts"
+unfolding compacts_def
+apply (rule contI2)
+apply (rule monofunI)
+apply (simp add: set_cpo_simps)
+apply (fast intro: trans_less)
+apply (simp add: set_cpo_simps)
+apply clarify
+apply simp
+apply (erule (1) compactD2 [OF compact_Rep_compact_basis])
+done
+
+lemma compacts_lessD: "compacts x \<subseteq> compacts y \<Longrightarrow> x \<sqsubseteq> y"
+apply (subgoal_tac "(\<Squnion>i. approx i\<cdot>x) \<sqsubseteq> y", simp)
+apply (rule admD [rule_format], simp, simp)
+apply (drule_tac c="Abs_compact_basis (approx i\<cdot>x)" in subsetD)
+apply (simp add: compacts_def Abs_compact_basis_inverse approx_less)
+apply (simp add: compacts_def Abs_compact_basis_inverse)
+done
+
+lemma compacts_mono: "x \<sqsubseteq> y \<Longrightarrow> compacts x \<subseteq> compacts y"
+unfolding compacts_def by (fast intro: trans_less)
+
+lemma less_compact_basis_iff: "(x \<sqsubseteq> y) = (compacts x \<subseteq> compacts y)"
+by (rule iffI [OF compacts_mono compacts_lessD])
+
+lemma compact_basis_induct:
+  "\<lbrakk>adm P; \<And>a. P (Rep_compact_basis a)\<rbrakk> \<Longrightarrow> P x"
+apply (erule approx_induct)
+apply (drule_tac x="Abs_compact_basis (approx n\<cdot>x)" in meta_spec)
+apply (simp add: Abs_compact_basis_inverse)
+done
+
+text {* approximation on compact bases *}
+
+definition
+  compact_approx :: "nat \<Rightarrow> 'a compact_basis \<Rightarrow> 'a compact_basis" where
+  "compact_approx = (\<lambda>n a. Abs_compact_basis (approx n\<cdot>(Rep_compact_basis a)))"
+
+lemma Rep_compact_approx:
+  "Rep_compact_basis (compact_approx n a) = approx n\<cdot>(Rep_compact_basis a)"
+unfolding compact_approx_def
+by (simp add: Abs_compact_basis_inverse)
+
+lemmas approx_Rep_compact_basis = Rep_compact_approx [symmetric]
+
+lemma compact_approx_le:
+  "compact_le (compact_approx n a) a"
+unfolding compact_le_def
+by (simp add: Rep_compact_approx approx_less)
+
+lemma compact_approx_mono1:
+  "i \<le> j \<Longrightarrow> compact_le (compact_approx i a) (compact_approx j a)"
+unfolding compact_le_def
+apply (simp add: Rep_compact_approx)
+apply (rule chain_mono3, simp, assumption)
+done
+
+lemma compact_approx_mono:
+  "compact_le a b \<Longrightarrow> compact_le (compact_approx n a) (compact_approx n b)"
+unfolding compact_le_def
+apply (simp add: Rep_compact_approx)
+apply (erule monofun_cfun_arg)
+done
+
+lemma ex_compact_approx_eq: "\<exists>n. compact_approx n a = a"
+apply (simp add: Rep_compact_basis_inject [symmetric])
+apply (simp add: Rep_compact_approx)
+apply (rule bifinite_compact_eq_approx)
+apply (rule compact_Rep_compact_basis)
+done
+
+lemma compact_approx_idem:
+  "compact_approx n (compact_approx n a) = compact_approx n a"
+apply (rule Rep_compact_basis_inject [THEN iffD1])
+apply (simp add: Rep_compact_approx)
+done
+
+lemma finite_fixes_compact_approx: "finite {a. compact_approx n a = a}"
+apply (subgoal_tac "finite (Rep_compact_basis ` {a. compact_approx n a = a})")
+apply (erule finite_imageD)
+apply (rule inj_onI, simp add: Rep_compact_basis_inject)
+apply (rule finite_subset [OF _ finite_fixes_approx [where i=n]])
+apply (rule subsetI, clarify, rename_tac a)
+apply (simp add: Rep_compact_basis_inject [symmetric])
+apply (simp add: Rep_compact_approx)
+done
+
+lemma finite_range_compact_approx: "finite (range (compact_approx n))"
+apply (cut_tac n=n in finite_fixes_compact_approx)
+apply (simp add: idem_fixes_eq_range compact_approx_idem)
+apply (simp add: image_def)
+done
+
+interpretation compact_basis:
+  bifinite_basis [compact_le Rep_compact_basis compacts compact_approx]
+apply unfold_locales
+apply (rule ideal_compacts)
+apply (rule cont_compacts)
+apply (rule compacts_Rep_compact_basis)
+apply (erule compacts_lessD)
+apply (rule compact_approx_le)
+apply (rule compact_approx_idem)
+apply (erule compact_approx_mono)
+apply (rule compact_approx_mono1, simp)
+apply (rule finite_range_compact_approx)
+apply (rule ex_compact_approx_eq)
+done
+
+
+subsection {* A compact basis for powerdomains *}
+
+typedef 'a pd_basis =
+  "{S::'a::bifinite compact_basis set. finite S \<and> S \<noteq> {}}"
+by (rule_tac x="{arbitrary}" in exI, simp)
+
+lemma finite_Rep_pd_basis [simp]: "finite (Rep_pd_basis u)"
+by (insert Rep_pd_basis [of u, unfolded pd_basis_def]) simp
+
+lemma Rep_pd_basis_nonempty [simp]: "Rep_pd_basis u \<noteq> {}"
+by (insert Rep_pd_basis [of u, unfolded pd_basis_def]) simp
+
+text {* unit and plus *}
+
+definition
+  PDUnit :: "'a compact_basis \<Rightarrow> 'a pd_basis" where
+  "PDUnit = (\<lambda>x. Abs_pd_basis {x})"
+
+definition
+  PDPlus :: "'a pd_basis \<Rightarrow> 'a pd_basis \<Rightarrow> 'a pd_basis" where
+  "PDPlus t u = Abs_pd_basis (Rep_pd_basis t \<union> Rep_pd_basis u)"
+
+lemma Rep_PDUnit:
+  "Rep_pd_basis (PDUnit x) = {x}"
+unfolding PDUnit_def by (rule Abs_pd_basis_inverse) (simp add: pd_basis_def)
+
+lemma Rep_PDPlus:
+  "Rep_pd_basis (PDPlus u v) = Rep_pd_basis u \<union> Rep_pd_basis v"
+unfolding PDPlus_def by (rule Abs_pd_basis_inverse) (simp add: pd_basis_def)
+
+lemma PDUnit_inject [simp]: "(PDUnit a = PDUnit b) = (a = b)"
+unfolding Rep_pd_basis_inject [symmetric] Rep_PDUnit by simp
+
+lemma PDPlus_assoc: "PDPlus (PDPlus t u) v = PDPlus t (PDPlus u v)"
+unfolding Rep_pd_basis_inject [symmetric] Rep_PDPlus by (rule Un_assoc)
+
+lemma PDPlus_commute: "PDPlus t u = PDPlus u t"
+unfolding Rep_pd_basis_inject [symmetric] Rep_PDPlus by (rule Un_commute)
+
+lemma PDPlus_absorb: "PDPlus t t = t"
+unfolding Rep_pd_basis_inject [symmetric] Rep_PDPlus by (rule Un_absorb)
+
+lemma pd_basis_induct1:
+  assumes PDUnit: "\<And>a. P (PDUnit a)"
+  assumes PDPlus: "\<And>a t. P t \<Longrightarrow> P (PDPlus (PDUnit a) t)"
+  shows "P x"
+apply (induct x, unfold pd_basis_def, clarify)
+apply (erule (1) finite_ne_induct)
+apply (cut_tac a=x in PDUnit)
+apply (simp add: PDUnit_def)
+apply (drule_tac a=x in PDPlus)
+apply (simp add: PDUnit_def PDPlus_def Abs_pd_basis_inverse [unfolded pd_basis_def])
+done
+
+lemma pd_basis_induct:
+  assumes PDUnit: "\<And>a. P (PDUnit a)"
+  assumes PDPlus: "\<And>t u. \<lbrakk>P t; P u\<rbrakk> \<Longrightarrow> P (PDPlus t u)"
+  shows "P x"
+apply (induct x rule: pd_basis_induct1)
+apply (rule PDUnit, erule PDPlus [OF PDUnit])
+done
+
+text {* fold-pd *}
+
+definition
+  fold_pd ::
+    "('a compact_basis \<Rightarrow> 'b::type) \<Rightarrow> ('b \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> 'a pd_basis \<Rightarrow> 'b"
+  where "fold_pd g f t = fold1 f (g ` Rep_pd_basis t)"
+
+lemma (in ACIf) fold_pd_PDUnit:
+  "fold_pd g f (PDUnit x) = g x"
+unfolding fold_pd_def Rep_PDUnit by simp
+
+lemma (in ACIf) fold_pd_PDPlus:
+  "fold_pd g f (PDPlus t u) = f (fold_pd g f t) (fold_pd g f u)"
+unfolding fold_pd_def Rep_PDPlus by (simp add: image_Un fold1_Un2)
+
+text {* approx-pd *}
+
+definition
+  approx_pd :: "nat \<Rightarrow> 'a pd_basis \<Rightarrow> 'a pd_basis" where
+  "approx_pd n = (\<lambda>t. Abs_pd_basis (compact_approx n ` Rep_pd_basis t))"
+
+lemma Rep_approx_pd:
+  "Rep_pd_basis (approx_pd n t) = compact_approx n ` Rep_pd_basis t"
+unfolding approx_pd_def
+apply (rule Abs_pd_basis_inverse)
+apply (simp add: pd_basis_def)
+done
+
+lemma approx_pd_simps [simp]:
+  "approx_pd n (PDUnit a) = PDUnit (compact_approx n a)"
+  "approx_pd n (PDPlus t u) = PDPlus (approx_pd n t) (approx_pd n u)"
+apply (simp_all add: Rep_pd_basis_inject [symmetric])
+apply (simp_all add: Rep_approx_pd Rep_PDUnit Rep_PDPlus image_Un)
+done
+
+lemma approx_pd_idem: "approx_pd n (approx_pd n t) = approx_pd n t"
+apply (induct t rule: pd_basis_induct)
+apply (simp add: compact_approx_idem)
+apply simp
+done
+
+lemma range_image_f: "range (image f) = Pow (range f)"
+apply (safe, fast)
+apply (rule_tac x="f -` x" in range_eqI)
+apply (simp, fast)
+done
+
+lemma finite_range_approx_pd: "finite (range (approx_pd n))"
+apply (subgoal_tac "finite (Rep_pd_basis ` range (approx_pd n))")
+apply (erule finite_imageD)
+apply (rule inj_onI, simp add: Rep_pd_basis_inject)
+apply (subst image_image)
+apply (subst Rep_approx_pd)
+apply (simp only: range_composition)
+apply (rule finite_subset [OF image_mono [OF subset_UNIV]])
+apply (simp add: range_image_f)
+apply (rule finite_range_compact_approx)
+done
+
+lemma ex_approx_pd_eq: "\<exists>n. approx_pd n t = t"
+apply (subgoal_tac "\<exists>n. \<forall>m\<ge>n. approx_pd m t = t", fast)
+apply (induct t rule: pd_basis_induct)
+apply (cut_tac a=a in ex_compact_approx_eq)
+apply (clarify, rule_tac x=n in exI)
+apply (clarify, simp)
+apply (rule compact_le_antisym)
+apply (rule compact_approx_le)
+apply (drule_tac a=a in compact_approx_mono1)
+apply simp
+apply (clarify, rename_tac i j)
+apply (rule_tac x="max i j" in exI, simp)
+done
+
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOLCF/ConvexPD.thy	Mon Jan 14 19:26:41 2008 +0100
@@ -0,0 +1,630 @@
+(*  Title:      HOLCF/ConvexPD.thy
+    ID:         $Id$
+    Author:     Brian Huffman
+*)
+
+header {* Convex powerdomain *}
+
+theory ConvexPD
+imports UpperPD LowerPD
+begin
+
+subsection {* Basis preorder *}
+
+definition
+  convex_le :: "'a pd_basis \<Rightarrow> 'a pd_basis \<Rightarrow> bool" (infix "\<le>\<natural>" 50) where
+  "convex_le = (\<lambda>u v. u \<le>\<sharp> v \<and> u \<le>\<flat> v)"
+
+lemma convex_le_refl [simp]: "t \<le>\<natural> t"
+unfolding convex_le_def by (fast intro: upper_le_refl lower_le_refl)
+
+lemma convex_le_trans: "\<lbrakk>t \<le>\<natural> u; u \<le>\<natural> v\<rbrakk> \<Longrightarrow> t \<le>\<natural> v"
+unfolding convex_le_def by (fast intro: upper_le_trans lower_le_trans)
+
+interpretation convex_le: preorder [convex_le]
+by (rule preorder.intro, rule convex_le_refl, rule convex_le_trans)
+
+lemma upper_le_minimal [simp]: "PDUnit compact_bot \<le>\<natural> t"
+unfolding convex_le_def Rep_PDUnit by simp
+
+lemma PDUnit_convex_mono: "compact_le x y \<Longrightarrow> PDUnit x \<le>\<natural> PDUnit y"
+unfolding convex_le_def by (fast intro: PDUnit_upper_mono PDUnit_lower_mono)
+
+lemma PDPlus_convex_mono: "\<lbrakk>s \<le>\<natural> t; u \<le>\<natural> v\<rbrakk> \<Longrightarrow> PDPlus s u \<le>\<natural> PDPlus t v"
+unfolding convex_le_def by (fast intro: PDPlus_upper_mono PDPlus_lower_mono)
+
+lemma convex_le_PDUnit_PDUnit_iff [simp]:
+  "(PDUnit a \<le>\<natural> PDUnit b) = compact_le a b"
+unfolding convex_le_def upper_le_def lower_le_def Rep_PDUnit by fast
+
+lemma convex_le_PDUnit_lemma1:
+  "(PDUnit a \<le>\<natural> t) = (\<forall>b\<in>Rep_pd_basis t. compact_le a b)"
+unfolding convex_le_def upper_le_def lower_le_def Rep_PDUnit
+using Rep_pd_basis_nonempty [of t, folded ex_in_conv] by fast
+
+lemma convex_le_PDUnit_PDPlus_iff [simp]:
+  "(PDUnit a \<le>\<natural> PDPlus t u) = (PDUnit a \<le>\<natural> t \<and> PDUnit a \<le>\<natural> u)"
+unfolding convex_le_PDUnit_lemma1 Rep_PDPlus by fast
+
+lemma convex_le_PDUnit_lemma2:
+  "(t \<le>\<natural> PDUnit b) = (\<forall>a\<in>Rep_pd_basis t. compact_le a b)"
+unfolding convex_le_def upper_le_def lower_le_def Rep_PDUnit
+using Rep_pd_basis_nonempty [of t, folded ex_in_conv] by fast
+
+lemma convex_le_PDPlus_PDUnit_iff [simp]:
+  "(PDPlus t u \<le>\<natural> PDUnit a) = (t \<le>\<natural> PDUnit a \<and> u \<le>\<natural> PDUnit a)"
+unfolding convex_le_PDUnit_lemma2 Rep_PDPlus by fast
+
+lemma convex_le_PDPlus_lemma:
+  assumes z: "PDPlus t u \<le>\<natural> z"
+  shows "\<exists>v w. z = PDPlus v w \<and> t \<le>\<natural> v \<and> u \<le>\<natural> w"
+proof (intro exI conjI)
+  let ?A = "{b\<in>Rep_pd_basis z. \<exists>a\<in>Rep_pd_basis t. compact_le a b}"
+  let ?B = "{b\<in>Rep_pd_basis z. \<exists>a\<in>Rep_pd_basis u. compact_le a b}"
+  let ?v = "Abs_pd_basis ?A"
+  let ?w = "Abs_pd_basis ?B"
+  have Rep_v: "Rep_pd_basis ?v = ?A"
+    apply (rule Abs_pd_basis_inverse)
+    apply (rule Rep_pd_basis_nonempty [of t, folded ex_in_conv, THEN exE])
+    apply (cut_tac z, simp only: convex_le_def lower_le_def, clarify)
+    apply (drule_tac x=x in bspec, simp add: Rep_PDPlus, erule bexE)
+    apply (simp add: pd_basis_def)
+    apply fast
+    done
+  have Rep_w: "Rep_pd_basis ?w = ?B"
+    apply (rule Abs_pd_basis_inverse)
+    apply (rule Rep_pd_basis_nonempty [of u, folded ex_in_conv, THEN exE])
+    apply (cut_tac z, simp only: convex_le_def lower_le_def, clarify)
+    apply (drule_tac x=x in bspec, simp add: Rep_PDPlus, erule bexE)
+    apply (simp add: pd_basis_def)
+    apply fast
+    done
+  show "z = PDPlus ?v ?w"
+    apply (insert z)
+    apply (simp add: convex_le_def, erule conjE)
+    apply (simp add: Rep_pd_basis_inject [symmetric] Rep_PDPlus)
+    apply (simp add: Rep_v Rep_w)
+    apply (rule equalityI)
+     apply (rule subsetI)
+     apply (simp only: upper_le_def)
+     apply (drule (1) bspec, erule bexE)
+     apply (simp add: Rep_PDPlus)
+     apply fast
+    apply fast
+    done
+  show "t \<le>\<natural> ?v" "u \<le>\<natural> ?w"
+   apply (insert z)
+   apply (simp_all add: convex_le_def upper_le_def lower_le_def Rep_PDPlus Rep_v Rep_w)
+   apply fast+
+   done
+qed
+
+lemma convex_le_induct [induct set: convex_le]:
+  assumes le: "t \<le>\<natural> u"
+  assumes 2: "\<And>t u v. \<lbrakk>P t u; P u v\<rbrakk> \<Longrightarrow> P t v"
+  assumes 3: "\<And>a b. compact_le a b \<Longrightarrow> P (PDUnit a) (PDUnit b)"
+  assumes 4: "\<And>t u v w. \<lbrakk>P t v; P u w\<rbrakk> \<Longrightarrow> P (PDPlus t u) (PDPlus v w)"
+  shows "P t u"
+using le apply (induct t arbitrary: u rule: pd_basis_induct)
+apply (erule rev_mp)
+apply (induct_tac u rule: pd_basis_induct1)
+apply (simp add: 3)
+apply (simp, clarify, rename_tac a b t)
+apply (subgoal_tac "P (PDPlus (PDUnit a) (PDUnit a)) (PDPlus (PDUnit b) t)")
+apply (simp add: PDPlus_absorb)
+apply (erule (1) 4 [OF 3])
+apply (drule convex_le_PDPlus_lemma, clarify)
+apply (simp add: 4)
+done
+
+lemma approx_pd_convex_mono1:
+  "i \<le> j \<Longrightarrow> approx_pd i t \<le>\<natural> approx_pd j t"
+apply (induct t rule: pd_basis_induct)
+apply (simp add: compact_approx_mono1)
+apply (simp add: PDPlus_convex_mono)
+done
+
+lemma approx_pd_convex_le: "approx_pd i t \<le>\<natural> t"
+apply (induct t rule: pd_basis_induct)
+apply (simp add: compact_approx_le)
+apply (simp add: PDPlus_convex_mono)
+done
+
+lemma approx_pd_convex_mono:
+  "t \<le>\<natural> u \<Longrightarrow> approx_pd n t \<le>\<natural> approx_pd n u"
+apply (erule convex_le_induct)
+apply (erule (1) convex_le_trans)
+apply (simp add: compact_approx_mono)
+apply (simp add: PDPlus_convex_mono)
+done
+
+
+subsection {* Type definition *}
+
+cpodef (open) 'a convex_pd =
+  "{S::'a::bifinite pd_basis set. convex_le.ideal S}"
+apply (simp add: convex_le.adm_ideal)
+apply (fast intro: convex_le.ideal_principal)
+done
+
+lemma ideal_Rep_convex_pd: "convex_le.ideal (Rep_convex_pd xs)"
+by (rule Rep_convex_pd [simplified])
+
+lemma Rep_convex_pd_mono: "xs \<sqsubseteq> ys \<Longrightarrow> Rep_convex_pd xs \<subseteq> Rep_convex_pd ys"
+unfolding less_convex_pd_def less_set_def .
+
+
+subsection {* Principal ideals *}
+
+definition
+  convex_principal :: "'a pd_basis \<Rightarrow> 'a convex_pd" where
+  "convex_principal t = Abs_convex_pd {u. u \<le>\<natural> t}"
+
+lemma Rep_convex_principal:
+  "Rep_convex_pd (convex_principal t) = {u. u \<le>\<natural> t}"
+unfolding convex_principal_def
+apply (rule Abs_convex_pd_inverse [simplified])
+apply (rule convex_le.ideal_principal)
+done
+
+interpretation convex_pd:
+  bifinite_basis [convex_le convex_principal Rep_convex_pd approx_pd]
+apply unfold_locales
+apply (rule ideal_Rep_convex_pd)
+apply (rule cont_Rep_convex_pd)
+apply (rule Rep_convex_principal)
+apply (simp only: less_convex_pd_def less_set_def)
+apply (rule approx_pd_convex_le)
+apply (rule approx_pd_idem)
+apply (erule approx_pd_convex_mono)
+apply (rule approx_pd_convex_mono1, simp)
+apply (rule finite_range_approx_pd)
+apply (rule ex_approx_pd_eq)
+done
+
+lemma convex_principal_less_iff [simp]:
+  "(convex_principal t \<sqsubseteq> convex_principal u) = (t \<le>\<natural> u)"
+unfolding less_convex_pd_def Rep_convex_principal less_set_def
+by (fast intro: convex_le_refl elim: convex_le_trans)
+
+lemma convex_principal_mono:
+  "t \<le>\<natural> u \<Longrightarrow> convex_principal t \<sqsubseteq> convex_principal u"
+by (rule convex_principal_less_iff [THEN iffD2])
+
+lemma compact_convex_principal: "compact (convex_principal t)"
+by (rule convex_pd.compact_principal)
+
+lemma convex_pd_minimal: "convex_principal (PDUnit compact_bot) \<sqsubseteq> ys"
+by (induct ys rule: convex_pd.principal_induct, simp, simp)
+
+instance convex_pd :: (bifinite) pcpo
+by (intro_classes, fast intro: convex_pd_minimal)
+
+lemma inst_convex_pd_pcpo: "\<bottom> = convex_principal (PDUnit compact_bot)"
+by (rule convex_pd_minimal [THEN UU_I, symmetric])
+
+
+subsection {* Approximation *}
+
+instance convex_pd :: (bifinite) approx ..
+
+defs (overloaded)
+  approx_convex_pd_def:
+    "approx \<equiv> (\<lambda>n. convex_pd.basis_fun (\<lambda>t. convex_principal (approx_pd n t)))"
+
+lemma approx_convex_principal [simp]:
+  "approx n\<cdot>(convex_principal t) = convex_principal (approx_pd n t)"
+unfolding approx_convex_pd_def
+apply (rule convex_pd.basis_fun_principal)
+apply (erule convex_principal_mono [OF approx_pd_convex_mono])
+done
+
+lemma chain_approx_convex_pd:
+  "chain (approx :: nat \<Rightarrow> 'a convex_pd \<rightarrow> 'a convex_pd)"
+unfolding approx_convex_pd_def
+by (rule convex_pd.chain_basis_fun_take)
+
+lemma lub_approx_convex_pd:
+  "(\<Squnion>i. approx i\<cdot>xs) = (xs::'a convex_pd)"
+unfolding approx_convex_pd_def
+by (rule convex_pd.lub_basis_fun_take)
+
+lemma approx_convex_pd_idem:
+  "approx n\<cdot>(approx n\<cdot>xs) = approx n\<cdot>(xs::'a convex_pd)"
+apply (induct xs rule: convex_pd.principal_induct, simp)
+apply (simp add: approx_pd_idem)
+done
+
+lemma approx_eq_convex_principal:
+  "\<exists>t\<in>Rep_convex_pd xs. approx n\<cdot>xs = convex_principal (approx_pd n t)"
+unfolding approx_convex_pd_def
+by (rule convex_pd.basis_fun_take_eq_principal)
+
+lemma finite_fixes_approx_convex_pd:
+  "finite {xs::'a convex_pd. approx n\<cdot>xs = xs}"
+unfolding approx_convex_pd_def
+by (rule convex_pd.finite_fixes_basis_fun_take)
+
+instance convex_pd :: (bifinite) bifinite
+apply intro_classes
+apply (simp add: chain_approx_convex_pd)
+apply (rule lub_approx_convex_pd)
+apply (rule approx_convex_pd_idem)
+apply (rule finite_fixes_approx_convex_pd)
+done
+
+lemma compact_imp_convex_principal:
+  "compact xs \<Longrightarrow> \<exists>t. xs = convex_principal t"
+apply (drule bifinite_compact_eq_approx)
+apply (erule exE)
+apply (erule subst)
+apply (cut_tac n=i and xs=xs in approx_eq_convex_principal)
+apply fast
+done
+
+lemma convex_principal_induct:
+  "\<lbrakk>adm P; \<And>t. P (convex_principal t)\<rbrakk> \<Longrightarrow> P xs"
+apply (erule approx_induct, rename_tac xs)
+apply (cut_tac n=n and xs=xs in approx_eq_convex_principal)
+apply (clarify, simp)
+done
+
+lemma convex_principal_induct2:
+  "\<lbrakk>\<And>ys. adm (\<lambda>xs. P xs ys); \<And>xs. adm (\<lambda>ys. P xs ys);
+    \<And>t u. P (convex_principal t) (convex_principal u)\<rbrakk> \<Longrightarrow> P xs ys"
+apply (rule_tac x=ys in spec)
+apply (rule_tac xs=xs in convex_principal_induct, simp)
+apply (rule allI, rename_tac ys)
+apply (rule_tac xs=ys in convex_principal_induct, simp)
+apply simp
+done
+
+
+subsection {* Monadic unit *}
+
+definition
+  convex_unit :: "'a \<rightarrow> 'a convex_pd" where
+  "convex_unit = compact_basis.basis_fun (\<lambda>a. convex_principal (PDUnit a))"
+
+lemma convex_unit_Rep_compact_basis [simp]:
+  "convex_unit\<cdot>(Rep_compact_basis a) = convex_principal (PDUnit a)"
+unfolding convex_unit_def
+apply (rule compact_basis.basis_fun_principal)
+apply (rule convex_principal_mono)
+apply (erule PDUnit_convex_mono)
+done
+
+lemma convex_unit_strict [simp]: "convex_unit\<cdot>\<bottom> = \<bottom>"
+unfolding inst_convex_pd_pcpo Rep_compact_bot [symmetric] by simp
+
+lemma approx_convex_unit [simp]:
+  "approx n\<cdot>(convex_unit\<cdot>x) = convex_unit\<cdot>(approx n\<cdot>x)"
+apply (induct x rule: compact_basis_induct, simp)
+apply (simp add: approx_Rep_compact_basis)
+done
+
+lemma convex_unit_less_iff [simp]:
+  "(convex_unit\<cdot>x \<sqsubseteq> convex_unit\<cdot>y) = (x \<sqsubseteq> y)"
+ apply (rule iffI)
+  apply (rule bifinite_less_ext)
+  apply (drule_tac f="approx i" in monofun_cfun_arg, simp)
+  apply (cut_tac x="approx i\<cdot>x" in compact_imp_Rep_compact_basis, simp)
+  apply (cut_tac x="approx i\<cdot>y" in compact_imp_Rep_compact_basis, simp)
+  apply (clarify, simp add: compact_le_def)
+ apply (erule monofun_cfun_arg)
+done
+
+lemma convex_unit_eq_iff [simp]:
+  "(convex_unit\<cdot>x = convex_unit\<cdot>y) = (x = y)"
+unfolding po_eq_conv by simp
+
+lemma convex_unit_strict_iff [simp]: "(convex_unit\<cdot>x = \<bottom>) = (x = \<bottom>)"
+unfolding convex_unit_strict [symmetric] by (rule convex_unit_eq_iff)
+
+lemma compact_convex_unit_iff [simp]:
+  "compact (convex_unit\<cdot>x) = compact x"
+unfolding bifinite_compact_iff by simp
+
+
+subsection {* Monadic plus *}
+
+definition
+  convex_plus :: "'a convex_pd \<rightarrow> 'a convex_pd \<rightarrow> 'a convex_pd" where
+  "convex_plus = convex_pd.basis_fun (\<lambda>t. convex_pd.basis_fun (\<lambda>u.
+      convex_principal (PDPlus t u)))"
+
+abbreviation
+  convex_add :: "'a convex_pd \<Rightarrow> 'a convex_pd \<Rightarrow> 'a convex_pd"
+    (infixl "+\<natural>" 65) where
+  "xs +\<natural> ys == convex_plus\<cdot>xs\<cdot>ys"
+
+lemma convex_plus_principal [simp]:
+  "convex_plus\<cdot>(convex_principal t)\<cdot>(convex_principal u) =
+   convex_principal (PDPlus t u)"
+unfolding convex_plus_def
+by (simp add: convex_pd.basis_fun_principal
+    convex_pd.basis_fun_mono PDPlus_convex_mono)
+
+lemma approx_convex_plus [simp]:
+  "approx n\<cdot>(convex_plus\<cdot>xs\<cdot>ys) = convex_plus\<cdot>(approx n\<cdot>xs)\<cdot>(approx n\<cdot>ys)"
+by (induct xs ys rule: convex_principal_induct2, simp, simp, simp)
+
+lemma convex_plus_commute: "convex_plus\<cdot>xs\<cdot>ys = convex_plus\<cdot>ys\<cdot>xs"
+apply (induct xs ys rule: convex_principal_induct2, simp, simp)
+apply (simp add: PDPlus_commute)
+done
+
+lemma convex_plus_assoc:
+  "convex_plus\<cdot>(convex_plus\<cdot>xs\<cdot>ys)\<cdot>zs = convex_plus\<cdot>xs\<cdot>(convex_plus\<cdot>ys\<cdot>zs)"
+apply (induct xs ys arbitrary: zs rule: convex_principal_induct2, simp, simp)
+apply (rule_tac xs=zs in convex_principal_induct, simp)
+apply (simp add: PDPlus_assoc)
+done
+
+lemma convex_plus_absorb: "convex_plus\<cdot>xs\<cdot>xs = xs"
+apply (induct xs rule: convex_principal_induct, simp)
+apply (simp add: PDPlus_absorb)
+done
+
+lemma convex_unit_less_plus_iff [simp]:
+  "(convex_unit\<cdot>x \<sqsubseteq> convex_plus\<cdot>ys\<cdot>zs) =
+   (convex_unit\<cdot>x \<sqsubseteq> ys \<and> convex_unit\<cdot>x \<sqsubseteq> zs)"
+ apply (rule iffI)
+  apply (subgoal_tac
+    "adm (\<lambda>f. f\<cdot>(convex_unit\<cdot>x) \<sqsubseteq> f\<cdot>ys \<and> f\<cdot>(convex_unit\<cdot>x) \<sqsubseteq> f\<cdot>zs)")
+   apply (drule admD [rule_format], rule chain_approx)
+    apply (drule_tac f="approx i" in monofun_cfun_arg)
+    apply (cut_tac x="approx i\<cdot>x" in compact_imp_Rep_compact_basis, simp)
+    apply (cut_tac xs="approx i\<cdot>ys" in compact_imp_convex_principal, simp)
+    apply (cut_tac xs="approx i\<cdot>zs" in compact_imp_convex_principal, simp)
+    apply (clarify, simp)
+   apply simp
+  apply simp
+ apply (erule conjE)
+ apply (subst convex_plus_absorb [of "convex_unit\<cdot>x", symmetric])
+ apply (erule (1) monofun_cfun [OF monofun_cfun_arg])
+done
+
+lemma convex_plus_less_unit_iff [simp]:
+  "(convex_plus\<cdot>xs\<cdot>ys \<sqsubseteq> convex_unit\<cdot>z) =
+   (xs \<sqsubseteq> convex_unit\<cdot>z \<and> ys \<sqsubseteq> convex_unit\<cdot>z)"
+ apply (rule iffI)
+  apply (subgoal_tac
+    "adm (\<lambda>f. f\<cdot>xs \<sqsubseteq> f\<cdot>(convex_unit\<cdot>z) \<and> f\<cdot>ys \<sqsubseteq> f\<cdot>(convex_unit\<cdot>z))")
+   apply (drule admD [rule_format], rule chain_approx)
+    apply (drule_tac f="approx i" in monofun_cfun_arg)
+    apply (cut_tac xs="approx i\<cdot>xs" in compact_imp_convex_principal, simp)
+    apply (cut_tac xs="approx i\<cdot>ys" in compact_imp_convex_principal, simp)
+    apply (cut_tac x="approx i\<cdot>z" in compact_imp_Rep_compact_basis, simp)
+    apply (clarify, simp)
+   apply simp
+  apply simp
+ apply (erule conjE)
+ apply (subst convex_plus_absorb [of "convex_unit\<cdot>z", symmetric])
+ apply (erule (1) monofun_cfun [OF monofun_cfun_arg])
+done
+
+
+subsection {* Induction rules *}
+
+lemma convex_pd_induct1:
+  assumes P: "adm P"
+  assumes unit: "\<And>x. P (convex_unit\<cdot>x)"
+  assumes insert:
+    "\<And>x ys. \<lbrakk>P (convex_unit\<cdot>x); P ys\<rbrakk> \<Longrightarrow> P (convex_plus\<cdot>(convex_unit\<cdot>x)\<cdot>ys)"
+  shows "P (xs::'a convex_pd)"
+apply (induct xs rule: convex_principal_induct, rule P)
+apply (induct_tac t rule: pd_basis_induct1)
+apply (simp only: convex_unit_Rep_compact_basis [symmetric])
+apply (rule unit)
+apply (simp only: convex_unit_Rep_compact_basis [symmetric]
+                  convex_plus_principal [symmetric])
+apply (erule insert [OF unit])
+done
+
+lemma convex_pd_induct:
+  assumes P: "adm P"
+  assumes unit: "\<And>x. P (convex_unit\<cdot>x)"
+  assumes plus: "\<And>xs ys. \<lbrakk>P xs; P ys\<rbrakk> \<Longrightarrow> P (convex_plus\<cdot>xs\<cdot>ys)"
+  shows "P (xs::'a convex_pd)"
+apply (induct xs rule: convex_principal_induct, rule P)
+apply (induct_tac t rule: pd_basis_induct)
+apply (simp only: convex_unit_Rep_compact_basis [symmetric] unit)
+apply (simp only: convex_plus_principal [symmetric] plus)
+done
+
+
+subsection {* Monadic bind *}
+
+definition
+  convex_bind_basis ::
+  "'a pd_basis \<Rightarrow> ('a \<rightarrow> 'b convex_pd) \<rightarrow> 'b convex_pd" where
+  "convex_bind_basis = fold_pd
+    (\<lambda>a. \<Lambda> f. f\<cdot>(Rep_compact_basis a))
+    (\<lambda>x y. \<Lambda> f. convex_plus\<cdot>(x\<cdot>f)\<cdot>(y\<cdot>f))"
+
+lemma ACI_convex_bind: "ACIf (\<lambda>x y. \<Lambda> f. convex_plus\<cdot>(x\<cdot>f)\<cdot>(y\<cdot>f))"
+apply unfold_locales
+apply (simp add: convex_plus_commute)
+apply (simp add: convex_plus_assoc)
+apply (simp add: convex_plus_absorb eta_cfun)
+done
+
+lemma convex_bind_basis_simps [simp]:
+  "convex_bind_basis (PDUnit a) =
+    (\<Lambda> f. f\<cdot>(Rep_compact_basis a))"
+  "convex_bind_basis (PDPlus t u) =
+    (\<Lambda> f. convex_plus\<cdot>(convex_bind_basis t\<cdot>f)\<cdot>(convex_bind_basis u\<cdot>f))"
+unfolding convex_bind_basis_def
+apply -
+apply (rule ACIf.fold_pd_PDUnit [OF ACI_convex_bind])
+apply (rule ACIf.fold_pd_PDPlus [OF ACI_convex_bind])
+done
+
+lemma monofun_LAM:
+  "\<lbrakk>cont f; cont g; \<And>x. f x \<sqsubseteq> g x\<rbrakk> \<Longrightarrow> (\<Lambda> x. f x) \<sqsubseteq> (\<Lambda> x. g x)"
+by (simp add: expand_cfun_less)
+
+lemma convex_bind_basis_mono:
+  "t \<le>\<natural> u \<Longrightarrow> convex_bind_basis t \<sqsubseteq> convex_bind_basis u"
+apply (erule convex_le_induct)
+apply (erule (1) trans_less)
+apply (simp add: monofun_LAM compact_le_def monofun_cfun)
+apply (simp add: monofun_LAM compact_le_def monofun_cfun)
+done
+
+definition
+  convex_bind :: "'a convex_pd \<rightarrow> ('a \<rightarrow> 'b convex_pd) \<rightarrow> 'b convex_pd" where
+  "convex_bind = convex_pd.basis_fun convex_bind_basis"
+
+lemma convex_bind_principal [simp]:
+  "convex_bind\<cdot>(convex_principal t) = convex_bind_basis t"
+unfolding convex_bind_def
+apply (rule convex_pd.basis_fun_principal)
+apply (erule convex_bind_basis_mono)
+done
+
+lemma convex_bind_unit [simp]:
+  "convex_bind\<cdot>(convex_unit\<cdot>x)\<cdot>f = f\<cdot>x"
+by (induct x rule: compact_basis_induct, simp, simp)
+
+lemma convex_bind_plus [simp]:
+  "convex_bind\<cdot>(convex_plus\<cdot>xs\<cdot>ys)\<cdot>f =
+   convex_plus\<cdot>(convex_bind\<cdot>xs\<cdot>f)\<cdot>(convex_bind\<cdot>ys\<cdot>f)"
+by (induct xs ys rule: convex_principal_induct2, simp, simp, simp)
+
+lemma convex_bind_strict [simp]: "convex_bind\<cdot>\<bottom>\<cdot>f = f\<cdot>\<bottom>"
+unfolding convex_unit_strict [symmetric] by (rule convex_bind_unit)
+
+
+subsection {* Map and join *}
+
+definition
+  convex_map :: "('a \<rightarrow> 'b) \<rightarrow> 'a convex_pd \<rightarrow> 'b convex_pd" where
+  "convex_map = (\<Lambda> f xs. convex_bind\<cdot>xs\<cdot>(\<Lambda> x. convex_unit\<cdot>(f\<cdot>x)))"
+
+definition
+  convex_join :: "'a convex_pd convex_pd \<rightarrow> 'a convex_pd" where
+  "convex_join = (\<Lambda> xss. convex_bind\<cdot>xss\<cdot>(\<Lambda> xs. xs))"
+
+lemma convex_map_unit [simp]:
+  "convex_map\<cdot>f\<cdot>(convex_unit\<cdot>x) = convex_unit\<cdot>(f\<cdot>x)"
+unfolding convex_map_def by simp
+
+lemma convex_map_plus [simp]:
+  "convex_map\<cdot>f\<cdot>(convex_plus\<cdot>xs\<cdot>ys) =
+   convex_plus\<cdot>(convex_map\<cdot>f\<cdot>xs)\<cdot>(convex_map\<cdot>f\<cdot>ys)"
+unfolding convex_map_def by simp
+
+lemma convex_join_unit [simp]:
+  "convex_join\<cdot>(convex_unit\<cdot>xs) = xs"
+unfolding convex_join_def by simp
+
+lemma convex_join_plus [simp]:
+  "convex_join\<cdot>(convex_plus\<cdot>xss\<cdot>yss) =
+   convex_plus\<cdot>(convex_join\<cdot>xss)\<cdot>(convex_join\<cdot>yss)"
+unfolding convex_join_def by simp
+
+lemma convex_map_ident: "convex_map\<cdot>(\<Lambda> x. x)\<cdot>xs = xs"
+by (induct xs rule: convex_pd_induct, simp_all)
+
+lemma convex_map_map:
+  "convex_map\<cdot>f\<cdot>(convex_map\<cdot>g\<cdot>xs) = convex_map\<cdot>(\<Lambda> x. f\<cdot>(g\<cdot>x))\<cdot>xs"
+by (induct xs rule: convex_pd_induct, simp_all)
+
+lemma convex_join_map_unit:
+  "convex_join\<cdot>(convex_map\<cdot>convex_unit\<cdot>xs) = xs"
+by (induct xs rule: convex_pd_induct, simp_all)
+
+lemma convex_join_map_join:
+  "convex_join\<cdot>(convex_map\<cdot>convex_join\<cdot>xsss) = convex_join\<cdot>(convex_join\<cdot>xsss)"
+by (induct xsss rule: convex_pd_induct, simp_all)
+
+lemma convex_join_map_map:
+  "convex_join\<cdot>(convex_map\<cdot>(convex_map\<cdot>f)\<cdot>xss) =
+   convex_map\<cdot>f\<cdot>(convex_join\<cdot>xss)"
+by (induct xss rule: convex_pd_induct, simp_all)
+
+lemma convex_map_approx: "convex_map\<cdot>(approx n)\<cdot>xs = approx n\<cdot>xs"
+by (induct xs rule: convex_pd_induct, simp_all)
+
+
+subsection {* Conversions to other powerdomains *}
+
+text {* Convex to upper *}
+
+lemma convex_le_imp_upper_le: "t \<le>\<natural> u \<Longrightarrow> t \<le>\<sharp> u"
+unfolding convex_le_def by simp
+
+definition
+  convex_to_upper :: "'a convex_pd \<rightarrow> 'a upper_pd" where
+  "convex_to_upper = convex_pd.basis_fun upper_principal"
+
+lemma convex_to_upper_principal [simp]:
+  "convex_to_upper\<cdot>(convex_principal t) = upper_principal t"
+unfolding convex_to_upper_def
+apply (rule convex_pd.basis_fun_principal)
+apply (rule upper_principal_mono)
+apply (erule convex_le_imp_upper_le)
+done
+
+lemma convex_to_upper_unit [simp]:
+  "convex_to_upper\<cdot>(convex_unit\<cdot>x) = upper_unit\<cdot>x"
+by (induct x rule: compact_basis_induct, simp, simp)
+
+lemma convex_to_upper_plus [simp]:
+  "convex_to_upper\<cdot>(convex_plus\<cdot>xs\<cdot>ys) =
+   upper_plus\<cdot>(convex_to_upper\<cdot>xs)\<cdot>(convex_to_upper\<cdot>ys)"
+by (induct xs ys rule: convex_principal_induct2, simp, simp, simp)
+
+lemma approx_convex_to_upper:
+  "approx i\<cdot>(convex_to_upper\<cdot>xs) = convex_to_upper\<cdot>(approx i\<cdot>xs)"
+by (induct xs rule: convex_pd_induct, simp, simp, simp)
+
+text {* Convex to lower *}
+
+lemma convex_le_imp_lower_le: "t \<le>\<natural> u \<Longrightarrow> t \<le>\<flat> u"
+unfolding convex_le_def by simp
+
+definition
+  convex_to_lower :: "'a convex_pd \<rightarrow> 'a lower_pd" where
+  "convex_to_lower = convex_pd.basis_fun lower_principal"
+
+lemma convex_to_lower_principal [simp]:
+  "convex_to_lower\<cdot>(convex_principal t) = lower_principal t"
+unfolding convex_to_lower_def
+apply (rule convex_pd.basis_fun_principal)
+apply (rule lower_principal_mono)
+apply (erule convex_le_imp_lower_le)
+done
+
+lemma convex_to_lower_unit [simp]:
+  "convex_to_lower\<cdot>(convex_unit\<cdot>x) = lower_unit\<cdot>x"
+by (induct x rule: compact_basis_induct, simp, simp)
+
+lemma convex_to_lower_plus [simp]:
+  "convex_to_lower\<cdot>(convex_plus\<cdot>xs\<cdot>ys) =
+   lower_plus\<cdot>(convex_to_lower\<cdot>xs)\<cdot>(convex_to_lower\<cdot>ys)"
+by (induct xs ys rule: convex_principal_induct2, simp, simp, simp)
+
+lemma approx_convex_to_lower:
+  "approx i\<cdot>(convex_to_lower\<cdot>xs) = convex_to_lower\<cdot>(approx i\<cdot>xs)"
+by (induct xs rule: convex_pd_induct, simp, simp, simp)
+
+text {* Ordering property *}
+
+lemma convex_pd_less_iff:
+  "(xs \<sqsubseteq> ys) =
+    (convex_to_upper\<cdot>xs \<sqsubseteq> convex_to_upper\<cdot>ys \<and>
+     convex_to_lower\<cdot>xs \<sqsubseteq> convex_to_lower\<cdot>ys)"
+ apply (safe elim!: monofun_cfun_arg)
+ apply (rule bifinite_less_ext)
+ apply (drule_tac f="approx i" in monofun_cfun_arg)
+ apply (drule_tac f="approx i" in monofun_cfun_arg)
+ apply (cut_tac xs="approx i\<cdot>xs" in compact_imp_convex_principal, simp)
+ apply (cut_tac xs="approx i\<cdot>ys" in compact_imp_convex_principal, simp)
+ apply clarify
+ apply (simp add: approx_convex_to_upper approx_convex_to_lower convex_le_def)
+done
+
+end
--- a/src/HOLCF/HOLCF.thy	Mon Jan 14 19:26:01 2008 +0100
+++ b/src/HOLCF/HOLCF.thy	Mon Jan 14 19:26:41 2008 +0100
@@ -6,7 +6,7 @@
 *)
 
 theory HOLCF
-imports Sprod Ssum Up Lift Discrete One Tr Domain Main
+imports Sprod Ssum Up Lift Discrete One Tr Domain ConvexPD Main
 uses
   "holcf_logic.ML"
   "Tools/cont_consts.ML"
@@ -19,6 +19,8 @@
 
 begin
 
+defaultsort pcpo
+
 ML_setup {*
   change_simpset (fn simpset => simpset addSolver
     (mk_solver' "adm_tac" (fn ss =>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOLCF/LowerPD.thy	Mon Jan 14 19:26:41 2008 +0100
@@ -0,0 +1,538 @@
+(*  Title:      HOLCF/LowerPD.thy
+    ID:         $Id$
+    Author:     Brian Huffman
+*)
+
+header {* Lower powerdomain *}
+
+theory LowerPD
+imports CompactBasis
+begin
+
+subsection {* Basis preorder *}
+
+definition
+  lower_le :: "'a pd_basis \<Rightarrow> 'a pd_basis \<Rightarrow> bool" (infix "\<le>\<flat>" 50) where
+  "lower_le = (\<lambda>u v. \<forall>x\<in>Rep_pd_basis u. \<exists>y\<in>Rep_pd_basis v. compact_le x y)"
+
+lemma lower_le_refl [simp]: "t \<le>\<flat> t"
+unfolding lower_le_def by (fast intro: compact_le_refl)
+
+lemma lower_le_trans: "\<lbrakk>t \<le>\<flat> u; u \<le>\<flat> v\<rbrakk> \<Longrightarrow> t \<le>\<flat> v"
+unfolding lower_le_def
+apply (rule ballI)
+apply (drule (1) bspec, erule bexE)
+apply (drule (1) bspec, erule bexE)
+apply (erule rev_bexI)
+apply (erule (1) compact_le_trans)
+done
+
+interpretation lower_le: preorder [lower_le]
+by (rule preorder.intro, rule lower_le_refl, rule lower_le_trans)
+
+lemma lower_le_minimal [simp]: "PDUnit compact_bot \<le>\<flat> t"
+unfolding lower_le_def Rep_PDUnit
+by (simp, rule Rep_pd_basis_nonempty [folded ex_in_conv])
+
+lemma PDUnit_lower_mono: "compact_le x y \<Longrightarrow> PDUnit x \<le>\<flat> PDUnit y"
+unfolding lower_le_def Rep_PDUnit by fast
+
+lemma PDPlus_lower_mono: "\<lbrakk>s \<le>\<flat> t; u \<le>\<flat> v\<rbrakk> \<Longrightarrow> PDPlus s u \<le>\<flat> PDPlus t v"
+unfolding lower_le_def Rep_PDPlus by fast
+
+lemma PDPlus_lower_less: "t \<le>\<flat> PDPlus t u"
+unfolding lower_le_def Rep_PDPlus by (fast intro: compact_le_refl)
+
+lemma lower_le_PDUnit_PDUnit_iff [simp]:
+  "(PDUnit a \<le>\<flat> PDUnit b) = compact_le a b"
+unfolding lower_le_def Rep_PDUnit by fast
+
+lemma lower_le_PDUnit_PDPlus_iff:
+  "(PDUnit a \<le>\<flat> PDPlus t u) = (PDUnit a \<le>\<flat> t \<or> PDUnit a \<le>\<flat> u)"
+unfolding lower_le_def Rep_PDPlus Rep_PDUnit by fast
+
+lemma lower_le_PDPlus_iff: "(PDPlus t u \<le>\<flat> v) = (t \<le>\<flat> v \<and> u \<le>\<flat> v)"
+unfolding lower_le_def Rep_PDPlus by fast
+
+lemma lower_le_induct [induct set: lower_le]:
+  assumes le: "t \<le>\<flat> u"
+  assumes 1: "\<And>a b. compact_le a b \<Longrightarrow> P (PDUnit a) (PDUnit b)"
+  assumes 2: "\<And>t u a. P (PDUnit a) t \<Longrightarrow> P (PDUnit a) (PDPlus t u)"
+  assumes 3: "\<And>t u v. \<lbrakk>P t v; P u v\<rbrakk> \<Longrightarrow> P (PDPlus t u) v"
+  shows "P t u"
+using le
+apply (induct t arbitrary: u rule: pd_basis_induct)
+apply (erule rev_mp)
+apply (induct_tac u rule: pd_basis_induct)
+apply (simp add: 1)
+apply (simp add: lower_le_PDUnit_PDPlus_iff)
+apply (simp add: 2)
+apply (subst PDPlus_commute)
+apply (simp add: 2)
+apply (simp add: lower_le_PDPlus_iff 3)
+done
+
+lemma approx_pd_lower_mono1:
+  "i \<le> j \<Longrightarrow> approx_pd i t \<le>\<flat> approx_pd j t"
+apply (induct t rule: pd_basis_induct)
+apply (simp add: compact_approx_mono1)
+apply (simp add: PDPlus_lower_mono)
+done
+
+lemma approx_pd_lower_le: "approx_pd i t \<le>\<flat> t"
+apply (induct t rule: pd_basis_induct)
+apply (simp add: compact_approx_le)
+apply (simp add: PDPlus_lower_mono)
+done
+
+lemma approx_pd_lower_mono:
+  "t \<le>\<flat> u \<Longrightarrow> approx_pd n t \<le>\<flat> approx_pd n u"
+apply (erule lower_le_induct)
+apply (simp add: compact_approx_mono)
+apply (simp add: lower_le_PDUnit_PDPlus_iff)
+apply (simp add: lower_le_PDPlus_iff)
+done
+
+
+subsection {* Type definition *}
+
+cpodef (open) 'a lower_pd =
+  "{S::'a::bifinite pd_basis set. lower_le.ideal S}"
+apply (simp add: lower_le.adm_ideal)
+apply (fast intro: lower_le.ideal_principal)
+done
+
+lemma ideal_Rep_lower_pd: "lower_le.ideal (Rep_lower_pd x)"
+by (rule Rep_lower_pd [simplified])
+
+lemma Rep_lower_pd_mono: "x \<sqsubseteq> y \<Longrightarrow> Rep_lower_pd x \<subseteq> Rep_lower_pd y"
+unfolding less_lower_pd_def less_set_def .
+
+
+subsection {* Principal ideals *}
+
+definition
+  lower_principal :: "'a pd_basis \<Rightarrow> 'a lower_pd" where
+  "lower_principal t = Abs_lower_pd {u. u \<le>\<flat> t}"
+
+lemma Rep_lower_principal:
+  "Rep_lower_pd (lower_principal t) = {u. u \<le>\<flat> t}"
+unfolding lower_principal_def
+apply (rule Abs_lower_pd_inverse [simplified])
+apply (rule lower_le.ideal_principal)
+done
+
+interpretation lower_pd:
+  bifinite_basis [lower_le lower_principal Rep_lower_pd approx_pd]
+apply unfold_locales
+apply (rule ideal_Rep_lower_pd)
+apply (rule cont_Rep_lower_pd)
+apply (rule Rep_lower_principal)
+apply (simp only: less_lower_pd_def less_set_def)
+apply (rule approx_pd_lower_le)
+apply (rule approx_pd_idem)
+apply (erule approx_pd_lower_mono)
+apply (rule approx_pd_lower_mono1, simp)
+apply (rule finite_range_approx_pd)
+apply (rule ex_approx_pd_eq)
+done
+
+lemma lower_principal_less_iff [simp]:
+  "(lower_principal t \<sqsubseteq> lower_principal u) = (t \<le>\<flat> u)"
+unfolding less_lower_pd_def Rep_lower_principal less_set_def
+by (fast intro: lower_le_refl elim: lower_le_trans)
+
+lemma lower_principal_mono:
+  "t \<le>\<flat> u \<Longrightarrow> lower_principal t \<sqsubseteq> lower_principal u"
+by (rule lower_principal_less_iff [THEN iffD2])
+
+lemma compact_lower_principal: "compact (lower_principal t)"
+apply (rule compactI2)
+apply (simp add: less_lower_pd_def)
+apply (simp add: cont2contlubE [OF cont_Rep_lower_pd])
+apply (simp add: Rep_lower_principal set_cpo_simps)
+apply (simp add: subset_def)
+apply (drule spec, drule mp, rule lower_le_refl)
+apply (erule exE, rename_tac i)
+apply (rule_tac x=i in exI)
+apply clarify
+apply (erule (1) lower_le.idealD3 [OF ideal_Rep_lower_pd])
+done
+
+lemma lower_pd_minimal: "lower_principal (PDUnit compact_bot) \<sqsubseteq> ys"
+by (induct ys rule: lower_pd.principal_induct, simp, simp)
+
+instance lower_pd :: (bifinite) pcpo
+by (intro_classes, fast intro: lower_pd_minimal)
+
+lemma inst_lower_pd_pcpo: "\<bottom> = lower_principal (PDUnit compact_bot)"
+by (rule lower_pd_minimal [THEN UU_I, symmetric])
+
+
+subsection {* Approximation *}
+
+instance lower_pd :: (bifinite) approx ..
+
+defs (overloaded)
+  approx_lower_pd_def:
+    "approx \<equiv> (\<lambda>n. lower_pd.basis_fun (\<lambda>t. lower_principal (approx_pd n t)))"
+
+lemma approx_lower_principal [simp]:
+  "approx n\<cdot>(lower_principal t) = lower_principal (approx_pd n t)"
+unfolding approx_lower_pd_def
+apply (rule lower_pd.basis_fun_principal)
+apply (erule lower_principal_mono [OF approx_pd_lower_mono])
+done
+
+lemma chain_approx_lower_pd:
+  "chain (approx :: nat \<Rightarrow> 'a lower_pd \<rightarrow> 'a lower_pd)"
+unfolding approx_lower_pd_def
+by (rule lower_pd.chain_basis_fun_take)
+
+lemma lub_approx_lower_pd:
+  "(\<Squnion>i. approx i\<cdot>xs) = (xs::'a lower_pd)"
+unfolding approx_lower_pd_def
+by (rule lower_pd.lub_basis_fun_take)
+
+lemma approx_lower_pd_idem:
+  "approx n\<cdot>(approx n\<cdot>xs) = approx n\<cdot>(xs::'a lower_pd)"
+apply (induct xs rule: lower_pd.principal_induct, simp)
+apply (simp add: approx_pd_idem)
+done
+
+lemma approx_eq_lower_principal:
+  "\<exists>t\<in>Rep_lower_pd xs. approx n\<cdot>xs = lower_principal (approx_pd n t)"
+unfolding approx_lower_pd_def
+by (rule lower_pd.basis_fun_take_eq_principal)
+
+lemma finite_fixes_approx_lower_pd:
+  "finite {xs::'a lower_pd. approx n\<cdot>xs = xs}"
+unfolding approx_lower_pd_def
+by (rule lower_pd.finite_fixes_basis_fun_take)
+
+instance lower_pd :: (bifinite) bifinite
+apply intro_classes
+apply (simp add: chain_approx_lower_pd)
+apply (rule lub_approx_lower_pd)
+apply (rule approx_lower_pd_idem)
+apply (rule finite_fixes_approx_lower_pd)
+done
+
+lemma compact_imp_lower_principal:
+  "compact xs \<Longrightarrow> \<exists>t. xs = lower_principal t"
+apply (drule bifinite_compact_eq_approx)
+apply (erule exE)
+apply (erule subst)
+apply (cut_tac n=i and xs=xs in approx_eq_lower_principal)
+apply fast
+done
+
+lemma lower_principal_induct:
+  "\<lbrakk>adm P; \<And>t. P (lower_principal t)\<rbrakk> \<Longrightarrow> P xs"
+apply (erule approx_induct, rename_tac xs)
+apply (cut_tac n=n and xs=xs in approx_eq_lower_principal)
+apply (clarify, simp)
+done
+
+lemma lower_principal_induct2:
+  "\<lbrakk>\<And>ys. adm (\<lambda>xs. P xs ys); \<And>xs. adm (\<lambda>ys. P xs ys);
+    \<And>t u. P (lower_principal t) (lower_principal u)\<rbrakk> \<Longrightarrow> P xs ys"
+apply (rule_tac x=ys in spec)
+apply (rule_tac xs=xs in lower_principal_induct, simp)
+apply (rule allI, rename_tac ys)
+apply (rule_tac xs=ys in lower_principal_induct, simp)
+apply simp
+done
+
+
+subsection {* Monadic unit *}
+
+definition
+  lower_unit :: "'a \<rightarrow> 'a lower_pd" where
+  "lower_unit = compact_basis.basis_fun (\<lambda>a. lower_principal (PDUnit a))"
+
+lemma lower_unit_Rep_compact_basis [simp]:
+  "lower_unit\<cdot>(Rep_compact_basis a) = lower_principal (PDUnit a)"
+unfolding lower_unit_def
+apply (rule compact_basis.basis_fun_principal)
+apply (rule lower_principal_mono)
+apply (erule PDUnit_lower_mono)
+done
+
+lemma lower_unit_strict [simp]: "lower_unit\<cdot>\<bottom> = \<bottom>"
+unfolding inst_lower_pd_pcpo Rep_compact_bot [symmetric] by simp
+
+lemma approx_lower_unit [simp]:
+  "approx n\<cdot>(lower_unit\<cdot>x) = lower_unit\<cdot>(approx n\<cdot>x)"
+apply (induct x rule: compact_basis_induct, simp)
+apply (simp add: approx_Rep_compact_basis)
+done
+
+lemma lower_unit_less_iff [simp]:
+  "(lower_unit\<cdot>x \<sqsubseteq> lower_unit\<cdot>y) = (x \<sqsubseteq> y)"
+ apply (rule iffI)
+  apply (rule bifinite_less_ext)
+  apply (drule_tac f="approx i" in monofun_cfun_arg, simp)
+  apply (cut_tac x="approx i\<cdot>x" in compact_imp_Rep_compact_basis, simp)
+  apply (cut_tac x="approx i\<cdot>y" in compact_imp_Rep_compact_basis, simp)
+  apply (clarify, simp add: compact_le_def)
+ apply (erule monofun_cfun_arg)
+done
+
+lemma lower_unit_eq_iff [simp]:
+  "(lower_unit\<cdot>x = lower_unit\<cdot>y) = (x = y)"
+unfolding po_eq_conv by simp
+
+lemma lower_unit_strict_iff [simp]: "(lower_unit\<cdot>x = \<bottom>) = (x = \<bottom>)"
+unfolding lower_unit_strict [symmetric] by (rule lower_unit_eq_iff)
+
+lemma compact_lower_unit_iff [simp]:
+  "compact (lower_unit\<cdot>x) = compact x"
+unfolding bifinite_compact_iff by simp
+
+
+subsection {* Monadic plus *}
+
+definition
+  lower_plus :: "'a lower_pd \<rightarrow> 'a lower_pd \<rightarrow> 'a lower_pd" where
+  "lower_plus = lower_pd.basis_fun (\<lambda>t. lower_pd.basis_fun (\<lambda>u.
+      lower_principal (PDPlus t u)))"
+
+abbreviation
+  lower_add :: "'a lower_pd \<Rightarrow> 'a lower_pd \<Rightarrow> 'a lower_pd"
+    (infixl "+\<flat>" 65) where
+  "xs +\<flat> ys == lower_plus\<cdot>xs\<cdot>ys"
+
+lemma lower_plus_principal [simp]:
+  "lower_plus\<cdot>(lower_principal t)\<cdot>(lower_principal u) =
+   lower_principal (PDPlus t u)"
+unfolding lower_plus_def
+by (simp add: lower_pd.basis_fun_principal
+    lower_pd.basis_fun_mono PDPlus_lower_mono)
+
+lemma approx_lower_plus [simp]:
+  "approx n\<cdot>(lower_plus\<cdot>xs\<cdot>ys) = lower_plus\<cdot>(approx n\<cdot>xs)\<cdot>(approx n\<cdot>ys)"
+by (induct xs ys rule: lower_principal_induct2, simp, simp, simp)
+
+lemma lower_plus_commute: "lower_plus\<cdot>xs\<cdot>ys = lower_plus\<cdot>ys\<cdot>xs"
+apply (induct xs ys rule: lower_principal_induct2, simp, simp)
+apply (simp add: PDPlus_commute)
+done
+
+lemma lower_plus_assoc:
+  "lower_plus\<cdot>(lower_plus\<cdot>xs\<cdot>ys)\<cdot>zs = lower_plus\<cdot>xs\<cdot>(lower_plus\<cdot>ys\<cdot>zs)"
+apply (induct xs ys arbitrary: zs rule: lower_principal_induct2, simp, simp)
+apply (rule_tac xs=zs in lower_principal_induct, simp)
+apply (simp add: PDPlus_assoc)
+done
+
+lemma lower_plus_absorb: "lower_plus\<cdot>xs\<cdot>xs = xs"
+apply (induct xs rule: lower_principal_induct, simp)
+apply (simp add: PDPlus_absorb)
+done
+
+lemma lower_plus_less1: "xs \<sqsubseteq> lower_plus\<cdot>xs\<cdot>ys"
+apply (induct xs ys rule: lower_principal_induct2, simp, simp)
+apply (simp add: PDPlus_lower_less)
+done
+
+lemma lower_plus_less2: "ys \<sqsubseteq> lower_plus\<cdot>xs\<cdot>ys"
+by (subst lower_plus_commute, rule lower_plus_less1)
+
+lemma lower_plus_least: "\<lbrakk>xs \<sqsubseteq> zs; ys \<sqsubseteq> zs\<rbrakk> \<Longrightarrow> lower_plus\<cdot>xs\<cdot>ys \<sqsubseteq> zs"
+apply (subst lower_plus_absorb [of zs, symmetric])
+apply (erule (1) monofun_cfun [OF monofun_cfun_arg])
+done
+
+lemma lower_plus_less_iff:
+  "(lower_plus\<cdot>xs\<cdot>ys \<sqsubseteq> zs) = (xs \<sqsubseteq> zs \<and> ys \<sqsubseteq> zs)"
+apply safe
+apply (erule trans_less [OF lower_plus_less1])
+apply (erule trans_less [OF lower_plus_less2])
+apply (erule (1) lower_plus_least)
+done
+
+lemma lower_plus_strict_iff [simp]:
+  "(lower_plus\<cdot>xs\<cdot>ys = \<bottom>) = (xs = \<bottom> \<and> ys = \<bottom>)"
+apply safe
+apply (rule UU_I, erule subst, rule lower_plus_less1)
+apply (rule UU_I, erule subst, rule lower_plus_less2)
+apply (rule lower_plus_absorb)
+done
+
+lemma lower_plus_strict1 [simp]: "lower_plus\<cdot>\<bottom>\<cdot>ys = ys"
+apply (rule antisym_less [OF _ lower_plus_less2])
+apply (simp add: lower_plus_least)
+done
+
+lemma lower_plus_strict2 [simp]: "lower_plus\<cdot>xs\<cdot>\<bottom> = xs"
+apply (rule antisym_less [OF _ lower_plus_less1])
+apply (simp add: lower_plus_least)
+done
+
+lemma lower_unit_less_plus_iff:
+  "(lower_unit\<cdot>x \<sqsubseteq> lower_plus\<cdot>ys\<cdot>zs) =
+    (lower_unit\<cdot>x \<sqsubseteq> ys \<or> lower_unit\<cdot>x \<sqsubseteq> zs)"
+ apply (rule iffI)
+  apply (subgoal_tac
+    "adm (\<lambda>f. f\<cdot>(lower_unit\<cdot>x) \<sqsubseteq> f\<cdot>ys \<or> f\<cdot>(lower_unit\<cdot>x) \<sqsubseteq> f\<cdot>zs)")
+   apply (drule admD [rule_format], rule chain_approx)
+    apply (drule_tac f="approx i" in monofun_cfun_arg)
+    apply (cut_tac x="approx i\<cdot>x" in compact_imp_Rep_compact_basis, simp)
+    apply (cut_tac xs="approx i\<cdot>ys" in compact_imp_lower_principal, simp)
+    apply (cut_tac xs="approx i\<cdot>zs" in compact_imp_lower_principal, simp)
+    apply (clarify, simp add: lower_le_PDUnit_PDPlus_iff)
+   apply simp
+  apply simp
+ apply (erule disjE)
+  apply (erule trans_less [OF _ lower_plus_less1])
+ apply (erule trans_less [OF _ lower_plus_less2])
+done
+
+lemmas lower_pd_less_simps =
+  lower_unit_less_iff
+  lower_plus_less_iff
+  lower_unit_less_plus_iff
+
+
+subsection {* Induction rules *}
+
+lemma lower_pd_induct1:
+  assumes P: "adm P"
+  assumes unit: "\<And>x. P (lower_unit\<cdot>x)"
+  assumes insert:
+    "\<And>x ys. \<lbrakk>P (lower_unit\<cdot>x); P ys\<rbrakk> \<Longrightarrow> P (lower_plus\<cdot>(lower_unit\<cdot>x)\<cdot>ys)"
+  shows "P (xs::'a lower_pd)"
+apply (induct xs rule: lower_principal_induct, rule P)
+apply (induct_tac t rule: pd_basis_induct1)
+apply (simp only: lower_unit_Rep_compact_basis [symmetric])
+apply (rule unit)
+apply (simp only: lower_unit_Rep_compact_basis [symmetric]
+                  lower_plus_principal [symmetric])
+apply (erule insert [OF unit])
+done
+
+lemma lower_pd_induct:
+  assumes P: "adm P"
+  assumes unit: "\<And>x. P (lower_unit\<cdot>x)"
+  assumes plus: "\<And>xs ys. \<lbrakk>P xs; P ys\<rbrakk> \<Longrightarrow> P (lower_plus\<cdot>xs\<cdot>ys)"
+  shows "P (xs::'a lower_pd)"
+apply (induct xs rule: lower_principal_induct, rule P)
+apply (induct_tac t rule: pd_basis_induct)
+apply (simp only: lower_unit_Rep_compact_basis [symmetric] unit)
+apply (simp only: lower_plus_principal [symmetric] plus)
+done
+
+
+subsection {* Monadic bind *}
+
+definition
+  lower_bind_basis ::
+  "'a pd_basis \<Rightarrow> ('a \<rightarrow> 'b lower_pd) \<rightarrow> 'b lower_pd" where
+  "lower_bind_basis = fold_pd
+    (\<lambda>a. \<Lambda> f. f\<cdot>(Rep_compact_basis a))
+    (\<lambda>x y. \<Lambda> f. lower_plus\<cdot>(x\<cdot>f)\<cdot>(y\<cdot>f))"
+
+lemma ACI_lower_bind: "ACIf (\<lambda>x y. \<Lambda> f. lower_plus\<cdot>(x\<cdot>f)\<cdot>(y\<cdot>f))"
+apply unfold_locales
+apply (simp add: lower_plus_commute)
+apply (simp add: lower_plus_assoc)
+apply (simp add: lower_plus_absorb eta_cfun)
+done
+
+lemma lower_bind_basis_simps [simp]:
+  "lower_bind_basis (PDUnit a) =
+    (\<Lambda> f. f\<cdot>(Rep_compact_basis a))"
+  "lower_bind_basis (PDPlus t u) =
+    (\<Lambda> f. lower_plus\<cdot>(lower_bind_basis t\<cdot>f)\<cdot>(lower_bind_basis u\<cdot>f))"
+unfolding lower_bind_basis_def
+apply -
+apply (rule ACIf.fold_pd_PDUnit [OF ACI_lower_bind])
+apply (rule ACIf.fold_pd_PDPlus [OF ACI_lower_bind])
+done
+
+lemma lower_bind_basis_mono:
+  "t \<le>\<flat> u \<Longrightarrow> lower_bind_basis t \<sqsubseteq> lower_bind_basis u"
+unfolding expand_cfun_less
+apply (erule lower_le_induct, safe)
+apply (simp add: compact_le_def monofun_cfun)
+apply (simp add: rev_trans_less [OF lower_plus_less1])
+apply (simp add: lower_plus_less_iff)
+done
+
+definition
+  lower_bind :: "'a lower_pd \<rightarrow> ('a \<rightarrow> 'b lower_pd) \<rightarrow> 'b lower_pd" where
+  "lower_bind = lower_pd.basis_fun lower_bind_basis"
+
+lemma lower_bind_principal [simp]:
+  "lower_bind\<cdot>(lower_principal t) = lower_bind_basis t"
+unfolding lower_bind_def
+apply (rule lower_pd.basis_fun_principal)
+apply (erule lower_bind_basis_mono)
+done
+
+lemma lower_bind_unit [simp]:
+  "lower_bind\<cdot>(lower_unit\<cdot>x)\<cdot>f = f\<cdot>x"
+by (induct x rule: compact_basis_induct, simp, simp)
+
+lemma lower_bind_plus [simp]:
+  "lower_bind\<cdot>(lower_plus\<cdot>xs\<cdot>ys)\<cdot>f =
+   lower_plus\<cdot>(lower_bind\<cdot>xs\<cdot>f)\<cdot>(lower_bind\<cdot>ys\<cdot>f)"
+by (induct xs ys rule: lower_principal_induct2, simp, simp, simp)
+
+lemma lower_bind_strict [simp]: "lower_bind\<cdot>\<bottom>\<cdot>f = f\<cdot>\<bottom>"
+unfolding lower_unit_strict [symmetric] by (rule lower_bind_unit)
+
+
+subsection {* Map and join *}
+
+definition
+  lower_map :: "('a \<rightarrow> 'b) \<rightarrow> 'a lower_pd \<rightarrow> 'b lower_pd" where
+  "lower_map = (\<Lambda> f xs. lower_bind\<cdot>xs\<cdot>(\<Lambda> x. lower_unit\<cdot>(f\<cdot>x)))"
+
+definition
+  lower_join :: "'a lower_pd lower_pd \<rightarrow> 'a lower_pd" where
+  "lower_join = (\<Lambda> xss. lower_bind\<cdot>xss\<cdot>(\<Lambda> xs. xs))"
+
+lemma lower_map_unit [simp]:
+  "lower_map\<cdot>f\<cdot>(lower_unit\<cdot>x) = lower_unit\<cdot>(f\<cdot>x)"
+unfolding lower_map_def by simp
+
+lemma lower_map_plus [simp]:
+  "lower_map\<cdot>f\<cdot>(lower_plus\<cdot>xs\<cdot>ys) =
+   lower_plus\<cdot>(lower_map\<cdot>f\<cdot>xs)\<cdot>(lower_map\<cdot>f\<cdot>ys)"
+unfolding lower_map_def by simp
+
+lemma lower_join_unit [simp]:
+  "lower_join\<cdot>(lower_unit\<cdot>xs) = xs"
+unfolding lower_join_def by simp
+
+lemma lower_join_plus [simp]:
+  "lower_join\<cdot>(lower_plus\<cdot>xss\<cdot>yss) =
+   lower_plus\<cdot>(lower_join\<cdot>xss)\<cdot>(lower_join\<cdot>yss)"
+unfolding lower_join_def by simp
+
+lemma lower_map_ident: "lower_map\<cdot>(\<Lambda> x. x)\<cdot>xs = xs"
+by (induct xs rule: lower_pd_induct, simp_all)
+
+lemma lower_map_map:
+  "lower_map\<cdot>f\<cdot>(lower_map\<cdot>g\<cdot>xs) = lower_map\<cdot>(\<Lambda> x. f\<cdot>(g\<cdot>x))\<cdot>xs"
+by (induct xs rule: lower_pd_induct, simp_all)
+
+lemma lower_join_map_unit:
+  "lower_join\<cdot>(lower_map\<cdot>lower_unit\<cdot>xs) = xs"
+by (induct xs rule: lower_pd_induct, simp_all)
+
+lemma lower_join_map_join:
+  "lower_join\<cdot>(lower_map\<cdot>lower_join\<cdot>xsss) = lower_join\<cdot>(lower_join\<cdot>xsss)"
+by (induct xsss rule: lower_pd_induct, simp_all)
+
+lemma lower_join_map_map:
+  "lower_join\<cdot>(lower_map\<cdot>(lower_map\<cdot>f)\<cdot>xss) =
+   lower_map\<cdot>f\<cdot>(lower_join\<cdot>xss)"
+by (induct xss rule: lower_pd_induct, simp_all)
+
+lemma lower_map_approx: "lower_map\<cdot>(approx n)\<cdot>xs = approx n\<cdot>xs"
+by (induct xs rule: lower_pd_induct, simp_all)
+
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOLCF/UpperPD.thy	Mon Jan 14 19:26:41 2008 +0100
@@ -0,0 +1,508 @@
+(*  Title:      HOLCF/UpperPD.thy
+    ID:         $Id$
+    Author:     Brian Huffman
+*)
+
+header {* Upper powerdomain *}
+
+theory UpperPD
+imports CompactBasis
+begin
+
+subsection {* Basis preorder *}
+
+definition
+  upper_le :: "'a pd_basis \<Rightarrow> 'a pd_basis \<Rightarrow> bool" (infix "\<le>\<sharp>" 50) where
+  "upper_le = (\<lambda>u v. \<forall>y\<in>Rep_pd_basis v. \<exists>x\<in>Rep_pd_basis u. compact_le x y)"
+
+lemma upper_le_refl [simp]: "t \<le>\<sharp> t"
+unfolding upper_le_def by (fast intro: compact_le_refl)
+
+lemma upper_le_trans: "\<lbrakk>t \<le>\<sharp> u; u \<le>\<sharp> v\<rbrakk> \<Longrightarrow> t \<le>\<sharp> v"
+unfolding upper_le_def
+apply (rule ballI)
+apply (drule (1) bspec, erule bexE)
+apply (drule (1) bspec, erule bexE)
+apply (erule rev_bexI)
+apply (erule (1) compact_le_trans)
+done
+
+interpretation upper_le: preorder [upper_le]
+by (rule preorder.intro, rule upper_le_refl, rule upper_le_trans)
+
+lemma upper_le_minimal [simp]: "PDUnit compact_bot \<le>\<sharp> t"
+unfolding upper_le_def Rep_PDUnit by simp
+
+lemma PDUnit_upper_mono: "compact_le x y \<Longrightarrow> PDUnit x \<le>\<sharp> PDUnit y"
+unfolding upper_le_def Rep_PDUnit by simp
+
+lemma PDPlus_upper_mono: "\<lbrakk>s \<le>\<sharp> t; u \<le>\<sharp> v\<rbrakk> \<Longrightarrow> PDPlus s u \<le>\<sharp> PDPlus t v"
+unfolding upper_le_def Rep_PDPlus by fast
+
+lemma PDPlus_upper_less: "PDPlus t u \<le>\<sharp> t"
+unfolding upper_le_def Rep_PDPlus by (fast intro: compact_le_refl)
+
+lemma upper_le_PDUnit_PDUnit_iff [simp]:
+  "(PDUnit a \<le>\<sharp> PDUnit b) = compact_le a b"
+unfolding upper_le_def Rep_PDUnit by fast
+
+lemma upper_le_PDPlus_PDUnit_iff:
+  "(PDPlus t u \<le>\<sharp> PDUnit a) = (t \<le>\<sharp> PDUnit a \<or> u \<le>\<sharp> PDUnit a)"
+unfolding upper_le_def Rep_PDPlus Rep_PDUnit by fast
+
+lemma upper_le_PDPlus_iff: "(t \<le>\<sharp> PDPlus u v) = (t \<le>\<sharp> u \<and> t \<le>\<sharp> v)"
+unfolding upper_le_def Rep_PDPlus by fast
+
+lemma upper_le_induct [induct set: upper_le]:
+  assumes le: "t \<le>\<sharp> u"
+  assumes 1: "\<And>a b. compact_le a b \<Longrightarrow> P (PDUnit a) (PDUnit b)"
+  assumes 2: "\<And>t u a. P t (PDUnit a) \<Longrightarrow> P (PDPlus t u) (PDUnit a)"
+  assumes 3: "\<And>t u v. \<lbrakk>P t u; P t v\<rbrakk> \<Longrightarrow> P t (PDPlus u v)"
+  shows "P t u"
+using le apply (induct u arbitrary: t rule: pd_basis_induct)
+apply (erule rev_mp)
+apply (induct_tac t rule: pd_basis_induct)
+apply (simp add: 1)
+apply (simp add: upper_le_PDPlus_PDUnit_iff)
+apply (simp add: 2)
+apply (subst PDPlus_commute)
+apply (simp add: 2)
+apply (simp add: upper_le_PDPlus_iff 3)
+done
+
+lemma approx_pd_upper_mono1:
+  "i \<le> j \<Longrightarrow> approx_pd i t \<le>\<sharp> approx_pd j t"
+apply (induct t rule: pd_basis_induct)
+apply (simp add: compact_approx_mono1)
+apply (simp add: PDPlus_upper_mono)
+done
+
+lemma approx_pd_upper_le: "approx_pd i t \<le>\<sharp> t"
+apply (induct t rule: pd_basis_induct)
+apply (simp add: compact_approx_le)
+apply (simp add: PDPlus_upper_mono)
+done
+
+lemma approx_pd_upper_mono:
+  "t \<le>\<sharp> u \<Longrightarrow> approx_pd n t \<le>\<sharp> approx_pd n u"
+apply (erule upper_le_induct)
+apply (simp add: compact_approx_mono)
+apply (simp add: upper_le_PDPlus_PDUnit_iff)
+apply (simp add: upper_le_PDPlus_iff)
+done
+
+
+subsection {* Type definition *}
+
+cpodef (open) 'a upper_pd =
+  "{S::'a::bifinite pd_basis set. upper_le.ideal S}"
+apply (simp add: upper_le.adm_ideal)
+apply (fast intro: upper_le.ideal_principal)
+done
+
+lemma ideal_Rep_upper_pd: "upper_le.ideal (Rep_upper_pd x)"
+by (rule Rep_upper_pd [simplified])
+
+definition
+  upper_principal :: "'a pd_basis \<Rightarrow> 'a upper_pd" where
+  "upper_principal t = Abs_upper_pd {u. u \<le>\<sharp> t}"
+
+lemma Rep_upper_principal:
+  "Rep_upper_pd (upper_principal t) = {u. u \<le>\<sharp> t}"
+unfolding upper_principal_def
+apply (rule Abs_upper_pd_inverse [simplified])
+apply (rule upper_le.ideal_principal)
+done
+
+interpretation upper_pd:
+  bifinite_basis [upper_le upper_principal Rep_upper_pd approx_pd]
+apply unfold_locales
+apply (rule ideal_Rep_upper_pd)
+apply (rule cont_Rep_upper_pd)
+apply (rule Rep_upper_principal)
+apply (simp only: less_upper_pd_def less_set_def)
+apply (rule approx_pd_upper_le)
+apply (rule approx_pd_idem)
+apply (erule approx_pd_upper_mono)
+apply (rule approx_pd_upper_mono1, simp)
+apply (rule finite_range_approx_pd)
+apply (rule ex_approx_pd_eq)
+done
+
+lemma upper_principal_less_iff [simp]:
+  "(upper_principal t \<sqsubseteq> upper_principal u) = (t \<le>\<sharp> u)"
+unfolding less_upper_pd_def Rep_upper_principal less_set_def
+by (fast intro: upper_le_refl elim: upper_le_trans)
+
+lemma upper_principal_mono:
+  "t \<le>\<sharp> u \<Longrightarrow> upper_principal t \<sqsubseteq> upper_principal u"
+by (rule upper_pd.principal_mono)
+
+lemma compact_upper_principal: "compact (upper_principal t)"
+by (rule upper_pd.compact_principal)
+
+lemma upper_pd_minimal: "upper_principal (PDUnit compact_bot) \<sqsubseteq> ys"
+by (induct ys rule: upper_pd.principal_induct, simp, simp)
+
+instance upper_pd :: (bifinite) pcpo
+by (intro_classes, fast intro: upper_pd_minimal)
+
+lemma inst_upper_pd_pcpo: "\<bottom> = upper_principal (PDUnit compact_bot)"
+by (rule upper_pd_minimal [THEN UU_I, symmetric])
+
+
+subsection {* Approximation *}
+
+instance upper_pd :: (bifinite) approx ..
+
+defs (overloaded)
+  approx_upper_pd_def:
+    "approx \<equiv> (\<lambda>n. upper_pd.basis_fun (\<lambda>t. upper_principal (approx_pd n t)))"
+
+lemma approx_upper_principal [simp]:
+  "approx n\<cdot>(upper_principal t) = upper_principal (approx_pd n t)"
+unfolding approx_upper_pd_def
+apply (rule upper_pd.basis_fun_principal)
+apply (erule upper_principal_mono [OF approx_pd_upper_mono])
+done
+
+lemma chain_approx_upper_pd:
+  "chain (approx :: nat \<Rightarrow> 'a upper_pd \<rightarrow> 'a upper_pd)"
+unfolding approx_upper_pd_def
+by (rule upper_pd.chain_basis_fun_take)
+
+lemma lub_approx_upper_pd:
+  "(\<Squnion>i. approx i\<cdot>xs) = (xs::'a upper_pd)"
+unfolding approx_upper_pd_def
+by (rule upper_pd.lub_basis_fun_take)
+
+lemma approx_upper_pd_idem:
+  "approx n\<cdot>(approx n\<cdot>xs) = approx n\<cdot>(xs::'a upper_pd)"
+apply (induct xs rule: upper_pd.principal_induct, simp)
+apply (simp add: approx_pd_idem)
+done
+
+lemma approx_eq_upper_principal:
+  "\<exists>t\<in>Rep_upper_pd xs. approx n\<cdot>xs = upper_principal (approx_pd n t)"
+unfolding approx_upper_pd_def
+by (rule upper_pd.basis_fun_take_eq_principal)
+
+lemma finite_fixes_approx_upper_pd:
+  "finite {xs::'a upper_pd. approx n\<cdot>xs = xs}"
+unfolding approx_upper_pd_def
+by (rule upper_pd.finite_fixes_basis_fun_take)
+
+instance upper_pd :: (bifinite) bifinite
+apply intro_classes
+apply (simp add: chain_approx_upper_pd)
+apply (rule lub_approx_upper_pd)
+apply (rule approx_upper_pd_idem)
+apply (rule finite_fixes_approx_upper_pd)
+done
+
+lemma compact_imp_upper_principal:
+  "compact xs \<Longrightarrow> \<exists>t. xs = upper_principal t"
+apply (drule bifinite_compact_eq_approx)
+apply (erule exE)
+apply (erule subst)
+apply (cut_tac n=i and xs=xs in approx_eq_upper_principal)
+apply fast
+done
+
+lemma upper_principal_induct:
+  "\<lbrakk>adm P; \<And>t. P (upper_principal t)\<rbrakk> \<Longrightarrow> P xs"
+apply (erule approx_induct, rename_tac xs)
+apply (cut_tac n=n and xs=xs in approx_eq_upper_principal)
+apply (clarify, simp)
+done
+
+lemma upper_principal_induct2:
+  "\<lbrakk>\<And>ys. adm (\<lambda>xs. P xs ys); \<And>xs. adm (\<lambda>ys. P xs ys);
+    \<And>t u. P (upper_principal t) (upper_principal u)\<rbrakk> \<Longrightarrow> P xs ys"
+apply (rule_tac x=ys in spec)
+apply (rule_tac xs=xs in upper_principal_induct, simp)
+apply (rule allI, rename_tac ys)
+apply (rule_tac xs=ys in upper_principal_induct, simp)
+apply simp
+done
+
+
+subsection {* Monadic unit *}
+
+definition
+  upper_unit :: "'a \<rightarrow> 'a upper_pd" where
+  "upper_unit = compact_basis.basis_fun (\<lambda>a. upper_principal (PDUnit a))"
+
+lemma upper_unit_Rep_compact_basis [simp]:
+  "upper_unit\<cdot>(Rep_compact_basis a) = upper_principal (PDUnit a)"
+unfolding upper_unit_def
+apply (rule compact_basis.basis_fun_principal)
+apply (rule upper_principal_mono)
+apply (erule PDUnit_upper_mono)
+done
+
+lemma upper_unit_strict [simp]: "upper_unit\<cdot>\<bottom> = \<bottom>"
+unfolding inst_upper_pd_pcpo Rep_compact_bot [symmetric] by simp
+
+lemma approx_upper_unit [simp]:
+  "approx n\<cdot>(upper_unit\<cdot>x) = upper_unit\<cdot>(approx n\<cdot>x)"
+apply (induct x rule: compact_basis_induct, simp)
+apply (simp add: approx_Rep_compact_basis)
+done
+
+lemma upper_unit_less_iff [simp]:
+  "(upper_unit\<cdot>x \<sqsubseteq> upper_unit\<cdot>y) = (x \<sqsubseteq> y)"
+ apply (rule iffI)
+  apply (rule bifinite_less_ext)
+  apply (drule_tac f="approx i" in monofun_cfun_arg, simp)
+  apply (cut_tac x="approx i\<cdot>x" in compact_imp_Rep_compact_basis, simp)
+  apply (cut_tac x="approx i\<cdot>y" in compact_imp_Rep_compact_basis, simp)
+  apply (clarify, simp add: compact_le_def)
+ apply (erule monofun_cfun_arg)
+done
+
+lemma upper_unit_eq_iff [simp]:
+  "(upper_unit\<cdot>x = upper_unit\<cdot>y) = (x = y)"
+unfolding po_eq_conv by simp
+
+lemma upper_unit_strict_iff [simp]: "(upper_unit\<cdot>x = \<bottom>) = (x = \<bottom>)"
+unfolding upper_unit_strict [symmetric] by (rule upper_unit_eq_iff)
+
+lemma compact_upper_unit_iff [simp]:
+  "compact (upper_unit\<cdot>x) = compact x"
+unfolding bifinite_compact_iff by simp
+
+
+subsection {* Monadic plus *}
+
+definition
+  upper_plus :: "'a upper_pd \<rightarrow> 'a upper_pd \<rightarrow> 'a upper_pd" where
+  "upper_plus = upper_pd.basis_fun (\<lambda>t. upper_pd.basis_fun (\<lambda>u.
+      upper_principal (PDPlus t u)))"
+
+abbreviation
+  upper_add :: "'a upper_pd \<Rightarrow> 'a upper_pd \<Rightarrow> 'a upper_pd"
+    (infixl "+\<sharp>" 65) where
+  "xs +\<sharp> ys == upper_plus\<cdot>xs\<cdot>ys"
+
+lemma upper_plus_principal [simp]:
+  "upper_plus\<cdot>(upper_principal t)\<cdot>(upper_principal u) =
+   upper_principal (PDPlus t u)"
+unfolding upper_plus_def
+by (simp add: upper_pd.basis_fun_principal
+    upper_pd.basis_fun_mono PDPlus_upper_mono)
+
+lemma approx_upper_plus [simp]:
+  "approx n\<cdot>(upper_plus\<cdot>xs\<cdot>ys) = upper_plus\<cdot>(approx n\<cdot>xs)\<cdot>(approx n\<cdot>ys)"
+by (induct xs ys rule: upper_principal_induct2, simp, simp, simp)
+
+lemma upper_plus_commute: "upper_plus\<cdot>xs\<cdot>ys = upper_plus\<cdot>ys\<cdot>xs"
+apply (induct xs ys rule: upper_principal_induct2, simp, simp)
+apply (simp add: PDPlus_commute)
+done
+
+lemma upper_plus_assoc:
+  "upper_plus\<cdot>(upper_plus\<cdot>xs\<cdot>ys)\<cdot>zs = upper_plus\<cdot>xs\<cdot>(upper_plus\<cdot>ys\<cdot>zs)"
+apply (induct xs ys arbitrary: zs rule: upper_principal_induct2, simp, simp)
+apply (rule_tac xs=zs in upper_principal_induct, simp)
+apply (simp add: PDPlus_assoc)
+done
+
+lemma upper_plus_absorb: "upper_plus\<cdot>xs\<cdot>xs = xs"
+apply (induct xs rule: upper_principal_induct, simp)
+apply (simp add: PDPlus_absorb)
+done
+
+lemma upper_plus_less1: "upper_plus\<cdot>xs\<cdot>ys \<sqsubseteq> xs"
+apply (induct xs ys rule: upper_principal_induct2, simp, simp)
+apply (simp add: PDPlus_upper_less)
+done
+
+lemma upper_plus_less2: "upper_plus\<cdot>xs\<cdot>ys \<sqsubseteq> ys"
+by (subst upper_plus_commute, rule upper_plus_less1)
+
+lemma upper_plus_greatest: "\<lbrakk>xs \<sqsubseteq> ys; xs \<sqsubseteq> zs\<rbrakk> \<Longrightarrow> xs \<sqsubseteq> upper_plus\<cdot>ys\<cdot>zs"
+apply (subst upper_plus_absorb [of xs, symmetric])
+apply (erule (1) monofun_cfun [OF monofun_cfun_arg])
+done
+
+lemma upper_less_plus_iff:
+  "(xs \<sqsubseteq> upper_plus\<cdot>ys\<cdot>zs) = (xs \<sqsubseteq> ys \<and> xs \<sqsubseteq> zs)"
+apply safe
+apply (erule trans_less [OF _ upper_plus_less1])
+apply (erule trans_less [OF _ upper_plus_less2])
+apply (erule (1) upper_plus_greatest)
+done
+
+lemma upper_plus_strict1 [simp]: "upper_plus\<cdot>\<bottom>\<cdot>ys = \<bottom>"
+by (rule UU_I, rule upper_plus_less1)
+
+lemma upper_plus_strict2 [simp]: "upper_plus\<cdot>xs\<cdot>\<bottom> = \<bottom>"
+by (rule UU_I, rule upper_plus_less2)
+
+lemma upper_plus_less_unit_iff:
+  "(upper_plus\<cdot>xs\<cdot>ys \<sqsubseteq> upper_unit\<cdot>z) =
+    (xs \<sqsubseteq> upper_unit\<cdot>z \<or> ys \<sqsubseteq> upper_unit\<cdot>z)"
+ apply (rule iffI)
+  apply (subgoal_tac
+    "adm (\<lambda>f. f\<cdot>xs \<sqsubseteq> f\<cdot>(upper_unit\<cdot>z) \<or> f\<cdot>ys \<sqsubseteq> f\<cdot>(upper_unit\<cdot>z))")
+   apply (drule admD [rule_format], rule chain_approx)
+    apply (drule_tac f="approx i" in monofun_cfun_arg)
+    apply (cut_tac xs="approx i\<cdot>xs" in compact_imp_upper_principal, simp)
+    apply (cut_tac xs="approx i\<cdot>ys" in compact_imp_upper_principal, simp)
+    apply (cut_tac x="approx i\<cdot>z" in compact_imp_Rep_compact_basis, simp)
+    apply (clarify, simp add: upper_le_PDPlus_PDUnit_iff)
+   apply simp
+  apply simp
+ apply (erule disjE)
+  apply (erule trans_less [OF upper_plus_less1])
+ apply (erule trans_less [OF upper_plus_less2])
+done
+
+lemmas upper_pd_less_simps =
+  upper_unit_less_iff
+  upper_less_plus_iff
+  upper_plus_less_unit_iff
+
+
+subsection {* Induction rules *}
+
+lemma upper_pd_induct1:
+  assumes P: "adm P"
+  assumes unit: "\<And>x. P (upper_unit\<cdot>x)"
+  assumes insert:
+    "\<And>x ys. \<lbrakk>P (upper_unit\<cdot>x); P ys\<rbrakk> \<Longrightarrow> P (upper_plus\<cdot>(upper_unit\<cdot>x)\<cdot>ys)"
+  shows "P (xs::'a upper_pd)"
+apply (induct xs rule: upper_principal_induct, rule P)
+apply (induct_tac t rule: pd_basis_induct1)
+apply (simp only: upper_unit_Rep_compact_basis [symmetric])
+apply (rule unit)
+apply (simp only: upper_unit_Rep_compact_basis [symmetric]
+                  upper_plus_principal [symmetric])
+apply (erule insert [OF unit])
+done
+
+lemma upper_pd_induct:
+  assumes P: "adm P"
+  assumes unit: "\<And>x. P (upper_unit\<cdot>x)"
+  assumes plus: "\<And>xs ys. \<lbrakk>P xs; P ys\<rbrakk> \<Longrightarrow> P (upper_plus\<cdot>xs\<cdot>ys)"
+  shows "P (xs::'a upper_pd)"
+apply (induct xs rule: upper_principal_induct, rule P)
+apply (induct_tac t rule: pd_basis_induct)
+apply (simp only: upper_unit_Rep_compact_basis [symmetric] unit)
+apply (simp only: upper_plus_principal [symmetric] plus)
+done
+
+
+subsection {* Monadic bind *}
+
+definition
+  upper_bind_basis ::
+  "'a pd_basis \<Rightarrow> ('a \<rightarrow> 'b upper_pd) \<rightarrow> 'b upper_pd" where
+  "upper_bind_basis = fold_pd
+    (\<lambda>a. \<Lambda> f. f\<cdot>(Rep_compact_basis a))
+    (\<lambda>x y. \<Lambda> f. upper_plus\<cdot>(x\<cdot>f)\<cdot>(y\<cdot>f))"
+
+lemma ACI_upper_bind: "ACIf (\<lambda>x y. \<Lambda> f. upper_plus\<cdot>(x\<cdot>f)\<cdot>(y\<cdot>f))"
+apply unfold_locales
+apply (simp add: upper_plus_commute)
+apply (simp add: upper_plus_assoc)
+apply (simp add: upper_plus_absorb eta_cfun)
+done
+
+lemma upper_bind_basis_simps [simp]:
+  "upper_bind_basis (PDUnit a) =
+    (\<Lambda> f. f\<cdot>(Rep_compact_basis a))"
+  "upper_bind_basis (PDPlus t u) =
+    (\<Lambda> f. upper_plus\<cdot>(upper_bind_basis t\<cdot>f)\<cdot>(upper_bind_basis u\<cdot>f))"
+unfolding upper_bind_basis_def
+apply -
+apply (rule ACIf.fold_pd_PDUnit [OF ACI_upper_bind])
+apply (rule ACIf.fold_pd_PDPlus [OF ACI_upper_bind])
+done
+
+lemma upper_bind_basis_mono:
+  "t \<le>\<sharp> u \<Longrightarrow> upper_bind_basis t \<sqsubseteq> upper_bind_basis u"
+unfolding expand_cfun_less
+apply (erule upper_le_induct, safe)
+apply (simp add: compact_le_def monofun_cfun)
+apply (simp add: trans_less [OF upper_plus_less1])
+apply (simp add: upper_less_plus_iff)
+done
+
+definition
+  upper_bind :: "'a upper_pd \<rightarrow> ('a \<rightarrow> 'b upper_pd) \<rightarrow> 'b upper_pd" where
+  "upper_bind = upper_pd.basis_fun upper_bind_basis"
+
+lemma upper_bind_principal [simp]:
+  "upper_bind\<cdot>(upper_principal t) = upper_bind_basis t"
+unfolding upper_bind_def
+apply (rule upper_pd.basis_fun_principal)
+apply (erule upper_bind_basis_mono)
+done
+
+lemma upper_bind_unit [simp]:
+  "upper_bind\<cdot>(upper_unit\<cdot>x)\<cdot>f = f\<cdot>x"
+by (induct x rule: compact_basis_induct, simp, simp)
+
+lemma upper_bind_plus [simp]:
+  "upper_bind\<cdot>(upper_plus\<cdot>xs\<cdot>ys)\<cdot>f =
+   upper_plus\<cdot>(upper_bind\<cdot>xs\<cdot>f)\<cdot>(upper_bind\<cdot>ys\<cdot>f)"
+by (induct xs ys rule: upper_principal_induct2, simp, simp, simp)
+
+lemma upper_bind_strict [simp]: "upper_bind\<cdot>\<bottom>\<cdot>f = f\<cdot>\<bottom>"
+unfolding upper_unit_strict [symmetric] by (rule upper_bind_unit)
+
+
+subsection {* Map and join *}
+
+definition
+  upper_map :: "('a \<rightarrow> 'b) \<rightarrow> 'a upper_pd \<rightarrow> 'b upper_pd" where
+  "upper_map = (\<Lambda> f xs. upper_bind\<cdot>xs\<cdot>(\<Lambda> x. upper_unit\<cdot>(f\<cdot>x)))"
+
+definition
+  upper_join :: "'a upper_pd upper_pd \<rightarrow> 'a upper_pd" where
+  "upper_join = (\<Lambda> xss. upper_bind\<cdot>xss\<cdot>(\<Lambda> xs. xs))"
+
+lemma upper_map_unit [simp]:
+  "upper_map\<cdot>f\<cdot>(upper_unit\<cdot>x) = upper_unit\<cdot>(f\<cdot>x)"
+unfolding upper_map_def by simp
+
+lemma upper_map_plus [simp]:
+  "upper_map\<cdot>f\<cdot>(upper_plus\<cdot>xs\<cdot>ys) =
+   upper_plus\<cdot>(upper_map\<cdot>f\<cdot>xs)\<cdot>(upper_map\<cdot>f\<cdot>ys)"
+unfolding upper_map_def by simp
+
+lemma upper_join_unit [simp]:
+  "upper_join\<cdot>(upper_unit\<cdot>xs) = xs"
+unfolding upper_join_def by simp
+
+lemma upper_join_plus [simp]:
+  "upper_join\<cdot>(upper_plus\<cdot>xss\<cdot>yss) =
+   upper_plus\<cdot>(upper_join\<cdot>xss)\<cdot>(upper_join\<cdot>yss)"
+unfolding upper_join_def by simp
+
+lemma upper_map_ident: "upper_map\<cdot>(\<Lambda> x. x)\<cdot>xs = xs"
+by (induct xs rule: upper_pd_induct, simp_all)
+
+lemma upper_map_map:
+  "upper_map\<cdot>f\<cdot>(upper_map\<cdot>g\<cdot>xs) = upper_map\<cdot>(\<Lambda> x. f\<cdot>(g\<cdot>x))\<cdot>xs"
+by (induct xs rule: upper_pd_induct, simp_all)
+
+lemma upper_join_map_unit:
+  "upper_join\<cdot>(upper_map\<cdot>upper_unit\<cdot>xs) = xs"
+by (induct xs rule: upper_pd_induct, simp_all)
+
+lemma upper_join_map_join:
+  "upper_join\<cdot>(upper_map\<cdot>upper_join\<cdot>xsss) = upper_join\<cdot>(upper_join\<cdot>xsss)"
+by (induct xsss rule: upper_pd_induct, simp_all)
+
+lemma upper_join_map_map:
+  "upper_join\<cdot>(upper_map\<cdot>(upper_map\<cdot>f)\<cdot>xss) =
+   upper_map\<cdot>f\<cdot>(upper_join\<cdot>xss)"
+by (induct xss rule: upper_pd_induct, simp_all)
+
+lemma upper_map_approx: "upper_map\<cdot>(approx n)\<cdot>xs = approx n\<cdot>xs"
+by (induct xs rule: upper_pd_induct, simp_all)
+
+end