|
1 (* Title: HOLCF/Sum_Cpo.thy |
|
2 Author: Brian Huffman |
|
3 *) |
|
4 |
|
5 header {* The cpo of disjoint sums *} |
|
6 |
|
7 theory Sum_Cpo |
|
8 imports HOLCF |
|
9 begin |
|
10 |
|
11 subsection {* Ordering on sum type *} |
|
12 |
|
13 instantiation sum :: (below, below) below |
|
14 begin |
|
15 |
|
16 definition below_sum_def: |
|
17 "x \<sqsubseteq> y \<equiv> case x of |
|
18 Inl a \<Rightarrow> (case y of Inl b \<Rightarrow> a \<sqsubseteq> b | Inr b \<Rightarrow> False) | |
|
19 Inr a \<Rightarrow> (case y of Inl b \<Rightarrow> False | Inr b \<Rightarrow> a \<sqsubseteq> b)" |
|
20 |
|
21 instance .. |
|
22 end |
|
23 |
|
24 lemma Inl_below_Inl [simp]: "Inl x \<sqsubseteq> Inl y \<longleftrightarrow> x \<sqsubseteq> y" |
|
25 unfolding below_sum_def by simp |
|
26 |
|
27 lemma Inr_below_Inr [simp]: "Inr x \<sqsubseteq> Inr y \<longleftrightarrow> x \<sqsubseteq> y" |
|
28 unfolding below_sum_def by simp |
|
29 |
|
30 lemma Inl_below_Inr [simp]: "\<not> Inl x \<sqsubseteq> Inr y" |
|
31 unfolding below_sum_def by simp |
|
32 |
|
33 lemma Inr_below_Inl [simp]: "\<not> Inr x \<sqsubseteq> Inl y" |
|
34 unfolding below_sum_def by simp |
|
35 |
|
36 lemma Inl_mono: "x \<sqsubseteq> y \<Longrightarrow> Inl x \<sqsubseteq> Inl y" |
|
37 by simp |
|
38 |
|
39 lemma Inr_mono: "x \<sqsubseteq> y \<Longrightarrow> Inr x \<sqsubseteq> Inr y" |
|
40 by simp |
|
41 |
|
42 lemma Inl_belowE: "\<lbrakk>Inl a \<sqsubseteq> x; \<And>b. \<lbrakk>x = Inl b; a \<sqsubseteq> b\<rbrakk> \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R" |
|
43 by (cases x, simp_all) |
|
44 |
|
45 lemma Inr_belowE: "\<lbrakk>Inr a \<sqsubseteq> x; \<And>b. \<lbrakk>x = Inr b; a \<sqsubseteq> b\<rbrakk> \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R" |
|
46 by (cases x, simp_all) |
|
47 |
|
48 lemmas sum_below_elims = Inl_belowE Inr_belowE |
|
49 |
|
50 lemma sum_below_cases: |
|
51 "\<lbrakk>x \<sqsubseteq> y; |
|
52 \<And>a b. \<lbrakk>x = Inl a; y = Inl b; a \<sqsubseteq> b\<rbrakk> \<Longrightarrow> R; |
|
53 \<And>a b. \<lbrakk>x = Inr a; y = Inr b; a \<sqsubseteq> b\<rbrakk> \<Longrightarrow> R\<rbrakk> |
|
54 \<Longrightarrow> R" |
|
55 by (cases x, safe elim!: sum_below_elims, auto) |
|
56 |
|
57 subsection {* Sum type is a complete partial order *} |
|
58 |
|
59 instance sum :: (po, po) po |
|
60 proof |
|
61 fix x :: "'a + 'b" |
|
62 show "x \<sqsubseteq> x" |
|
63 by (induct x, simp_all) |
|
64 next |
|
65 fix x y :: "'a + 'b" |
|
66 assume "x \<sqsubseteq> y" and "y \<sqsubseteq> x" thus "x = y" |
|
67 by (induct x, auto elim!: sum_below_elims intro: below_antisym) |
|
68 next |
|
69 fix x y z :: "'a + 'b" |
|
70 assume "x \<sqsubseteq> y" and "y \<sqsubseteq> z" thus "x \<sqsubseteq> z" |
|
71 by (induct x, auto elim!: sum_below_elims intro: below_trans) |
|
72 qed |
|
73 |
|
74 lemma monofun_inv_Inl: "monofun (\<lambda>p. THE a. p = Inl a)" |
|
75 by (rule monofunI, erule sum_below_cases, simp_all) |
|
76 |
|
77 lemma monofun_inv_Inr: "monofun (\<lambda>p. THE b. p = Inr b)" |
|
78 by (rule monofunI, erule sum_below_cases, simp_all) |
|
79 |
|
80 lemma sum_chain_cases: |
|
81 assumes Y: "chain Y" |
|
82 assumes A: "\<And>A. \<lbrakk>chain A; Y = (\<lambda>i. Inl (A i))\<rbrakk> \<Longrightarrow> R" |
|
83 assumes B: "\<And>B. \<lbrakk>chain B; Y = (\<lambda>i. Inr (B i))\<rbrakk> \<Longrightarrow> R" |
|
84 shows "R" |
|
85 apply (cases "Y 0") |
|
86 apply (rule A) |
|
87 apply (rule ch2ch_monofun [OF monofun_inv_Inl Y]) |
|
88 apply (rule ext) |
|
89 apply (cut_tac j=i in chain_mono [OF Y le0], simp) |
|
90 apply (erule Inl_belowE, simp) |
|
91 apply (rule B) |
|
92 apply (rule ch2ch_monofun [OF monofun_inv_Inr Y]) |
|
93 apply (rule ext) |
|
94 apply (cut_tac j=i in chain_mono [OF Y le0], simp) |
|
95 apply (erule Inr_belowE, simp) |
|
96 done |
|
97 |
|
98 lemma is_lub_Inl: "range S <<| x \<Longrightarrow> range (\<lambda>i. Inl (S i)) <<| Inl x" |
|
99 apply (rule is_lubI) |
|
100 apply (rule ub_rangeI) |
|
101 apply (simp add: is_lub_rangeD1) |
|
102 apply (frule ub_rangeD [where i=arbitrary]) |
|
103 apply (erule Inl_belowE, simp) |
|
104 apply (erule is_lubD2) |
|
105 apply (rule ub_rangeI) |
|
106 apply (drule ub_rangeD, simp) |
|
107 done |
|
108 |
|
109 lemma is_lub_Inr: "range S <<| x \<Longrightarrow> range (\<lambda>i. Inr (S i)) <<| Inr x" |
|
110 apply (rule is_lubI) |
|
111 apply (rule ub_rangeI) |
|
112 apply (simp add: is_lub_rangeD1) |
|
113 apply (frule ub_rangeD [where i=arbitrary]) |
|
114 apply (erule Inr_belowE, simp) |
|
115 apply (erule is_lubD2) |
|
116 apply (rule ub_rangeI) |
|
117 apply (drule ub_rangeD, simp) |
|
118 done |
|
119 |
|
120 instance sum :: (cpo, cpo) cpo |
|
121 apply intro_classes |
|
122 apply (erule sum_chain_cases, safe) |
|
123 apply (rule exI) |
|
124 apply (rule is_lub_Inl) |
|
125 apply (erule cpo_lubI) |
|
126 apply (rule exI) |
|
127 apply (rule is_lub_Inr) |
|
128 apply (erule cpo_lubI) |
|
129 done |
|
130 |
|
131 subsection {* Continuity of \emph{Inl}, \emph{Inr}, and case function *} |
|
132 |
|
133 lemma cont_Inl: "cont Inl" |
|
134 by (intro contI is_lub_Inl cpo_lubI) |
|
135 |
|
136 lemma cont_Inr: "cont Inr" |
|
137 by (intro contI is_lub_Inr cpo_lubI) |
|
138 |
|
139 lemmas cont2cont_Inl [simp, cont2cont] = cont_compose [OF cont_Inl] |
|
140 lemmas cont2cont_Inr [simp, cont2cont] = cont_compose [OF cont_Inr] |
|
141 |
|
142 lemmas ch2ch_Inl [simp] = ch2ch_cont [OF cont_Inl] |
|
143 lemmas ch2ch_Inr [simp] = ch2ch_cont [OF cont_Inr] |
|
144 |
|
145 lemmas lub_Inl = cont2contlubE [OF cont_Inl, symmetric] |
|
146 lemmas lub_Inr = cont2contlubE [OF cont_Inr, symmetric] |
|
147 |
|
148 lemma cont_sum_case1: |
|
149 assumes f: "\<And>a. cont (\<lambda>x. f x a)" |
|
150 assumes g: "\<And>b. cont (\<lambda>x. g x b)" |
|
151 shows "cont (\<lambda>x. case y of Inl a \<Rightarrow> f x a | Inr b \<Rightarrow> g x b)" |
|
152 by (induct y, simp add: f, simp add: g) |
|
153 |
|
154 lemma cont_sum_case2: "\<lbrakk>cont f; cont g\<rbrakk> \<Longrightarrow> cont (sum_case f g)" |
|
155 apply (rule contI) |
|
156 apply (erule sum_chain_cases) |
|
157 apply (simp add: cont2contlubE [OF cont_Inl, symmetric] contE) |
|
158 apply (simp add: cont2contlubE [OF cont_Inr, symmetric] contE) |
|
159 done |
|
160 |
|
161 lemma cont2cont_sum_case: |
|
162 assumes f1: "\<And>a. cont (\<lambda>x. f x a)" and f2: "\<And>x. cont (\<lambda>a. f x a)" |
|
163 assumes g1: "\<And>b. cont (\<lambda>x. g x b)" and g2: "\<And>x. cont (\<lambda>b. g x b)" |
|
164 assumes h: "cont (\<lambda>x. h x)" |
|
165 shows "cont (\<lambda>x. case h x of Inl a \<Rightarrow> f x a | Inr b \<Rightarrow> g x b)" |
|
166 apply (rule cont_apply [OF h]) |
|
167 apply (rule cont_sum_case2 [OF f2 g2]) |
|
168 apply (rule cont_sum_case1 [OF f1 g1]) |
|
169 done |
|
170 |
|
171 lemma cont2cont_sum_case' [simp, cont2cont]: |
|
172 assumes f: "cont (\<lambda>p. f (fst p) (snd p))" |
|
173 assumes g: "cont (\<lambda>p. g (fst p) (snd p))" |
|
174 assumes h: "cont (\<lambda>x. h x)" |
|
175 shows "cont (\<lambda>x. case h x of Inl a \<Rightarrow> f x a | Inr b \<Rightarrow> g x b)" |
|
176 using assms by (simp add: cont2cont_sum_case prod_cont_iff) |
|
177 |
|
178 subsection {* Compactness and chain-finiteness *} |
|
179 |
|
180 lemma compact_Inl: "compact a \<Longrightarrow> compact (Inl a)" |
|
181 apply (rule compactI2) |
|
182 apply (erule sum_chain_cases, safe) |
|
183 apply (simp add: lub_Inl) |
|
184 apply (erule (2) compactD2) |
|
185 apply (simp add: lub_Inr) |
|
186 done |
|
187 |
|
188 lemma compact_Inr: "compact a \<Longrightarrow> compact (Inr a)" |
|
189 apply (rule compactI2) |
|
190 apply (erule sum_chain_cases, safe) |
|
191 apply (simp add: lub_Inl) |
|
192 apply (simp add: lub_Inr) |
|
193 apply (erule (2) compactD2) |
|
194 done |
|
195 |
|
196 lemma compact_Inl_rev: "compact (Inl a) \<Longrightarrow> compact a" |
|
197 unfolding compact_def |
|
198 by (drule adm_subst [OF cont_Inl], simp) |
|
199 |
|
200 lemma compact_Inr_rev: "compact (Inr a) \<Longrightarrow> compact a" |
|
201 unfolding compact_def |
|
202 by (drule adm_subst [OF cont_Inr], simp) |
|
203 |
|
204 lemma compact_Inl_iff [simp]: "compact (Inl a) = compact a" |
|
205 by (safe elim!: compact_Inl compact_Inl_rev) |
|
206 |
|
207 lemma compact_Inr_iff [simp]: "compact (Inr a) = compact a" |
|
208 by (safe elim!: compact_Inr compact_Inr_rev) |
|
209 |
|
210 instance sum :: (chfin, chfin) chfin |
|
211 apply intro_classes |
|
212 apply (erule compact_imp_max_in_chain) |
|
213 apply (case_tac "\<Squnion>i. Y i", simp_all) |
|
214 done |
|
215 |
|
216 instance sum :: (discrete_cpo, discrete_cpo) discrete_cpo |
|
217 by intro_classes (simp add: below_sum_def split: sum.split) |
|
218 |
|
219 subsection {* Using sum types with fixrec *} |
|
220 |
|
221 definition |
|
222 "match_Inl = (\<Lambda> x k. case x of Inl a \<Rightarrow> k\<cdot>a | Inr b \<Rightarrow> Fixrec.fail)" |
|
223 |
|
224 definition |
|
225 "match_Inr = (\<Lambda> x k. case x of Inl a \<Rightarrow> Fixrec.fail | Inr b \<Rightarrow> k\<cdot>b)" |
|
226 |
|
227 lemma match_Inl_simps [simp]: |
|
228 "match_Inl\<cdot>(Inl a)\<cdot>k = k\<cdot>a" |
|
229 "match_Inl\<cdot>(Inr b)\<cdot>k = Fixrec.fail" |
|
230 unfolding match_Inl_def by simp_all |
|
231 |
|
232 lemma match_Inr_simps [simp]: |
|
233 "match_Inr\<cdot>(Inl a)\<cdot>k = Fixrec.fail" |
|
234 "match_Inr\<cdot>(Inr b)\<cdot>k = k\<cdot>b" |
|
235 unfolding match_Inr_def by simp_all |
|
236 |
|
237 setup {* |
|
238 Fixrec.add_matchers |
|
239 [ (@{const_name Inl}, @{const_name match_Inl}), |
|
240 (@{const_name Inr}, @{const_name match_Inr}) ] |
|
241 *} |
|
242 |
|
243 subsection {* Disjoint sum is a predomain *} |
|
244 |
|
245 definition |
|
246 "encode_sum_u = |
|
247 (\<Lambda>(up\<cdot>x). case x of Inl a \<Rightarrow> sinl\<cdot>(up\<cdot>a) | Inr b \<Rightarrow> sinr\<cdot>(up\<cdot>b))" |
|
248 |
|
249 definition |
|
250 "decode_sum_u = sscase\<cdot>(\<Lambda>(up\<cdot>a). up\<cdot>(Inl a))\<cdot>(\<Lambda>(up\<cdot>b). up\<cdot>(Inr b))" |
|
251 |
|
252 lemma decode_encode_sum_u [simp]: "decode_sum_u\<cdot>(encode_sum_u\<cdot>x) = x" |
|
253 unfolding decode_sum_u_def encode_sum_u_def |
|
254 by (case_tac x, simp, rename_tac y, case_tac y, simp_all) |
|
255 |
|
256 lemma encode_decode_sum_u [simp]: "encode_sum_u\<cdot>(decode_sum_u\<cdot>x) = x" |
|
257 unfolding decode_sum_u_def encode_sum_u_def |
|
258 apply (case_tac x, simp) |
|
259 apply (rename_tac a, case_tac a, simp, simp) |
|
260 apply (rename_tac b, case_tac b, simp, simp) |
|
261 done |
|
262 |
|
263 instantiation sum :: (predomain, predomain) predomain |
|
264 begin |
|
265 |
|
266 definition |
|
267 "liftemb = (udom_emb ssum_approx oo ssum_map\<cdot>emb\<cdot>emb) oo encode_sum_u" |
|
268 |
|
269 definition |
|
270 "liftprj = |
|
271 decode_sum_u oo (ssum_map\<cdot>prj\<cdot>prj oo udom_prj ssum_approx)" |
|
272 |
|
273 definition |
|
274 "liftdefl (t::('a + 'b) itself) = ssum_defl\<cdot>DEFL('a u)\<cdot>DEFL('b u)" |
|
275 |
|
276 instance proof |
|
277 show "ep_pair liftemb (liftprj :: udom \<rightarrow> ('a + 'b) u)" |
|
278 unfolding liftemb_sum_def liftprj_sum_def |
|
279 apply (rule ep_pair_comp) |
|
280 apply (rule ep_pair.intro, simp, simp) |
|
281 apply (rule ep_pair_comp) |
|
282 apply (intro ep_pair_ssum_map ep_pair_emb_prj) |
|
283 apply (rule ep_pair_udom [OF ssum_approx]) |
|
284 done |
|
285 show "cast\<cdot>LIFTDEFL('a + 'b) = liftemb oo (liftprj :: udom \<rightarrow> ('a + 'b) u)" |
|
286 unfolding liftemb_sum_def liftprj_sum_def liftdefl_sum_def |
|
287 by (simp add: cast_ssum_defl cast_DEFL cfcomp1 ssum_map_map) |
|
288 qed |
|
289 |
|
290 end |
|
291 |
|
292 end |