diff -r 4094d788b904 -r 7c6265ba6d43 src/HOLCF/Domain.thy --- a/src/HOLCF/Domain.thy Wed Nov 10 18:15:21 2010 -0800 +++ b/src/HOLCF/Domain.thy Wed Nov 10 18:30:17 2010 -0800 @@ -5,10 +5,330 @@ header {* Domain package *} theory Domain -imports Representable +imports Bifinite Domain_Aux uses - "Tools/Domain/domain_axioms.ML" - "Tools/Domain/domain.ML" + ("Tools/repdef.ML") + ("Tools/Domain/domain_isomorphism.ML") + ("Tools/Domain/domain_axioms.ML") + ("Tools/Domain/domain.ML") begin +default_sort "domain" + +subsection {* Representations of types *} + +lemma emb_prj: "emb\((prj\x)::'a) = cast\DEFL('a)\x" +by (simp add: cast_DEFL) + +lemma emb_prj_emb: + fixes x :: "'a" + assumes "DEFL('a) \ DEFL('b)" + shows "emb\(prj\(emb\x) :: 'b) = emb\x" +unfolding emb_prj +apply (rule cast.belowD) +apply (rule monofun_cfun_arg [OF assms]) +apply (simp add: cast_DEFL) +done + +lemma prj_emb_prj: + assumes "DEFL('a) \ DEFL('b)" + shows "prj\(emb\(prj\x :: 'b)) = (prj\x :: 'a)" + apply (rule emb_eq_iff [THEN iffD1]) + apply (simp only: emb_prj) + apply (rule deflation_below_comp1) + apply (rule deflation_cast) + apply (rule deflation_cast) + apply (rule monofun_cfun_arg [OF assms]) +done + +text {* Isomorphism lemmas used internally by the domain package: *} + +lemma domain_abs_iso: + fixes abs and rep + assumes DEFL: "DEFL('b) = DEFL('a)" + assumes abs_def: "(abs :: 'a \ 'b) \ prj oo emb" + assumes rep_def: "(rep :: 'b \ 'a) \ prj oo emb" + shows "rep\(abs\x) = x" +unfolding abs_def rep_def +by (simp add: emb_prj_emb DEFL) + +lemma domain_rep_iso: + fixes abs and rep + assumes DEFL: "DEFL('b) = DEFL('a)" + assumes abs_def: "(abs :: 'a \ 'b) \ prj oo emb" + assumes rep_def: "(rep :: 'b \ 'a) \ prj oo emb" + shows "abs\(rep\x) = x" +unfolding abs_def rep_def +by (simp add: emb_prj_emb DEFL) + +subsection {* Deflations as sets *} + +definition defl_set :: "defl \ udom set" +where "defl_set A = {x. cast\A\x = x}" + +lemma adm_defl_set: "adm (\x. x \ defl_set A)" +unfolding defl_set_def by simp + +lemma defl_set_bottom: "\ \ defl_set A" +unfolding defl_set_def by simp + +lemma defl_set_cast [simp]: "cast\A\x \ defl_set A" +unfolding defl_set_def by simp + +lemma defl_set_subset_iff: "defl_set A \ defl_set B \ A \ B" +apply (simp add: defl_set_def subset_eq cast_below_cast [symmetric]) +apply (auto simp add: cast.belowI cast.belowD) +done + +subsection {* Proving a subtype is representable *} + +text {* Temporarily relax type constraints. *} + +setup {* + fold Sign.add_const_constraint + [ (@{const_name defl}, SOME @{typ "'a::pcpo itself \ defl"}) + , (@{const_name emb}, SOME @{typ "'a::pcpo \ udom"}) + , (@{const_name prj}, SOME @{typ "udom \ 'a::pcpo"}) + , (@{const_name liftdefl}, SOME @{typ "'a::pcpo itself \ defl"}) + , (@{const_name liftemb}, SOME @{typ "'a::pcpo u \ udom"}) + , (@{const_name liftprj}, SOME @{typ "udom \ 'a::pcpo u"}) ] +*} + +lemma typedef_rep_class: + fixes Rep :: "'a::pcpo \ udom" + fixes Abs :: "udom \ 'a::pcpo" + fixes t :: defl + assumes type: "type_definition Rep Abs (defl_set t)" + assumes below: "op \ \ \x y. Rep x \ Rep y" + assumes emb: "emb \ (\ x. Rep x)" + assumes prj: "prj \ (\ x. Abs (cast\t\x))" + assumes defl: "defl \ (\ a::'a itself. t)" + assumes liftemb: "(liftemb :: 'a u \ udom) \ udom_emb u_approx oo u_map\emb" + assumes liftprj: "(liftprj :: udom \ 'a u) \ u_map\prj oo udom_prj u_approx" + assumes liftdefl: "(liftdefl :: 'a itself \ defl) \ (\t. u_defl\DEFL('a))" + shows "OFCLASS('a, liftdomain_class)" +using liftemb [THEN meta_eq_to_obj_eq] +using liftprj [THEN meta_eq_to_obj_eq] +proof (rule liftdomain_class_intro) + have emb_beta: "\x. emb\x = Rep x" + unfolding emb + apply (rule beta_cfun) + apply (rule typedef_cont_Rep [OF type below adm_defl_set]) + done + have prj_beta: "\y. prj\y = Abs (cast\t\y)" + unfolding prj + apply (rule beta_cfun) + apply (rule typedef_cont_Abs [OF type below adm_defl_set]) + apply simp_all + done + have prj_emb: "\x::'a. prj\(emb\x) = x" + using type_definition.Rep [OF type] + unfolding prj_beta emb_beta defl_set_def + by (simp add: type_definition.Rep_inverse [OF type]) + have emb_prj: "\y. emb\(prj\y :: 'a) = cast\t\y" + unfolding prj_beta emb_beta + by (simp add: type_definition.Abs_inverse [OF type]) + show "ep_pair (emb :: 'a \ udom) prj" + apply default + apply (simp add: prj_emb) + apply (simp add: emb_prj cast.below) + done + show "cast\DEFL('a) = emb oo (prj :: udom \ 'a)" + by (rule cfun_eqI, simp add: defl emb_prj) + show "LIFTDEFL('a) = u_defl\DEFL('a)" + unfolding liftdefl .. +qed + +lemma typedef_DEFL: + assumes "defl \ (\a::'a::pcpo itself. t)" + shows "DEFL('a::pcpo) = t" +unfolding assms .. + +text {* Restore original typing constraints. *} + +setup {* + fold Sign.add_const_constraint + [ (@{const_name defl}, SOME @{typ "'a::domain itself \ defl"}) + , (@{const_name emb}, SOME @{typ "'a::domain \ udom"}) + , (@{const_name prj}, SOME @{typ "udom \ 'a::domain"}) + , (@{const_name liftdefl}, SOME @{typ "'a::predomain itself \ defl"}) + , (@{const_name liftemb}, SOME @{typ "'a::predomain u \ udom"}) + , (@{const_name liftprj}, SOME @{typ "udom \ 'a::predomain u"}) ] +*} + +use "Tools/repdef.ML" + +subsection {* Isomorphic deflations *} + +definition + isodefl :: "('a \ 'a) \ defl \ bool" +where + "isodefl d t \ cast\t = emb oo d oo prj" + +lemma isodeflI: "(\x. cast\t\x = emb\(d\(prj\x))) \ isodefl d t" +unfolding isodefl_def by (simp add: cfun_eqI) + +lemma cast_isodefl: "isodefl d t \ cast\t = (\ x. emb\(d\(prj\x)))" +unfolding isodefl_def by (simp add: cfun_eqI) + +lemma isodefl_strict: "isodefl d t \ d\\ = \" +unfolding isodefl_def +by (drule cfun_fun_cong [where x="\"], simp) + +lemma isodefl_imp_deflation: + fixes d :: "'a \ 'a" + assumes "isodefl d t" shows "deflation d" +proof + note assms [unfolded isodefl_def, simp] + fix x :: 'a + show "d\(d\x) = d\x" + using cast.idem [of t "emb\x"] by simp + show "d\x \ x" + using cast.below [of t "emb\x"] by simp +qed + +lemma isodefl_ID_DEFL: "isodefl (ID :: 'a \ 'a) DEFL('a)" +unfolding isodefl_def by (simp add: cast_DEFL) + +lemma isodefl_LIFTDEFL: + "isodefl (u_map\(ID :: 'a \ 'a)) LIFTDEFL('a::predomain)" +unfolding u_map_ID DEFL_u [symmetric] +by (rule isodefl_ID_DEFL) + +lemma isodefl_DEFL_imp_ID: "isodefl (d :: 'a \ 'a) DEFL('a) \ d = ID" +unfolding isodefl_def +apply (simp add: cast_DEFL) +apply (simp add: cfun_eq_iff) +apply (rule allI) +apply (drule_tac x="emb\x" in spec) +apply simp +done + +lemma isodefl_bottom: "isodefl \ \" +unfolding isodefl_def by (simp add: cfun_eq_iff) + +lemma adm_isodefl: + "cont f \ cont g \ adm (\x. isodefl (f x) (g x))" +unfolding isodefl_def by simp + +lemma isodefl_lub: + assumes "chain d" and "chain t" + assumes "\i. isodefl (d i) (t i)" + shows "isodefl (\i. d i) (\i. t i)" +using prems unfolding isodefl_def +by (simp add: contlub_cfun_arg contlub_cfun_fun) + +lemma isodefl_fix: + assumes "\d t. isodefl d t \ isodefl (f\d) (g\t)" + shows "isodefl (fix\f) (fix\g)" +unfolding fix_def2 +apply (rule isodefl_lub, simp, simp) +apply (induct_tac i) +apply (simp add: isodefl_bottom) +apply (simp add: assms) +done + +lemma isodefl_abs_rep: + fixes abs and rep and d + assumes DEFL: "DEFL('b) = DEFL('a)" + assumes abs_def: "(abs :: 'a \ 'b) \ prj oo emb" + assumes rep_def: "(rep :: 'b \ 'a) \ prj oo emb" + shows "isodefl d t \ isodefl (abs oo d oo rep) t" +unfolding isodefl_def +by (simp add: cfun_eq_iff assms prj_emb_prj emb_prj_emb) + +lemma isodefl_cfun: + "isodefl d1 t1 \ isodefl d2 t2 \ + isodefl (cfun_map\d1\d2) (cfun_defl\t1\t2)" +apply (rule isodeflI) +apply (simp add: cast_cfun_defl cast_isodefl) +apply (simp add: emb_cfun_def prj_cfun_def) +apply (simp add: cfun_map_map cfcomp1) +done + +lemma isodefl_ssum: + "isodefl d1 t1 \ isodefl d2 t2 \ + isodefl (ssum_map\d1\d2) (ssum_defl\t1\t2)" +apply (rule isodeflI) +apply (simp add: cast_ssum_defl cast_isodefl) +apply (simp add: emb_ssum_def prj_ssum_def) +apply (simp add: ssum_map_map isodefl_strict) +done + +lemma isodefl_sprod: + "isodefl d1 t1 \ isodefl d2 t2 \ + isodefl (sprod_map\d1\d2) (sprod_defl\t1\t2)" +apply (rule isodeflI) +apply (simp add: cast_sprod_defl cast_isodefl) +apply (simp add: emb_sprod_def prj_sprod_def) +apply (simp add: sprod_map_map isodefl_strict) +done + +lemma isodefl_cprod: + "isodefl d1 t1 \ isodefl d2 t2 \ + isodefl (cprod_map\d1\d2) (prod_defl\t1\t2)" +apply (rule isodeflI) +apply (simp add: cast_prod_defl cast_isodefl) +apply (simp add: emb_prod_def prj_prod_def) +apply (simp add: cprod_map_map cfcomp1) +done + +lemma isodefl_u: + fixes d :: "'a::liftdomain \ 'a" + shows "isodefl (d :: 'a \ 'a) t \ isodefl (u_map\d) (u_defl\t)" +apply (rule isodeflI) +apply (simp add: cast_u_defl cast_isodefl) +apply (simp add: emb_u_def prj_u_def liftemb_eq liftprj_eq) +apply (simp add: u_map_map) +done + +lemma encode_prod_u_map: + "encode_prod_u\(u_map\(cprod_map\f\g)\(decode_prod_u\x)) + = sprod_map\(u_map\f)\(u_map\g)\x" +unfolding encode_prod_u_def decode_prod_u_def +apply (case_tac x, simp, rename_tac a b) +apply (case_tac a, simp, case_tac b, simp, simp) +done + +lemma isodefl_cprod_u: + assumes "isodefl (u_map\d1) t1" and "isodefl (u_map\d2) t2" + shows "isodefl (u_map\(cprod_map\d1\d2)) (sprod_defl\t1\t2)" +using assms unfolding isodefl_def +apply (simp add: emb_u_def prj_u_def liftemb_prod_def liftprj_prod_def) +apply (simp add: emb_u_def [symmetric] prj_u_def [symmetric]) +apply (simp add: cfcomp1 encode_prod_u_map cast_sprod_defl sprod_map_map) +done + +subsection {* Setting up the domain package *} + +use "Tools/Domain/domain_isomorphism.ML" +use "Tools/Domain/domain_axioms.ML" +use "Tools/Domain/domain.ML" + +setup Domain_Isomorphism.setup + +lemmas [domain_defl_simps] = + DEFL_cfun DEFL_ssum DEFL_sprod DEFL_prod DEFL_u + liftdefl_eq LIFTDEFL_prod + +lemmas [domain_map_ID] = + cfun_map_ID ssum_map_ID sprod_map_ID cprod_map_ID u_map_ID + +lemmas [domain_isodefl] = + isodefl_u isodefl_cfun isodefl_ssum isodefl_sprod + isodefl_cprod isodefl_cprod_u + +lemmas [domain_deflation] = + deflation_cfun_map deflation_ssum_map deflation_sprod_map + deflation_cprod_map deflation_u_map + +setup {* + fold Domain_Take_Proofs.add_map_function + [(@{type_name cfun}, @{const_name cfun_map}, [true, true]), + (@{type_name ssum}, @{const_name ssum_map}, [true, true]), + (@{type_name sprod}, @{const_name sprod_map}, [true, true]), + (@{type_name prod}, @{const_name cprod_map}, [true, true]), + (@{type_name "u"}, @{const_name u_map}, [true])] +*} + end