3 *) |
3 *) |
4 |
4 |
5 header {* Predomain class instance for HOL list type *} |
5 header {* Predomain class instance for HOL list type *} |
6 |
6 |
7 theory List_Predomain |
7 theory List_Predomain |
8 imports List_Cpo |
8 imports List_Cpo Sum_Cpo |
9 begin |
9 begin |
10 |
10 |
11 subsection {* Strict list type *} |
11 subsection {* Strict list type *} |
12 |
12 |
13 domain 'a slist = SNil | SCons "'a" "'a slist" |
13 domain 'a slist = SNil | SCons "'a" "'a slist" |
|
14 |
|
15 text {* Polymorphic map function for strict lists. *} |
|
16 |
|
17 text {* FIXME: The domain package should generate this! *} |
|
18 |
|
19 fixrec slist_map' :: "('a \<rightarrow> 'b) \<rightarrow> 'a slist \<rightarrow> 'b slist" |
|
20 where "slist_map'\<cdot>f\<cdot>SNil = SNil" |
|
21 | "\<lbrakk>x \<noteq> \<bottom>; xs \<noteq> \<bottom>\<rbrakk> \<Longrightarrow> |
|
22 slist_map'\<cdot>f\<cdot>(SCons\<cdot>x\<cdot>xs) = SCons\<cdot>(f\<cdot>x)\<cdot>(slist_map'\<cdot>f\<cdot>xs)" |
|
23 |
|
24 lemma slist_map'_strict [simp]: "slist_map'\<cdot>f\<cdot>\<bottom> = \<bottom>" |
|
25 by fixrec_simp |
|
26 |
|
27 lemma slist_map_conv [simp]: "slist_map = slist_map'" |
|
28 apply (rule cfun_eqI, rule cfun_eqI, rename_tac f xs) |
|
29 apply (induct_tac xs, simp_all) |
|
30 apply (subst slist_map_unfold, simp) |
|
31 apply (subst slist_map_unfold, simp add: SNil_def) |
|
32 apply (subst slist_map_unfold, simp add: SCons_def) |
|
33 done |
|
34 |
|
35 lemma slist_map'_slist_map': |
|
36 "f\<cdot>\<bottom> = \<bottom> \<Longrightarrow> slist_map'\<cdot>f\<cdot>(slist_map'\<cdot>g\<cdot>xs) = slist_map'\<cdot>(\<Lambda> x. f\<cdot>(g\<cdot>x))\<cdot>xs" |
|
37 apply (induct xs, simp, simp) |
|
38 apply (case_tac "g\<cdot>a = \<bottom>", simp, simp) |
|
39 apply (case_tac "slist_map'\<cdot>g\<cdot>xs = \<bottom>", simp, simp) |
|
40 done |
|
41 |
|
42 lemma slist_map'_oo: |
|
43 "f\<cdot>\<bottom> = \<bottom> \<Longrightarrow> slist_map'\<cdot>(f oo g) = slist_map'\<cdot>f oo slist_map'\<cdot>g" |
|
44 by (simp add: cfcomp1 slist_map'_slist_map' eta_cfun) |
|
45 |
|
46 lemma slist_map'_ID: "slist_map'\<cdot>ID = ID" |
|
47 by (rule cfun_eqI, induct_tac x, simp_all) |
|
48 |
|
49 lemma ep_pair_slist_map': |
|
50 "ep_pair e p \<Longrightarrow> ep_pair (slist_map'\<cdot>e) (slist_map'\<cdot>p)" |
|
51 apply (rule ep_pair.intro) |
|
52 apply (subst slist_map'_slist_map') |
|
53 apply (erule pcpo_ep_pair.p_strict [unfolded pcpo_ep_pair_def]) |
|
54 apply (simp add: ep_pair.e_inverse ID_def [symmetric] slist_map'_ID) |
|
55 apply (subst slist_map'_slist_map') |
|
56 apply (erule pcpo_ep_pair.e_strict [unfolded pcpo_ep_pair_def]) |
|
57 apply (rule below_eq_trans [OF _ ID1]) |
|
58 apply (subst slist_map'_ID [symmetric]) |
|
59 apply (intro monofun_cfun below_refl) |
|
60 apply (simp add: cfun_below_iff ep_pair.e_p_below) |
|
61 done |
14 |
62 |
15 text {* |
63 text {* |
16 Types @{typ "'a list u"}. and @{typ "'a u slist"} are isomorphic. |
64 Types @{typ "'a list u"}. and @{typ "'a u slist"} are isomorphic. |
17 *} |
65 *} |
18 |
66 |
46 apply (case_tac "decode_list_u\<cdot>y", simp, simp) |
94 apply (case_tac "decode_list_u\<cdot>y", simp, simp) |
47 done |
95 done |
48 |
96 |
49 subsection {* Lists are a predomain *} |
97 subsection {* Lists are a predomain *} |
50 |
98 |
|
99 definition udefl :: "udom defl \<rightarrow> udom u defl" |
|
100 where "udefl = defl_fun1 (strictify\<cdot>up) (fup\<cdot>ID) ID" |
|
101 |
|
102 lemma cast_udefl: |
|
103 "cast\<cdot>(udefl\<cdot>t) = strictify\<cdot>up oo cast\<cdot>t oo fup\<cdot>ID" |
|
104 unfolding udefl_def by (simp add: cast_defl_fun1 ep_pair_strictify_up) |
|
105 |
|
106 definition list_liftdefl :: "udom u defl \<rightarrow> udom u defl" |
|
107 where "list_liftdefl = (\<Lambda> a. udefl\<cdot>(slist_defl\<cdot>(u_defl\<cdot>a)))" |
|
108 |
|
109 lemma cast_slist_defl: "cast\<cdot>(slist_defl\<cdot>a) = emb oo slist_map\<cdot>(cast\<cdot>a) oo prj" |
|
110 using isodefl_slist [where fa="cast\<cdot>a" and da="a"] |
|
111 unfolding isodefl_def by simp |
|
112 |
|
113 lemma u_emb_bottom: "u_emb\<cdot>\<bottom> = \<bottom>" |
|
114 by (rule pcpo_ep_pair.e_strict [unfolded pcpo_ep_pair_def, OF ep_pair_u]) |
|
115 |
51 instantiation list :: (predomain) predomain |
116 instantiation list :: (predomain) predomain |
52 begin |
117 begin |
53 |
118 |
54 definition |
119 definition |
55 "liftemb = emb oo encode_list_u" |
120 "liftemb = (strictify\<cdot>up oo emb oo slist_map'\<cdot>u_emb) oo slist_map'\<cdot>liftemb oo encode_list_u" |
56 |
121 |
57 definition |
122 definition |
58 "liftprj = decode_list_u oo prj" |
123 "liftprj = (decode_list_u oo slist_map'\<cdot>liftprj) oo (slist_map'\<cdot>u_prj oo prj) oo fup\<cdot>ID" |
59 |
124 |
60 definition |
125 definition |
61 "liftdefl (t::('a list) itself) = DEFL(('a\<^sub>\<bottom>) slist)" |
126 "liftdefl (t::('a list) itself) = list_liftdefl\<cdot>LIFTDEFL('a)" |
62 |
127 |
63 instance proof |
128 instance proof |
64 have "ep_pair encode_list_u decode_list_u" |
129 show "ep_pair liftemb (liftprj :: udom u \<rightarrow> ('a list) u)" |
65 by (rule ep_pair.intro, simp_all) |
|
66 thus "ep_pair liftemb (liftprj :: udom \<rightarrow> ('a list) u)" |
|
67 unfolding liftemb_list_def liftprj_list_def |
130 unfolding liftemb_list_def liftprj_list_def |
68 using ep_pair_emb_prj by (rule ep_pair_comp) |
131 by (intro ep_pair_comp ep_pair_slist_map' ep_pair_strictify_up |
69 show "cast\<cdot>LIFTDEFL('a list) = liftemb oo (liftprj :: udom \<rightarrow> ('a list) u)" |
132 ep_pair_emb_prj predomain_ep ep_pair_u, simp add: ep_pair.intro) |
|
133 show "cast\<cdot>LIFTDEFL('a list) = liftemb oo (liftprj :: udom u \<rightarrow> ('a list) u)" |
70 unfolding liftemb_list_def liftprj_list_def liftdefl_list_def |
134 unfolding liftemb_list_def liftprj_list_def liftdefl_list_def |
71 by (simp add: cfcomp1 cast_DEFL) |
135 apply (simp add: list_liftdefl_def cast_udefl cast_slist_defl cast_u_defl cast_liftdefl) |
|
136 apply (simp add: slist_map'_oo u_emb_bottom cfun_eq_iff) |
|
137 done |
72 qed |
138 qed |
73 |
139 |
74 end |
140 end |
75 |
141 |
76 lemma liftdefl_list [domain_defl_simps]: |
142 lemma liftdefl_list [domain_defl_simps]: |
77 "LIFTDEFL('a::predomain list) = slist_defl\<cdot>LIFTDEFL('a)" |
143 "LIFTDEFL('a::predomain list) = list_liftdefl\<cdot>LIFTDEFL('a)" |
78 unfolding liftdefl_list_def by (simp add: domain_defl_simps) |
144 by (rule liftdefl_list_def) |
79 |
145 |
80 subsection {* Continuous map operation for lists *} |
146 subsection {* Continuous map operation for lists *} |
81 |
147 |
82 definition |
148 definition |
83 list_map :: "('a::predomain \<rightarrow> 'b::predomain) \<rightarrow> 'a list \<rightarrow> 'b list" |
149 list_map :: "('a::predomain \<rightarrow> 'b::predomain) \<rightarrow> 'a list \<rightarrow> 'b list" |
103 subsection {* Configuring list type to work with domain package *} |
169 subsection {* Configuring list type to work with domain package *} |
104 |
170 |
105 lemma encode_list_u_map: |
171 lemma encode_list_u_map: |
106 "encode_list_u\<cdot>(u_map\<cdot>(list_map\<cdot>f)\<cdot>(decode_list_u\<cdot>xs)) |
172 "encode_list_u\<cdot>(u_map\<cdot>(list_map\<cdot>f)\<cdot>(decode_list_u\<cdot>xs)) |
107 = slist_map\<cdot>(u_map\<cdot>f)\<cdot>xs" |
173 = slist_map\<cdot>(u_map\<cdot>f)\<cdot>xs" |
108 apply (induct xs) |
174 apply (induct xs, simp, simp) |
109 apply (simp, subst slist_map_unfold, simp) |
|
110 apply (simp, subst slist_map_unfold, simp add: SNil_def) |
|
111 apply (case_tac a, simp, rename_tac b) |
175 apply (case_tac a, simp, rename_tac b) |
112 apply (case_tac "decode_list_u\<cdot>xs") |
176 apply (case_tac "decode_list_u\<cdot>xs") |
113 apply (drule_tac f="encode_list_u" in cfun_arg_cong, simp) |
177 apply (drule_tac f="encode_list_u" in cfun_arg_cong, simp, simp) |
114 by (simp, subst slist_map_unfold, simp add: SCons_def) |
178 done |
115 |
179 |
116 lemma isodefl_list_u [domain_isodefl]: |
180 lemma isodefl_list_u [domain_isodefl]: |
117 fixes d :: "'a::predomain \<rightarrow> 'a" |
181 fixes d :: "'a::predomain \<rightarrow> 'a" |
118 assumes "isodefl (u_map\<cdot>d) t" |
182 assumes "isodefl' d t" |
119 shows "isodefl (u_map\<cdot>(list_map\<cdot>d)) (slist_defl\<cdot>t)" |
183 shows "isodefl' (list_map\<cdot>d) (list_liftdefl\<cdot>t)" |
120 using assms [THEN isodefl_slist] unfolding isodefl_def |
184 using assms unfolding isodefl'_def liftemb_list_def liftprj_list_def |
121 unfolding emb_u_def prj_u_def liftemb_list_def liftprj_list_def |
185 apply (simp add: list_liftdefl_def cast_udefl cast_slist_defl cast_u_defl) |
122 by (simp add: cfcomp1 encode_list_u_map) |
186 apply (simp add: cfcomp1 encode_list_u_map) |
|
187 apply (simp add: slist_map'_slist_map' u_emb_bottom) |
|
188 done |
123 |
189 |
124 setup {* |
190 setup {* |
125 Domain_Take_Proofs.add_rec_type (@{type_name "list"}, [true]) |
191 Domain_Take_Proofs.add_rec_type (@{type_name "list"}, [true]) |
126 *} |
192 *} |
127 |
193 |