5 Sugared datatype and codatatype constructions. |
5 Sugared datatype and codatatype constructions. |
6 *) |
6 *) |
7 |
7 |
8 signature BNF_FP_SUGAR = |
8 signature BNF_FP_SUGAR = |
9 sig |
9 sig |
10 val datatyp: bool -> |
10 val datatypes: bool -> |
11 (mixfix list -> (string * sort) list option -> binding list -> typ list * typ list list -> |
11 (mixfix list -> (string * sort) list option -> binding list -> typ list * typ list list -> |
12 BNF_Def.BNF list -> local_theory -> |
12 BNF_Def.BNF list -> local_theory -> |
13 (term list * term list * term list * term list * thm * thm list * thm list * thm list * |
13 (term list * term list * term list *term list * term list * thm * thm list * thm list * |
14 thm list * thm list) * local_theory) -> |
14 thm list * thm list * thm list) * local_theory) -> |
15 bool * ((((typ * sort) list * binding) * mixfix) * ((((binding * binding) * |
15 bool * ((((typ * sort) list * binding) * mixfix) * ((((binding * binding) * |
16 (binding * typ) list) * (binding * term) list) * mixfix) list) list -> |
16 (binding * typ) list) * (binding * term) list) * mixfix) list) list -> |
17 local_theory -> local_theory |
17 local_theory -> local_theory |
18 val parse_datatype_cmd: bool -> |
18 val parse_datatype_cmd: bool -> |
19 (mixfix list -> (string * sort) list option -> binding list -> typ list * typ list list -> |
19 (mixfix list -> (string * sort) list option -> binding list -> typ list * typ list list -> |
20 BNF_Def.BNF list -> local_theory -> |
20 BNF_Def.BNF list -> local_theory -> |
21 (term list * term list * term list * term list * thm * thm list * thm list * thm list * |
21 (term list * term list * term list * term list * term list * thm * thm list * thm list * |
22 thm list * thm list) * local_theory) -> |
22 thm list * thm list * thm list) * local_theory) -> |
23 (local_theory -> local_theory) parser |
23 (local_theory -> local_theory) parser |
24 end; |
24 end; |
25 |
25 |
26 structure BNF_FP_Sugar : BNF_FP_SUGAR = |
26 structure BNF_FP_Sugar : BNF_FP_SUGAR = |
27 struct |
27 struct |
50 fun mk_tupled_fun x f xs = HOLogic.tupled_lambda x (Term.list_comb (f, xs)); |
51 fun mk_tupled_fun x f xs = HOLogic.tupled_lambda x (Term.list_comb (f, xs)); |
51 fun mk_uncurried_fun f xs = mk_tupled_fun (HOLogic.mk_tuple xs) f xs; |
52 fun mk_uncurried_fun f xs = mk_tupled_fun (HOLogic.mk_tuple xs) f xs; |
52 fun mk_uncurried2_fun f xss = |
53 fun mk_uncurried2_fun f xss = |
53 mk_tupled_fun (HOLogic.mk_tuple (map HOLogic.mk_tuple xss)) f (flat xss); |
54 mk_tupled_fun (HOLogic.mk_tuple (map HOLogic.mk_tuple xss)) f (flat xss); |
54 |
55 |
|
56 fun mk_ctor_or_dtor get_T Ts t = |
|
57 let val Type (_, Ts0) = get_T (fastype_of t) in |
|
58 Term.subst_atomic_types (Ts0 ~~ Ts) t |
|
59 end; |
|
60 |
|
61 val mk_ctor = mk_ctor_or_dtor range_type; |
|
62 val mk_dtor = mk_ctor_or_dtor domain_type; |
|
63 |
|
64 fun mk_rec_like lfp Ts Us t = |
|
65 let |
|
66 val (bindings, body) = strip_type (fastype_of t); |
|
67 val (f_Us, prebody) = split_last bindings; |
|
68 val Type (_, Ts0) = if lfp then prebody else body; |
|
69 val Us0 = distinct (op =) (map (if lfp then body_type else domain_type) f_Us); |
|
70 in |
|
71 Term.subst_atomic_types (Ts0 @ Us0 ~~ Ts @ Us) t |
|
72 end; |
|
73 |
|
74 fun mk_map live Ts Us t = |
|
75 let val (Type (_, Ts0), Type (_, Us0)) = strip_typeN (live + 1) (fastype_of t) |>> List.last in |
|
76 Term.subst_atomic_types (Ts0 @ Us0 ~~ Ts @ Us) t |
|
77 end; |
|
78 |
|
79 fun mk_rel Ts Us t = |
|
80 let |
|
81 val ((Type (_, Ts0), Type (_, Us0)), body) = |
|
82 strip_type (fastype_of t) |>> split_last |>> apfst List.last; |
|
83 val _ = tracing ("*** " ^ PolyML.makestring (Ts, "***", Us, "***", t, Ts0, Us0)) (*###*) |
|
84 in |
|
85 Term.subst_atomic_types (Ts0 @ Us0 ~~ Ts @ Us) t |
|
86 end; |
|
87 |
55 fun tick u f = Term.lambda u (HOLogic.mk_prod (u, f $ u)); |
88 fun tick u f = Term.lambda u (HOLogic.mk_prod (u, f $ u)); |
56 |
89 |
57 fun tack z_name (c, u) f = |
90 fun tack z_name (c, u) f = |
58 let val z = Free (z_name, mk_sumT (fastype_of u, fastype_of c)) in |
91 let val z = Free (z_name, mk_sumT (fastype_of u, fastype_of c)) in |
59 Term.lambda z (mk_sum_case (Term.lambda u u, Term.lambda c (f $ c)) $ z) |
92 Term.lambda z (mk_sum_case (Term.lambda u u, Term.lambda c (f $ c)) $ z) |
158 s = s' andalso (Us = Us' orelse error ("Illegal occurrence of recursive type " ^ |
191 s = s' andalso (Us = Us' orelse error ("Illegal occurrence of recursive type " ^ |
159 quote (Syntax.string_of_typ fake_lthy T))) |
192 quote (Syntax.string_of_typ fake_lthy T))) |
160 | eq_fpT _ _ = false; |
193 | eq_fpT _ _ = false; |
161 |
194 |
162 fun freeze_fp (T as Type (s, Us)) = |
195 fun freeze_fp (T as Type (s, Us)) = |
163 (case find_index (eq_fpT T) fake_Ts of ~1 => Type (s, map freeze_fp Us) | j => nth Bs j) |
196 (case find_index (eq_fpT T) fake_Ts of ~1 => Type (s, map freeze_fp Us) | j => nth Xs j) |
164 | freeze_fp T = T; |
197 | freeze_fp T = T; |
165 |
198 |
166 val ctr_TsssBs = map (map (map freeze_fp)) fake_ctr_Tsss; |
199 val ctr_TsssXs = map (map (map freeze_fp)) fake_ctr_Tsss; |
167 val ctr_sum_prod_TsBs = map (mk_sumTN_balanced o map HOLogic.mk_tupleT) ctr_TsssBs; |
200 val ctr_sum_prod_TsXs = map (mk_sumTN_balanced o map HOLogic.mk_tupleT) ctr_TsssXs; |
168 |
201 |
169 val fp_eqs = |
202 val fp_eqs = |
170 map dest_TFree Bs ~~ map (Term.typ_subst_atomic (As ~~ unsorted_As)) ctr_sum_prod_TsBs; |
203 map dest_TFree Xs ~~ map (Term.typ_subst_atomic (As ~~ unsorted_As)) ctr_sum_prod_TsXs; |
171 |
204 |
172 val (pre_bnfs, ((dtors0, ctors0, fp_folds0, fp_recs0, fp_induct, dtor_ctors, ctor_dtors, |
205 val (pre_bnfs, ((dtors0, ctors0, rels0, fp_folds0, fp_recs0, fp_induct, dtor_ctors, ctor_dtors, |
173 ctor_injects, fp_fold_thms, fp_rec_thms), lthy)) = |
206 ctor_injects, fp_fold_thms, fp_rec_thms), lthy)) = |
174 fp_bnf construct fp_bs mixfixes (map dest_TFree unsorted_As) fp_eqs no_defs_lthy0; |
207 fp_bnf construct fp_bs mixfixes (map dest_TFree unsorted_As) fp_eqs no_defs_lthy0; |
175 |
208 |
176 fun add_nesty_bnf_names Us = |
209 fun add_nesty_bnf_names Us = |
177 let |
210 let |
181 end |
214 end |
182 | add T ss = (member (op =) Us T, ss); |
215 | add T ss = (member (op =) Us T, ss); |
183 in snd oo add end; |
216 in snd oo add end; |
184 |
217 |
185 fun nesty_bnfs Us = |
218 fun nesty_bnfs Us = |
186 map_filter (bnf_of lthy) (fold (fold (fold (add_nesty_bnf_names Us))) ctr_TsssBs []); |
219 map_filter (bnf_of lthy) (fold (fold (fold (add_nesty_bnf_names Us))) ctr_TsssXs []); |
187 |
220 |
188 val nesting_bnfs = nesty_bnfs As; |
221 val nesting_bnfs = nesty_bnfs As; |
189 val nested_bnfs = nesty_bnfs Bs; |
222 val nested_bnfs = nesty_bnfs Xs; |
190 |
223 |
191 val timer = time (Timer.startRealTimer ()); |
224 val timer = time (Timer.startRealTimer ()); |
192 |
|
193 fun mk_ctor_or_dtor get_T Ts t = |
|
194 let val Type (_, Ts0) = get_T (fastype_of t) in |
|
195 Term.subst_atomic_types (Ts0 ~~ Ts) t |
|
196 end; |
|
197 |
|
198 val mk_ctor = mk_ctor_or_dtor range_type; |
|
199 val mk_dtor = mk_ctor_or_dtor domain_type; |
|
200 |
225 |
201 val ctors = map (mk_ctor As) ctors0; |
226 val ctors = map (mk_ctor As) ctors0; |
202 val dtors = map (mk_dtor As) dtors0; |
227 val dtors = map (mk_dtor As) dtors0; |
|
228 val rels = map (mk_rel As As) rels0; (*FIXME*) |
203 |
229 |
204 val fpTs = map (domain_type o fastype_of) dtors; |
230 val fpTs = map (domain_type o fastype_of) dtors; |
205 |
231 |
206 val exists_fp_subtype = exists_subtype (member (op =) fpTs); |
232 val exists_fp_subtype = exists_subtype (member (op =) fpTs); |
207 |
233 |
208 val ctr_Tsss = map (map (map (Term.typ_subst_atomic (Bs ~~ fpTs)))) ctr_TsssBs; |
234 val ctr_Tsss = map (map (map (Term.typ_subst_atomic (Xs ~~ fpTs)))) ctr_TsssXs; |
209 val ns = map length ctr_Tsss; |
235 val ns = map length ctr_Tsss; |
210 val kss = map (fn n => 1 upto n) ns; |
236 val kss = map (fn n => 1 upto n) ns; |
211 val mss = map (map length) ctr_Tsss; |
237 val mss = map (map length) ctr_Tsss; |
212 val Css = map2 replicate ns Cs; |
238 val Css = map2 replicate ns Cs; |
213 |
239 |
214 fun mk_rec_like Ts Us t = |
240 val fp_folds as fp_fold1 :: _ = map (mk_rec_like lfp As Cs) fp_folds0; |
215 let |
241 val fp_recs as fp_rec1 :: _ = map (mk_rec_like lfp As Cs) fp_recs0; |
216 val (bindings, body) = strip_type (fastype_of t); |
|
217 val (f_Us, prebody) = split_last bindings; |
|
218 val Type (_, Ts0) = if lfp then prebody else body; |
|
219 val Us0 = distinct (op =) (map (if lfp then body_type else domain_type) f_Us); |
|
220 in |
|
221 Term.subst_atomic_types (Ts0 @ Us0 ~~ Ts @ Us) t |
|
222 end; |
|
223 |
|
224 val fp_folds as fp_fold1 :: _ = map (mk_rec_like As Cs) fp_folds0; |
|
225 val fp_recs as fp_rec1 :: _ = map (mk_rec_like As Cs) fp_recs0; |
|
226 |
242 |
227 val fp_fold_fun_Ts = fst (split_last (binder_types (fastype_of fp_fold1))); |
243 val fp_fold_fun_Ts = fst (split_last (binder_types (fastype_of fp_fold1))); |
228 val fp_rec_fun_Ts = fst (split_last (binder_types (fastype_of fp_rec1))); |
244 val fp_rec_fun_Ts = fst (split_last (binder_types (fastype_of fp_rec1))); |
229 |
245 |
230 val (((fold_only as (gss, _, _), rec_only as (hss, _, _)), |
246 val (((fold_only as (gss, _, _), rec_only as (hss, _, _)), |
338 val dtorT = domain_type (fastype_of ctor); |
354 val dtorT = domain_type (fastype_of ctor); |
339 val ctr_prod_Ts = map HOLogic.mk_tupleT ctr_Tss; |
355 val ctr_prod_Ts = map HOLogic.mk_tupleT ctr_Tss; |
340 val ctr_sum_prod_T = mk_sumTN_balanced ctr_prod_Ts; |
356 val ctr_sum_prod_T = mk_sumTN_balanced ctr_prod_Ts; |
341 val case_Ts = map (fn Ts => Ts ---> C) ctr_Tss; |
357 val case_Ts = map (fn Ts => Ts ---> C) ctr_Tss; |
342 |
358 |
343 val ((((w, fs), xss), u'), _) = |
359 val (((((w, fs), xss), yss), u'), _) = |
344 no_defs_lthy |
360 no_defs_lthy |
345 |> yield_singleton (mk_Frees "w") dtorT |
361 |> yield_singleton (mk_Frees "w") dtorT |
346 ||>> mk_Frees "f" case_Ts |
362 ||>> mk_Frees "f" case_Ts |
347 ||>> mk_Freess "x" ctr_Tss |
363 ||>> mk_Freess "x" ctr_Tss |
|
364 ||>> mk_Freess "y" ctr_Tss |
348 ||>> yield_singleton Variable.variant_fixes fp_b_name; |
365 ||>> yield_singleton Variable.variant_fixes fp_b_name; |
349 |
366 |
350 val u = Free (u', fpT); |
367 val u = Free (u', fpT); |
351 |
368 |
352 val ctr_rhss = |
369 val ctr_rhss = |
481 |
498 |
482 val phi = Proof_Context.export_morphism lthy lthy'; |
499 val phi = Proof_Context.export_morphism lthy lthy'; |
483 |
500 |
484 val [unfold_def, corec_def] = map (Morphism.thm phi) defs; |
501 val [unfold_def, corec_def] = map (Morphism.thm phi) defs; |
485 |
502 |
486 val [unfold, corec] = map (mk_rec_like As Cs o Morphism.term phi) csts; |
503 val [unfold, corec] = map (mk_rec_like lfp As Cs o Morphism.term phi) csts; |
487 in |
504 in |
488 ((wrap_res, ctrs, unfold, corec, xss, ctr_defs, unfold_def, corec_def), lthy) |
505 ((wrap_res, ctrs, unfold, corec, xss, yss, ctr_defs, unfold_def, corec_def), lthy) |
489 end; |
506 end; |
490 |
507 |
491 fun wrap lthy = |
508 fun wrap lthy = |
492 let val sel_defaultss = map (map (apsnd (prepare_term lthy))) raw_sel_defaultss in |
509 let val sel_defaultss = map (map (apsnd (prepare_term lthy))) raw_sel_defaultss in |
493 wrap_datatype tacss (((no_dests, ctrs0), casex0), (disc_bindings, (sel_bindingss, |
510 wrap_datatype tacss (((no_dests, ctrs0), casex0), (disc_bindings, (sel_bindingss, |
498 in |
515 in |
499 ((wrap, define_rec_likes), lthy') |
516 ((wrap, define_rec_likes), lthy') |
500 end; |
517 end; |
501 |
518 |
502 fun wrap_types_and_define_rec_likes ((wraps, define_rec_likess), lthy) = |
519 fun wrap_types_and_define_rec_likes ((wraps, define_rec_likess), lthy) = |
503 fold_map2 (curry (op o)) define_rec_likess wraps lthy |>> split_list8 |
520 fold_map2 (curry (op o)) define_rec_likess wraps lthy |>> split_list9 |
504 |
521 |
505 val pre_map_defs = map map_def_of_bnf pre_bnfs; |
522 val pre_map_defs = map map_def_of_bnf pre_bnfs; |
506 val pre_set_defss = map set_defs_of_bnf pre_bnfs; |
523 val pre_set_defss = map set_defs_of_bnf pre_bnfs; |
507 val nested_set_natural's = maps set_natural'_of_bnf nested_bnfs; |
524 val nested_set_natural's = maps set_natural'_of_bnf nested_bnfs; |
508 val nesting_map_ids = map map_id_of_bnf nesting_bnfs; |
525 val nesting_map_ids = map map_id_of_bnf nesting_bnfs; |
509 |
|
510 fun mk_map live Ts Us t = |
|
511 let |
|
512 val (Type (_, Ts0), Type (_, Us0)) = strip_typeN (live + 1) (fastype_of t) |>> List.last |
|
513 in |
|
514 Term.subst_atomic_types (Ts0 @ Us0 ~~ Ts @ Us) t |
|
515 end; |
|
516 |
526 |
517 fun build_map build_arg (Type (s, Ts)) (Type (_, Us)) = |
527 fun build_map build_arg (Type (s, Ts)) (Type (_, Us)) = |
518 let |
528 let |
519 val bnf = the (bnf_of lthy s); |
529 val bnf = the (bnf_of lthy s); |
520 val live = live_of_bnf bnf; |
530 val live = live_of_bnf bnf; |
525 |
535 |
526 val mk_simp_thmss = |
536 val mk_simp_thmss = |
527 map3 (fn (_, _, injects, distincts, cases, _, _, _) => fn rec_likes => fn fold_likes => |
537 map3 (fn (_, _, injects, distincts, cases, _, _, _) => fn rec_likes => fn fold_likes => |
528 injects @ distincts @ cases @ rec_likes @ fold_likes); |
538 injects @ distincts @ cases @ rec_likes @ fold_likes); |
529 |
539 |
530 fun derive_induct_fold_rec_thms_for_types ((wrap_ress, ctrss, folds, recs, xsss, ctr_defss, |
540 fun derive_induct_fold_rec_thms_for_types ((wrap_ress, ctrss, folds, recs, xsss, _, ctr_defss, |
531 fold_defs, rec_defs), lthy) = |
541 fold_defs, rec_defs), lthy) = |
532 let |
542 let |
533 val (((phis, phis'), us'), names_lthy) = |
543 val (((phis, phis'), us'), names_lthy) = |
534 lthy |
544 lthy |
535 |> mk_Frees' "P" (map mk_pred1T fpTs) |
545 |> mk_Frees' "P" (map mk_pred1T fpTs) |
681 val notes = |
691 val notes = |
682 [(inductN, map single induct_thms, |
692 [(inductN, map single induct_thms, |
683 fn T_name => [induct_case_names_attr, induct_type_attr T_name]), |
693 fn T_name => [induct_case_names_attr, induct_type_attr T_name]), |
684 (foldsN, fold_thmss, K (Code.add_default_eqn_attrib :: simp_attrs)), |
694 (foldsN, fold_thmss, K (Code.add_default_eqn_attrib :: simp_attrs)), |
685 (recsN, rec_thmss, K (Code.add_default_eqn_attrib :: simp_attrs)), |
695 (recsN, rec_thmss, K (Code.add_default_eqn_attrib :: simp_attrs)), |
686 (simpsN, simp_thmss, K [])] |
696 (simpsN, simp_thmss, K [])] (* TODO: Add relator simps *) |
687 |> maps (fn (thmN, thmss, attrs) => |
697 |> maps (fn (thmN, thmss, attrs) => |
688 map3 (fn b => fn Type (T_name, _) => fn thms => |
698 map3 (fn b => fn Type (T_name, _) => fn thms => |
689 ((Binding.qualify true (Binding.name_of b) (Binding.name thmN), attrs T_name), |
699 ((Binding.qualify true (Binding.name_of b) (Binding.name thmN), attrs T_name), |
690 [(thms, [])])) fp_bs fpTs thmss); |
700 [(thms, [])])) fp_bs fpTs thmss); |
691 in |
701 in |
692 lthy |> Local_Theory.notes (common_notes @ notes) |> snd |
702 lthy |> Local_Theory.notes (common_notes @ notes) |> snd |
693 end; |
703 end; |
694 |
704 |
695 fun derive_coinduct_unfold_corec_thms_for_types ((wrap_ress, ctrss, unfolds, corecs, _, |
705 fun derive_coinduct_unfold_corec_thms_for_types ((wrap_ress, ctrss, unfolds, corecs, _, _, |
696 ctr_defss, unfold_defs, corec_defs), lthy) = |
706 ctr_defss, unfold_defs, corec_defs), lthy) = |
697 let |
707 let |
698 val discss = map (map (mk_disc_or_sel As) o #1) wrap_ress; |
708 val discss = map (map (mk_disc_or_sel As) o #1) wrap_ress; |
699 val selsss = map #2 wrap_ress; |
709 val selsss = map #2 wrap_ress; |
700 val disc_thmsss = map #6 wrap_ress; |
710 val disc_thmsss = map #6 wrap_ress; |
862 (disc_unfoldsN, disc_unfold_thmss, simp_attrs), |
872 (disc_unfoldsN, disc_unfold_thmss, simp_attrs), |
863 (disc_corec_iffN, disc_corec_iff_thmss, simp_attrs), |
873 (disc_corec_iffN, disc_corec_iff_thmss, simp_attrs), |
864 (disc_corecsN, disc_corec_thmss, simp_attrs), |
874 (disc_corecsN, disc_corec_thmss, simp_attrs), |
865 (sel_unfoldsN, sel_unfold_thmss, simp_attrs), |
875 (sel_unfoldsN, sel_unfold_thmss, simp_attrs), |
866 (sel_corecsN, sel_corec_thmss, simp_attrs), |
876 (sel_corecsN, sel_corec_thmss, simp_attrs), |
867 (simpsN, simp_thmss, []), |
877 (simpsN, simp_thmss, []), (* TODO: Add relator simps *) |
868 (unfoldsN, unfold_thmss, [])] |
878 (unfoldsN, unfold_thmss, [])] |
869 |> maps (fn (thmN, thmss, attrs) => |
879 |> maps (fn (thmN, thmss, attrs) => |
870 map_filter (fn (_, []) => NONE | (b, thms) => |
880 map_filter (fn (_, []) => NONE | (b, thms) => |
871 SOME ((Binding.qualify true (Binding.name_of b) (Binding.name thmN), attrs), |
881 SOME ((Binding.qualify true (Binding.name_of b) (Binding.name thmN), attrs), |
872 [(thms, [])])) (fp_bs ~~ thmss)); |
882 [(thms, [])])) (fp_bs ~~ thmss)); |
873 in |
883 in |
874 lthy |> Local_Theory.notes (anonymous_notes @ common_notes @ notes) |> snd |
884 lthy |> Local_Theory.notes (anonymous_notes @ common_notes @ notes) |> snd |
875 end; |
885 end; |
876 |
886 |
877 fun derive_pred_thms_for_types ((wrap_ress, ctrss, unfolds, corecs, _, ctr_defss, unfold_defs, |
887 fun derive_rel_thms_for_types ((wrap_ress, ctrss, unfolds, corecs, xsss, ysss, ctr_defss, |
878 corec_defs), lthy) = |
888 unfold_defs, corec_defs), lthy) = |
879 lthy; |
889 let |
|
890 val selsss = map #2 wrap_ress; |
|
891 |
|
892 val theta_Ts = [] (*###*) |
|
893 |
|
894 val (thetas, _) = |
|
895 lthy |
|
896 |> mk_Frees "Q" (map mk_pred1T theta_Ts); |
|
897 |
|
898 val (rel_thmss, rel_thmsss) = |
|
899 let |
|
900 val xctrss = map2 (map2 (curry Term.list_comb)) ctrss xsss; |
|
901 val yctrss = map2 (map2 (curry Term.list_comb)) ctrss ysss; |
|
902 val threls = map (fold_rev rapp thetas) rels; |
|
903 |
|
904 fun mk_goal threl (xctr, xs) (yctr, ys) = |
|
905 let |
|
906 val lhs = threl $ xctr $ yctr; |
|
907 |
|
908 (* ### fixme: lift rel *) |
|
909 fun mk_conjunct x y = HOLogic.mk_eq (x, y); |
|
910 |
|
911 fun mk_rhs () = |
|
912 Library.foldr1 HOLogic.mk_conj (map2 mk_conjunct xs ys); |
|
913 in |
|
914 HOLogic.mk_Trueprop |
|
915 (if Term.head_of xctr = Term.head_of yctr then |
|
916 if null xs then |
|
917 lhs |
|
918 else |
|
919 HOLogic.mk_eq (lhs, mk_rhs ()) |
|
920 else |
|
921 HOLogic.mk_not lhs) |
|
922 end; |
|
923 |
|
924 (*###*) |
|
925 (* TODO: Prove and exploit symmetry of relators to halve the number of goals. *) |
|
926 fun mk_goals threl xctrs xss yctrs yss = |
|
927 map_product (mk_goal threl) (xctrs ~~ xss) (yctrs ~~ yss); |
|
928 |
|
929 val goalsss = map5 mk_goals threls xctrss xsss yctrss ysss; |
|
930 |
|
931 (*### |
|
932 val goalsss = map6 (fn threl => |
|
933 map5 (fn xctr => fn xs => fn sels => |
|
934 map2 (mk_goal threl xctr xs sels))) threls xctrss xsss selsss yctrss ysss; |
|
935 *) |
|
936 val _ = tracing ("goalsss: " ^ PolyML.makestring goalsss) (*###*) |
|
937 in |
|
938 ([], []) |
|
939 end; |
|
940 |
|
941 val (sel_rel_thmss, sel_rel_thmsss) = |
|
942 let |
|
943 in |
|
944 ([], []) |
|
945 end; |
|
946 |
|
947 val notes = |
|
948 [(* (relsN, rel_thmss, []), |
|
949 (sel_relsN, sel_rel_thmss, []) *)] |
|
950 |> maps (fn (thmN, thmss, attrs) => |
|
951 map2 (fn b => fn thms => |
|
952 ((Binding.qualify true (Binding.name_of b) (Binding.name thmN), attrs), |
|
953 [(thms, [])])) fp_bs thmss); |
|
954 in |
|
955 lthy |> Local_Theory.notes notes |> snd |
|
956 end; |
880 |
957 |
881 val lthy' = lthy |
958 val lthy' = lthy |
882 |> fold_map define_ctrs_case_for_type (fp_bs ~~ fpTs ~~ Cs ~~ ctors ~~ dtors ~~ fp_folds ~~ |
959 |> fold_map define_ctrs_case_for_type (fp_bs ~~ fpTs ~~ Cs ~~ ctors ~~ dtors ~~ fp_folds ~~ |
883 fp_recs ~~ ctor_dtors ~~ dtor_ctors ~~ ctor_injects ~~ ns ~~ kss ~~ mss ~~ ctr_bindingss ~~ |
960 fp_recs ~~ ctor_dtors ~~ dtor_ctors ~~ ctor_injects ~~ ns ~~ kss ~~ mss ~~ ctr_bindingss ~~ |
884 ctr_mixfixess ~~ ctr_Tsss ~~ disc_bindingss ~~ sel_bindingsss ~~ raw_sel_defaultsss) |
961 ctr_mixfixess ~~ ctr_Tsss ~~ disc_bindingss ~~ sel_bindingsss ~~ raw_sel_defaultsss) |
885 |>> split_list |> wrap_types_and_define_rec_likes |
962 |>> split_list |> wrap_types_and_define_rec_likes |
886 |> `(if lfp then derive_induct_fold_rec_thms_for_types |
963 |> `(if lfp then derive_induct_fold_rec_thms_for_types |
887 else derive_coinduct_unfold_corec_thms_for_types) |
964 else derive_coinduct_unfold_corec_thms_for_types) |
888 |> swap |>> fst |
965 |> swap |>> fst |
889 |> derive_pred_thms_for_types; |
966 |> (if null rels then snd else derive_rel_thms_for_types); |
890 |
967 |
891 val timer = time (timer ("Constructors, discriminators, selectors, etc., for the new " ^ |
968 val timer = time (timer ("Constructors, discriminators, selectors, etc., for the new " ^ |
892 (if lfp then "" else "co") ^ "datatype")); |
969 (if lfp then "" else "co") ^ "datatype")); |
893 in |
970 in |
894 timer; lthy' |
971 timer; lthy' |
895 end; |
972 end; |
896 |
973 |
897 val datatyp = define_datatype (K I) (K I) (K I); |
974 val datatypes = define_datatypes (K I) (K I) (K I); |
898 |
975 |
899 val datatype_cmd = define_datatype Typedecl.read_constraint Syntax.parse_typ Syntax.read_term; |
976 val datatype_cmd = define_datatypes Typedecl.read_constraint Syntax.parse_typ Syntax.read_term; |
900 |
977 |
901 val parse_ctr_arg = |
978 val parse_ctr_arg = |
902 @{keyword "("} |-- parse_binding_colon -- Parse.typ --| @{keyword ")"} || |
979 @{keyword "("} |-- parse_binding_colon -- Parse.typ --| @{keyword ")"} || |
903 (Parse.typ >> pair Binding.empty); |
980 (Parse.typ >> pair Binding.empty); |
904 |
981 |