separated registration of BNFs from bnf_def (BNFs are now stored only for bnf_def and (co)data commands)
1 (* Title: HOL/Codatatype/Basic_BNFs.thy
2 Author: Dmitriy Traytel, TU Muenchen
3 Author: Andrei Popescu, TU Muenchen
4 Author: Jasmin Blanchette, TU Muenchen
7 Registration of basic types as bounded natural functors.
10 header {* Registration of Basic Types as Bounded Natural Functors *}
16 lemma wpull_id: "wpull UNIV B1 B2 id id id id"
17 unfolding wpull_def by simp
19 lemmas natLeq_card_order = natLeq_Card_order[unfolded Field_natLeq]
21 lemma ctwo_card_order: "card_order ctwo"
22 using Card_order_ctwo by (unfold ctwo_def Field_card_of)
24 lemma natLeq_cinfinite: "cinfinite natLeq"
25 unfolding cinfinite_def Field_natLeq by (rule nat_infinite)
27 bnf_def ID: "id :: ('a \<Rightarrow> 'b) \<Rightarrow> 'a \<Rightarrow> 'b" ["\<lambda>x. {x}"] "\<lambda>_:: 'a. natLeq" ["id :: 'a \<Rightarrow> 'a"]
29 apply (rule natLeq_card_order)
30 apply (rule natLeq_cinfinite)
31 apply (rule ordLess_imp_ordLeq[OF finite_ordLess_infinite[OF _ natLeq_Well_order]])
32 apply (auto simp add: Field_card_of Field_natLeq card_of_well_order_on)
33 apply (rule ordLeq_transitive)
34 apply (rule ordLeq_cexp1[of natLeq])
35 apply (rule Cinfinite_Cnotzero)
37 apply (rule natLeq_cinfinite)
38 apply (rule natLeq_Card_order)
39 apply (rule card_of_Card_order)
40 apply (rule cexp_mono1)
41 apply (rule ordLeq_csum1)
42 apply (rule card_of_Card_order)
44 apply (rule cone_ordLeq_cexp)
45 apply (rule ordLeq_transitive)
46 apply (rule cone_ordLeq_ctwo)
47 apply (rule ordLeq_csum2)
48 apply (rule Card_order_ctwo)
49 apply (rule natLeq_Card_order)
52 lemma ID_pred[simp]: "ID_pred \<phi> = \<phi>"
53 unfolding ID_pred_def ID_rel_def Gr_def fun_eq_iff by auto
55 bnf_def DEADID: "id :: 'a \<Rightarrow> 'a" [] "\<lambda>_:: 'a. natLeq +c |UNIV :: 'a set|" ["SOME x :: 'a. True"]
56 apply (auto simp add: wpull_id)
57 apply (rule card_order_csum)
58 apply (rule natLeq_card_order)
59 apply (rule card_of_card_order_on)
60 apply (rule cinfinite_csum)
62 apply (rule natLeq_cinfinite)
63 apply (rule ordLess_imp_ordLeq)
64 apply (rule ordLess_ordLeq_trans)
65 apply (rule ordLess_ctwo_cexp)
66 apply (rule card_of_Card_order)
67 apply (rule cexp_mono2'')
68 apply (rule ordLeq_csum2)
69 apply (rule card_of_Card_order)
70 apply (rule ctwo_Cnotzero)
71 by (rule card_of_Card_order)
73 lemma DEADID_pred[simp]: "DEADID_pred = (op =)"
74 unfolding DEADID_pred_def DEADID.rel_Id by simp
77 signature BASIC_BNFS =
79 val ID_bnf: BNF_Def.BNF
83 val DEADID_bnf: BNF_Def.BNF
86 structure Basic_BNFs : BASIC_BNFS =
89 val ID_bnf = the (BNF_Def.bnf_of @{context} "Basic_BNFs.ID");
90 val DEADID_bnf = the (BNF_Def.bnf_of @{context} "Basic_BNFs.DEADID");
92 val rel_def = BNF_Def.rel_def_of_bnf ID_bnf;
93 val ID_rel_def = rel_def RS sym;
94 val ID_pred_def = Local_Defs.unfold @{context} [rel_def] (BNF_Def.pred_def_of_bnf ID_bnf) RS sym;
99 definition sum_setl :: "'a + 'b \<Rightarrow> 'a set" where
100 "sum_setl x = (case x of Inl z => {z} | _ => {})"
102 definition sum_setr :: "'a + 'b \<Rightarrow> 'b set" where
103 "sum_setr x = (case x of Inr z => {z} | _ => {})"
105 lemmas sum_set_defs = sum_setl_def[abs_def] sum_setr_def[abs_def]
107 bnf_def sum_map [sum_setl, sum_setr] "\<lambda>_::'a + 'b. natLeq" [Inl, Inr]
109 show "sum_map id id = id" by (rule sum_map.id)
112 show "sum_map (g1 o f1) (g2 o f2) = sum_map g1 g2 o sum_map f1 f2"
113 by (rule sum_map.comp[symmetric])
116 assume a1: "\<And>z. z \<in> sum_setl x \<Longrightarrow> f1 z = g1 z" and
117 a2: "\<And>z. z \<in> sum_setr x \<Longrightarrow> f2 z = g2 z"
118 thus "sum_map f1 f2 x = sum_map g1 g2 x"
120 case Inl thus ?thesis using a1 by (clarsimp simp: sum_setl_def)
122 case Inr thus ?thesis using a2 by (clarsimp simp: sum_setr_def)
126 show "sum_setl o sum_map f1 f2 = image f1 o sum_setl"
127 by (rule ext, unfold o_apply) (simp add: sum_setl_def split: sum.split)
130 show "sum_setr o sum_map f1 f2 = image f2 o sum_setr"
131 by (rule ext, unfold o_apply) (simp add: sum_setr_def split: sum.split)
133 show "card_order natLeq" by (rule natLeq_card_order)
135 show "cinfinite natLeq" by (rule natLeq_cinfinite)
138 show "|sum_setl x| \<le>o natLeq"
139 apply (rule ordLess_imp_ordLeq)
140 apply (rule finite_iff_ordLess_natLeq[THEN iffD1])
141 by (simp add: sum_setl_def split: sum.split)
144 show "|sum_setr x| \<le>o natLeq"
145 apply (rule ordLess_imp_ordLeq)
146 apply (rule finite_iff_ordLess_natLeq[THEN iffD1])
147 by (simp add: sum_setr_def split: sum.split)
149 fix A1 :: "'a set" and A2 :: "'b set"
150 have in_alt: "{x. (case x of Inl z => {z} | _ => {}) \<subseteq> A1 \<and>
151 (case x of Inr z => {z} | _ => {}) \<subseteq> A2} = A1 <+> A2" (is "?L = ?R")
154 assume "(case x of Inl z \<Rightarrow> {z} | _ \<Rightarrow> {}) \<subseteq> A1" "(case x of Inr z \<Rightarrow> {z} | _ \<Rightarrow> {}) \<subseteq> A2"
155 hence "x \<in> Inl ` A1 \<or> x \<in> Inr ` A2" by (cases x) simp+
156 thus "x \<in> A1 <+> A2" by blast
157 qed (auto split: sum.split)
158 show "|{x. sum_setl x \<subseteq> A1 \<and> sum_setr x \<subseteq> A2}| \<le>o
159 (( |A1| +c |A2| ) +c ctwo) ^c natLeq"
160 apply (rule ordIso_ordLeq_trans)
161 apply (rule card_of_ordIso_subst)
162 apply (unfold sum_set_defs)
164 apply (rule ordIso_ordLeq_trans)
165 apply (rule Plus_csum)
166 apply (rule ordLeq_transitive)
167 apply (rule ordLeq_csum1)
168 apply (rule Card_order_csum)
169 apply (rule ordLeq_cexp1)
171 using Field_natLeq UNIV_not_empty czeroE apply fast
172 apply (rule natLeq_Card_order)
173 by (rule Card_order_csum)
175 fix A1 A2 B11 B12 B21 B22 f11 f12 f21 f22 p11 p12 p21 p22
176 assume "wpull A1 B11 B21 f11 f21 p11 p21" "wpull A2 B12 B22 f12 f22 p12 p22"
178 pull1: "\<And>b1 b2. \<lbrakk>b1 \<in> B11; b2 \<in> B21; f11 b1 = f21 b2\<rbrakk> \<Longrightarrow> \<exists>a \<in> A1. p11 a = b1 \<and> p21 a = b2"
179 and pull2: "\<And>b1 b2. \<lbrakk>b1 \<in> B12; b2 \<in> B22; f12 b1 = f22 b2\<rbrakk> \<Longrightarrow> \<exists>a \<in> A2. p12 a = b1 \<and> p22 a = b2"
180 unfolding wpull_def by blast+
181 show "wpull {x. sum_setl x \<subseteq> A1 \<and> sum_setr x \<subseteq> A2}
182 {x. sum_setl x \<subseteq> B11 \<and> sum_setr x \<subseteq> B12} {x. sum_setl x \<subseteq> B21 \<and> sum_setr x \<subseteq> B22}
183 (sum_map f11 f12) (sum_map f21 f22) (sum_map p11 p12) (sum_map p21 p22)"
184 (is "wpull ?in ?in1 ?in2 ?mapf1 ?mapf2 ?mapp1 ?mapp2")
185 proof (unfold wpull_def)
187 assume *: "B1 \<in> ?in1" "B2 \<in> ?in2" "?mapf1 B1 = ?mapf2 B2"
188 have "\<exists>A \<in> ?in. ?mapp1 A = B1 \<and> ?mapp2 A = B2"
191 { fix b2 assume "B2 = Inr b2"
192 with Inl *(3) have False by simp
193 } then obtain b2 where Inl': "B2 = Inl b2" by (cases B2) (simp, blast)
194 with Inl * have "b1 \<in> B11" "b2 \<in> B21" "f11 b1 = f21 b2"
195 by (simp add: sum_setl_def)+
196 with pull1 obtain a where "a \<in> A1" "p11 a = b1" "p21 a = b2" by blast+
197 with Inl Inl' have "Inl a \<in> ?in" "?mapp1 (Inl a) = B1 \<and> ?mapp2 (Inl a) = B2"
198 by (simp add: sum_set_defs)+
199 thus ?thesis by blast
202 { fix b2 assume "B2 = Inl b2"
203 with Inr *(3) have False by simp
204 } then obtain b2 where Inr': "B2 = Inr b2" by (cases B2) (simp, blast)
205 with Inr * have "b1 \<in> B12" "b2 \<in> B22" "f12 b1 = f22 b2"
206 by (simp add: sum_set_defs)+
207 with pull2 obtain a where "a \<in> A2" "p12 a = b1" "p22 a = b2" by blast+
208 with Inr Inr' have "Inr a \<in> ?in" "?mapp1 (Inr a) = B1 \<and> ?mapp2 (Inr a) = B2"
209 by (simp add: sum_set_defs)+
210 thus ?thesis by blast
213 thus "\<forall>B1 B2. B1 \<in> ?in1 \<and> B2 \<in> ?in2 \<and> ?mapf1 B1 = ?mapf2 B2 \<longrightarrow>
214 (\<exists>A \<in> ?in. ?mapp1 A = B1 \<and> ?mapp2 A = B2)" by fastforce
216 qed (auto simp: sum_set_defs)
218 lemma sum_pred[simp]:
219 "sum_pred \<phi> \<psi> x y =
220 (case x of Inl a1 \<Rightarrow> (case y of Inl a2 \<Rightarrow> \<phi> a1 a2 | Inr _ \<Rightarrow> False)
221 | Inr b1 \<Rightarrow> (case y of Inl _ \<Rightarrow> False | Inr b2 \<Rightarrow> \<psi> b1 b2))"
222 unfolding sum_setl_def sum_setr_def sum_pred_def sum_rel_def Gr_def relcomp_unfold converse_unfold
223 by (fastforce split: sum.splits)+
225 lemma singleton_ordLeq_ctwo_natLeq: "|{x}| \<le>o ctwo *c natLeq"
226 apply (rule ordLeq_transitive)
227 apply (rule ordLeq_cprod2)
228 apply (rule ctwo_Cnotzero)
229 apply (auto simp: Field_card_of intro: card_of_card_order_on)
230 apply (rule cprod_mono2)
231 apply (rule ordLess_imp_ordLeq)
232 apply (unfold finite_iff_ordLess_natLeq[symmetric])
235 definition fsts :: "'a \<times> 'b \<Rightarrow> 'a set" where
238 definition snds :: "'a \<times> 'b \<Rightarrow> 'b set" where
241 lemmas prod_set_defs = fsts_def[abs_def] snds_def[abs_def]
243 bnf_def map_pair [fsts, snds] "\<lambda>_::'a \<times> 'b. ctwo *c natLeq" [Pair]
244 proof (unfold prod_set_defs)
245 show "map_pair id id = id" by (rule map_pair.id)
248 show "map_pair (g1 o f1) (g2 o f2) = map_pair g1 g2 o map_pair f1 f2"
249 by (rule map_pair.comp[symmetric])
252 assume "\<And>z. z \<in> {fst x} \<Longrightarrow> f1 z = g1 z" "\<And>z. z \<in> {snd x} \<Longrightarrow> f2 z = g2 z"
253 thus "map_pair f1 f2 x = map_pair g1 g2 x" by (cases x) simp
256 show "(\<lambda>x. {fst x}) o map_pair f1 f2 = image f1 o (\<lambda>x. {fst x})"
257 by (rule ext, unfold o_apply) simp
260 show "(\<lambda>x. {snd x}) o map_pair f1 f2 = image f2 o (\<lambda>x. {snd x})"
261 by (rule ext, unfold o_apply) simp
263 show "card_order (ctwo *c natLeq)"
264 apply (rule card_order_cprod)
265 apply (rule ctwo_card_order)
266 by (rule natLeq_card_order)
268 show "cinfinite (ctwo *c natLeq)"
269 apply (rule cinfinite_cprod2)
270 apply (rule ctwo_Cnotzero)
271 apply (rule conjI[OF _ natLeq_Card_order])
272 by (rule natLeq_cinfinite)
275 show "|{fst x}| \<le>o ctwo *c natLeq"
276 by (rule singleton_ordLeq_ctwo_natLeq)
279 show "|{snd x}| \<le>o ctwo *c natLeq"
280 by (rule singleton_ordLeq_ctwo_natLeq)
282 fix A1 :: "'a set" and A2 :: "'b set"
283 have in_alt: "{x. {fst x} \<subseteq> A1 \<and> {snd x} \<subseteq> A2} = A1 \<times> A2" by auto
284 show "|{x. {fst x} \<subseteq> A1 \<and> {snd x} \<subseteq> A2}| \<le>o
285 ( ( |A1| +c |A2| ) +c ctwo) ^c (ctwo *c natLeq)"
286 apply (rule ordIso_ordLeq_trans)
287 apply (rule card_of_ordIso_subst)
289 apply (rule ordIso_ordLeq_trans)
290 apply (rule Times_cprod)
291 apply (rule ordLeq_transitive)
292 apply (rule cprod_csum_cexp)
293 apply (rule cexp_mono)
294 apply (rule ordLeq_csum1)
295 apply (rule Card_order_csum)
296 apply (rule ordLeq_cprod1)
297 apply (rule Card_order_ctwo)
298 apply (rule Cinfinite_Cnotzero)
299 apply (rule conjI[OF _ natLeq_Card_order])
300 apply (rule natLeq_cinfinite)
302 apply (rule cone_ordLeq_cexp)
303 apply (rule ordLeq_transitive)
304 apply (rule cone_ordLeq_ctwo)
305 apply (rule ordLeq_csum2)
306 apply (rule Card_order_ctwo)
308 apply (rule ctwo_not_czero)
310 by (rule Card_order_ctwo)
312 fix A1 A2 B11 B12 B21 B22 f11 f12 f21 f22 p11 p12 p21 p22
313 assume "wpull A1 B11 B21 f11 f21 p11 p21" "wpull A2 B12 B22 f12 f22 p12 p22"
314 thus "wpull {x. {fst x} \<subseteq> A1 \<and> {snd x} \<subseteq> A2}
315 {x. {fst x} \<subseteq> B11 \<and> {snd x} \<subseteq> B12} {x. {fst x} \<subseteq> B21 \<and> {snd x} \<subseteq> B22}
316 (map_pair f11 f12) (map_pair f21 f22) (map_pair p11 p12) (map_pair p21 p22)"
317 unfolding wpull_def by simp fast
320 lemma prod_pred[simp]:
321 "prod_pred \<phi> \<psi> p1 p2 = (case p1 of (a1, b1) \<Rightarrow> case p2 of (a2, b2) \<Rightarrow> (\<phi> a1 a2 \<and> \<psi> b1 b2))"
322 unfolding prod_set_defs prod_pred_def prod_rel_def Gr_def relcomp_unfold converse_unfold by auto
323 (* TODO: pred characterization for each basic BNF *)
325 (* Categorical version of pullback: *)
327 assumes p: "wpull A B1 B2 f1 f2 p1 p2"
328 and c: "f1 o q1 = f2 o q2"
329 and r: "range q1 \<subseteq> B1" "range q2 \<subseteq> B2"
330 obtains h where "range h \<subseteq> A \<and> q1 = p1 o h \<and> q2 = p2 o h"
332 have *: "\<forall>d. \<exists>a \<in> A. p1 a = q1 d & p2 a = q2 d"
335 have "f1 (q1 d) = f2 (q2 d)" using c unfolding comp_def[abs_def] by (rule fun_cong)
337 have "q1 d : B1" "q2 d : B2" using r unfolding image_def by auto
338 ultimately show "\<exists>a \<in> A. p1 a = q1 d \<and> p2 a = q2 d"
339 using p unfolding wpull_def by auto
341 then obtain h where "!! d. h d \<in> A & p1 (h d) = q1 d & p2 (h d) = q2 d" by metis
342 thus ?thesis using that by fastforce
345 lemma card_of_bounded_range:
346 "|{f :: 'd \<Rightarrow> 'a. range f \<subseteq> B}| \<le>o |Func (UNIV :: 'd set) B|" (is "|?LHS| \<le>o |?RHS|")
348 let ?f = "\<lambda>f. %x. if f x \<in> B then Some (f x) else None"
349 have "inj_on ?f ?LHS" unfolding inj_on_def
350 proof (unfold fun_eq_iff, safe)
351 fix g :: "'d \<Rightarrow> 'a" and f :: "'d \<Rightarrow> 'a" and x
352 assume "range f \<subseteq> B" "range g \<subseteq> B" and eq: "\<forall>x. ?f f x = ?f g x"
353 hence "f x \<in> B" "g x \<in> B" by auto
354 with eq have "Some (f x) = Some (g x)" by metis
355 thus "f x = g x" by simp
357 moreover have "?f ` ?LHS \<subseteq> ?RHS" unfolding Func_def by fastforce
358 ultimately show ?thesis using card_of_ordLeq by fast
361 bnf_def "op \<circ>" [range] "\<lambda>_:: 'a \<Rightarrow> 'b. natLeq +c |UNIV :: 'a set|"
362 ["%c x::'b::type. c::'a::type"]
364 fix f show "id \<circ> f = id f" by simp
366 fix f g show "op \<circ> (g \<circ> f) = op \<circ> g \<circ> op \<circ> f"
367 unfolding comp_def[abs_def] ..
370 assume "\<And>z. z \<in> range x \<Longrightarrow> f z = g z"
371 thus "f \<circ> x = g \<circ> x" by auto
373 fix f show "range \<circ> op \<circ> f = op ` f \<circ> range"
374 unfolding image_def comp_def[abs_def] by auto
376 show "card_order (natLeq +c |UNIV| )" (is "_ (_ +c ?U)")
377 apply (rule card_order_csum)
378 apply (rule natLeq_card_order)
379 by (rule card_of_card_order_on)
381 show "cinfinite (natLeq +c ?U)"
382 apply (rule cinfinite_csum)
384 by (rule natLeq_cinfinite)
387 have "|range f| \<le>o | (UNIV::'d set) |" (is "_ \<le>o ?U") by (rule card_of_image)
388 also have "?U \<le>o natLeq +c ?U" by (rule ordLeq_csum2) (rule card_of_Card_order)
389 finally show "|range f| \<le>o natLeq +c ?U" .
392 have "|{f::'d => 'a. range f \<subseteq> B}| \<le>o |Func (UNIV :: 'd set) B|" by (rule card_of_bounded_range)
393 also have "|Func (UNIV :: 'd set) B| =o |B| ^c |UNIV :: 'd set|"
394 unfolding cexp_def Field_card_of by (rule card_of_refl)
395 also have "|B| ^c |UNIV :: 'd set| \<le>o
396 ( |B| +c ctwo) ^c (natLeq +c |UNIV :: 'd set| )"
397 apply (rule cexp_mono)
398 apply (rule ordLeq_csum1) apply (rule card_of_Card_order)
399 apply (rule ordLeq_csum2) apply (rule card_of_Card_order)
400 apply (rule disjI2) apply (rule cone_ordLeq_cexp)
401 apply (rule ordLeq_transitive) apply (rule cone_ordLeq_ctwo) apply (rule ordLeq_csum2)
402 apply (rule Card_order_ctwo)
403 apply (rule notE) apply (rule conjunct1) apply (rule Cnotzero_UNIV) apply blast
404 apply (rule card_of_Card_order)
407 show "|{f::'d => 'a. range f \<subseteq> B}| \<le>o
408 ( |B| +c ctwo) ^c (natLeq +c |UNIV :: 'd set| )" .
410 fix A B1 B2 f1 f2 p1 p2 assume p: "wpull A B1 B2 f1 f2 p1 p2"
411 show "wpull {h. range h \<subseteq> A} {g1. range g1 \<subseteq> B1} {g2. range g2 \<subseteq> B2}
412 (op \<circ> f1) (op \<circ> f2) (op \<circ> p1) (op \<circ> p2)"
415 fix g1 g2 assume r: "range g1 \<subseteq> B1" "range g2 \<subseteq> B2"
416 and c: "f1 \<circ> g1 = f2 \<circ> g2"
417 show "\<exists>h \<in> {h. range h \<subseteq> A}. p1 \<circ> h = g1 \<and> p2 \<circ> h = g2"
418 using wpull_cat[OF p c r] by simp metis
422 lemma fun_pred[simp]: "fun_pred \<phi> f g = (\<forall>x. \<phi> (f x) (g x))"
423 unfolding fun_rel_def fun_pred_def Gr_def relcomp_unfold converse_unfold
424 by (auto intro!: exI dest!: in_mono)