673 (fold_thmss, code_simp_attrs), (rec_thmss, code_simp_attrs)) |
673 (fold_thmss, code_simp_attrs), (rec_thmss, code_simp_attrs)) |
674 end; |
674 end; |
675 |
675 |
676 fun derive_coinduct_coiters_thms_for_types pre_bnfs (dtor_coiters1 :: _) dtor_coinduct |
676 fun derive_coinduct_coiters_thms_for_types pre_bnfs (dtor_coiters1 :: _) dtor_coinduct |
677 dtor_strong_induct dtor_ctors [dtor_unfold_thms, dtor_corec_thms] nesting_bnfs nested_bnfs fpTs |
677 dtor_strong_induct dtor_ctors [dtor_unfold_thms, dtor_corec_thms] nesting_bnfs nested_bnfs fpTs |
678 Cs As kss mss ns ctr_defss ctr_sugars iterss iter_defss lthy = |
678 Cs As kss mss ns ctr_defss ctr_sugars coiterss coiter_defss lthy = |
679 let |
679 let |
680 val [unfolds, corecs] = transpose iterss; |
680 val coiterss' = transpose coiterss; |
681 val [unfold_defs, corec_defs] = transpose iter_defss; |
681 val coiter_defss' = transpose coiter_defss; |
|
682 |
|
683 val [unfolds, corecs] = coiterss'; |
|
684 val [unfold_defs, corec_defs] = coiter_defss'; |
682 |
685 |
683 val nn = length pre_bnfs; |
686 val nn = length pre_bnfs; |
684 |
687 |
685 val pre_map_defs = map map_def_of_bnf pre_bnfs; |
688 val pre_map_defs = map map_def_of_bnf pre_bnfs; |
686 val pre_rel_defs = map rel_def_of_bnf pre_bnfs; |
689 val pre_rel_defs = map rel_def_of_bnf pre_bnfs; |
690 val nested_map_comps'' = map ((fn thm => thm RS sym) o map_comp_of_bnf) nested_bnfs; |
693 val nested_map_comps'' = map ((fn thm => thm RS sym) o map_comp_of_bnf) nested_bnfs; |
691 val nested_map_ids'' = map (unfold_thms lthy @{thms id_def} o map_id_of_bnf) nested_bnfs; |
694 val nested_map_ids'' = map (unfold_thms lthy @{thms id_def} o map_id_of_bnf) nested_bnfs; |
692 |
695 |
693 val fp_b_names = map base_name_of_typ fpTs; |
696 val fp_b_names = map base_name_of_typ fpTs; |
694 |
697 |
695 val dtor_unfold_fun_Ts = mk_fp_iter_fun_types (un_fold_of dtor_coiters1); |
698 val dtor_iter_fun_Tss' = map mk_fp_iter_fun_types dtor_coiters1; |
696 val dtor_corec_fun_Ts = mk_fp_iter_fun_types (co_rec_of dtor_coiters1); |
|
697 |
699 |
698 val ctrss = map (map (mk_ctr As) o #ctrs) ctr_sugars; |
700 val ctrss = map (map (mk_ctr As) o #ctrs) ctr_sugars; |
699 val discss = map (map (mk_disc_or_sel As) o #discs) ctr_sugars; |
701 val discss = map (map (mk_disc_or_sel As) o #discs) ctr_sugars; |
700 val selsss = map (map (map (mk_disc_or_sel As)) o #selss) ctr_sugars; |
702 val selsss = map (map (map (mk_disc_or_sel As)) o #selss) ctr_sugars; |
701 val exhausts = map #exhaust ctr_sugars; |
703 val exhausts = map #exhaust ctr_sugars; |
702 val disc_thmsss = map #disc_thmss ctr_sugars; |
704 val disc_thmsss = map #disc_thmss ctr_sugars; |
703 val discIss = map #discIs ctr_sugars; |
705 val discIss = map #discIs ctr_sugars; |
704 val sel_thmsss = map #sel_thmss ctr_sugars; |
706 val sel_thmsss = map #sel_thmss ctr_sugars; |
705 |
707 |
706 (* TODO: avoid duplication *) |
708 (* TODO: avoid duplication *) |
707 val ((cs, cpss, [((pgss, crssss, cgssss), _), ((phss, csssss, chssss), _)]), names_lthy0) = |
709 val ((cs, cpss, [(unfold_args as (pgss, crssss, cgssss), _), |
708 mk_coiters_args_types Cs ns mss (transpose [dtor_unfold_fun_Ts, dtor_corec_fun_Ts]) lthy; |
710 (corec_args as (phss, csssss, chssss), _)]), names_lthy0) = |
|
711 mk_coiters_args_types Cs ns mss (transpose dtor_iter_fun_Tss') lthy; |
709 |
712 |
710 val (((rs, us'), vs'), names_lthy) = |
713 val (((rs, us'), vs'), names_lthy) = |
711 names_lthy0 |
714 names_lthy0 |
712 |> mk_Frees "R" (map (fn T => mk_pred2T T T) fpTs) |
715 |> mk_Frees "R" (map (fn T => mk_pred2T T T) fpTs) |
713 ||>> Variable.variant_fixes fp_b_names |
716 ||>> Variable.variant_fixes fp_b_names |
806 val coinduct_conclss = |
809 val coinduct_conclss = |
807 map3 (quasi_unambiguous_case_names ooo mk_coinduct_concls) mss discss ctrss; |
810 map3 (quasi_unambiguous_case_names ooo mk_coinduct_concls) mss discss ctrss; |
808 |
811 |
809 fun mk_maybe_not pos = not pos ? HOLogic.mk_not; |
812 fun mk_maybe_not pos = not pos ? HOLogic.mk_not; |
810 |
813 |
811 val gunfolds = map (lists_bmoc pgss) unfolds; |
814 val fcoiterss' as [gunfolds, hcorecs] = |
812 val hcorecs = map (lists_bmoc phss) corecs; |
815 map2 (fn (pfss, _, _) => map (lists_bmoc pfss)) [unfold_args, corec_args] coiterss'; |
813 |
816 |
814 val (unfold_thmss, corec_thmss, safe_unfold_thmss, safe_corec_thmss) = |
817 val (unfold_thmss, corec_thmss, safe_unfold_thmss, safe_corec_thmss) = |
815 let |
818 let |
816 fun mk_goal pfss c cps fcoiter n k ctr m cfs' = |
819 fun mk_goal pfss c cps fcoiter n k ctr m cfs' = |
817 fold_rev (fold_rev Logic.all) ([c] :: pfss) |
820 fold_rev (fold_rev Logic.all) ([c] :: pfss) |
818 (Logic.list_implies (seq_conds (HOLogic.mk_Trueprop oo mk_maybe_not) n k cps, |
821 (Logic.list_implies (seq_conds (HOLogic.mk_Trueprop oo mk_maybe_not) n k cps, |
819 mk_Trueprop_eq (fcoiter $ c, Term.list_comb (ctr, take m cfs')))); |
822 mk_Trueprop_eq (fcoiter $ c, Term.list_comb (ctr, take m cfs')))); |
820 |
823 |
821 (* TODO: get rid of "mk_U" *) |
824 val substC = typ_subst_nonatomic (map2 pair Cs fpTs); |
822 val mk_U = typ_subst_nonatomic (map2 pair Cs fpTs); |
|
823 |
825 |
824 fun intr_coiters fcoiters [] [cf] = |
826 fun intr_coiters fcoiters [] [cf] = |
825 let val T = fastype_of cf in |
827 let val T = fastype_of cf in |
826 if exists_subtype_in Cs T then |
828 if exists_subtype_in Cs T then |
827 build_map lthy (indexify fst Cs (K o nth fcoiters)) (T, mk_U T) $ cf |
829 build_map lthy (indexify fst Cs (K o nth fcoiters)) (T, substC T) $ cf |
828 else |
830 else |
829 cf |
831 cf |
830 end |
832 end |
831 | intr_coiters fcoiters [cq] [cf, cf'] = |
833 | intr_coiters fcoiters [cq] [cf, cf'] = |
832 mk_If cq (intr_coiters fcoiters [] [cf]) (intr_coiters fcoiters [] [cf']); |
834 mk_If cq (intr_coiters fcoiters [] [cf]) (intr_coiters fcoiters [] [cf']); |
833 |
835 |
834 val crgsss = map2 (map2 (map2 (intr_coiters gunfolds))) crssss cgssss; |
836 val [crgsss, cshsss] = |
835 val cshsss = map2 (map2 (map2 (intr_coiters hcorecs))) csssss chssss; |
837 map2 (fn fcoiters => fn (_, cqssss, cfssss) => |
|
838 map2 (map2 (map2 (intr_coiters fcoiters))) cqssss cfssss) |
|
839 fcoiterss' [unfold_args, corec_args]; |
836 |
840 |
837 val unfold_goalss = map8 (map4 oooo mk_goal pgss) cs cpss gunfolds ns kss ctrss mss crgsss; |
841 val unfold_goalss = map8 (map4 oooo mk_goal pgss) cs cpss gunfolds ns kss ctrss mss crgsss; |
838 val corec_goalss = map8 (map4 oooo mk_goal phss) cs cpss hcorecs ns kss ctrss mss cshsss; |
842 val corec_goalss = map8 (map4 oooo mk_goal phss) cs cpss hcorecs ns kss ctrss mss cshsss; |
839 |
843 |
840 fun mk_map_if_distrib bnf = |
844 fun mk_map_if_distrib bnf = |