1 (* Title: HOL/Codatatype/Tools/bnf_lfp.ML
2 Author: Dmitriy Traytel, TU Muenchen
3 Author: Andrei Popescu, TU Muenchen
11 val bnf_lfp: binding list -> typ list list -> BNF_Def.BNF list -> Proof.context -> Proof.context
14 structure BNF_LFP : BNF_LFP =
24 (*all bnfs have the same lives*)
25 fun bnf_lfp bs Dss_insts bnfs lthy =
27 val timer = time (Timer.startRealTimer ());
28 val live = live_of_bnf (hd bnfs)
29 val n = length bnfs; (*active*)
31 val m = live - n (*passive, if 0 don't generate a new bnf*)
32 val b = Binding.name (fold_rev (fn b => fn s => Binding.name_of b ^ s) bs "");
34 fun note thmN thms = snd o Local_Theory.note
35 ((Binding.qualify true (Binding.name_of b) (Binding.name thmN), []), thms);
36 fun notes thmN thmss = fold2 (fn b => fn thms => snd o Local_Theory.note
37 ((Binding.qualify true (Binding.name_of b) (Binding.name thmN), []), thms)) bs thmss;
39 (* TODO: check if m, n etc are sane *)
41 val Dss = map (fn Ds => map TFree (fold Term.add_tfreesT Ds [])) Dss_insts;
42 val deads = distinct (op =) (flat Dss);
43 val names_lthy = fold Variable.declare_typ deads lthy;
46 val (((((((passiveAs, activeAs), allAs)), (passiveBs, activeBs)),
47 activeCs), passiveXs), passiveYs) = names_lthy
54 ||> fst o mk_TFrees m;
56 val Ass = replicate n allAs;
57 val allBs = passiveAs @ activeBs;
58 val Bss = replicate n allBs;
59 val allCs = passiveAs @ activeCs;
60 val allCs' = passiveBs @ activeCs;
61 val Css' = replicate n allCs';
64 fun mk_FTs Ts = map2 (fn Ds => mk_T_of_bnf Ds Ts) Dss bnfs;
65 val (params, params') = `(map dest_TFree) (deads @ passiveAs);
66 val FTsAs = mk_FTs allAs;
67 val FTsBs = mk_FTs allBs;
68 val FTsCs = mk_FTs allCs;
69 val ATs = map HOLogic.mk_setT passiveAs;
70 val BTs = map HOLogic.mk_setT activeAs;
71 val B'Ts = map HOLogic.mk_setT activeBs;
72 val B''Ts = map HOLogic.mk_setT activeCs;
73 val sTs = map2 (curry (op -->)) FTsAs activeAs;
74 val s'Ts = map2 (curry (op -->)) FTsBs activeBs;
75 val s''Ts = map2 (curry (op -->)) FTsCs activeCs;
76 val fTs = map2 (curry (op -->)) activeAs activeBs;
77 val inv_fTs = map2 (curry (op -->)) activeBs activeAs;
78 val self_fTs = map2 (curry (op -->)) activeAs activeAs;
79 val gTs = map2 (curry (op -->)) activeBs activeCs;
80 val all_gTs = map2 (curry (op -->)) allBs allCs';
81 val prodBsAs = map2 (curry HOLogic.mk_prodT) activeBs activeAs;
82 val prodFTs = mk_FTs (passiveAs @ prodBsAs);
83 val prod_sTs = map2 (curry (op -->)) prodFTs activeAs;
86 val mapsAsAs = map4 mk_map_of_bnf Dss Ass Ass bnfs;
87 val mapsAsBs = map4 mk_map_of_bnf Dss Ass Bss bnfs;
88 val mapsBsAs = map4 mk_map_of_bnf Dss Bss Ass bnfs;
89 val mapsBsCs' = map4 mk_map_of_bnf Dss Bss Css' bnfs;
90 val mapsAsCs' = map4 mk_map_of_bnf Dss Ass Css' bnfs;
91 val map_fsts = map4 mk_map_of_bnf Dss (replicate n (passiveAs @ prodBsAs)) Bss bnfs;
92 val map_fsts_rev = map4 mk_map_of_bnf Dss Bss (replicate n (passiveAs @ prodBsAs)) bnfs;
93 fun mk_setss Ts = map3 mk_sets_of_bnf (map (replicate live) Dss)
94 (map (replicate live) (replicate n Ts)) bnfs;
95 val setssAs = mk_setss allAs;
96 val bds = map3 mk_bd_of_bnf Dss Ass bnfs;
97 val witss = map wits_of_bnf bnfs;
99 val (((((((((((((((((((zs, zs'), As), Bs), Bs_copy), B's), B''s), ss), prod_ss), s's), s''s),
100 fs), fs_copy), inv_fs), self_fs), gs), all_gs), (xFs, xFs')), (yFs, yFs')),
102 |> mk_Frees' "z" activeAs
103 ||>> mk_Frees "A" ATs
104 ||>> mk_Frees "B" BTs
105 ||>> mk_Frees "B" BTs
106 ||>> mk_Frees "B'" B'Ts
107 ||>> mk_Frees "B''" B''Ts
108 ||>> mk_Frees "s" sTs
109 ||>> mk_Frees "prods" prod_sTs
110 ||>> mk_Frees "s'" s'Ts
111 ||>> mk_Frees "s''" s''Ts
112 ||>> mk_Frees "f" fTs
113 ||>> mk_Frees "f" fTs
114 ||>> mk_Frees "f" inv_fTs
115 ||>> mk_Frees "f" self_fTs
116 ||>> mk_Frees "g" gTs
117 ||>> mk_Frees "g" all_gTs
118 ||>> mk_Frees' "x" FTsAs
119 ||>> mk_Frees' "y" FTsBs;
121 val passive_UNIVs = map HOLogic.mk_UNIV passiveAs;
122 val active_UNIVs = map HOLogic.mk_UNIV activeAs;
123 val prod_UNIVs = map HOLogic.mk_UNIV prodBsAs;
124 val passive_ids = map HOLogic.id_const passiveAs;
125 val active_ids = map HOLogic.id_const activeAs;
126 val fsts = map fst_const prodBsAs;
129 val bd_card_orders = map bd_card_order_of_bnf bnfs;
130 val bd_Card_orders = map bd_Card_order_of_bnf bnfs;
131 val bd_Card_order = hd bd_Card_orders;
132 val bd_Cinfinite = bd_Cinfinite_of_bnf (hd bnfs);
133 val bd_Cnotzeros = map bd_Cnotzero_of_bnf bnfs;
134 val bd_Cnotzero = hd bd_Cnotzeros;
135 val in_bds = map in_bd_of_bnf bnfs;
136 val map_comp's = map map_comp'_of_bnf bnfs;
137 val map_congs = map map_cong_of_bnf bnfs;
138 val map_ids = map map_id_of_bnf bnfs;
139 val map_id's = map map_id'_of_bnf bnfs;
140 val map_wpulls = map map_wpull_of_bnf bnfs;
141 val set_bdss = map set_bd_of_bnf bnfs;
142 val set_natural'ss = map set_natural'_of_bnf bnfs;
144 val timer = time (timer "Extracted terms & thms");
146 (* nonemptiness check *)
147 fun new_wit X wit = subset (op =) (#I wit, (0 upto m - 1) @ map snd X);
149 fun enrich X = map_filter (fn i =>
150 (case find_first (fn (_, i') => i = i') X of
152 (case find_index (new_wit X) (nth witss (i - m)) of
155 | SOME ji => SOME ji)) (m upto m + n - 1);
156 val reachable = fixpoint (op =) enrich [];
157 val _ = if map snd reachable = (m upto m + n - 1) then ()
158 else error "The datatype could not be generated because nonemptiness could not be proved";
161 flat (map2 (fn bnf => fn (j, _) => nth (wit_thmss_of_bnf bnf) j) bnfs reachable);
163 val timer = time (timer "Checked nonemptiness");
167 (*map g1 ... gm g(m+1) ... g(m+n) (map id ... id f(m+1) ... f(m+n) x)=
168 map g1 ... gm (g(m+1) o f(m+1)) ... (g(m+n) o f(m+n)) x*)
169 fun mk_map_comp_id x mapAsBs mapBsCs mapAsCs map_comp =
171 val lhs = Term.list_comb (mapBsCs, all_gs) $
172 (Term.list_comb (mapAsBs, passive_ids @ fs) $ x);
173 val rhs = Term.list_comb (mapAsCs,
174 take m all_gs @ map HOLogic.mk_comp (drop m all_gs ~~ fs)) $ x;
176 Skip_Proof.prove lthy [] []
177 (fold_rev Logic.all (x :: fs @ all_gs) (HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs))))
178 (K (mk_map_comp_id_tac map_comp))
181 val map_comp_id_thms = map5 mk_map_comp_id xFs mapsAsBs mapsBsCs' mapsAsCs' map_comp's;
183 (*forall a : set(m+1) x. f(m+1) a = a; ...; forall a : set(m+n) x. f(m+n) a = a ==>
184 map id ... id f(m+1) ... f(m+n) x = x*)
185 fun mk_map_congL x mapAsAs sets map_cong map_id' =
187 fun mk_prem set f z z' = HOLogic.mk_Trueprop
188 (mk_Ball (set $ x) (Term.absfree z' (HOLogic.mk_eq (f $ z, z))));
189 val prems = map4 mk_prem (drop m sets) self_fs zs zs';
190 val goal = HOLogic.mk_Trueprop (HOLogic.mk_eq
191 (Term.list_comb (mapAsAs, passive_ids @ self_fs) $ x, x))
193 Skip_Proof.prove lthy [] []
194 (fold_rev Logic.all (x :: self_fs) (Logic.list_implies (prems, goal)))
195 (K (mk_map_congL_tac m map_cong map_id'))
198 val map_congL_thms = map5 mk_map_congL xFs mapsAsAs setssAs map_congs map_id's;
199 val in_mono'_thms = map (fn bnf => in_mono_of_bnf bnf OF (replicate m subset_refl)) bnfs
200 val in_cong'_thms = map (fn bnf => in_cong_of_bnf bnf OF (replicate m refl)) bnfs
202 val timer = time (timer "Derived simple theorems");
206 val alg_bind = Binding.suffix_name ("_" ^ algN) b;
207 val alg_name = Binding.name_of alg_bind;
208 val alg_def_bind = (Thm.def_binding alg_bind, []);
210 (*forall i = 1 ... n: (\<forall>x \<in> Fi_in A1 .. Am B1 ... Bn. si x \<in> Bi)*)
213 val algT = Library.foldr (op -->) (ATs @ BTs @ sTs, HOLogic.boolT);
215 val ins = map3 mk_in (replicate n (As @ Bs)) setssAs FTsAs;
216 fun mk_alg_conjunct B s X x x' =
217 mk_Ball X (Term.absfree x' (HOLogic.mk_mem (s $ x, B)));
219 val lhs = Term.list_comb (Free (alg_name, algT), As @ Bs @ ss);
220 val rhs = Library.foldr1 HOLogic.mk_conj (map5 mk_alg_conjunct Bs ss ins xFs xFs')
222 HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs))
225 val ((alg_free, (_, alg_def_free)), (lthy, lthy_old)) =
227 |> Specification.definition (SOME (alg_bind, NONE, NoSyn), (alg_def_bind, alg_spec))
228 ||> `Local_Theory.restore;
230 (*transforms defined frees into consts*)
231 val phi = Proof_Context.export_morphism lthy_old lthy;
232 val alg = fst (Term.dest_Const (Morphism.term phi alg_free));
233 val alg_def = Morphism.thm phi alg_def_free;
235 fun mk_alg As Bs ss =
237 val args = As @ Bs @ ss;
238 val Ts = map fastype_of args;
239 val algT = Library.foldr (op -->) (Ts, HOLogic.boolT);
241 Term.list_comb (Const (alg, algT), args)
246 val alg_prem = HOLogic.mk_Trueprop (mk_alg As Bs ss);
247 fun mk_prem x set B = HOLogic.mk_Trueprop (mk_subset (set $ x) B);
248 fun mk_concl s x B = HOLogic.mk_Trueprop (HOLogic.mk_mem (s $ x, B));
249 val premss = map2 ((fn x => fn sets => map2 (mk_prem x) sets (As @ Bs))) xFs setssAs;
250 val concls = map3 mk_concl ss xFs Bs;
251 val goals = map3 (fn x => fn prems => fn concl =>
252 fold_rev Logic.all (x :: As @ Bs @ ss)
253 (Logic.list_implies (alg_prem :: prems, concl))) xFs premss concls;
255 map (fn goal => Skip_Proof.prove lthy [] [] goal
256 (K (mk_alg_set_tac alg_def))) goals
259 fun mk_talg ATs BTs = mk_alg (map HOLogic.mk_UNIV ATs) (map HOLogic.mk_UNIV BTs);
263 val goal = fold_rev Logic.all ss
264 (HOLogic.mk_Trueprop (mk_talg passiveAs activeAs ss))
266 Skip_Proof.prove lthy [] [] goal
267 (K (stac alg_def 1 THEN CONJ_WRAP (K (EVERY' [rtac ballI, rtac UNIV_I] 1)) ss))
270 val timer = time (timer "Algebra definition & thms");
272 val alg_not_empty_thms =
275 HOLogic.mk_Trueprop (mk_alg passive_UNIVs Bs ss);
276 val concls = map (HOLogic.mk_Trueprop o mk_not_empty) Bs;
279 fold_rev Logic.all (Bs @ ss) (Logic.mk_implies (alg_prem, concl))) concls;
281 map2 (fn goal => fn alg_set =>
282 Skip_Proof.prove lthy [] []
283 goal (K (mk_alg_not_empty_tac alg_set alg_set_thms wit_thms)))
287 val timer = time (timer "Proved nonemptiness");
291 val mor_bind = Binding.suffix_name ("_" ^ morN) b;
292 val mor_name = Binding.name_of mor_bind;
293 val mor_def_bind = (Thm.def_binding mor_bind, []);
295 (*fbetw) forall i = 1 ... n: (\<forall>x \<in> Bi. f x \<in> B'i)*)
296 (*mor) forall i = 1 ... n: (\<forall>x \<in> Fi_in UNIV ... UNIV B1 ... Bn.
297 f (s1 x) = s1' (Fi_map id ... id f1 ... fn x))*)
300 val morT = Library.foldr (op -->) (BTs @ sTs @ B'Ts @ s'Ts @ fTs, HOLogic.boolT);
302 fun mk_fbetw f B1 B2 z z' =
303 mk_Ball B1 (Term.absfree z' (HOLogic.mk_mem (f $ z, B2)));
304 fun mk_mor sets mapAsBs f s s' T x x' =
305 mk_Ball (mk_in (passive_UNIVs @ Bs) sets T)
306 (Term.absfree x' (HOLogic.mk_eq (f $ (s $ x), s' $
307 (Term.list_comb (mapAsBs, passive_ids @ fs) $ x))));
308 val lhs = Term.list_comb (Free (mor_name, morT), Bs @ ss @ B's @ s's @ fs);
309 val rhs = HOLogic.mk_conj
310 (Library.foldr1 HOLogic.mk_conj (map5 mk_fbetw fs Bs B's zs zs'),
311 Library.foldr1 HOLogic.mk_conj
312 (map8 mk_mor setssAs mapsAsBs fs ss s's FTsAs xFs xFs'))
314 HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs))
317 val ((mor_free, (_, mor_def_free)), (lthy, lthy_old)) =
319 |> Specification.definition (SOME (mor_bind, NONE, NoSyn), (mor_def_bind, mor_spec))
320 ||> `Local_Theory.restore;
322 (*transforms defined frees into consts*)
323 val phi = Proof_Context.export_morphism lthy_old lthy;
324 val mor = fst (Term.dest_Const (Morphism.term phi mor_free));
325 val mor_def = Morphism.thm phi mor_def_free;
327 fun mk_mor Bs1 ss1 Bs2 ss2 fs =
329 val args = Bs1 @ ss1 @ Bs2 @ ss2 @ fs;
330 val Ts = map fastype_of (Bs1 @ ss1 @ Bs2 @ ss2 @ fs);
331 val morT = Library.foldr (op -->) (Ts, HOLogic.boolT);
333 Term.list_comb (Const (mor, morT), args)
336 val (mor_image_thms, morE_thms) =
338 val prem = HOLogic.mk_Trueprop (mk_mor Bs ss B's s's fs);
339 fun mk_image_goal f B1 B2 = fold_rev Logic.all (Bs @ ss @ B's @ s's @ fs)
340 (Logic.mk_implies (prem, HOLogic.mk_Trueprop (mk_subset (mk_image f $ B1) B2)));
341 val image_goals = map3 mk_image_goal fs Bs B's;
342 fun mk_elim_prem sets x T = HOLogic.mk_Trueprop
343 (HOLogic.mk_mem (x, mk_in (passive_UNIVs @ Bs) sets T));
344 fun mk_elim_goal sets mapAsBs f s s' x T =
345 fold_rev Logic.all (x :: Bs @ ss @ B's @ s's @ fs)
346 (Logic.list_implies ([prem, mk_elim_prem sets x T],
347 HOLogic.mk_Trueprop (HOLogic.mk_eq (f $ (s $ x),
348 s' $ Term.list_comb (mapAsBs, passive_ids @ fs @ [x])))));
349 val elim_goals = map7 mk_elim_goal setssAs mapsAsBs fs ss s's xFs FTsAs;
351 Skip_Proof.prove lthy [] [] goal (K (mk_mor_elim_tac mor_def));
353 (map prove image_goals, map prove elim_goals)
358 val prems = map2 (HOLogic.mk_Trueprop oo mk_subset) Bs Bs_copy;
359 val concl = HOLogic.mk_Trueprop (mk_mor Bs ss Bs_copy ss active_ids);
361 Skip_Proof.prove lthy [] []
362 (fold_rev Logic.all (Bs @ ss @ Bs_copy) (Logic.list_implies (prems, concl)))
363 (K (mk_mor_incl_tac mor_def map_id's))
369 [HOLogic.mk_Trueprop (mk_mor Bs ss B's s's fs),
370 HOLogic.mk_Trueprop (mk_mor B's s's B''s s''s gs)];
372 HOLogic.mk_Trueprop (mk_mor Bs ss B''s s''s (map2 (curry HOLogic.mk_comp) gs fs));
374 Skip_Proof.prove lthy [] []
375 (fold_rev Logic.all (Bs @ ss @ B's @ s's @ B''s @ s''s @ fs @ gs)
376 (Logic.list_implies (prems, concl)))
377 (K (mk_mor_comp_tac mor_def set_natural'ss map_comp_id_thms))
382 fun mk_inv_prem f inv_f B B' = HOLogic.mk_conj (mk_subset (mk_image inv_f $ B') B,
383 HOLogic.mk_conj (mk_inver inv_f f B, mk_inver f inv_f B'));
384 val prems = map HOLogic.mk_Trueprop
385 ([mk_mor Bs ss B's s's fs,
386 mk_alg passive_UNIVs Bs ss,
387 mk_alg passive_UNIVs B's s's] @
388 map4 mk_inv_prem fs inv_fs Bs B's);
389 val concl = HOLogic.mk_Trueprop (mk_mor B's s's Bs ss inv_fs);
391 Skip_Proof.prove lthy [] []
392 (fold_rev Logic.all (Bs @ ss @ B's @ s's @ fs @ inv_fs)
393 (Logic.list_implies (prems, concl)))
394 (K (mk_mor_inv_tac alg_def mor_def
395 set_natural'ss morE_thms map_comp_id_thms map_congL_thms))
400 val prems = map HOLogic.mk_Trueprop
401 (map2 (curry HOLogic.mk_eq) fs_copy fs @ [mk_mor Bs ss B's s's fs])
402 val concl = HOLogic.mk_Trueprop (mk_mor Bs ss B's s's fs_copy);
404 Skip_Proof.prove lthy [] []
405 (fold_rev Logic.all (Bs @ ss @ B's @ s's @ fs @ fs_copy)
406 (Logic.list_implies (prems, concl)))
407 (K ((hyp_subst_tac THEN' atac) 1))
412 val maps = map2 (fn Ds => fn bnf => Term.list_comb
413 (mk_map_of_bnf Ds (passiveAs @ FTsAs) allAs bnf, passive_ids @ ss)) Dss bnfs;
415 Skip_Proof.prove lthy [] []
416 (fold_rev Logic.all ss (HOLogic.mk_Trueprop
417 (mk_mor (map HOLogic.mk_UNIV FTsAs) maps active_UNIVs ss ss)))
418 (K (mk_mor_str_tac ks mor_def))
423 val maps = map3 (fn s => fn prod_s => fn map =>
424 mk_convol (HOLogic.mk_comp (s, Term.list_comb (map, passive_ids @ fsts)), prod_s))
425 s's prod_ss map_fsts;
427 Skip_Proof.prove lthy [] []
428 (fold_rev Logic.all (s's @ prod_ss) (HOLogic.mk_Trueprop
429 (mk_mor prod_UNIVs maps (map HOLogic.mk_UNIV activeBs) s's fsts)))
430 (K (mk_mor_convol_tac ks mor_def))
435 fun mk_conjunct mapAsBs f s s' = HOLogic.mk_eq
436 (HOLogic.mk_comp (f, s),
437 HOLogic.mk_comp (s', Term.list_comb (mapAsBs, passive_ids @ fs)));
438 val lhs = mk_mor active_UNIVs ss (map HOLogic.mk_UNIV activeBs) s's fs;
439 val rhs = Library.foldr1 HOLogic.mk_conj (map4 mk_conjunct mapsAsBs fs ss s's);
441 Skip_Proof.prove lthy [] []
442 (fold_rev Logic.all (ss @ s's @ fs) (HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs))))
443 (K (mk_mor_UNIV_tac m morE_thms mor_def))
446 val timer = time (timer "Morphism definition & thms");
450 (*mor Bs1 ss1 Bs2 ss2 fs \<and> (\<exists>gs. mor Bs2 ss2 Bs1 ss1 fs \<and>
451 forall i = 1 ... n. (inver gs[i] fs[i] Bs1[i] \<and> inver fs[i] gs[i] Bs2[i]))*)
452 fun mk_iso Bs1 ss1 Bs2 ss2 fs gs =
454 val ex_inv_mor = list_exists_free gs
455 (HOLogic.mk_conj (mk_mor Bs2 ss2 Bs1 ss1 gs,
456 Library.foldr1 HOLogic.mk_conj (map2 (curry HOLogic.mk_conj)
457 (map3 mk_inver gs fs Bs1) (map3 mk_inver fs gs Bs2))));
459 HOLogic.mk_conj (mk_mor Bs1 ss1 Bs2 ss2 fs, ex_inv_mor)
464 val prems = map HOLogic.mk_Trueprop
465 [mk_alg passive_UNIVs Bs ss,
466 mk_alg passive_UNIVs B's s's]
467 val concl = HOLogic.mk_Trueprop (HOLogic.mk_eq (mk_iso Bs ss B's s's fs inv_fs,
468 HOLogic.mk_conj (mk_mor Bs ss B's s's fs,
469 Library.foldr1 HOLogic.mk_conj (map3 mk_bij_betw fs Bs B's))));
471 Skip_Proof.prove lthy [] []
472 (fold_rev Logic.all (Bs @ ss @ B's @ s's @ fs) (Logic.list_implies (prems, concl)))
473 (K (mk_iso_alt_tac mor_image_thms mor_inv_thm))
476 val timer = time (timer "Isomorphism definition & thms");
480 val (copy_alg_thm, ex_copy_alg_thm) =
482 val prems = map HOLogic.mk_Trueprop
483 (mk_alg passive_UNIVs Bs ss :: map3 mk_bij_betw inv_fs B's Bs);
484 val inver_prems = map HOLogic.mk_Trueprop
485 (map3 mk_inver inv_fs fs Bs @ map3 mk_inver fs inv_fs B's);
486 val all_prems = prems @ inver_prems;
487 fun mk_s f s mapT y y' = Term.absfree y' (f $ (s $
488 (Term.list_comb (mapT, passive_ids @ inv_fs) $ y)));
490 val alg = HOLogic.mk_Trueprop
491 (mk_alg passive_UNIVs B's (map5 mk_s fs ss mapsBsAs yFs yFs'));
492 val copy_str_thm = Skip_Proof.prove lthy [] []
493 (fold_rev Logic.all (Bs @ ss @ B's @ inv_fs @ fs)
494 (Logic.list_implies (all_prems, alg)))
495 (K (mk_copy_str_tac set_natural'ss alg_def alg_set_thms));
497 val iso = HOLogic.mk_Trueprop
498 (mk_iso B's (map5 mk_s fs ss mapsBsAs yFs yFs') Bs ss inv_fs fs_copy);
499 val copy_alg_thm = Skip_Proof.prove lthy [] []
500 (fold_rev Logic.all (Bs @ ss @ B's @ inv_fs @ fs)
501 (Logic.list_implies (all_prems, iso)))
502 (K (mk_copy_alg_tac set_natural'ss alg_set_thms mor_def iso_alt_thm copy_str_thm));
504 val ex = HOLogic.mk_Trueprop
505 (list_exists_free s's
506 (HOLogic.mk_conj (mk_alg passive_UNIVs B's s's,
507 mk_iso B's s's Bs ss inv_fs fs_copy)));
508 val ex_copy_alg_thm = Skip_Proof.prove lthy [] []
509 (fold_rev Logic.all (Bs @ ss @ B's @ inv_fs @ fs)
510 (Logic.list_implies (prems, ex)))
511 (K (mk_ex_copy_alg_tac n copy_str_thm copy_alg_thm));
513 (copy_alg_thm, ex_copy_alg_thm)
516 val timer = time (timer "Copy thms");
521 val sum_Card_order = if n = 1 then bd_Card_order else @{thm Card_order_csum};
522 val sum_Cnotzero = if n = 1 then bd_Cnotzero else bd_Cnotzero RS @{thm csum_Cnotzero1};
523 val sum_Cinfinite = if n = 1 then bd_Cinfinite else bd_Cinfinite RS @{thm Cinfinite_csum1};
524 fun mk_set_bd_sums i bd_Card_order bds =
526 else map (fn thm => bd_Card_order RS mk_ordLeq_csum n i thm) bds;
527 val set_bd_sumss = map3 mk_set_bd_sums ks bd_Card_orders set_bdss;
529 fun mk_in_bd_sum i Co Cnz bd =
531 else Cnz RS ((Co RS mk_ordLeq_csum n i (Co RS @{thm ordLeq_refl})) RS
532 (bd RS @{thm ordLeq_transitive[OF _
533 cexp_mono2_Cnotzero[OF _ csum_Cnotzero2[OF ctwo_Cnotzero]]]}));
534 val in_bd_sums = map4 mk_in_bd_sum ks bd_Card_orders bd_Cnotzeros in_bds;
536 val sum_bd = Library.foldr1 (uncurry mk_csum) bds;
537 val suc_bd = mk_cardSuc sum_bd;
538 val field_suc_bd = mk_Field suc_bd;
539 val suc_bdT = fst (dest_relT (fastype_of suc_bd));
540 fun mk_Asuc_bd [] = mk_cexp ctwo suc_bd
542 mk_cexp (mk_csum (Library.foldr1 (uncurry mk_csum) (map mk_card_of As)) ctwo) suc_bd;
544 val suc_bd_Card_order = if n = 1 then bd_Card_order RS @{thm cardSuc_Card_order}
545 else @{thm cardSuc_Card_order[OF Card_order_csum]};
546 val suc_bd_Cinfinite = if n = 1 then bd_Cinfinite RS @{thm Cinfinite_cardSuc}
547 else bd_Cinfinite RS @{thm Cinfinite_cardSuc[OF Cinfinite_csum1]};
548 val suc_bd_Cnotzero = suc_bd_Cinfinite RS @{thm Cinfinite_Cnotzero};
549 val suc_bd_worel = suc_bd_Card_order RS @{thm Card_order_wo_rel}
550 val basis_Asuc = if m = 0 then @{thm ordLeq_refl[OF Card_order_ctwo]}
551 else @{thm ordLeq_csum2[OF Card_order_ctwo]};
552 val Asuc_bd_Cinfinite = suc_bd_Cinfinite RS (basis_Asuc RS @{thm Cinfinite_cexp});
553 val Asuc_bd_Cnotzero = Asuc_bd_Cinfinite RS @{thm Cinfinite_Cnotzero};
555 val suc_bd_Asuc_bd = @{thm ordLess_ordLeq_trans[OF
557 cexp_mono1_Cnotzero[OF _ ctwo_Cnotzero]]} OF
558 [suc_bd_Card_order, basis_Asuc, suc_bd_Card_order];
560 val Asuc_bdT = fst (dest_relT (fastype_of (mk_Asuc_bd As)));
561 val II_BTs = replicate n (HOLogic.mk_setT Asuc_bdT);
562 val II_sTs = map2 (fn Ds => fn bnf =>
563 mk_T_of_bnf Ds (passiveAs @ replicate n Asuc_bdT) bnf --> Asuc_bdT) Dss bnfs;
565 val (((((((idxs, Asi_name), (idx, idx')), (jdx, jdx')), II_Bs), II_ss), Asuc_fs),
566 names_lthy) = names_lthy
567 |> mk_Frees "i" (replicate n suc_bdT)
568 ||>> (fn ctxt => apfst the_single (mk_fresh_names ctxt 1 "Asi"))
569 ||>> yield_singleton (apfst (op ~~) oo mk_Frees' "i") suc_bdT
570 ||>> yield_singleton (apfst (op ~~) oo mk_Frees' "j") suc_bdT
571 ||>> mk_Frees "IIB" II_BTs
572 ||>> mk_Frees "IIs" II_sTs
573 ||>> mk_Frees "f" (map (fn T => Asuc_bdT --> T) activeAs);
575 val suc_bd_limit_thm =
577 val prem = HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
578 (map (fn idx => HOLogic.mk_mem (idx, field_suc_bd)) idxs));
579 fun mk_conjunct idx = HOLogic.mk_conj (mk_not_eq idx jdx,
580 HOLogic.mk_mem (HOLogic.mk_prod (idx, jdx), suc_bd));
581 val concl = HOLogic.mk_Trueprop (mk_Bex field_suc_bd
582 (Term.absfree jdx' (Library.foldr1 HOLogic.mk_conj (map mk_conjunct idxs))));
584 Skip_Proof.prove lthy [] []
585 (fold_rev Logic.all idxs (Logic.list_implies ([prem], concl)))
586 (K (mk_bd_limit_tac n suc_bd_Cinfinite))
589 val timer = time (timer "Bounds");
592 (* minimal algebra *)
594 fun mk_minG Asi i k = mk_UNION (mk_underS suc_bd $ i)
595 (Term.absfree jdx' (mk_nthN n (Asi $ jdx) k));
597 fun mk_minH_component As Asi i sets Ts s k =
598 HOLogic.mk_binop @{const_name "sup"}
599 (mk_minG Asi i k, mk_image s $ mk_in (As @ map (mk_minG Asi i) ks) sets Ts);
601 fun mk_min_algs As ss =
603 val BTs = map (range_type o fastype_of) ss;
604 val Ts = map (HOLogic.dest_setT o fastype_of) As @ BTs;
605 val (Asi, Asi') = `Free (Asi_name, suc_bdT -->
606 Library.foldr1 HOLogic.mk_prodT (map HOLogic.mk_setT BTs));
608 mk_worec suc_bd (Term.absfree Asi' (Term.absfree idx' (HOLogic.mk_tuple
609 (map4 (mk_minH_component As Asi idx) (mk_setss Ts) (mk_FTs Ts) ss ks))))
612 val (min_algs_thms, min_algs_mono_thms, card_of_min_algs_thm, least_min_algs_thm) =
614 val i_field = HOLogic.mk_mem (idx, field_suc_bd);
615 val min_algs = mk_min_algs As ss;
616 val min_algss = map (fn k => mk_nthN n (min_algs $ idx) k) ks;
618 val concl = HOLogic.mk_Trueprop
619 (HOLogic.mk_eq (min_algs $ idx, HOLogic.mk_tuple
620 (map4 (mk_minH_component As min_algs idx) setssAs FTsAs ss ks)));
621 val goal = fold_rev Logic.all (idx :: As @ ss)
622 (Logic.mk_implies (HOLogic.mk_Trueprop i_field, concl));
624 val min_algs_thm = Skip_Proof.prove lthy [] [] goal
625 (K (mk_min_algs_tac suc_bd_worel in_cong'_thms));
627 val min_algs_thms = map (fn k => min_algs_thm RS mk_nthI n k) ks;
629 fun mk_mono_goal min_alg =
630 fold_rev Logic.all (As @ ss) (HOLogic.mk_Trueprop (mk_relChain suc_bd
631 (Term.absfree idx' min_alg)));
633 val monos = map2 (fn goal => fn min_algs =>
634 Skip_Proof.prove lthy [] [] goal (K (mk_min_algs_mono_tac min_algs)))
635 (map mk_mono_goal min_algss) min_algs_thms;
637 val Asuc_bd = mk_Asuc_bd As;
639 fun mk_card_conjunct min_alg = mk_ordLeq (mk_card_of min_alg) Asuc_bd;
640 val card_conjunction = Library.foldr1 HOLogic.mk_conj (map mk_card_conjunct min_algss);
641 val card_cT = certifyT lthy suc_bdT;
642 val card_ct = certify lthy (Term.absfree idx' card_conjunction);
644 val card_of = singleton (Proof_Context.export names_lthy lthy)
645 (Skip_Proof.prove lthy [] []
646 (HOLogic.mk_Trueprop (HOLogic.mk_imp (i_field, card_conjunction)))
647 (K (mk_min_algs_card_of_tac card_cT card_ct
648 m suc_bd_worel min_algs_thms in_bd_sums
649 sum_Card_order sum_Cnotzero suc_bd_Card_order suc_bd_Cinfinite suc_bd_Cnotzero
650 suc_bd_Asuc_bd Asuc_bd_Cinfinite Asuc_bd_Cnotzero)));
652 val least_prem = HOLogic.mk_Trueprop (mk_alg As Bs ss);
653 val least_conjunction = Library.foldr1 HOLogic.mk_conj (map2 mk_subset min_algss Bs);
654 val least_cT = certifyT lthy suc_bdT;
655 val least_ct = certify lthy (Term.absfree idx' least_conjunction);
657 val least = singleton (Proof_Context.export names_lthy lthy)
658 (Skip_Proof.prove lthy [] []
659 (Logic.mk_implies (least_prem,
660 HOLogic.mk_Trueprop (HOLogic.mk_imp (i_field, least_conjunction))))
661 (K (mk_min_algs_least_tac least_cT least_ct
662 suc_bd_worel min_algs_thms alg_set_thms)));
664 (min_algs_thms, monos, card_of, least)
667 val timer = time (timer "min_algs definition & thms");
669 fun min_alg_bind i = Binding.suffix_name
670 ("_" ^ min_algN ^ (if n = 1 then "" else string_of_int i)) b;
671 val min_alg_name = Binding.name_of o min_alg_bind;
672 val min_alg_def_bind = rpair [] o Thm.def_binding o min_alg_bind;
677 Library.foldr (op -->) (ATs @ sTs, HOLogic.mk_setT (nth activeAs (i - 1)));
679 val lhs = Term.list_comb (Free (min_alg_name i, min_algT), As @ ss);
680 val rhs = mk_UNION (field_suc_bd)
681 (Term.absfree idx' (mk_nthN n (mk_min_algs As ss $ idx) i));
683 HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs))
686 val ((min_alg_frees, (_, min_alg_def_frees)), (lthy, lthy_old)) =
688 |> fold_map (fn i => Specification.definition
689 (SOME (min_alg_bind i, NONE, NoSyn), (min_alg_def_bind i, min_alg_spec i))) ks
690 |>> apsnd split_list o split_list
691 ||> `Local_Theory.restore;
693 (*transforms defined frees into consts*)
694 val phi = Proof_Context.export_morphism lthy_old lthy;
695 val min_algs = map (fst o Term.dest_Const o Morphism.term phi) min_alg_frees;
696 val min_alg_defs = map (Morphism.thm phi) min_alg_def_frees;
698 fun mk_min_alg As ss i =
700 val T = HOLogic.mk_setT (range_type (fastype_of (nth ss (i - 1))))
702 val Ts = map fastype_of args;
703 val min_algT = Library.foldr (op -->) (Ts, T);
705 Term.list_comb (Const (nth min_algs (i - 1), min_algT), args)
708 val (alg_min_alg_thm, card_of_min_alg_thms, least_min_alg_thms, mor_incl_min_alg_thm) =
710 val min_algs = map (mk_min_alg As ss) ks;
712 val goal = fold_rev Logic.all (As @ ss) (HOLogic.mk_Trueprop (mk_alg As min_algs ss));
713 val alg_min_alg = Skip_Proof.prove lthy [] [] goal
714 (K (mk_alg_min_alg_tac m alg_def min_alg_defs suc_bd_limit_thm sum_Cinfinite
715 set_bd_sumss min_algs_thms min_algs_mono_thms));
717 val Asuc_bd = mk_Asuc_bd As;
718 fun mk_card_of_thm min_alg def = Skip_Proof.prove lthy [] []
719 (fold_rev Logic.all (As @ ss)
720 (HOLogic.mk_Trueprop (mk_ordLeq (mk_card_of min_alg) Asuc_bd)))
721 (K (mk_card_of_min_alg_tac def card_of_min_algs_thm
722 suc_bd_Card_order suc_bd_Asuc_bd Asuc_bd_Cinfinite));
724 val least_prem = HOLogic.mk_Trueprop (mk_alg As Bs ss);
725 fun mk_least_thm min_alg B def = Skip_Proof.prove lthy [] []
726 (fold_rev Logic.all (As @ Bs @ ss)
727 (Logic.mk_implies (least_prem, HOLogic.mk_Trueprop (mk_subset min_alg B))))
728 (K (mk_least_min_alg_tac def least_min_algs_thm));
730 val leasts = map3 mk_least_thm min_algs Bs min_alg_defs;
732 val incl_prem = HOLogic.mk_Trueprop (mk_alg passive_UNIVs Bs ss);
733 val incl_min_algs = map (mk_min_alg passive_UNIVs ss) ks;
734 val incl = Skip_Proof.prove lthy [] []
735 (fold_rev Logic.all (Bs @ ss)
736 (Logic.mk_implies (incl_prem,
737 HOLogic.mk_Trueprop (mk_mor incl_min_algs ss Bs ss active_ids))))
738 (K (EVERY' (rtac mor_incl_thm :: map etac leasts) 1));
741 map2 mk_card_of_thm min_algs min_alg_defs,
745 val timer = time (timer "Minimal algebra definition & thms");
747 val II_repT = HOLogic.mk_prodT (HOLogic.mk_tupleT II_BTs, HOLogic.mk_tupleT II_sTs);
748 val IIT_bind = Binding.suffix_name ("_" ^ IITN) b;
750 val ((IIT_name, (IIT_glob_info, IIT_loc_info)), lthy) =
751 typedef true NONE (IIT_bind, params, NoSyn)
752 (HOLogic.mk_UNIV II_repT) NONE (EVERY' [rtac exI, rtac UNIV_I] 1) lthy;
754 val IIT = Type (IIT_name, params');
755 val Abs_IIT = Const (#Abs_name IIT_glob_info, II_repT --> IIT);
756 val Rep_IIT = Const (#Rep_name IIT_glob_info, IIT --> II_repT);
757 val Abs_IIT_inverse_thm =
758 mk_Abs_inverse_thm (the (#set_def IIT_loc_info)) (#Abs_inverse IIT_loc_info);
760 val initT = IIT --> Asuc_bdT;
761 val active_initTs = replicate n initT;
762 val init_FTs = map2 (fn Ds => mk_T_of_bnf Ds (passiveAs @ active_initTs)) Dss bnfs;
763 val init_fTs = map (fn T => initT --> T) activeAs;
765 val (((((((iidx, iidx'), init_xs), (init_xFs, init_xFs')),
766 init_fs), init_fs_copy), init_phis), names_lthy) = names_lthy
767 |> yield_singleton (apfst (op ~~) oo mk_Frees' "i") IIT
768 ||>> mk_Frees "ix" active_initTs
769 ||>> mk_Frees' "x" init_FTs
770 ||>> mk_Frees "f" init_fTs
771 ||>> mk_Frees "f" init_fTs
772 ||>> mk_Frees "phi" (replicate n (initT --> HOLogic.boolT));
774 val II = HOLogic.mk_Collect (fst iidx', IIT, list_exists_free (II_Bs @ II_ss)
775 (HOLogic.mk_conj (HOLogic.mk_eq (iidx,
776 Abs_IIT $ (HOLogic.mk_prod (HOLogic.mk_tuple II_Bs, HOLogic.mk_tuple II_ss))),
777 mk_alg passive_UNIVs II_Bs II_ss)));
779 val select_Bs = map (mk_nthN n (HOLogic.mk_fst (Rep_IIT $ iidx))) ks;
780 val select_ss = map (mk_nthN n (HOLogic.mk_snd (Rep_IIT $ iidx))) ks;
782 fun str_init_bind i = Binding.suffix_name ("_" ^ str_initN ^ (if n = 1 then "" else
784 val str_init_name = Binding.name_of o str_init_bind;
785 val str_init_def_bind = rpair [] o Thm.def_binding o str_init_bind;
787 fun str_init_spec i =
789 val T = nth init_FTs (i - 1);
790 val init_xF = nth init_xFs (i - 1)
791 val select_s = nth select_ss (i - 1);
792 val map = mk_map_of_bnf (nth Dss (i - 1))
793 (passiveAs @ active_initTs) (passiveAs @ replicate n Asuc_bdT)
795 val map_args = passive_ids @ replicate n (mk_rapp iidx Asuc_bdT);
796 val str_initT = T --> IIT --> Asuc_bdT;
798 val lhs = Term.list_comb (Free (str_init_name i, str_initT), [init_xF, iidx]);
799 val rhs = select_s $ (Term.list_comb (map, map_args) $ init_xF);
801 HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs))
804 val ((str_init_frees, (_, str_init_def_frees)), (lthy, lthy_old)) =
806 |> fold_map (fn i => Specification.definition
807 (SOME (str_init_bind i, NONE, NoSyn), (str_init_def_bind i, str_init_spec i))) ks
808 |>> apsnd split_list o split_list
809 ||> `Local_Theory.restore;
811 (*transforms defined frees into consts*)
812 val phi = Proof_Context.export_morphism lthy_old lthy;
814 map (Term.subst_atomic_types (map (`(Morphism.typ phi)) params') o Morphism.term phi)
817 val str_init_defs = map (Morphism.thm phi) str_init_def_frees;
819 val car_inits = map (mk_min_alg passive_UNIVs str_inits) ks;
821 (*TODO: replace with instantiate? (problem: figure out right type instantiation)*)
822 val alg_init_thm = Skip_Proof.prove lthy [] []
823 (HOLogic.mk_Trueprop (mk_alg passive_UNIVs car_inits str_inits))
824 (K (rtac alg_min_alg_thm 1));
826 val alg_select_thm = Skip_Proof.prove lthy [] []
827 (HOLogic.mk_Trueprop (mk_Ball II
828 (Term.absfree iidx' (mk_alg passive_UNIVs select_Bs select_ss))))
829 (mk_alg_select_tac Abs_IIT_inverse_thm)
833 val alg_prem = HOLogic.mk_Trueprop (mk_alg passive_UNIVs Bs ss);
834 val i_prem = HOLogic.mk_Trueprop (HOLogic.mk_mem (iidx, II));
835 val mor_prem = HOLogic.mk_Trueprop (mk_mor select_Bs select_ss Bs ss Asuc_fs);
836 val prems = [alg_prem, i_prem, mor_prem];
837 val concl = HOLogic.mk_Trueprop
838 (mk_mor car_inits str_inits Bs ss
839 (map (fn f => HOLogic.mk_comp (f, mk_rapp iidx Asuc_bdT)) Asuc_fs));
841 Skip_Proof.prove lthy [] []
842 (fold_rev Logic.all (iidx :: Bs @ ss @ Asuc_fs) (Logic.list_implies (prems, concl)))
843 (K (mk_mor_select_tac mor_def mor_cong_thm mor_comp_thm mor_incl_min_alg_thm alg_def
844 alg_select_thm alg_set_thms set_natural'ss str_init_defs))
847 val (init_ex_mor_thm, init_unique_mor_thms) =
849 val prem = HOLogic.mk_Trueprop (mk_alg passive_UNIVs Bs ss);
850 val concl = HOLogic.mk_Trueprop
851 (list_exists_free init_fs (mk_mor car_inits str_inits Bs ss init_fs));
852 val ex_mor = Skip_Proof.prove lthy [] []
853 (fold_rev Logic.all (Bs @ ss) (Logic.mk_implies (prem, concl)))
854 (mk_init_ex_mor_tac Abs_IIT_inverse_thm ex_copy_alg_thm alg_min_alg_thm
855 card_of_min_alg_thms mor_comp_thm mor_select_thm mor_incl_min_alg_thm);
857 val prems = map2 (HOLogic.mk_Trueprop oo curry HOLogic.mk_mem) init_xs car_inits
858 val mor_prems = map HOLogic.mk_Trueprop
859 [mk_mor car_inits str_inits Bs ss init_fs,
860 mk_mor car_inits str_inits Bs ss init_fs_copy];
861 fun mk_fun_eq f g x = HOLogic.mk_eq (f $ x, g $ x);
862 val unique = HOLogic.mk_Trueprop
863 (Library.foldr1 HOLogic.mk_conj (map3 mk_fun_eq init_fs init_fs_copy init_xs));
864 val unique_mor = Skip_Proof.prove lthy [] []
865 (fold_rev Logic.all (init_xs @ Bs @ ss @ init_fs @ init_fs_copy)
866 (Logic.list_implies (prems @ mor_prems, unique)))
867 (K (mk_init_unique_mor_tac m alg_def alg_init_thm least_min_alg_thms
868 in_mono'_thms alg_set_thms morE_thms map_congs));
870 (ex_mor, split_conj_thm unique_mor)
873 val init_setss = mk_setss (passiveAs @ active_initTs);
874 val active_init_setss = map (drop m) init_setss;
875 val init_ins = map2 (fn sets => mk_in (passive_UNIVs @ car_inits) sets) init_setss init_FTs;
879 fun mk_conjunct phi str_init init_sets init_in x x' =
881 val prem = Library.foldr1 HOLogic.mk_conj
882 (map2 (fn set => mk_Ball (set $ x)) init_sets phis);
883 val concl = phi $ (str_init $ x);
885 mk_Ball init_in (Term.absfree x' (HOLogic.mk_imp (prem, concl)))
888 Library.foldr1 HOLogic.mk_conj
889 (map6 mk_conjunct phis str_inits active_init_setss init_ins init_xFs init_xFs')
892 val init_induct_thm =
894 val prem = HOLogic.mk_Trueprop (mk_closed init_phis);
895 val concl = HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
896 (map2 mk_Ball car_inits init_phis));
898 Skip_Proof.prove lthy [] []
899 (fold_rev Logic.all init_phis (Logic.mk_implies (prem, concl)))
900 (K (mk_init_induct_tac m alg_def alg_init_thm least_min_alg_thms alg_set_thms))
903 val timer = time (timer "Initiality definition & thms");
905 val ((T_names, (T_glob_infos, T_loc_infos)), lthy) =
907 |> fold_map2 (fn b => fn car_init => typedef true NONE (b, params, NoSyn) car_init NONE
908 (EVERY' [rtac ssubst, rtac @{thm ex_in_conv}, resolve_tac alg_not_empty_thms,
909 rtac alg_init_thm] 1)) bs car_inits
910 |>> apsnd split_list o split_list;
912 val Ts = map (fn name => Type (name, params')) T_names;
913 fun mk_Ts passive = map (Term.typ_subst_atomic (passiveAs ~~ passive)) Ts;
914 val Ts' = mk_Ts passiveBs;
915 val Rep_Ts = map2 (fn info => fn T => Const (#Rep_name info, T --> initT)) T_glob_infos Ts;
916 val Abs_Ts = map2 (fn info => fn T => Const (#Abs_name info, initT --> T)) T_glob_infos Ts;
918 val set_defs = map (the o #set_def) T_loc_infos;
919 val type_defs = map #type_definition T_loc_infos;
920 val Reps = map #Rep T_loc_infos;
921 val Rep_casess = map #Rep_cases T_loc_infos;
922 val Rep_injects = map #Rep_inject T_loc_infos;
923 val Rep_inverses = map #Rep_inverse T_loc_infos;
924 val Abs_inverses = map #Abs_inverse T_loc_infos;
926 val T_subset1s = map mk_T_subset1 set_defs;
927 val T_subset2s = map mk_T_subset2 set_defs;
929 fun mk_inver_thm mk_tac rep abs X thm =
930 Skip_Proof.prove lthy [] []
931 (HOLogic.mk_Trueprop (mk_inver rep abs X))
932 (K (EVERY' [rtac ssubst, rtac @{thm inver_def}, rtac ballI, mk_tac thm] 1));
934 val inver_Reps = map4 (mk_inver_thm rtac) Abs_Ts Rep_Ts (map HOLogic.mk_UNIV Ts) Rep_inverses;
935 val inver_Abss = map4 (mk_inver_thm etac) Rep_Ts Abs_Ts car_inits
936 (map2 (curry op RS) T_subset1s Abs_inverses);
938 val timer = time (timer "THE TYPEDEFs & Rep/Abs thms");
940 val UNIVs = map HOLogic.mk_UNIV Ts;
941 val FTs = mk_FTs (passiveAs @ Ts);
942 val FTs' = mk_FTs (passiveBs @ Ts');
943 fun mk_set_Ts T = passiveAs @ replicate n (HOLogic.mk_setT T);
944 val setFTss = map (mk_FTs o mk_set_Ts) passiveAs;
945 val FTs_setss = mk_setss (passiveAs @ Ts);
946 val FTs'_setss = mk_setss (passiveBs @ Ts');
947 val map_FT_inits = map2 (fn Ds =>
948 mk_map_of_bnf Ds (passiveAs @ Ts) (passiveAs @ active_initTs)) Dss bnfs;
949 val fTs = map2 (curry op -->) Ts activeAs;
950 val iterT = Library.foldr1 HOLogic.mk_prodT (map2 (curry op -->) Ts activeAs);
951 val rec_sTs = map (Term.typ_subst_atomic (activeBs ~~ Ts)) prod_sTs;
952 val rec_maps = map (Term.subst_atomic_types (activeBs ~~ Ts)) map_fsts;
953 val rec_maps_rev = map (Term.subst_atomic_types (activeBs ~~ Ts)) map_fsts_rev;
954 val rec_fsts = map (Term.subst_atomic_types (activeBs ~~ Ts)) fsts;
956 val (((((((((((Izs, (Izs1, Izs1')), (Izs2, Izs2')), (xFs, xFs')), yFs), (AFss, AFss')),
957 (iter_f, iter_f')), fs), phis), phi2s), rec_ss), names_lthy) = names_lthy
959 ||>> mk_Frees' "z1" Ts
960 ||>> mk_Frees' "z2" Ts'
961 ||>> mk_Frees' "x" FTs
962 ||>> mk_Frees "y" FTs'
963 ||>> mk_Freess' "z" setFTss
964 ||>> yield_singleton (apfst (op ~~) oo mk_Frees' "f") iterT
965 ||>> mk_Frees "f" fTs
966 ||>> mk_Frees "phi" (map (fn T => T --> HOLogic.boolT) Ts)
967 ||>> mk_Frees "phi" (map2 (fn T => fn U => T --> U --> HOLogic.boolT) Ts Ts')
968 ||>> mk_Frees "s" rec_sTs;
970 fun fld_bind i = Binding.suffix_name ("_" ^ fldN) (nth bs (i - 1));
971 val fld_name = Binding.name_of o fld_bind;
972 val fld_def_bind = rpair [] o Thm.def_binding o fld_bind;
974 fun fld_spec i abs str map_FT_init x x' =
976 val fldT = nth FTs (i - 1) --> nth Ts (i - 1);
978 val lhs = Free (fld_name i, fldT);
979 val rhs = Term.absfree x' (abs $ (str $
980 (Term.list_comb (map_FT_init, map HOLogic.id_const passiveAs @ Rep_Ts) $ x)));
982 HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs))
985 val ((fld_frees, (_, fld_def_frees)), (lthy, lthy_old)) =
987 |> fold_map6 (fn i => fn abs => fn str => fn map => fn x => fn x' =>
988 Specification.definition
989 (SOME (fld_bind i, NONE, NoSyn), (fld_def_bind i, fld_spec i abs str map x x')))
990 ks Abs_Ts str_inits map_FT_inits xFs xFs'
991 |>> apsnd split_list o split_list
992 ||> `Local_Theory.restore;
994 (*transforms defined frees into consts*)
995 val phi = Proof_Context.export_morphism lthy_old lthy;
996 fun mk_flds passive =
997 map (Term.subst_atomic_types (map (Morphism.typ phi) params' ~~ (deads @ passive)) o
998 Morphism.term phi) fld_frees;
999 val flds = mk_flds passiveAs;
1000 val fld's = mk_flds passiveBs;
1001 val fld_defs = map (Morphism.thm phi) fld_def_frees;
1003 val (mor_Rep_thm, mor_Abs_thm) =
1005 val copy = alg_init_thm RS copy_alg_thm;
1006 fun mk_bij inj subset1 subset2 Rep cases = @{thm bij_betwI'} OF
1007 [inj, Rep RS subset2, subset1 RS cases];
1008 val bijs = map5 mk_bij Rep_injects T_subset1s T_subset2s Reps Rep_casess;
1010 Skip_Proof.prove lthy [] []
1011 (HOLogic.mk_Trueprop (mk_mor UNIVs flds car_inits str_inits Rep_Ts))
1012 (mk_mor_Rep_tac fld_defs copy bijs inver_Abss inver_Reps);
1014 val inv = mor_inv_thm OF [mor_Rep, talg_thm, alg_init_thm];
1016 Skip_Proof.prove lthy [] []
1017 (HOLogic.mk_Trueprop (mk_mor car_inits str_inits UNIVs flds Abs_Ts))
1018 (K (mk_mor_Abs_tac inv inver_Abss inver_Reps));
1023 val timer = time (timer "fld definitions & thms");
1025 val iter_fun = Term.absfree iter_f'
1026 (mk_mor UNIVs flds active_UNIVs ss (map (mk_nthN n iter_f) ks));
1027 val iter = HOLogic.choice_const iterT $ iter_fun;
1029 fun iter_bind i = Binding.suffix_name ("_" ^ iterN) (nth bs (i - 1));
1030 val iter_name = Binding.name_of o iter_bind;
1031 val iter_def_bind = rpair [] o Thm.def_binding o iter_bind;
1033 fun iter_spec i T AT =
1035 val iterT = Library.foldr (op -->) (sTs, T --> AT);
1037 val lhs = Term.list_comb (Free (iter_name i, iterT), ss);
1038 val rhs = mk_nthN n iter i;
1040 HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs))
1043 val ((iter_frees, (_, iter_def_frees)), (lthy, lthy_old)) =
1045 |> fold_map3 (fn i => fn T => fn AT =>
1046 Specification.definition
1047 (SOME (iter_bind i, NONE, NoSyn), (iter_def_bind i, iter_spec i T AT)))
1049 |>> apsnd split_list o split_list
1050 ||> `Local_Theory.restore;
1052 (*transforms defined frees into consts*)
1053 val phi = Proof_Context.export_morphism lthy_old lthy;
1054 val iters = map (fst o dest_Const o Morphism.term phi) iter_frees;
1055 fun mk_iter Ts ss i = Term.list_comb (Const (nth iters (i - 1), Library.foldr (op -->)
1056 (map fastype_of ss, nth Ts (i - 1) --> range_type (fastype_of (nth ss (i - 1))))), ss);
1057 val iter_defs = map (Morphism.thm phi) iter_def_frees;
1061 val ex_mor = talg_thm RS init_ex_mor_thm;
1062 val mor_cong = mor_cong_thm OF (map (mk_nth_conv n) ks);
1063 val mor_comp = mor_Rep_thm RS mor_comp_thm;
1064 val cT = certifyT lthy iterT;
1065 val ct = certify lthy iter_fun
1067 singleton (Proof_Context.export names_lthy lthy)
1068 (Skip_Proof.prove lthy [] []
1069 (HOLogic.mk_Trueprop (mk_mor UNIVs flds active_UNIVs ss (map (mk_iter Ts ss) ks)))
1070 (K (mk_mor_iter_tac cT ct iter_defs ex_mor (mor_comp RS mor_cong))))
1073 val iter_thms = map (fn morE => rule_by_tactic lthy
1074 ((rtac CollectI THEN' CONJ_WRAP' (K (rtac @{thm subset_UNIV})) (1 upto m + n)) 1)
1075 (mor_iter_thm RS morE)) morE_thms;
1077 val (iter_unique_mor_thms, iter_unique_mor_thm) =
1079 val prem = HOLogic.mk_Trueprop (mk_mor UNIVs flds active_UNIVs ss fs);
1080 fun mk_fun_eq f i = HOLogic.mk_eq (f, mk_iter Ts ss i);
1081 val unique = HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj (map2 mk_fun_eq fs ks));
1082 val unique_mor = Skip_Proof.prove lthy [] []
1083 (fold_rev Logic.all (ss @ fs) (Logic.mk_implies (prem, unique)))
1084 (K (mk_iter_unique_mor_tac type_defs init_unique_mor_thms T_subset2s Reps
1085 mor_comp_thm mor_Abs_thm mor_iter_thm));
1087 `split_conj_thm unique_mor
1090 val (iter_unique_thms, iter_unique_thm) =
1091 `split_conj_thm (mk_conjIN n RS
1092 (mor_UNIV_thm RS @{thm ssubst[of _ _ "%x. x"]} RS iter_unique_mor_thm))
1095 map (fn thm => (mor_incl_thm OF replicate n @{thm subset_UNIV}) RS thm RS sym)
1096 iter_unique_mor_thms;
1098 val fld_o_iter_thms =
1100 val mor = mor_comp_thm OF [mor_iter_thm, mor_str_thm];
1102 map2 (fn unique => fn iter_fld =>
1103 trans OF [mor RS unique, iter_fld]) iter_unique_mor_thms iter_fld_thms
1106 val timer = time (timer "iter definitions & thms");
1108 val map_flds = map2 (fn Ds => fn bnf =>
1109 Term.list_comb (mk_map_of_bnf Ds (passiveAs @ FTs) (passiveAs @ Ts) bnf,
1110 map HOLogic.id_const passiveAs @ flds)) Dss bnfs;
1112 fun unf_bind i = Binding.suffix_name ("_" ^ unfN) (nth bs (i - 1));
1113 val unf_name = Binding.name_of o unf_bind;
1114 val unf_def_bind = rpair [] o Thm.def_binding o unf_bind;
1116 fun unf_spec i FT T =
1118 val unfT = T --> FT;
1120 val lhs = Free (unf_name i, unfT);
1121 val rhs = mk_iter Ts map_flds i;
1123 HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs))
1126 val ((unf_frees, (_, unf_def_frees)), (lthy, lthy_old)) =
1128 |> fold_map3 (fn i => fn FT => fn T =>
1129 Specification.definition
1130 (SOME (unf_bind i, NONE, NoSyn), (unf_def_bind i, unf_spec i FT T))) ks FTs Ts
1131 |>> apsnd split_list o split_list
1132 ||> `Local_Theory.restore;
1134 (*transforms defined frees into consts*)
1135 val phi = Proof_Context.export_morphism lthy_old lthy;
1136 fun mk_unfs params =
1137 map (Term.subst_atomic_types (map (Morphism.typ phi) params' ~~ params) o Morphism.term phi)
1139 val unfs = mk_unfs params';
1140 val unf_defs = map (Morphism.thm phi) unf_def_frees;
1142 val fld_o_unf_thms = map2 (Local_Defs.fold lthy o single) unf_defs fld_o_iter_thms;
1144 val unf_o_fld_thms =
1146 fun mk_goal unf fld FT =
1147 HOLogic.mk_Trueprop (HOLogic.mk_eq (HOLogic.mk_comp (unf, fld), HOLogic.id_const FT));
1148 val goals = map3 mk_goal unfs flds FTs;
1150 map5 (fn goal => fn unf_def => fn iter => fn map_comp_id => fn map_congL =>
1151 Skip_Proof.prove lthy [] [] goal
1152 (K (mk_unf_o_fld_tac unf_def iter map_comp_id map_congL fld_o_iter_thms)))
1153 goals unf_defs iter_thms map_comp_id_thms map_congL_thms
1156 val unf_fld_thms = map (fn thm => thm RS @{thm pointfree_idE}) unf_o_fld_thms;
1157 val fld_unf_thms = map (fn thm => thm RS @{thm pointfree_idE}) fld_o_unf_thms;
1160 map2 (fn thm1 => fn thm2 => @{thm o_bij} OF [thm1, thm2]) fld_o_unf_thms unf_o_fld_thms;
1161 val inj_unf_thms = map (fn thm => thm RS @{thm bij_is_inj}) bij_unf_thms;
1162 val surj_unf_thms = map (fn thm => thm RS @{thm bij_is_surj}) bij_unf_thms;
1163 val unf_nchotomy_thms = map (fn thm => thm RS @{thm surjD}) surj_unf_thms;
1164 val unf_inject_thms = map (fn thm => thm RS @{thm inj_eq}) inj_unf_thms;
1165 val unf_exhaust_thms = map (fn thm => thm RS exE) unf_nchotomy_thms;
1168 map2 (fn thm1 => fn thm2 => @{thm o_bij} OF [thm1, thm2]) unf_o_fld_thms fld_o_unf_thms;
1169 val inj_fld_thms = map (fn thm => thm RS @{thm bij_is_inj}) bij_fld_thms;
1170 val surj_fld_thms = map (fn thm => thm RS @{thm bij_is_surj}) bij_fld_thms;
1171 val fld_nchotomy_thms = map (fn thm => thm RS @{thm surjD}) surj_fld_thms;
1172 val fld_inject_thms = map (fn thm => thm RS @{thm inj_eq}) inj_fld_thms;
1173 val fld_exhaust_thms = map (fn thm => thm RS exE) fld_nchotomy_thms;
1175 val timer = time (timer "unf definitions & thms");
1177 val fst_rec_pair_thms =
1179 val mor = mor_comp_thm OF [mor_iter_thm, mor_convol_thm];
1181 map2 (fn unique => fn iter_fld =>
1182 trans OF [mor RS unique, iter_fld]) iter_unique_mor_thms iter_fld_thms
1185 fun rec_bind i = Binding.suffix_name ("_" ^ recN) (nth bs (i - 1));
1186 val rec_name = Binding.name_of o rec_bind;
1187 val rec_def_bind = rpair [] o Thm.def_binding o rec_bind;
1189 fun rec_spec i T AT =
1191 val recT = Library.foldr (op -->) (rec_sTs, T --> AT);
1192 val maps = map3 (fn fld => fn prod_s => fn map =>
1193 mk_convol (HOLogic.mk_comp (fld, Term.list_comb (map, passive_ids @ rec_fsts)), prod_s))
1194 flds rec_ss rec_maps;
1196 val lhs = Term.list_comb (Free (rec_name i, recT), rec_ss);
1197 val rhs = HOLogic.mk_comp (snd_const (HOLogic.mk_prodT (T, AT)), mk_iter Ts maps i);
1199 HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs))
1202 val ((rec_frees, (_, rec_def_frees)), (lthy, lthy_old)) =
1204 |> fold_map3 (fn i => fn T => fn AT =>
1205 Specification.definition
1206 (SOME (rec_bind i, NONE, NoSyn), (rec_def_bind i, rec_spec i T AT)))
1208 |>> apsnd split_list o split_list
1209 ||> `Local_Theory.restore;
1211 (*transforms defined frees into consts*)
1212 val phi = Proof_Context.export_morphism lthy_old lthy;
1213 val recs = map (fst o dest_Const o Morphism.term phi) rec_frees;
1214 fun mk_rec ss i = Term.list_comb (Const (nth recs (i - 1), Library.foldr (op -->)
1215 (map fastype_of ss, nth Ts (i - 1) --> range_type (fastype_of (nth ss (i - 1))))), ss);
1216 val rec_defs = map (Morphism.thm phi) rec_def_frees;
1218 val convols = map2 (fn T => fn i => mk_convol (HOLogic.id_const T, mk_rec rec_ss i)) Ts ks;
1221 fun mk_goal i rec_s rec_map fld x =
1223 val lhs = mk_rec rec_ss i $ (fld $ x);
1224 val rhs = rec_s $ (Term.list_comb (rec_map, passive_ids @ convols) $ x);
1226 fold_rev Logic.all (x :: rec_ss) (HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, rhs)))
1228 val goals = map5 mk_goal ks rec_ss rec_maps_rev flds xFs;
1230 map2 (fn goal => fn iter =>
1231 Skip_Proof.prove lthy [] [] goal (mk_rec_tac rec_defs iter fst_rec_pair_thms))
1235 val timer = time (timer "rec definitions & thms");
1237 val (fld_induct_thm, induct_params) =
1239 fun mk_prem phi fld sets x =
1241 fun mk_IH phi set z =
1243 val prem = HOLogic.mk_Trueprop (HOLogic.mk_mem (z, set $ x));
1244 val concl = HOLogic.mk_Trueprop (phi $ z);
1246 Logic.all z (Logic.mk_implies (prem, concl))
1249 val IHs = map3 mk_IH phis (drop m sets) Izs;
1250 val concl = HOLogic.mk_Trueprop (phi $ (fld $ x));
1252 Logic.all x (Logic.list_implies (IHs, concl))
1255 val prems = map4 mk_prem phis flds FTs_setss xFs;
1257 fun mk_concl phi z = phi $ z;
1259 HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj (map2 mk_concl phis Izs));
1261 val goal = Logic.list_implies (prems, concl);
1263 (Skip_Proof.prove lthy [] []
1264 (fold_rev Logic.all (phis @ Izs) goal)
1265 (K (mk_fld_induct_tac m set_natural'ss init_induct_thm morE_thms mor_Abs_thm
1266 Rep_inverses Abs_inverses Reps T_subset1s T_subset2s)), rev (Term.add_tfrees goal []))
1269 val cTs = map (SOME o certifyT lthy o TFree) induct_params;
1271 val weak_fld_induct_thms =
1272 let fun insts i = (replicate (i - 1) TrueI) @ (@{thm asm_rl} :: replicate (n - i) TrueI);
1273 in map (fn i => (fld_induct_thm OF insts i) RS mk_conjunctN n i) ks end;
1275 val (fld_induct2_thm, induct2_params) =
1277 fun mk_prem phi fld fld' sets sets' x y =
1279 fun mk_IH phi set set' z1 z2 =
1281 val prem1 = HOLogic.mk_Trueprop (HOLogic.mk_mem (z1, (set $ x)));
1282 val prem2 = HOLogic.mk_Trueprop (HOLogic.mk_mem (z2, (set' $ y)));
1283 val concl = HOLogic.mk_Trueprop (phi $ z1 $ z2);
1285 fold_rev Logic.all [z1, z2] (Logic.list_implies ([prem1, prem2], concl))
1288 val IHs = map5 mk_IH phi2s (drop m sets) (drop m sets') Izs1 Izs2;
1289 val concl = HOLogic.mk_Trueprop (phi $ (fld $ x) $ (fld' $ y));
1291 fold_rev Logic.all [x, y] (Logic.list_implies (IHs, concl))
1294 val prems = map7 mk_prem phi2s flds fld's FTs_setss FTs'_setss xFs yFs;
1296 fun mk_concl phi z1 z2 = phi $ z1 $ z2;
1297 val concl = HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
1298 (map3 mk_concl phi2s Izs1 Izs2));
1299 fun mk_t phi (z1, z1') (z2, z2') =
1300 Term.absfree z1' (HOLogic.mk_all (fst z2', snd z2', phi $ z1 $ z2));
1301 val cts = map3 (SOME o certify lthy ooo mk_t) phi2s (Izs1 ~~ Izs1') (Izs2 ~~ Izs2');
1302 val goal = Logic.list_implies (prems, concl);
1304 (singleton (Proof_Context.export names_lthy lthy)
1305 (Skip_Proof.prove lthy [] [] goal
1306 (mk_fld_induct2_tac cTs cts fld_induct_thm weak_fld_induct_thms)),
1307 rev (Term.add_tfrees goal []))
1310 val timer = time (timer "induction");
1312 (*register new datatypes as BNFs*)
1313 val lthy = if m = 0 then lthy else
1315 val fTs = map2 (curry op -->) passiveAs passiveBs;
1316 val f1Ts = map2 (curry op -->) passiveAs passiveYs;
1317 val f2Ts = map2 (curry op -->) passiveBs passiveYs;
1318 val p1Ts = map2 (curry op -->) passiveXs passiveAs;
1319 val p2Ts = map2 (curry op -->) passiveXs passiveBs;
1320 val uTs = map2 (curry op -->) Ts Ts';
1321 val B1Ts = map HOLogic.mk_setT passiveAs;
1322 val B2Ts = map HOLogic.mk_setT passiveBs;
1323 val AXTs = map HOLogic.mk_setT passiveXs;
1324 val XTs = mk_Ts passiveXs;
1325 val YTs = mk_Ts passiveYs;
1326 val IRTs = map2 (curry mk_relT) passiveAs passiveBs;
1327 val IphiTs = map2 (fn T => fn U => T --> U --> HOLogic.boolT) passiveAs passiveBs;
1329 val (((((((((((((((fs, fs'), fs_copy), us),
1330 B1s), B2s), AXs), (xs, xs')), f1s), f2s), p1s), p2s), (ys, ys')), IRs), Iphis),
1331 names_lthy) = names_lthy
1332 |> mk_Frees' "f" fTs
1333 ||>> mk_Frees "f" fTs
1334 ||>> mk_Frees "u" uTs
1335 ||>> mk_Frees "B1" B1Ts
1336 ||>> mk_Frees "B2" B2Ts
1337 ||>> mk_Frees "A" AXTs
1338 ||>> mk_Frees' "x" XTs
1339 ||>> mk_Frees "f1" f1Ts
1340 ||>> mk_Frees "f2" f2Ts
1341 ||>> mk_Frees "p1" p1Ts
1342 ||>> mk_Frees "p2" p2Ts
1343 ||>> mk_Frees' "y" passiveAs
1344 ||>> mk_Frees "R" IRTs
1345 ||>> mk_Frees "phi" IphiTs;
1347 val map_FTFT's = map2 (fn Ds =>
1348 mk_map_of_bnf Ds (passiveAs @ Ts) (passiveBs @ Ts')) Dss bnfs;
1349 fun mk_passive_maps ATs BTs Ts =
1350 map2 (fn Ds => mk_map_of_bnf Ds (ATs @ Ts) (BTs @ Ts)) Dss bnfs;
1351 fun mk_map_iter_arg fs Ts fld fmap =
1352 HOLogic.mk_comp (fld, Term.list_comb (fmap, fs @ map HOLogic.id_const Ts));
1353 fun mk_map Ts fs Ts' flds mk_maps =
1354 mk_iter Ts (map2 (mk_map_iter_arg fs Ts') flds (mk_maps Ts'));
1355 val pmapsABT' = mk_passive_maps passiveAs passiveBs;
1356 val fs_maps = map (mk_map Ts fs Ts' fld's pmapsABT') ks;
1357 val fs_copy_maps = map (mk_map Ts fs_copy Ts' fld's pmapsABT') ks;
1358 val Yflds = mk_flds passiveYs;
1359 val f1s_maps = map (mk_map Ts f1s YTs Yflds (mk_passive_maps passiveAs passiveYs)) ks;
1360 val f2s_maps = map (mk_map Ts' f2s YTs Yflds (mk_passive_maps passiveBs passiveYs)) ks;
1361 val p1s_maps = map (mk_map XTs p1s Ts flds (mk_passive_maps passiveXs passiveAs)) ks;
1362 val p2s_maps = map (mk_map XTs p2s Ts' fld's (mk_passive_maps passiveXs passiveBs)) ks;
1364 val (map_simp_thms, map_thms) =
1366 fun mk_goal fs_map map fld fld' = fold_rev Logic.all fs
1367 (HOLogic.mk_Trueprop (HOLogic.mk_eq (HOLogic.mk_comp (fs_map, fld),
1368 HOLogic.mk_comp (fld', Term.list_comb (map, fs @ fs_maps)))));
1369 val goals = map4 mk_goal fs_maps map_FTFT's flds fld's;
1370 val maps = map4 (fn goal => fn iter => fn map_comp_id => fn map_cong =>
1371 Skip_Proof.prove lthy [] [] goal
1372 (K (mk_map_tac m n iter map_comp_id map_cong)))
1373 goals iter_thms map_comp_id_thms map_congs;
1375 map_split (fn thm => (thm RS @{thm pointfreeE}, thm)) maps
1378 val (map_unique_thms, map_unique_thm) =
1380 fun mk_prem u map fld fld' =
1381 HOLogic.mk_Trueprop (HOLogic.mk_eq (HOLogic.mk_comp (u, fld),
1382 HOLogic.mk_comp (fld', Term.list_comb (map, fs @ us))));
1383 val prems = map4 mk_prem us map_FTFT's flds fld's;
1385 HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
1386 (map2 (curry HOLogic.mk_eq) us fs_maps));
1387 val unique = Skip_Proof.prove lthy [] []
1388 (fold_rev Logic.all (us @ fs) (Logic.list_implies (prems, goal)))
1389 (K (mk_map_unique_tac m mor_def iter_unique_mor_thm map_comp_id_thms map_congs));
1391 `split_conj_thm unique
1394 val timer = time (timer "map functions for the new datatypes");
1396 val bd = mk_cpow sum_bd;
1397 val bd_Cinfinite = sum_Cinfinite RS @{thm Cinfinite_cpow};
1398 fun mk_cpow_bd thm = @{thm ordLeq_transitive} OF
1399 [thm, sum_Card_order RS @{thm cpow_greater_eq}];
1400 val set_bd_cpowss = map (map mk_cpow_bd) set_bd_sumss;
1402 val timer = time (timer "bounds for the new datatypes");
1405 val setsss = map (mk_setss o mk_set_Ts) passiveAs;
1406 val map_setss = map (fn T => map2 (fn Ds =>
1407 mk_map_of_bnf Ds (passiveAs @ Ts) (mk_set_Ts T)) Dss bnfs) passiveAs;
1409 fun mk_col l T z z' sets =
1411 fun mk_UN set = mk_Union T $ (set $ z);
1414 (mk_union (nth sets (l - 1) $ z,
1415 Library.foldl1 mk_union (map mk_UN (drop m sets))))
1418 val colss = map5 (fn l => fn T => map3 (mk_col l T)) ls passiveAs AFss AFss' setsss;
1419 val setss_by_range = map (fn cols => map (mk_iter Ts cols) ks) colss;
1420 val setss_by_bnf = transpose setss_by_range;
1422 val (set_simp_thmss, set_thmss) =
1424 fun mk_goal sets fld set col map =
1425 HOLogic.mk_Trueprop (HOLogic.mk_eq (HOLogic.mk_comp (set, fld),
1426 HOLogic.mk_comp (col, Term.list_comb (map, passive_ids @ sets))));
1428 map3 (fn sets => map4 (mk_goal sets) flds sets) setss_by_range colss map_setss;
1429 val setss = map (map2 (fn iter => fn goal =>
1430 Skip_Proof.prove lthy [] [] goal (K (mk_set_tac iter)))
1433 fun mk_simp_goal pas_set act_sets sets fld z set =
1434 Logic.all z (HOLogic.mk_Trueprop (HOLogic.mk_eq (set $ (fld $ z),
1435 mk_union (pas_set $ z,
1436 Library.foldl1 mk_union (map2 (fn X => mk_UNION (X $ z)) act_sets sets)))));
1438 map2 (fn i => fn sets =>
1439 map4 (fn Fsets => mk_simp_goal (nth Fsets (i - 1)) (drop m Fsets) sets)
1440 FTs_setss flds xFs sets)
1443 val set_simpss = map3 (fn i => map3 (fn set_nats => fn goal => fn set =>
1444 Skip_Proof.prove lthy [] [] goal
1445 (K (mk_set_simp_tac set (nth set_nats (i - 1)) (drop m set_nats))))
1446 set_natural'ss) ls simp_goalss setss;
1451 fun mk_set_thms set_simp = (@{thm xt1(3)} OF [set_simp, @{thm Un_upper1}]) ::
1452 map (fn i => (@{thm xt1(3)} OF [set_simp, @{thm Un_upper2}]) RS
1453 (mk_Un_upper n i RS subset_trans) RSN
1454 (2, @{thm UN_upper} RS subset_trans))
1456 val Fset_set_thmsss = transpose (map (map mk_set_thms) set_simp_thmss);
1458 val timer = time (timer "set functions for the new datatypes");
1460 val cxs = map (SOME o certify lthy) Izs;
1462 map (map (Term.subst_atomic_types (passiveAs ~~ passiveBs))) setss_by_bnf;
1463 val setss_by_range' = transpose setss_by_bnf';
1465 val set_natural_thmss =
1467 fun mk_set_natural f map z set set' =
1468 HOLogic.mk_eq (mk_image f $ (set $ z), set' $ (map $ z));
1470 fun mk_cphi f map z set set' = certify lthy
1471 (Term.absfree (dest_Free z) (mk_set_natural f map z set set'));
1473 val csetss = map (map (certify lthy)) setss_by_range';
1475 val cphiss = map3 (fn f => fn sets => fn sets' =>
1476 (map4 (mk_cphi f) fs_maps Izs sets sets')) fs setss_by_range setss_by_range';
1478 val inducts = map (fn cphis =>
1479 Drule.instantiate' cTs (map SOME cphis @ cxs) fld_induct_thm) cphiss;
1482 map3 (fn f => fn sets => fn sets' =>
1483 HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
1484 (map4 (mk_set_natural f) fs_maps Izs sets sets')))
1485 fs setss_by_range setss_by_range';
1487 fun mk_tac induct = mk_set_nat_tac m (rtac induct) set_natural'ss map_simp_thms;
1488 val thms = map5 (fn goal => fn csets => fn set_simps => fn induct => fn i =>
1489 singleton (Proof_Context.export names_lthy lthy)
1490 (Skip_Proof.prove lthy [] [] goal
1491 (mk_tac induct csets set_simps i)))
1492 goals csetss set_simp_thmss inducts ls;
1494 map split_conj_thm thms
1499 fun mk_set_bd z set = mk_ordLeq (mk_card_of (set $ z)) bd;
1501 fun mk_cphi z set = certify lthy (Term.absfree (dest_Free z) (mk_set_bd z set));
1503 val cphiss = map (map2 mk_cphi Izs) setss_by_range;
1505 val inducts = map (fn cphis =>
1506 Drule.instantiate' cTs (map SOME cphis @ cxs) fld_induct_thm) cphiss;
1510 HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
1511 (map2 mk_set_bd Izs sets))) setss_by_range;
1513 fun mk_tac induct = mk_set_bd_tac m (rtac induct) bd_Cinfinite set_bd_cpowss;
1514 val thms = map4 (fn goal => fn set_simps => fn induct => fn i =>
1515 singleton (Proof_Context.export names_lthy lthy)
1516 (Skip_Proof.prove lthy [] [] goal (mk_tac induct set_simps i)))
1517 goals set_simp_thmss inducts ls;
1519 map split_conj_thm thms
1524 fun mk_prem z set f g y y' =
1525 mk_Ball (set $ z) (Term.absfree y' (HOLogic.mk_eq (f $ y, g $ y)));
1527 fun mk_map_cong sets z fmap gmap =
1529 (Library.foldr1 HOLogic.mk_conj (map5 (mk_prem z) sets fs fs_copy ys ys'),
1530 HOLogic.mk_eq (fmap $ z, gmap $ z));
1532 fun mk_cphi sets z fmap gmap =
1533 certify lthy (Term.absfree (dest_Free z) (mk_map_cong sets z fmap gmap));
1535 val cphis = map4 mk_cphi setss_by_bnf Izs fs_maps fs_copy_maps;
1537 val induct = Drule.instantiate' cTs (map SOME cphis @ cxs) fld_induct_thm;
1540 HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
1541 (map4 mk_map_cong setss_by_bnf Izs fs_maps fs_copy_maps));
1543 val thm = singleton (Proof_Context.export names_lthy lthy)
1544 (Skip_Proof.prove lthy [] [] goal
1545 (mk_mcong_tac (rtac induct) Fset_set_thmsss map_congs map_simp_thms));
1550 val in_incl_min_alg_thms =
1552 fun mk_prem z sets =
1553 HOLogic.mk_mem (z, mk_in As sets (fastype_of z));
1555 fun mk_incl z sets i =
1556 HOLogic.mk_imp (mk_prem z sets, HOLogic.mk_mem (z, mk_min_alg As flds i));
1558 fun mk_cphi z sets i =
1559 certify lthy (Term.absfree (dest_Free z) (mk_incl z sets i));
1561 val cphis = map3 mk_cphi Izs setss_by_bnf ks;
1563 val induct = Drule.instantiate' cTs (map SOME cphis @ cxs) fld_induct_thm;
1566 HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
1567 (map3 mk_incl Izs setss_by_bnf ks));
1569 val thm = singleton (Proof_Context.export names_lthy lthy)
1570 (Skip_Proof.prove lthy [] [] goal
1571 (mk_incl_min_alg_tac (rtac induct) Fset_set_thmsss alg_set_thms alg_min_alg_thm));
1576 val Xsetss = map (map (Term.subst_atomic_types (passiveAs ~~ passiveXs))) setss_by_bnf;
1578 val map_wpull_thms =
1580 val cTs = map (SOME o certifyT lthy o TFree) induct2_params;
1581 val cxs = map (SOME o certify lthy) (interleave Izs1 Izs2);
1583 fun mk_prem z1 z2 sets1 sets2 map1 map2 =
1585 (HOLogic.mk_mem (z1, mk_in B1s sets1 (fastype_of z1)),
1587 (HOLogic.mk_mem (z2, mk_in B2s sets2 (fastype_of z2)),
1588 HOLogic.mk_eq (map1 $ z1, map2 $ z2)));
1590 val prems = map6 mk_prem Izs1 Izs2 setss_by_bnf setss_by_bnf' f1s_maps f2s_maps;
1592 fun mk_concl z1 z2 sets map1 map2 T x x' =
1593 mk_Bex (mk_in AXs sets T) (Term.absfree x'
1594 (HOLogic.mk_conj (HOLogic.mk_eq (map1 $ x, z1), HOLogic.mk_eq (map2 $ x, z2))));
1596 val concls = map8 mk_concl Izs1 Izs2 Xsetss p1s_maps p2s_maps XTs xs xs';
1598 val goals = map2 (curry HOLogic.mk_imp) prems concls;
1600 fun mk_cphi z1 z2 goal = certify lthy (Term.absfree z1 (Term.absfree z2 goal));
1602 val cphis = map3 mk_cphi Izs1' Izs2' goals;
1604 val induct = Drule.instantiate' cTs (map SOME cphis @ cxs) fld_induct2_thm;
1606 val goal = Logic.list_implies (map HOLogic.mk_Trueprop
1607 (map8 mk_wpull AXs B1s B2s f1s f2s (replicate m NONE) p1s p2s),
1608 HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj goals));
1610 val thm = singleton (Proof_Context.export names_lthy lthy)
1611 (Skip_Proof.prove lthy [] [] goal
1612 (K (mk_lfp_map_wpull_tac m (rtac induct) map_wpulls map_simp_thms
1613 (transpose set_simp_thmss) Fset_set_thmsss fld_inject_thms)));
1618 val timer = time (timer "helpers for BNF properties");
1620 val map_id_tacs = map (K o mk_map_id_tac map_ids) map_unique_thms;
1622 map2 (K oo mk_map_comp_tac map_comp's map_simp_thms) map_unique_thms ks;
1623 val map_cong_tacs = map (mk_map_cong_tac m) map_cong_thms;
1624 val set_nat_tacss = map (map (K o mk_set_natural_tac)) (transpose set_natural_thmss);
1625 val bd_co_tacs = replicate n (K (mk_bd_card_order_tac bd_card_orders));
1626 val bd_cinf_tacs = replicate n (K (rtac (bd_Cinfinite RS conjunct1) 1));
1627 val set_bd_tacss = map (map (fn thm => K (rtac thm 1))) (transpose set_bd_thmss);
1628 val in_bd_tacs = map2 (K oo mk_in_bd_tac sum_Card_order suc_bd_Cnotzero)
1629 in_incl_min_alg_thms card_of_min_alg_thms;
1630 val map_wpull_tacs = map (K o mk_wpull_tac) map_wpull_thms;
1632 val tacss = map9 mk_tactics map_id_tacs map_comp_tacs map_cong_tacs set_nat_tacss bd_co_tacs
1633 bd_cinf_tacs set_bd_tacss in_bd_tacs map_wpull_tacs;
1637 val witss = map2 (fn Ds => fn bnf => mk_wits_of_bnf
1638 (replicate (nwits_of_bnf bnf) Ds)
1639 (replicate (nwits_of_bnf bnf) (passiveAs @ Ts)) bnf) Dss bnfs;
1640 fun close_wit (I, wit) = fold_rev Term.absfree (map (nth ys') I) wit;
1641 fun wit_apply (arg_I, arg_wit) (fun_I, fun_wit) =
1642 (union (op =) arg_I fun_I, fun_wit $ arg_wit);
1644 fun gen_arg support i =
1645 if i < m then [([i], nth ys i)]
1646 else maps (mk_wit support (nth flds (i - m)) (i - m)) (nth support (i - m))
1647 and mk_wit support fld i (I, wit) =
1648 let val args = map (gen_arg (nth_map i (remove (op =) (I, wit)) support)) I;
1651 |-> fold (map_product wit_apply)
1652 |> map (apsnd (fn t => fld $ t))
1656 map3 (fn fld => fn i => map close_wit o minimize_wits o maps (mk_wit witss fld i))
1657 flds (0 upto n - 1) witss
1660 fun wit_tac _ = mk_wit_tac n (flat set_simp_thmss) (maps wit_thms_of_bnf bnfs);
1663 fold_map6 (fn tacs => fn b => fn map => fn sets => fn T => fn wits =>
1664 bnf_def Dont_Inline user_policy I tacs wit_tac (SOME deads)
1665 ((((b, fold_rev Term.absfree fs' map), sets), absdummy T bd), wits))
1666 tacss bs fs_maps setss_by_bnf Ts fld_witss lthy;
1668 val fold_maps = Local_Defs.fold lthy (map (fn bnf =>
1669 mk_unabs_def m (map_def_of_bnf bnf RS @{thm meta_eq_to_obj_eq})) Ibnfs);
1671 val fold_sets = Local_Defs.fold lthy (maps (fn bnf =>
1672 map (fn thm => thm RS @{thm meta_eq_to_obj_eq}) (set_defs_of_bnf bnf)) Ibnfs);
1674 val timer = time (timer "registered new datatypes as BNFs");
1676 val rels = map2 (fn Ds => mk_rel_of_bnf Ds (passiveAs @ Ts) (passiveBs @ Ts')) Dss bnfs;
1677 val Irels = map (mk_rel_of_bnf deads passiveAs passiveBs) Ibnfs;
1678 val preds = map2 (fn Ds => mk_pred_of_bnf Ds (passiveAs @ Ts) (passiveBs @ Ts')) Dss bnfs;
1679 val Ipreds = map (mk_pred_of_bnf deads passiveAs passiveBs) Ibnfs;
1681 val IrelRs = map (fn Irel => Term.list_comb (Irel, IRs)) Irels;
1682 val relRs = map (fn rel => Term.list_comb (rel, IRs @ IrelRs)) rels;
1683 val Ipredphis = map (fn Irel => Term.list_comb (Irel, Iphis)) Ipreds;
1684 val predphis = map (fn rel => Term.list_comb (rel, Iphis @ Ipredphis)) preds;
1686 val in_rels = map in_rel_of_bnf bnfs;
1687 val in_Irels = map in_rel_of_bnf Ibnfs;
1688 val pred_defs = map pred_def_of_bnf bnfs;
1690 map (Drule.abs_def o (fn thm => thm RS @{thm eq_reflection}) o pred_def_of_bnf) Ibnfs;
1692 val set_incl_thmss = map (map (fold_sets o hd)) Fset_set_thmsss;
1693 val set_set_incl_thmsss = map (transpose o map (map fold_sets o tl)) Fset_set_thmsss;
1694 val folded_map_simp_thms = map fold_maps map_simp_thms;
1695 val folded_set_simp_thmss = map (map fold_sets) set_simp_thmss;
1696 val folded_set_simp_thmss' = transpose folded_set_simp_thmss;
1698 val Irel_unfold_thms =
1700 fun mk_goal xF yF fld fld' IrelR relR = fold_rev Logic.all (xF :: yF :: IRs)
1701 (HOLogic.mk_Trueprop (HOLogic.mk_eq
1702 (HOLogic.mk_mem (HOLogic.mk_prod (fld $ xF, fld' $ yF), IrelR),
1703 HOLogic.mk_mem (HOLogic.mk_prod (xF, yF), relR))));
1704 val goals = map6 mk_goal xFs yFs flds fld's IrelRs relRs;
1706 map12 (fn i => fn goal => fn in_rel => fn map_comp => fn map_cong =>
1707 fn map_simp => fn set_simps => fn fld_inject => fn fld_unf =>
1708 fn set_naturals => fn set_incls => fn set_set_inclss =>
1709 Skip_Proof.prove lthy [] [] goal
1710 (K (mk_rel_unfold_tac in_Irels i in_rel map_comp map_cong map_simp set_simps
1711 fld_inject fld_unf set_naturals set_incls set_set_inclss)))
1712 ks goals in_rels map_comp's map_congs folded_map_simp_thms folded_set_simp_thmss'
1713 fld_inject_thms fld_unf_thms set_natural'ss set_incl_thmss set_set_incl_thmsss
1716 val Ipred_unfold_thms =
1718 fun mk_goal xF yF fld fld' Ipredphi predphi = fold_rev Logic.all (xF :: yF :: Iphis)
1719 (HOLogic.mk_Trueprop (HOLogic.mk_eq
1720 (Ipredphi $ (fld $ xF) $ (fld' $ yF), predphi $ xF $ yF)));
1721 val goals = map6 mk_goal xFs yFs flds fld's Ipredphis predphis;
1723 map3 (fn goal => fn pred_def => fn Irel_unfold =>
1724 Skip_Proof.prove lthy [] [] goal (mk_pred_unfold_tac pred_def Ipred_defs Irel_unfold))
1725 goals pred_defs Irel_unfold_thms
1728 val timer = time (timer "additional properties");
1730 val ls' = if m = 1 then [0] else ls
1733 |> note map_uniqueN [fold_maps map_unique_thm]
1734 |> notes map_simpsN (map single folded_map_simp_thms)
1735 |> fold2 (fn i => notes (mk_set_simpsN i) o map single) ls' folded_set_simp_thmss
1736 |> notes set_inclN set_incl_thmss
1737 |> notes set_set_inclN (map flat set_set_incl_thmsss)
1738 |> notes rel_unfoldN (map single Irel_unfold_thms)
1739 |> notes pred_unfoldN (map single Ipred_unfold_thms)
1744 |> notes iterN (map single iter_thms)
1745 |> notes iter_uniqueN (map single iter_unique_thms)
1746 |> notes recN (map single rec_thms)
1747 |> notes unf_fldN (map single unf_fld_thms)
1748 |> notes fld_unfN (map single fld_unf_thms)
1749 |> notes unf_injectN (map single unf_inject_thms)
1750 |> notes unf_exhaustN (map single unf_exhaust_thms)
1751 |> notes fld_injectN (map single fld_inject_thms)
1752 |> notes fld_exhaustN (map single fld_exhaust_thms)
1753 |> note fld_inductN [fld_induct_thm]
1754 |> note fld_induct2N [fld_induct2_thm]
1758 Outer_Syntax.local_theory @{command_spec "bnf_data"} "least fixed points for BNF equations"
1760 ((Parse.binding --| Parse.$$$ ":") -- (Parse.typ --| Parse.$$$ "=" -- Parse.typ)) >>
1761 (fp_bnf_cmd bnf_lfp o apsnd split_list o split_list));