503 val (Type (_, Ts0), Type (_, Us0)) = strip_typeN (live + 1) (fastype_of t) |>> List.last |
503 val (Type (_, Ts0), Type (_, Us0)) = strip_typeN (live + 1) (fastype_of t) |>> List.last |
504 in |
504 in |
505 Term.subst_atomic_types (Ts0 @ Us0 ~~ Ts @ Us) t |
505 Term.subst_atomic_types (Ts0 @ Us0 ~~ Ts @ Us) t |
506 end; |
506 end; |
507 |
507 |
508 fun build_map build_arg (T as Type (s, Ts)) (U as Type (_, Us)) = |
508 fun build_map build_arg (Type (s, Ts)) (Type (_, Us)) = |
509 let |
509 let |
510 val bnf = the (bnf_of lthy s); |
510 val bnf = the (bnf_of lthy s); |
511 val live = live_of_bnf bnf; |
511 val live = live_of_bnf bnf; |
512 val mapx = mk_map live Ts Us (map_of_bnf bnf); |
512 val mapx = mk_map live Ts Us (map_of_bnf bnf); |
513 val TUs = map dest_funT (fst (strip_typeN live (fastype_of mapx))); |
513 val TUs = map dest_funT (fst (strip_typeN live (fastype_of mapx))); |
601 |> singleton (Proof_Context.export names_lthy lthy) |
601 |> singleton (Proof_Context.export names_lthy lthy) |
602 in |
602 in |
603 `(conj_dests nn) induct_thm |
603 `(conj_dests nn) induct_thm |
604 end; |
604 end; |
605 |
605 |
|
606 val induct_cases = Datatype_Prop.indexify_names (maps (map base_name_of_ctr) ctrss); |
|
607 |
606 val (iter_thmss, rec_thmss) = |
608 val (iter_thmss, rec_thmss) = |
607 let |
609 let |
608 val xctrss = map2 (map2 (curry Term.list_comb)) ctrss xsss; |
610 val xctrss = map2 (map2 (curry Term.list_comb)) ctrss xsss; |
609 val giters = map (lists_bmoc gss) iters; |
611 val giters = map (lists_bmoc gss) iters; |
610 val hrecs = map (lists_bmoc hss) recs; |
612 val hrecs = map (lists_bmoc hss) recs; |
649 goal_iterss iter_tacss, |
651 goal_iterss iter_tacss, |
650 map2 (map2 (fn goal => fn tac => Skip_Proof.prove lthy [] [] goal (tac o #context))) |
652 map2 (map2 (fn goal => fn tac => Skip_Proof.prove lthy [] [] goal (tac o #context))) |
651 goal_recss rec_tacss) |
653 goal_recss rec_tacss) |
652 end; |
654 end; |
653 |
655 |
|
656 val induct_case_names_attr = Attrib.internal (K (Rule_Cases.case_names induct_cases)); |
|
657 fun induct_type_attr T_name = Attrib.internal (K (Induct.induct_type T_name)); |
|
658 |
654 val common_notes = |
659 val common_notes = |
655 (if nn > 1 then [(inductN, [induct_thm], [])] (* FIXME: attribs *) else []) |
660 (if nn > 1 then [(inductN, [induct_thm], [induct_case_names_attr])] else []) |
656 |> map (fn (thmN, thms, attrs) => |
661 |> map (fn (thmN, thms, attrs) => |
657 ((Binding.qualify true fp_common_name (Binding.name thmN), attrs), [(thms, [])])); |
662 ((Binding.qualify true fp_common_name (Binding.name thmN), attrs), [(thms, [])])); |
658 |
663 |
659 val notes = |
664 val notes = |
660 [(inductN, map single induct_thms, []), (* FIXME: attribs *) |
665 [(inductN, map single induct_thms, |
661 (itersN, iter_thmss, simp_attrs), |
666 fn T_name => [induct_case_names_attr, induct_type_attr T_name]), |
662 (recsN, rec_thmss, Code.add_default_eqn_attrib :: simp_attrs)] |
667 (itersN, iter_thmss, K simp_attrs), |
|
668 (recsN, rec_thmss, K (Code.add_default_eqn_attrib :: simp_attrs))] |
663 |> maps (fn (thmN, thmss, attrs) => |
669 |> maps (fn (thmN, thmss, attrs) => |
664 map2 (fn b => fn thms => |
670 map3 (fn b => fn Type (T_name, _) => fn thms => |
665 ((Binding.qualify true (Binding.name_of b) (Binding.name thmN), attrs), |
671 ((Binding.qualify true (Binding.name_of b) (Binding.name thmN), attrs T_name), |
666 [(thms, [])])) fp_bs thmss); |
672 [(thms, [])])) fp_bs fpTs thmss); |
667 in |
673 in |
668 lthy |> Local_Theory.notes (common_notes @ notes) |> snd |
674 lthy |> Local_Theory.notes (common_notes @ notes) |> snd |
669 end; |
675 end; |
670 |
676 |
671 fun derive_coinduct_coiter_corec_thms_for_types ((ctrss, selsss, coiters, corecs, _, ctr_defss, |
677 fun derive_coinduct_coiter_corec_thms_for_types ((ctrss, selsss, coiters, corecs, _, ctr_defss, |