equal
deleted
inserted
replaced
89 (* TODO: sanity checks on arguments *) |
89 (* TODO: sanity checks on arguments *) |
90 |
90 |
91 val _ = if not lfp andalso no_dests then error "Cannot define destructor-less codatatypes" |
91 val _ = if not lfp andalso no_dests then error "Cannot define destructor-less codatatypes" |
92 else (); |
92 else (); |
93 |
93 |
94 val N = length specs; |
94 val nn = length specs; |
95 val fp_bs = map type_binding_of specs; |
95 val fp_bs = map type_binding_of specs; |
96 val fp_common_name = mk_common_name fp_bs; |
96 val fp_common_name = mk_common_name fp_bs; |
97 |
97 |
98 fun prepare_type_arg (ty, c) = |
98 fun prepare_type_arg (ty, c) = |
99 let val TFree (s, _) = prepare_typ no_defs_lthy0 ty in |
99 let val TFree (s, _) = prepare_typ no_defs_lthy0 ty in |
105 val unsorted_As = Library.foldr1 merge_type_args unsorted_Ass0; |
105 val unsorted_As = Library.foldr1 merge_type_args unsorted_Ass0; |
106 |
106 |
107 val (((Bs, Cs), vs'), no_defs_lthy) = |
107 val (((Bs, Cs), vs'), no_defs_lthy) = |
108 no_defs_lthy0 |
108 no_defs_lthy0 |
109 |> fold (Variable.declare_typ o resort_tfree dummyS) unsorted_As |
109 |> fold (Variable.declare_typ o resort_tfree dummyS) unsorted_As |
110 |> mk_TFrees N |
110 |> mk_TFrees nn |
111 ||>> mk_TFrees N |
111 ||>> mk_TFrees nn |
112 ||>> Variable.variant_fixes (map Binding.name_of fp_bs); |
112 ||>> Variable.variant_fixes (map Binding.name_of fp_bs); |
113 |
113 |
114 (* TODO: cleaner handling of fake contexts, without "background_theory" *) |
114 (* TODO: cleaner handling of fake contexts, without "background_theory" *) |
115 (*the "perhaps o try" below helps gracefully handles the case where the new type is defined in a |
115 (*the "perhaps o try" below helps gracefully handles the case where the new type is defined in a |
116 locale and shadows an existing global type*) |
116 locale and shadows an existing global type*) |
566 end) |
566 end) |
567 | i => [HOLogic.mk_Trueprop (nth phis i $ x)]) |
567 | i => [HOLogic.mk_Trueprop (nth phis i $ x)]) |
568 | mk_prem_prems _ _ = []; |
568 | mk_prem_prems _ _ = []; |
569 |
569 |
570 fun close_prem_prem (Free x') t = |
570 fun close_prem_prem (Free x') t = |
571 fold_rev Logic.all (map Free (drop (N + 1) (rev (Term.add_frees t (x' :: phis'))))) t; |
571 fold_rev Logic.all |
|
572 (map Free (drop (nn + 1) (rev (Term.add_frees t (x' :: phis'))))) t; |
572 |
573 |
573 fun mk_prem phi ctr ctr_Ts = |
574 fun mk_prem phi ctr ctr_Ts = |
574 let |
575 let |
575 val (xs, names_lthy') = names_lthy |> mk_Frees "x" ctr_Ts; |
576 val (xs, names_lthy') = names_lthy |> mk_Frees "x" ctr_Ts; |
576 val prem_prems = |
577 val prem_prems = |
589 |
590 |
590 val induct_thm = |
591 val induct_thm = |
591 Skip_Proof.prove lthy [] [] goal (fn {context = ctxt, ...} => |
592 Skip_Proof.prove lthy [] [] goal (fn {context = ctxt, ...} => |
592 mk_induct_tac ctxt); |
593 mk_induct_tac ctxt); |
593 in |
594 in |
594 `(conj_dests N) induct_thm |
595 `(conj_dests nn) induct_thm |
595 end; |
596 end; |
596 |
597 |
597 val (iter_thmss, rec_thmss) = |
598 val (iter_thmss, rec_thmss) = |
598 let |
599 let |
599 val xctrss = map2 (map2 (curry Term.list_comb)) ctrss xsss; |
600 val xctrss = map2 (map2 (curry Term.list_comb)) ctrss xsss; |
641 map2 (map2 (fn goal => fn tac => Skip_Proof.prove lthy [] [] goal (tac o #context))) |
642 map2 (map2 (fn goal => fn tac => Skip_Proof.prove lthy [] [] goal (tac o #context))) |
642 goal_recss rec_tacss) |
643 goal_recss rec_tacss) |
643 end; |
644 end; |
644 |
645 |
645 val common_notes = |
646 val common_notes = |
646 (if N > 1 then [(inductN, [induct_thm], [])] (* FIXME: attribs *) else []) |
647 (if nn > 1 then [(inductN, [induct_thm], [])] (* FIXME: attribs *) else []) |
647 |> map (fn (thmN, thms, attrs) => |
648 |> map (fn (thmN, thms, attrs) => |
648 ((Binding.qualify true fp_common_name (Binding.name thmN), attrs), [(thms, [])])); |
649 ((Binding.qualify true fp_common_name (Binding.name thmN), attrs), [(thms, [])])); |
649 |
650 |
650 val notes = |
651 val notes = |
651 [(inductN, map single induct_thms, []), (* FIXME: attribs *) |
652 [(inductN, map single induct_thms, []), (* FIXME: attribs *) |
664 let |
665 let |
665 val (coinduct_thms, coinduct_thm) = |
666 val (coinduct_thms, coinduct_thm) = |
666 let |
667 let |
667 val coinduct_thm = fp_induct; |
668 val coinduct_thm = fp_induct; |
668 in |
669 in |
669 `(conj_dests N) coinduct_thm |
670 `(conj_dests nn) coinduct_thm |
670 end; |
671 end; |
671 |
672 |
672 val (coiter_thmss, corec_thmss) = |
673 val (coiter_thmss, corec_thmss) = |
673 let |
674 let |
674 val z = the_single zs; |
675 val z = the_single zs; |
747 map3 (map3 (map2 o mk_sel_coiter_like_thm)) coiter_thmss selsss sel_thmsss; |
748 map3 (map3 (map2 o mk_sel_coiter_like_thm)) coiter_thmss selsss sel_thmsss; |
748 val sel_corec_thmsss = |
749 val sel_corec_thmsss = |
749 map3 (map3 (map2 o mk_sel_coiter_like_thm)) corec_thmss selsss sel_thmsss; |
750 map3 (map3 (map2 o mk_sel_coiter_like_thm)) corec_thmss selsss sel_thmsss; |
750 |
751 |
751 val common_notes = |
752 val common_notes = |
752 (if N > 1 then [(coinductN, [coinduct_thm], [])] (* FIXME: attribs *) else []) |
753 (if nn > 1 then [(coinductN, [coinduct_thm], [])] (* FIXME: attribs *) else []) |
753 |> map (fn (thmN, thms, attrs) => |
754 |> map (fn (thmN, thms, attrs) => |
754 ((Binding.qualify true fp_common_name (Binding.name thmN), attrs), [(thms, [])])); |
755 ((Binding.qualify true fp_common_name (Binding.name thmN), attrs), [(thms, [])])); |
755 |
756 |
756 val notes = |
757 val notes = |
757 [(coinductN, map single coinduct_thms, []), (* FIXME: attribs *) |
758 [(coinductN, map single coinduct_thms, []), (* FIXME: attribs *) |