src/HOL/BNF/Tools/bnf_fp_def_sugar.ML
changeset 51829 3cc93eeac8cc
parent 51828 67c6d6136915
child 51830 403f7ecd061f
equal deleted inserted replaced
51828:67c6d6136915 51829:3cc93eeac8cc
    19     thm list -> thm list -> BNF_Def.BNF list -> BNF_Def.BNF list -> typ list -> typ list ->
    19     thm list -> thm list -> BNF_Def.BNF list -> BNF_Def.BNF list -> typ list -> typ list ->
    20     typ list -> term list list -> thm list list -> term list -> term list -> thm list -> thm list ->
    20     typ list -> term list list -> thm list list -> term list -> term list -> thm list -> thm list ->
    21     Proof.context ->
    21     Proof.context ->
    22     (thm * thm list * Args.src list) * (thm list list * Args.src list)
    22     (thm * thm list * Args.src list) * (thm list list * Args.src list)
    23     * (thm list list * Args.src list)
    23     * (thm list list * Args.src list)
    24   val derive_coinduct_unfold_corec_thms_for_types: Proof.context -> Proof.context ->
    24   val derive_coinduct_unfold_corec_thms_for_types: BNF_Def.BNF list -> term list -> term list ->
    25     BNF_Def.BNF list -> thm -> thm -> thm list -> thm list -> thm list -> BNF_Def.BNF list ->
    25     thm -> thm -> thm list -> thm list -> thm list -> BNF_Def.BNF list -> BNF_Def.BNF list ->
    26     BNF_Def.BNF list -> typ list -> typ list -> typ list -> int list list -> int list list ->
    26     typ list -> typ list -> typ list -> int list list -> int list list -> int list ->
    27     int list -> term list -> term list list -> term list list -> term list list list list ->
    27     term list list -> thm list list -> BNF_Ctr_Sugar.ctr_wrap_result list -> term list ->
    28     term list list list list -> term list list -> term list list list list ->
    28     term list -> thm list -> thm list -> Proof.context ->
    29     term list list list list -> term list list -> thm list list ->
       
    30     BNF_Ctr_Sugar.ctr_wrap_result list -> term list -> term list -> thm list -> thm list ->
       
    31     Proof.context ->
       
    32     (thm * thm list * thm * thm list * Args.src list) * (thm list list * thm list list * 'e list)
    29     (thm * thm list * thm * thm list * Args.src list) * (thm list list * thm list list * 'e list)
    33     * (thm list list * thm list list) * (thm list list * thm list list * Args.src list)
    30     * (thm list list * thm list list) * (thm list list * thm list list * Args.src list)
    34     * (thm list list * thm list list * Args.src list)
    31     * (thm list list * thm list list * Args.src list)
    35     * (thm list list * thm list list * Args.src list)
    32     * (thm list list * thm list list * Args.src list)
    36 
    33 
   156     maps (op @) ps
   153     maps (op @) ps
   157 *)
   154 *)
   158     maps fst ps @ maps snd ps
   155     maps fst ps @ maps snd ps
   159   end;
   156   end;
   160 
   157 
       
   158 fun flat_predss_getterss qss fss = maps (op @) (qss ~~ fss);
       
   159 
       
   160 fun flat_preds_predsss_gettersss [] [qss] [fss] = flat_predss_getterss qss fss
       
   161   | flat_preds_predsss_gettersss (p :: ps) (qss :: qsss) (fss :: fsss) =
       
   162     p :: flat_predss_getterss qss fss @ flat_preds_predsss_gettersss ps qsss fsss;
       
   163 
   161 fun mk_flip (x, Type (_, [T1, Type (_, [T2, T3])])) =
   164 fun mk_flip (x, Type (_, [T1, Type (_, [T2, T3])])) =
   162   Abs ("x", T1, Abs ("y", T2, Var (x, T2 --> T1 --> T3) $ Bound 0 $ Bound 1));
   165   Abs ("x", T1, Abs ("y", T2, Var (x, T2 --> T1 --> T3) $ Bound 0 $ Bound 1));
   163 
   166 
   164 fun flip_rels lthy n thm =
   167 fun flip_rels lthy n thm =
   165   let
   168   let
   194   map (mk_rec_like lfp As Cs) fp_rec_likes0
   197   map (mk_rec_like lfp As Cs) fp_rec_likes0
   195   |> (fn ts => (ts, mk_fp_rec_like_fun_types ts));
   198   |> (fn ts => (ts, mk_fp_rec_like_fun_types ts));
   196 
   199 
   197 fun mk_rec_like_fun_arg_typess n ms = map2 dest_tupleT ms o dest_sumTN_balanced n o domain_type;
   200 fun mk_rec_like_fun_arg_typess n ms = map2 dest_tupleT ms o dest_sumTN_balanced n o domain_type;
   198 
   201 
   199 fun project_recT fpTs proj =
   202 fun massage_rec_fun_arg_typesss fpTs =
   200   let
   203   let
   201     fun project (Type (s as @{type_name prod}, Ts as [T, U])) =
   204     fun project_recT proj =
   202         if member (op =) fpTs T then proj (T, U) else Type (s, map project Ts)
   205       let
   203       | project (Type (s, Ts)) = Type (s, map project Ts)
   206         fun project (Type (s as @{type_name prod}, Ts as [T, U])) =
   204       | project T = T;
   207             if member (op =) fpTs T then proj (T, U) else Type (s, map project Ts)
   205   in project end;
   208           | project (Type (s, Ts)) = Type (s, map project Ts)
   206 
   209           | project T = T;
   207 fun unzip_recT fpTs T =
   210       in project end;
   208   if exists_subtype_in fpTs T then ([project_recT fpTs fst T], [project_recT fpTs snd T])
   211     fun unzip_recT T =
   209   else ([T], []);
   212       if exists_subtype_in fpTs T then ([project_recT fst T], [project_recT snd T]) else ([T], []);
   210 
   213   in
   211 fun massage_rec_fun_arg_typesss fpTs = map (map (flat_rec (unzip_recT fpTs)));
   214     map (map (flat_rec unzip_recT))
       
   215   end;
   212 
   216 
   213 val mk_fold_fun_typess = map2 (map2 (curry (op --->)));
   217 val mk_fold_fun_typess = map2 (map2 (curry (op --->)));
   214 val mk_rec_fun_typess = mk_fold_fun_typess oo massage_rec_fun_arg_typesss;
   218 val mk_rec_fun_typess = mk_fold_fun_typess oo massage_rec_fun_arg_typesss;
       
   219 
       
   220 fun mk_corec_like_pred_types n = replicate (Int.max (0, n - 1)) o mk_pred1T;
       
   221 
       
   222 fun mk_unfold_corec_types fpTs Cs ns mss dtor_unfold_fun_Ts dtor_corec_fun_Ts =
       
   223   let
       
   224     (*avoid "'a itself" arguments in coiterators and corecursors*)
       
   225     fun repair_arity [0] = [1]
       
   226       | repair_arity ms = ms;
       
   227 
       
   228     fun project_corecT proj =
       
   229       let
       
   230         fun project (Type (s as @{type_name sum}, Ts as [T, U])) =
       
   231             if member (op =) fpTs T then proj (T, U) else Type (s, map project Ts)
       
   232           | project (Type (s, Ts)) = Type (s, map project Ts)
       
   233           | project T = T;
       
   234       in project end;
       
   235 
       
   236     fun unzip_corecT T =
       
   237       if exists_subtype_in fpTs T then [project_corecT fst T, project_corecT snd T] else [T];
       
   238 
       
   239     val p_Tss = map2 mk_corec_like_pred_types ns Cs;
       
   240 
       
   241     fun mk_types maybe_unzipT fun_Ts =
       
   242       let
       
   243         val f_sum_prod_Ts = map range_type fun_Ts;
       
   244         val f_prod_Tss = map2 dest_sumTN_balanced ns f_sum_prod_Ts;
       
   245         val f_Tsss = map2 (map2 dest_tupleT o repair_arity) mss f_prod_Tss;
       
   246         val f_Tssss =
       
   247           map2 (fn C => map (map (map (curry (op -->) C) o maybe_unzipT))) Cs f_Tsss;
       
   248         val q_Tssss =
       
   249           map (map (map (fn [_] => [] | [_, C] => [mk_pred1T (domain_type C)]))) f_Tssss;
       
   250         val pf_Tss = map3 flat_preds_predsss_gettersss p_Tss q_Tssss f_Tssss;
       
   251       in (q_Tssss, f_sum_prod_Ts, f_Tsss, f_Tssss, pf_Tss) end;
       
   252   in
       
   253     (p_Tss, mk_types single dtor_unfold_fun_Ts, mk_types unzip_corecT dtor_corec_fun_Ts)
       
   254   end
       
   255 
       
   256 fun mk_unfold_corec_vars Cs p_Tss g_Tssss r_Tssss h_Tssss s_Tssss lthy =
       
   257   let
       
   258     val (((cs, pss), gssss), lthy) =
       
   259       lthy
       
   260       |> mk_Frees "a" Cs
       
   261       ||>> mk_Freess "p" p_Tss
       
   262       ||>> mk_Freessss "g" g_Tssss;
       
   263     val rssss = map (map (map (fn [] => []))) r_Tssss;
       
   264 
       
   265     val hssss_hd = map2 (map2 (map2 (fn T :: _ => fn [g] => retype_free T g))) h_Tssss gssss;
       
   266     val ((sssss, hssss_tl), lthy) =
       
   267       lthy
       
   268       |> mk_Freessss "q" s_Tssss
       
   269       ||>> mk_Freessss "h" (map (map (map tl)) h_Tssss);
       
   270     val hssss = map2 (map2 (map2 cons)) hssss_hd hssss_tl;
       
   271   in
       
   272     ((cs, pss, (gssss, rssss), (hssss, sssss)), lthy)
       
   273   end;
       
   274 
       
   275 fun mk_corec_like_terms cs pss qssss fssss =
       
   276   let
       
   277     val pfss = map3 flat_preds_predsss_gettersss pss qssss fssss;
       
   278     val cqssss = map2 (map o map o map o rapp) cs qssss;
       
   279     val cfssss = map2 (map o map o map o rapp) cs fssss;
       
   280   in (pfss, cqssss, cfssss) end;
   215 
   281 
   216 fun mk_map live Ts Us t =
   282 fun mk_map live Ts Us t =
   217   let val (Type (_, Ts0), Type (_, Us0)) = strip_typeN (live + 1) (fastype_of t) |>> List.last in
   283   let val (Type (_, Ts0), Type (_, Us0)) = strip_typeN (live + 1) (fastype_of t) |>> List.last in
   218     Term.subst_atomic_types (Ts0 @ Us0 ~~ Ts @ Us) t
   284     Term.subst_atomic_types (Ts0 @ Us0 ~~ Ts @ Us) t
   219   end;
   285   end;
   438   in
   504   in
   439     ((induct_thm, induct_thms, [induct_case_names_attr]),
   505     ((induct_thm, induct_thms, [induct_case_names_attr]),
   440      (fold_thmss, code_simp_attrs), (rec_thmss, code_simp_attrs))
   506      (fold_thmss, code_simp_attrs), (rec_thmss, code_simp_attrs))
   441   end;
   507   end;
   442 
   508 
   443 fun derive_coinduct_unfold_corec_thms_for_types names_lthy0 no_defs_lthy pre_bnfs dtor_coinduct
   509 fun derive_coinduct_unfold_corec_thms_for_types pre_bnfs dtor_unfolds0 dtor_corecs0 dtor_coinduct
   444     dtor_strong_induct dtor_ctors dtor_unfold_thms dtor_corec_thms nesting_bnfs nested_bnfs fpTs Cs
   510     dtor_strong_induct dtor_ctors dtor_unfold_thms dtor_corec_thms nesting_bnfs nested_bnfs fpTs Cs
   445     As kss mss ns cs cpss pgss crssss cgssss phss csssss chssss ctrss ctr_defss ctr_wrap_ress
   511     As kss mss ns ctrss ctr_defss ctr_wrap_ress unfolds corecs unfold_defs corec_defs lthy =
   446     unfolds corecs unfold_defs corec_defs lthy =
       
   447   let
   512   let
   448     val nn = length pre_bnfs;
   513     val nn = length pre_bnfs;
   449 
   514 
   450     val pre_map_defs = map map_def_of_bnf pre_bnfs;
   515     val pre_map_defs = map map_def_of_bnf pre_bnfs;
   451     val pre_rel_defs = map rel_def_of_bnf pre_bnfs;
   516     val pre_rel_defs = map rel_def_of_bnf pre_bnfs;
   455     val nesting_map_ids'' = map (unfold_thms lthy @{thms id_def} o map_id_of_bnf) nesting_bnfs;
   520     val nesting_map_ids'' = map (unfold_thms lthy @{thms id_def} o map_id_of_bnf) nesting_bnfs;
   456     val nesting_rel_eqs = map rel_eq_of_bnf nesting_bnfs;
   521     val nesting_rel_eqs = map rel_eq_of_bnf nesting_bnfs;
   457 
   522 
   458     val fp_b_names = map base_name_of_typ fpTs;
   523     val fp_b_names = map base_name_of_typ fpTs;
   459 
   524 
       
   525     val (_, dtor_unfold_fun_Ts) = mk_fp_rec_like false As Cs dtor_unfolds0;
       
   526     val (_, dtor_corec_fun_Ts) = mk_fp_rec_like false As Cs dtor_corecs0;
       
   527 
   460     val discss = map (map (mk_disc_or_sel As) o #discs) ctr_wrap_ress;
   528     val discss = map (map (mk_disc_or_sel As) o #discs) ctr_wrap_ress;
   461     val selsss = map (map (map (mk_disc_or_sel As)) o #selss) ctr_wrap_ress;
   529     val selsss = map (map (map (mk_disc_or_sel As)) o #selss) ctr_wrap_ress;
   462     val exhausts = map #exhaust ctr_wrap_ress;
   530     val exhausts = map #exhaust ctr_wrap_ress;
   463     val disc_thmsss = map #disc_thmss ctr_wrap_ress;
   531     val disc_thmsss = map #disc_thmss ctr_wrap_ress;
   464     val discIss = map #discIs ctr_wrap_ress;
   532     val discIss = map #discIs ctr_wrap_ress;
   468       lthy
   536       lthy
   469       |> mk_Frees "R" (map (fn T => mk_pred2T T T) fpTs)
   537       |> mk_Frees "R" (map (fn T => mk_pred2T T T) fpTs)
   470       ||>> Variable.variant_fixes fp_b_names
   538       ||>> Variable.variant_fixes fp_b_names
   471       ||>> Variable.variant_fixes (map (suffix "'") fp_b_names);
   539       ||>> Variable.variant_fixes (map (suffix "'") fp_b_names);
   472 
   540 
       
   541     val (p_Tss, (r_Tssss, g_sum_prod_Ts, g_Tsss, g_Tssss, pg_Tss),
       
   542          (s_Tssss, h_sum_prod_Ts, h_Tsss, h_Tssss, ph_Tss)) =
       
   543       mk_unfold_corec_types fpTs Cs ns mss dtor_unfold_fun_Ts dtor_corec_fun_Ts;
       
   544 
       
   545     val ((cs, pss, (gssss, rssss), (hssss, sssss)), names_lthy) =
       
   546       mk_unfold_corec_vars Cs p_Tss g_Tssss r_Tssss h_Tssss s_Tssss names_lthy;
       
   547 
       
   548     val cpss = map2 (map o rapp) cs pss;
       
   549 
   473     val us = map2 (curry Free) us' fpTs;
   550     val us = map2 (curry Free) us' fpTs;
   474     val udiscss = map2 (map o rapp) us discss;
   551     val udiscss = map2 (map o rapp) us discss;
   475     val uselsss = map2 (map o map o rapp) us selsss;
   552     val uselsss = map2 (map o map o rapp) us selsss;
   476 
   553 
   477     val vs = map2 (curry Free) vs' fpTs;
   554     val vs = map2 (curry Free) vs' fpTs;
   478     val vdiscss = map2 (map o rapp) vs discss;
   555     val vdiscss = map2 (map o rapp) vs discss;
   479     val vselsss = map2 (map o map o rapp) vs selsss;
   556     val vselsss = map2 (map o map o rapp) vs selsss;
       
   557 
       
   558     val (pgss, crssss, cgssss) = mk_corec_like_terms cs pss rssss gssss;
       
   559     val (phss, csssss, chssss) = mk_corec_like_terms cs pss sssss hssss;
   480 
   560 
   481     val ((coinduct_thms, coinduct_thm), (strong_coinduct_thms, strong_coinduct_thm)) =
   561     val ((coinduct_thms, coinduct_thm), (strong_coinduct_thms, strong_coinduct_thm)) =
   482       let
   562       let
   483         val uvrs = map3 (fn r => fn u => fn v => r $ u $ v) rs us vs;
   563         val uvrs = map3 (fn r => fn u => fn v => r $ u $ v) rs us vs;
   484         val uv_eqs = map2 (curry HOLogic.mk_eq) us vs;
   564         val uv_eqs = map2 (curry HOLogic.mk_eq) us vs;
   650         val corec_tacss =
   730         val corec_tacss =
   651           map3 (map oo mk_disc_corec_like_iff_tac) case_splitss' corec_thmss disc_thmsss;
   731           map3 (map oo mk_disc_corec_like_iff_tac) case_splitss' corec_thmss disc_thmsss;
   652 
   732 
   653         fun prove goal tac =
   733         fun prove goal tac =
   654           Goal.prove_sorry lthy [] [] goal (tac o #context)
   734           Goal.prove_sorry lthy [] [] goal (tac o #context)
   655           |> singleton (Proof_Context.export names_lthy0 no_defs_lthy)
   735           |> singleton (Proof_Context.export names_lthy lthy)
   656           |> Thm.close_derivation;
   736           |> Thm.close_derivation;
   657 
   737 
   658         fun proves [_] [_] = []
   738         fun proves [_] [_] = []
   659           | proves goals tacs = map2 prove goals tacs;
   739           | proves goals tacs = map2 prove goals tacs;
   660       in
   740       in
   892           ((((gss, g_Tss, ysss), (hss, h_Tss, zsss)),
   972           ((((gss, g_Tss, ysss), (hss, h_Tss, zsss)),
   893             ([], [], (([], [], []), ([], [], [])), (([], [], []), ([], [], [])))), lthy)
   973             ([], [], (([], [], []), ([], [], [])), (([], [], []), ([], [], [])))), lthy)
   894         end
   974         end
   895       else
   975       else
   896         let
   976         let
   897           (*avoid "'a itself" arguments in coiterators and corecursors*)
   977           val (p_Tss, (r_Tssss, g_sum_prod_Ts, g_Tsss, g_Tssss, pg_Tss),
   898           val mss' =  map (fn [0] => [1] | ms => ms) mss;
   978                (s_Tssss, h_sum_prod_Ts, h_Tsss, h_Tssss, ph_Tss)) =
   899 
   979             mk_unfold_corec_types fpTs Cs ns mss fp_fold_fun_Ts fp_rec_fun_Ts;
   900           val p_Tss = map2 (fn n => replicate (Int.max (0, n - 1)) o mk_pred1T) ns Cs;
   980 
   901 
   981           val ((cs, pss, (gssss, rssss), (hssss, sssss)), lthy) =
   902           fun flat_predss_getterss qss fss = maps (op @) (qss ~~ fss);
   982             mk_unfold_corec_vars Cs p_Tss g_Tssss r_Tssss h_Tssss s_Tssss lthy;
   903 
       
   904           fun flat_preds_predsss_gettersss [] [qss] [fss] = flat_predss_getterss qss fss
       
   905             | flat_preds_predsss_gettersss (p :: ps) (qss :: qsss) (fss :: fsss) =
       
   906               p :: flat_predss_getterss qss fss @ flat_preds_predsss_gettersss ps qsss fsss;
       
   907 
       
   908           fun mk_types maybe_unzipT fun_Ts =
       
   909             let
       
   910               val f_sum_prod_Ts = map range_type fun_Ts;
       
   911               val f_prod_Tss = map2 dest_sumTN_balanced ns f_sum_prod_Ts;
       
   912               val f_Tsss = map2 (map2 dest_tupleT) mss' f_prod_Tss;
       
   913               val f_Tssss =
       
   914                 map2 (fn C => map (map (map (curry (op -->) C) o maybe_unzipT))) Cs f_Tsss;
       
   915               val q_Tssss =
       
   916                 map (map (map (fn [_] => [] | [_, C] => [mk_pred1T (domain_type C)]))) f_Tssss;
       
   917               val pf_Tss = map3 flat_preds_predsss_gettersss p_Tss q_Tssss f_Tssss;
       
   918             in (q_Tssss, f_sum_prod_Ts, f_Tsss, f_Tssss, pf_Tss) end;
       
   919 
       
   920           val (r_Tssss, g_sum_prod_Ts, g_Tsss, g_Tssss, pg_Tss) = mk_types single fp_fold_fun_Ts;
       
   921 
       
   922           val (((cs, pss), gssss), lthy) =
       
   923             lthy
       
   924             |> mk_Frees "a" Cs
       
   925             ||>> mk_Freess "p" p_Tss
       
   926             ||>> mk_Freessss "g" g_Tssss;
       
   927           val rssss = map (map (map (fn [] => []))) r_Tssss;
       
   928 
       
   929           fun proj_corecT proj (Type (s as @{type_name sum}, Ts as [T, U])) =
       
   930               if member (op =) fpTs T then proj (T, U) else Type (s, map (proj_corecT proj) Ts)
       
   931             | proj_corecT proj (Type (s, Ts)) = Type (s, map (proj_corecT proj) Ts)
       
   932             | proj_corecT _ T = T;
       
   933 
       
   934           fun unzip_corecT T =
       
   935             if exists_subtype_in fpTs T then [proj_corecT fst T, proj_corecT snd T] else [T];
       
   936 
       
   937           val (s_Tssss, h_sum_prod_Ts, h_Tsss, h_Tssss, ph_Tss) =
       
   938             mk_types unzip_corecT fp_rec_fun_Ts;
       
   939 
       
   940           val hssss_hd = map2 (map2 (map2 (fn T :: _ => fn [g] => retype_free T g))) h_Tssss gssss;
       
   941           val ((sssss, hssss_tl), lthy) =
       
   942             lthy
       
   943             |> mk_Freessss "q" s_Tssss
       
   944             ||>> mk_Freessss "h" (map (map (map tl)) h_Tssss);
       
   945           val hssss = map2 (map2 (map2 cons)) hssss_hd hssss_tl;
       
   946 
   983 
   947           val cpss = map2 (map o rapp) cs pss;
   984           val cpss = map2 (map o rapp) cs pss;
   948 
       
   949           fun mk_terms qssss fssss =
       
   950             let
       
   951               val pfss = map3 flat_preds_predsss_gettersss pss qssss fssss;
       
   952               val cqssss = map2 (map o map o map o rapp) cs qssss;
       
   953               val cfssss = map2 (map o map o map o rapp) cs fssss;
       
   954             in (pfss, cqssss, cfssss) end;
       
   955         in
   985         in
   956           (((([], [], []), ([], [], [])),
   986           (((([], [], []), ([], [], [])),
   957             (cs, cpss, (mk_terms rssss gssss, (g_sum_prod_Ts, g_Tsss, pg_Tss)),
   987             (cs, cpss, (mk_corec_like_terms cs pss rssss gssss, (g_sum_prod_Ts, g_Tsss, pg_Tss)),
   958              (mk_terms sssss hssss, (h_sum_prod_Ts, h_Tsss, ph_Tss)))), lthy)
   988              (mk_corec_like_terms cs pss sssss hssss, (h_sum_prod_Ts, h_Tsss, ph_Tss)))), lthy)
   959         end;
   989         end;
   960 
   990 
   961     fun define_ctrs_case_for_type (((((((((((((((((((((((((fp_bnf, fp_b), fpT), C), ctor), dtor),
   991     fun define_ctrs_case_for_type (((((((((((((((((((((((((fp_bnf, fp_b), fpT), C), ctor), dtor),
   962             fp_fold), fp_rec), ctor_dtor), dtor_ctor), ctor_inject), pre_map_def), pre_set_defs),
   992             fp_fold), fp_rec), ctor_dtor), dtor_ctor), ctor_inject), pre_map_def), pre_set_defs),
   963           pre_rel_def), fp_map_thm), fp_set_thms), fp_rel_thm), n), ks), ms), ctr_bindings),
   993           pre_rel_def), fp_map_thm), fp_set_thms), fp_rel_thm), n), ks), ms), ctr_bindings),
  1309              (unfold_thmss, corec_thmss, corec_like_attrs),
  1339              (unfold_thmss, corec_thmss, corec_like_attrs),
  1310              (safe_unfold_thmss, safe_corec_thmss),
  1340              (safe_unfold_thmss, safe_corec_thmss),
  1311              (disc_unfold_thmss, disc_corec_thmss, disc_corec_like_attrs),
  1341              (disc_unfold_thmss, disc_corec_thmss, disc_corec_like_attrs),
  1312              (disc_unfold_iff_thmss, disc_corec_iff_thmss, disc_corec_like_iff_attrs),
  1342              (disc_unfold_iff_thmss, disc_corec_iff_thmss, disc_corec_like_iff_attrs),
  1313              (sel_unfold_thmss, sel_corec_thmss, sel_corec_like_attrs)) =
  1343              (sel_unfold_thmss, sel_corec_thmss, sel_corec_like_attrs)) =
  1314           derive_coinduct_unfold_corec_thms_for_types names_lthy0 no_defs_lthy pre_bnfs fp_induct
  1344           derive_coinduct_unfold_corec_thms_for_types pre_bnfs fp_folds0 fp_recs0 fp_induct
  1315             fp_strong_induct dtor_ctors fp_fold_thms fp_rec_thms nesting_bnfs nested_bnfs fpTs Cs As
  1345             fp_strong_induct dtor_ctors fp_fold_thms fp_rec_thms nesting_bnfs nested_bnfs fpTs Cs As
  1316             kss mss ns cs cpss pgss crssss cgssss phss csssss chssss ctrss ctr_defss ctr_wrap_ress
  1346             kss mss ns ctrss ctr_defss ctr_wrap_ress unfolds corecs unfold_defs corec_defs lthy;
  1317             unfolds corecs unfold_defs corec_defs lthy;
       
  1318 
  1347 
  1319         fun coinduct_type_attr T_name = Attrib.internal (K (Induct.coinduct_type T_name));
  1348         fun coinduct_type_attr T_name = Attrib.internal (K (Induct.coinduct_type T_name));
  1320 
  1349 
  1321         fun flat_corec_like_thms corec_likes disc_corec_likes sel_corec_likes =
  1350         fun flat_corec_like_thms corec_likes disc_corec_likes sel_corec_likes =
  1322           corec_likes @ disc_corec_likes @ sel_corec_likes;
  1351           corec_likes @ disc_corec_likes @ sel_corec_likes;