src/HOL/BNF/Tools/bnf_fp_def_sugar.ML
changeset 52339 844b1c8e3d9e
parent 52338 8bf544733e0e
child 52340 754bc55dcb09
equal deleted inserted replaced
52338:8bf544733e0e 52339:844b1c8e3d9e
   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 =