src/HOL/Tools/BNF/bnf_fp_def_sugar.ML
changeset 58634 9f10d82e8188
parent 58586 1b11669a5c66
child 58659 6c9821c32dd5
equal deleted inserted replaced
58633:8529745af3dc 58634:9f10d82e8188
   522     ((Binding.qualify true base (Binding.name thmN), []),
   522     ((Binding.qualify true base (Binding.name thmN), []),
   523      map_index (fn (i, thm) => ([thm], f_attrs i)) thms));
   523      map_index (fn (i, thm) => ([thm], f_attrs i)) thms));
   524 
   524 
   525 fun massage_multi_notes b_names Ts =
   525 fun massage_multi_notes b_names Ts =
   526   maps (fn (thmN, thmss, attrs) =>
   526   maps (fn (thmN, thmss, attrs) =>
   527     map3 (fn b_name => fn Type (T_name, _) => fn thms =>
   527     @{map 3} (fn b_name => fn Type (T_name, _) => fn thms =>
   528         ((Binding.qualify true b_name (Binding.name thmN), attrs T_name), [(thms, [])]))
   528         ((Binding.qualify true b_name (Binding.name thmN), attrs T_name), [(thms, [])]))
   529       b_names Ts thmss)
   529       b_names Ts thmss)
   530   #> filter_out (null o fst o hd o snd);
   530   #> filter_out (null o fst o hd o snd);
   531 
   531 
   532 fun derive_map_set_rel_thms plugins fp live As Bs abs_inverses ctr_defs' fp_nesting_set_maps
   532 fun derive_map_set_rel_thms plugins fp live As Bs abs_inverses ctr_defs' fp_nesting_set_maps
   786           val goals =
   786           val goals =
   787             if n = 0 then
   787             if n = 0 then
   788               []
   788               []
   789             else
   789             else
   790               [mk_Trueprop_eq (build_rel_app names_lthy Rs [] ta tb,
   790               [mk_Trueprop_eq (build_rel_app names_lthy Rs [] ta tb,
   791                  (case flat (map5 (mk_conjunct n) (1 upto n) discAs selAss discBs selBss) of
   791                  (case flat (@{map 5} (mk_conjunct n) (1 upto n) discAs selAss discBs selBss) of
   792                    [] => @{term True}
   792                    [] => @{term True}
   793                  | conjuncts => Library.foldr1 HOLogic.mk_conj conjuncts))];
   793                  | conjuncts => Library.foldr1 HOLogic.mk_conj conjuncts))];
   794 
   794 
   795           fun prove goal =
   795           fun prove goal =
   796             Goal.prove_sorry lthy [] [] goal (fn {context = ctxt, prems = _} =>
   796             Goal.prove_sorry lthy [] [] goal (fn {context = ctxt, prems = _} =>
   822                     map2 (HOLogic.mk_Trueprop oo build_rel_app lthy Rs []) argAs argBs,
   822                     map2 (HOLogic.mk_Trueprop oo build_rel_app lthy Rs []) argAs argBs,
   823                   thesis)),
   823                   thesis)),
   824                names_ctxt)
   824                names_ctxt)
   825             end;
   825             end;
   826 
   826 
   827           val (assms, names_lthy) = fold_map2 mk_assms ctrAs ctrBs names_lthy;
   827           val (assms, names_lthy) = @{fold_map 2} mk_assms ctrAs ctrBs names_lthy;
   828           val goal = Logic.list_implies (HOLogic.mk_Trueprop rel_Rs_a_b :: assms, thesis);
   828           val goal = Logic.list_implies (HOLogic.mk_Trueprop rel_Rs_a_b :: assms, thesis);
   829           val thm =
   829           val thm =
   830             Goal.prove_sorry lthy [] [] goal (fn {context = ctxt, prems = _} =>
   830             Goal.prove_sorry lthy [] [] goal (fn {context = ctxt, prems = _} =>
   831               mk_rel_cases_tac ctxt (certify ctxt ta) (certify ctxt tb) exhaust injects
   831               mk_rel_cases_tac ctxt (certify ctxt ta) (certify ctxt tb) exhaust injects
   832                 rel_inject_thms distincts rel_distinct_thms live_nesting_rel_eqs)
   832                 rel_inject_thms distincts rel_distinct_thms live_nesting_rel_eqs)
   966                 else (map (Logic.mk_implies o pair (HOLogic.mk_Trueprop prem)) concls, ctxt')
   966                 else (map (Logic.mk_implies o pair (HOLogic.mk_Trueprop prem)) concls, ctxt')
   967               else
   967               else
   968                 ([], ctxt)
   968                 ([], ctxt)
   969             end;
   969             end;
   970           val (goals, names_lthy) = apfst (flat o flat o flat)
   970           val (goals, names_lthy) = apfst (flat o flat o flat)
   971             (fold_map2 (fn disc =>
   971             (@{fold_map 2} (fn disc =>
   972                  fold_map (fn sel => fold_map (mk_goal disc sel) setAs))
   972                  fold_map (fn sel => fold_map (mk_goal disc sel) setAs))
   973                discAs selAss names_lthy);
   973                discAs selAss names_lthy);
   974         in
   974         in
   975           if null goals then
   975           if null goals then
   976             []
   976             []
  1070 
  1070 
  1071 fun mk_recs_args_types ctr_Tsss Cs absTs repTs ns mss ctor_rec_fun_Ts lthy =
  1071 fun mk_recs_args_types ctr_Tsss Cs absTs repTs ns mss ctor_rec_fun_Ts lthy =
  1072   let
  1072   let
  1073     val Css = map2 replicate ns Cs;
  1073     val Css = map2 replicate ns Cs;
  1074     val x_Tssss =
  1074     val x_Tssss =
  1075       map6 (fn absT => fn repT => fn n => fn ms => fn ctr_Tss => fn ctor_rec_fun_T =>
  1075       @{map 6} (fn absT => fn repT => fn n => fn ms => fn ctr_Tss => fn ctor_rec_fun_T =>
  1076           map2 (map2 unzip_recT)
  1076           map2 (map2 unzip_recT)
  1077             ctr_Tss (dest_absumprodT absT repT n ms (domain_type ctor_rec_fun_T)))
  1077             ctr_Tss (dest_absumprodT absT repT n ms (domain_type ctor_rec_fun_T)))
  1078         absTs repTs ns mss ctr_Tsss ctor_rec_fun_Ts;
  1078         absTs repTs ns mss ctr_Tsss ctor_rec_fun_Ts;
  1079 
  1079 
  1080     val x_Tsss' = map (map flat_rec_arg_args) x_Tssss;
  1080     val x_Tsss' = map (map flat_rec_arg_args) x_Tssss;
  1098 
  1098 
  1099 fun mk_corec_fun_arg_types0 ctr_Tsss Cs absTs repTs ns mss fun_Ts =
  1099 fun mk_corec_fun_arg_types0 ctr_Tsss Cs absTs repTs ns mss fun_Ts =
  1100   let
  1100   let
  1101     val ctr_Tsss' = map repair_nullary_single_ctr ctr_Tsss;
  1101     val ctr_Tsss' = map repair_nullary_single_ctr ctr_Tsss;
  1102     val g_absTs = map range_type fun_Ts;
  1102     val g_absTs = map range_type fun_Ts;
  1103     val g_Tsss = map repair_nullary_single_ctr (map5 dest_absumprodT absTs repTs ns mss g_absTs);
  1103     val g_Tsss = map repair_nullary_single_ctr (@{map 5} dest_absumprodT absTs repTs ns mss g_absTs);
  1104     val g_Tssss = map3 (fn C => map2 (map2 (map (curry (op -->) C) oo unzip_corecT)))
  1104     val g_Tssss = @{map 3} (fn C => map2 (map2 (map (curry (op -->) C) oo unzip_corecT)))
  1105       Cs ctr_Tsss' g_Tsss;
  1105       Cs ctr_Tsss' g_Tsss;
  1106     val q_Tssss = map (map (map (fn [_] => [] | [_, T] => [mk_pred1T (domain_type T)]))) g_Tssss;
  1106     val q_Tssss = map (map (map (fn [_] => [] | [_, T] => [mk_pred1T (domain_type T)]))) g_Tssss;
  1107   in
  1107   in
  1108     (q_Tssss, g_Tsss, g_Tssss, g_absTs)
  1108     (q_Tssss, g_Tsss, g_Tssss, g_absTs)
  1109   end;
  1109   end;
  1137     fun build_dtor_corec_arg _ [] [cg] = cg
  1137     fun build_dtor_corec_arg _ [] [cg] = cg
  1138       | build_dtor_corec_arg T [cq] [cg, cg'] =
  1138       | build_dtor_corec_arg T [cq] [cg, cg'] =
  1139         mk_If cq (build_sum_inj Inl_const (fastype_of cg, T) $ cg)
  1139         mk_If cq (build_sum_inj Inl_const (fastype_of cg, T) $ cg)
  1140           (build_sum_inj Inr_const (fastype_of cg', T) $ cg');
  1140           (build_sum_inj Inr_const (fastype_of cg', T) $ cg');
  1141 
  1141 
  1142     val pgss = map3 flat_corec_preds_predsss_gettersss pss qssss gssss;
  1142     val pgss = @{map 3} flat_corec_preds_predsss_gettersss pss qssss gssss;
  1143     val cqssss = map2 (map o map o map o rapp) cs qssss;
  1143     val cqssss = map2 (map o map o map o rapp) cs qssss;
  1144     val cgssss = map2 (map o map o map o rapp) cs gssss;
  1144     val cgssss = map2 (map o map o map o rapp) cs gssss;
  1145     val cqgsss = map3 (map3 (map3 build_dtor_corec_arg)) g_Tsss cqssss cgssss;
  1145     val cqgsss = @{map 3} (@{map 3} (@{map 3} build_dtor_corec_arg)) g_Tsss cqssss cgssss;
  1146   in
  1146   in
  1147     ((x, cs, cpss, (((pgss, pss, qssss, gssss), cqgsss), corec_types)), lthy)
  1147     ((x, cs, cpss, (((pgss, pss, qssss, gssss), cqgsss), corec_types)), lthy)
  1148   end;
  1148   end;
  1149 
  1149 
  1150 fun mk_co_recs_prelims fp ctr_Tsss fpTs Cs absTs repTs ns mss xtor_co_recs0 lthy =
  1150 fun mk_co_recs_prelims fp ctr_Tsss fpTs Cs absTs repTs ns mss xtor_co_recs0 lthy =
  1198     val (ctor_rec_absTs, fpT) = strip_typeN nn (fastype_of ctor_rec)
  1198     val (ctor_rec_absTs, fpT) = strip_typeN nn (fastype_of ctor_rec)
  1199       |>> map domain_type ||> domain_type;
  1199       |>> map domain_type ||> domain_type;
  1200   in
  1200   in
  1201     define_co_rec_as Least_FP Cs fpT (mk_binding recN)
  1201     define_co_rec_as Least_FP Cs fpT (mk_binding recN)
  1202       (fold_rev (fold_rev Term.lambda) fss (Term.list_comb (ctor_rec,
  1202       (fold_rev (fold_rev Term.lambda) fss (Term.list_comb (ctor_rec,
  1203          map4 (fn ctor_rec_absT => fn rep => fn fs => fn xsss =>
  1203          @{map 4} (fn ctor_rec_absT => fn rep => fn fs => fn xsss =>
  1204              mk_case_absumprod ctor_rec_absT rep fs (map (map HOLogic.mk_tuple) xsss)
  1204              mk_case_absumprod ctor_rec_absT rep fs (map (map HOLogic.mk_tuple) xsss)
  1205                (map flat_rec_arg_args xsss))
  1205                (map flat_rec_arg_args xsss))
  1206            ctor_rec_absTs reps fss xssss)))
  1206            ctor_rec_absTs reps fss xssss)))
  1207   end;
  1207   end;
  1208 
  1208 
  1211     val nn = length fpTs;
  1211     val nn = length fpTs;
  1212     val fpT = range_type (snd (strip_typeN nn (fastype_of dtor_corec)));
  1212     val fpT = range_type (snd (strip_typeN nn (fastype_of dtor_corec)));
  1213   in
  1213   in
  1214     define_co_rec_as Greatest_FP Cs fpT (mk_binding corecN)
  1214     define_co_rec_as Greatest_FP Cs fpT (mk_binding corecN)
  1215       (fold_rev (fold_rev Term.lambda) pgss (Term.list_comb (dtor_corec,
  1215       (fold_rev (fold_rev Term.lambda) pgss (Term.list_comb (dtor_corec,
  1216          map5 mk_preds_getterss_join cs cpss f_absTs abss cqgsss)))
  1216          @{map 5} mk_preds_getterss_join cs cpss f_absTs abss cqgsss)))
  1217   end;
  1217   end;
  1218 
  1218 
  1219 fun postproc_co_induct lthy nn prop prop_conj =
  1219 fun postproc_co_induct lthy nn prop prop_conj =
  1220   Drule.zero_var_indexes
  1220   Drule.zero_var_indexes
  1221   #> `(conj_dests nn)
  1221   #> `(conj_dests nn)
  1254           fold_rev Logic.all (argAs @ argBs) (fold_rev (curry Logic.mk_implies)
  1254           fold_rev Logic.all (argAs @ argBs) (fold_rev (curry Logic.mk_implies)
  1255             (map2 (HOLogic.mk_Trueprop oo build_rel_app names_lthy (Rs @ IRs) fpA_Ts) argAs argBs)
  1255             (map2 (HOLogic.mk_Trueprop oo build_rel_app names_lthy (Rs @ IRs) fpA_Ts) argAs argBs)
  1256             (HOLogic.mk_Trueprop (build_rel_app names_lthy (Rs @ IRs) fpA_Ts
  1256             (HOLogic.mk_Trueprop (build_rel_app names_lthy (Rs @ IRs) fpA_Ts
  1257               (Term.list_comb (ctrA, argAs)) (Term.list_comb (ctrB, argBs)))));
  1257               (Term.list_comb (ctrA, argAs)) (Term.list_comb (ctrB, argBs)))));
  1258       in
  1258       in
  1259         flat (map4 (map4 mk_prem) ctrAss ctrBss ctrAsss ctrBsss)
  1259         flat (@{map 4} (@{map 4} mk_prem) ctrAss ctrBss ctrAsss ctrBsss)
  1260       end;
  1260       end;
  1261 
  1261 
  1262     val goal = HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj (map2 mk_leq
  1262     val goal = HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj (map2 mk_leq
  1263       (map2 (build_the_rel [] lthy (Rs @ IRs) []) fpA_Ts fpB_Ts) IRs));
  1263       (map2 (build_the_rel [] lthy (Rs @ IRs) []) fpA_Ts fpB_Ts) IRs));
  1264 
  1264 
  1352           in (xs, pprems, HOLogic.mk_Trueprop (phi $ Term.list_comb (ctr, xs))) end;
  1352           in (xs, pprems, HOLogic.mk_Trueprop (phi $ Term.list_comb (ctr, xs))) end;
  1353 
  1353 
  1354         fun mk_prem (xs, raw_pprems, concl) =
  1354         fun mk_prem (xs, raw_pprems, concl) =
  1355           fold_rev Logic.all xs (Logic.list_implies (map (mk_prem_prem xs) raw_pprems, concl));
  1355           fold_rev Logic.all xs (Logic.list_implies (map (mk_prem_prem xs) raw_pprems, concl));
  1356 
  1356 
  1357         val raw_premss = map4 (map3 o mk_raw_prem) ps ctrss ctr_Tsss ctrXs_Tsss;
  1357         val raw_premss = @{map 4} (@{map 3} o mk_raw_prem) ps ctrss ctr_Tsss ctrXs_Tsss;
  1358 
  1358 
  1359         val goal =
  1359         val goal =
  1360           Library.foldr (Logic.list_implies o apfst (map mk_prem)) (raw_premss,
  1360           Library.foldr (Logic.list_implies o apfst (map mk_prem)) (raw_premss,
  1361             HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj (map2 (curry (op $)) ps us)));
  1361             HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj (map2 (curry (op $)) ps us)));
  1362 
  1362 
  1400             in
  1400             in
  1401               build_map lthy [] build_simple (T, U) $ x
  1401               build_map lthy [] build_simple (T, U) $ x
  1402             end;
  1402             end;
  1403 
  1403 
  1404         val fxsss = map2 (map2 (flat_rec_arg_args oo map2 (map o build_rec))) xsss x_Tssss;
  1404         val fxsss = map2 (map2 (flat_rec_arg_args oo map2 (map o build_rec))) xsss x_Tssss;
  1405         val goalss = map5 (map4 o mk_goal) frecs xctrss fss xsss fxsss;
  1405         val goalss = @{map 5} (@{map 4} o mk_goal) frecs xctrss fss xsss fxsss;
  1406 
  1406 
  1407         val tacss = map4 (map ooo
  1407         val tacss = @{map 4} (map ooo
  1408               mk_rec_tac pre_map_defs (fp_nesting_map_ident0s @ live_nesting_map_ident0s) rec_defs)
  1408               mk_rec_tac pre_map_defs (fp_nesting_map_ident0s @ live_nesting_map_ident0s) rec_defs)
  1409             ctor_rec_thms fp_abs_inverses abs_inverses ctr_defss;
  1409             ctor_rec_thms fp_abs_inverses abs_inverses ctr_defss;
  1410 
  1410 
  1411         fun prove goal tac =
  1411         fun prove goal tac =
  1412           Goal.prove_sorry lthy [] [] goal (tac o #context)
  1412           Goal.prove_sorry lthy [] [] goal (tac o #context)
  1439         flat (map2 append disc_concls ctr_concls)
  1439         flat (map2 append disc_concls ctr_concls)
  1440       end;
  1440       end;
  1441 
  1441 
  1442     val coinduct_cases = quasi_unambiguous_case_names (map (prefix EqN) fp_b_names);
  1442     val coinduct_cases = quasi_unambiguous_case_names (map (prefix EqN) fp_b_names);
  1443     val coinduct_conclss =
  1443     val coinduct_conclss =
  1444       map3 (quasi_unambiguous_case_names ooo mk_coinduct_concls) mss discss ctrss;
  1444       @{map 3} (quasi_unambiguous_case_names ooo mk_coinduct_concls) mss discss ctrss;
  1445 
  1445 
  1446     val common_coinduct_consumes_attr = Attrib.internal (K (Rule_Cases.consumes nn));
  1446     val common_coinduct_consumes_attr = Attrib.internal (K (Rule_Cases.consumes nn));
  1447     val coinduct_consumes_attr = Attrib.internal (K (Rule_Cases.consumes 1));
  1447     val coinduct_consumes_attr = Attrib.internal (K (Rule_Cases.consumes 1));
  1448 
  1448 
  1449     val coinduct_case_names_attr = Attrib.internal (K (Rule_Cases.case_names coinduct_cases));
  1449     val coinduct_case_names_attr = Attrib.internal (K (Rule_Cases.case_names coinduct_cases));
  1504               (if n = 1 then [] else [discA_t, discB_t],
  1504               (if n = 1 then [] else [discA_t, discB_t],
  1505                Library.foldr1 HOLogic.mk_conj
  1505                Library.foldr1 HOLogic.mk_conj
  1506                  (map2 (build_rel_app lthy (Rs @ IRs) fpA_Ts) selA_ts selB_ts))]);
  1506                  (map2 (build_rel_app lthy (Rs @ IRs) fpA_Ts) selA_ts selB_ts))]);
  1507 
  1507 
  1508         fun mk_prem_concl n discA_ts selA_tss discB_ts selB_tss =
  1508         fun mk_prem_concl n discA_ts selA_tss discB_ts selB_tss =
  1509           Library.foldr1 HOLogic.mk_conj (flat (map5 (mk_prem_ctr_concls n)
  1509           Library.foldr1 HOLogic.mk_conj (flat (@{map 5} (mk_prem_ctr_concls n)
  1510             (1 upto n) discA_ts selA_tss discB_ts selB_tss))
  1510             (1 upto n) discA_ts selA_tss discB_ts selB_tss))
  1511           handle List.Empty => @{term True};
  1511           handle List.Empty => @{term True};
  1512 
  1512 
  1513         fun mk_prem IR tA tB n discA_ts selA_tss discB_ts selB_tss =
  1513         fun mk_prem IR tA tB n discA_ts selA_tss discB_ts selB_tss =
  1514           fold_rev Logic.all [tA, tB] (Logic.mk_implies (HOLogic.mk_Trueprop (IR $ tA $ tB),
  1514           fold_rev Logic.all [tA, tB] (Logic.mk_implies (HOLogic.mk_Trueprop (IR $ tA $ tB),
  1515             HOLogic.mk_Trueprop (mk_prem_concl n discA_ts selA_tss discB_ts selB_tss)));
  1515             HOLogic.mk_Trueprop (mk_prem_concl n discA_ts selA_tss discB_ts selB_tss)));
  1516       in
  1516       in
  1517         map8 mk_prem IRs fpAs fpBs ns discA_tss selA_tsss discB_tss selB_tsss
  1517         @{map 8} mk_prem IRs fpAs fpBs ns discA_tss selA_tsss discB_tss selB_tsss
  1518       end;
  1518       end;
  1519 
  1519 
  1520     val goal = HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj (map2 mk_leq
  1520     val goal = HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj (map2 mk_leq
  1521       IRs (map2 (build_the_rel [] lthy (Rs @ IRs) []) fpA_Ts fpB_Ts)));
  1521       IRs (map2 (build_the_rel [] lthy (Rs @ IRs) []) fpA_Ts fpB_Ts)));
  1522 
  1522 
  1630     corecs corec_defs export_args lthy =
  1630     corecs corec_defs export_args lthy =
  1631   let
  1631   let
  1632     fun mk_ctor_dtor_corec_thm dtor_inject dtor_ctor corec =
  1632     fun mk_ctor_dtor_corec_thm dtor_inject dtor_ctor corec =
  1633       iffD1 OF [dtor_inject, trans OF [corec, dtor_ctor RS sym]];
  1633       iffD1 OF [dtor_inject, trans OF [corec, dtor_ctor RS sym]];
  1634 
  1634 
  1635     val ctor_dtor_corec_thms = map3 mk_ctor_dtor_corec_thm dtor_injects dtor_ctors dtor_corec_thms;
  1635     val ctor_dtor_corec_thms =
       
  1636       @{map 3} mk_ctor_dtor_corec_thm dtor_injects dtor_ctors dtor_corec_thms;
  1636 
  1637 
  1637     val nn = length pre_bnfs;
  1638     val nn = length pre_bnfs;
  1638 
  1639 
  1639     val pre_map_defs = map map_def_of_bnf pre_bnfs;
  1640     val pre_map_defs = map map_def_of_bnf pre_bnfs;
  1640     val pre_rel_defs = map rel_def_of_bnf pre_bnfs;
  1641     val pre_rel_defs = map rel_def_of_bnf pre_bnfs;
  1665     val vdiscss = map2 (map o rapp) vs discss;
  1666     val vdiscss = map2 (map o rapp) vs discss;
  1666     val vselsss = map2 (map o map o rapp) vs selsss;
  1667     val vselsss = map2 (map o map o rapp) vs selsss;
  1667 
  1668 
  1668     val coinduct_thms_pairs =
  1669     val coinduct_thms_pairs =
  1669       let
  1670       let
  1670         val uvrs = map3 (fn r => fn u => fn v => r $ u $ v) rs us vs;
  1671         val uvrs = @{map 3} (fn r => fn u => fn v => r $ u $ v) rs us vs;
  1671         val uv_eqs = map2 (curry HOLogic.mk_eq) us vs;
  1672         val uv_eqs = map2 (curry HOLogic.mk_eq) us vs;
  1672         val strong_rs =
  1673         val strong_rs =
  1673           map4 (fn u => fn v => fn uvr => fn uv_eq =>
  1674           @{map 4} (fn u => fn v => fn uvr => fn uv_eq =>
  1674             fold_rev Term.lambda [u, v] (HOLogic.mk_disj (uvr, uv_eq))) us vs uvrs uv_eqs;
  1675             fold_rev Term.lambda [u, v] (HOLogic.mk_disj (uvr, uv_eq))) us vs uvrs uv_eqs;
  1675 
  1676 
  1676         fun build_the_rel rs' T Xs_T =
  1677         fun build_the_rel rs' T Xs_T =
  1677           build_rel [] lthy [] (fn (_, X) => nth rs' (find_index (curry (op =) X) Xs)) (T, Xs_T)
  1678           build_rel [] lthy [] (fn (_, X) => nth rs' (find_index (curry (op =) X) Xs)) (T, Xs_T)
  1678           |> Term.subst_atomic_types (Xs ~~ fpTs);
  1679           |> Term.subst_atomic_types (Xs ~~ fpTs);
  1684           (if k = n then [] else [HOLogic.mk_eq (udisc, vdisc)]) @
  1685           (if k = n then [] else [HOLogic.mk_eq (udisc, vdisc)]) @
  1685           (if null usels then
  1686           (if null usels then
  1686              []
  1687              []
  1687            else
  1688            else
  1688              [Library.foldr HOLogic.mk_imp (if n = 1 then [] else [udisc, vdisc],
  1689              [Library.foldr HOLogic.mk_imp (if n = 1 then [] else [udisc, vdisc],
  1689                 Library.foldr1 HOLogic.mk_conj (map3 (build_rel_app rs') usels vsels ctrXs_Ts))]);
  1690                 Library.foldr1 HOLogic.mk_conj (@{map 3} (build_rel_app rs') usels vsels ctrXs_Ts))]);
  1690 
  1691 
  1691         fun mk_prem_concl rs' n udiscs uselss vdiscs vselss ctrXs_Tss =
  1692         fun mk_prem_concl rs' n udiscs uselss vdiscs vselss ctrXs_Tss =
  1692           Library.foldr1 HOLogic.mk_conj (flat (map6 (mk_prem_ctr_concls rs' n)
  1693           Library.foldr1 HOLogic.mk_conj (flat (@{map 6} (mk_prem_ctr_concls rs' n)
  1693             (1 upto n) udiscs uselss vdiscs vselss ctrXs_Tss))
  1694             (1 upto n) udiscs uselss vdiscs vselss ctrXs_Tss))
  1694           handle List.Empty => @{term True};
  1695           handle List.Empty => @{term True};
  1695 
  1696 
  1696         fun mk_prem rs' uvr u v n udiscs uselss vdiscs vselss ctrXs_Tss =
  1697         fun mk_prem rs' uvr u v n udiscs uselss vdiscs vselss ctrXs_Tss =
  1697           fold_rev Logic.all [u, v] (Logic.mk_implies (HOLogic.mk_Trueprop uvr,
  1698           fold_rev Logic.all [u, v] (Logic.mk_implies (HOLogic.mk_Trueprop uvr,
  1698             HOLogic.mk_Trueprop (mk_prem_concl rs' n udiscs uselss vdiscs vselss ctrXs_Tss)));
  1699             HOLogic.mk_Trueprop (mk_prem_concl rs' n udiscs uselss vdiscs vselss ctrXs_Tss)));
  1699 
  1700 
  1700         val concl =
  1701         val concl =
  1701           HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
  1702           HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
  1702             (map3 (fn uvr => fn u => fn v => HOLogic.mk_imp (uvr, HOLogic.mk_eq (u, v)))
  1703             (@{map 3} (fn uvr => fn u => fn v => HOLogic.mk_imp (uvr, HOLogic.mk_eq (u, v)))
  1703                uvrs us vs));
  1704                uvrs us vs));
  1704 
  1705 
  1705         fun mk_goal rs' =
  1706         fun mk_goal rs' =
  1706           Logic.list_implies (map9 (mk_prem rs') uvrs us vs ns udiscss uselsss vdiscss vselsss
  1707           Logic.list_implies (@{map 9} (mk_prem rs') uvrs us vs ns udiscss uselsss vdiscss vselsss
  1707             ctrXs_Tsss, concl);
  1708             ctrXs_Tsss, concl);
  1708 
  1709 
  1709         val goals = map mk_goal [rs, strong_rs];
  1710         val goals = map mk_goal [rs, strong_rs];
  1710 
  1711 
  1711         fun prove dtor_coinduct' goal =
  1712         fun prove dtor_coinduct' goal =
  1755             else
  1756             else
  1756               cqg
  1757               cqg
  1757           end;
  1758           end;
  1758 
  1759 
  1759         val cqgsss' = map (map (map build_corec)) cqgsss;
  1760         val cqgsss' = map (map (map build_corec)) cqgsss;
  1760         val goalss = map8 (map4 oooo mk_goal) cs cpss gcorecs ns kss ctrss mss cqgsss';
  1761         val goalss = @{map 8} (@{map 4} oooo mk_goal) cs cpss gcorecs ns kss ctrss mss cqgsss';
  1761 
  1762 
  1762         val tacss =
  1763         val tacss =
  1763           map4 (map ooo mk_corec_tac corec_defs live_nesting_map_ident0s)
  1764           @{map 4} (map ooo mk_corec_tac corec_defs live_nesting_map_ident0s)
  1764             ctor_dtor_corec_thms pre_map_defs abs_inverses ctr_defss;
  1765             ctor_dtor_corec_thms pre_map_defs abs_inverses ctr_defss;
  1765 
  1766 
  1766         fun prove goal tac =
  1767         fun prove goal tac =
  1767           Goal.prove_sorry lthy [] [] goal (tac o #context)
  1768           Goal.prove_sorry lthy [] [] goal (tac o #context)
  1768           |> Thm.close_derivation;
  1769           |> Thm.close_derivation;
  1776         fun mk_goal c cps gcorec n k disc =
  1777         fun mk_goal c cps gcorec n k disc =
  1777           mk_Trueprop_eq (disc $ (gcorec $ c),
  1778           mk_Trueprop_eq (disc $ (gcorec $ c),
  1778             if n = 1 then @{const True}
  1779             if n = 1 then @{const True}
  1779             else Library.foldr1 HOLogic.mk_conj (seq_conds mk_maybe_not n k cps));
  1780             else Library.foldr1 HOLogic.mk_conj (seq_conds mk_maybe_not n k cps));
  1780 
  1781 
  1781         val goalss = map6 (map2 oooo mk_goal) cs cpss gcorecs ns kss discss;
  1782         val goalss = @{map 6} (map2 oooo mk_goal) cs cpss gcorecs ns kss discss;
  1782 
  1783 
  1783         fun mk_case_split' cp = Drule.instantiate' [] [SOME (certify lthy cp)] @{thm case_split};
  1784         fun mk_case_split' cp = Drule.instantiate' [] [SOME (certify lthy cp)] @{thm case_split};
  1784 
  1785 
  1785         val case_splitss' = map (map mk_case_split') cpss;
  1786         val case_splitss' = map (map mk_case_split') cpss;
  1786 
  1787 
  1787         val tacss = map3 (map oo mk_corec_disc_iff_tac) case_splitss' corec_thmss disc_thmsss;
  1788         val tacss = @{map 3} (map oo mk_corec_disc_iff_tac) case_splitss' corec_thmss disc_thmsss;
  1788 
  1789 
  1789         fun prove goal tac =
  1790         fun prove goal tac =
  1790           Goal.prove_sorry lthy [] [] goal (tac o #context)
  1791           Goal.prove_sorry lthy [] [] goal (tac o #context)
  1791           |> singleton export_args
  1792           |> singleton export_args
  1792           |> singleton (Proof_Context.export names_lthy lthy)
  1793           |> singleton (Proof_Context.export names_lthy lthy)
  1813       in
  1814       in
  1814         corec_thm RS arg_cong' RS sel_thm'
  1815         corec_thm RS arg_cong' RS sel_thm'
  1815       end;
  1816       end;
  1816 
  1817 
  1817     fun mk_corec_sel_thms corec_thmss =
  1818     fun mk_corec_sel_thms corec_thmss =
  1818       map3 (map3 (map2 o mk_corec_sel_thm)) corec_thmss selsss sel_thmsss;
  1819       @{map 3} (@{map 3} (map2 o mk_corec_sel_thm)) corec_thmss selsss sel_thmsss;
  1819 
  1820 
  1820     val corec_sel_thmsss = mk_corec_sel_thms corec_thmss;
  1821     val corec_sel_thmsss = mk_corec_sel_thms corec_thmss;
  1821   in
  1822   in
  1822     ((coinduct_thms_pairs,
  1823     ((coinduct_thms_pairs,
  1823       mk_coinduct_attrs fpTs (map #ctrs ctr_sugars) (map #discs ctr_sugars) mss),
  1824       mk_coinduct_attrs fpTs (map #ctrs ctr_sugars) (map #discs ctr_sugars) mss),
  1995         warning "Map function and relator names ignored"
  1996         warning "Map function and relator names ignored"
  1996       else
  1997       else
  1997         ();
  1998         ();
  1998 
  1999 
  1999     val Bs =
  2000     val Bs =
  2000       map3 (fn alive => fn A as TFree (_, S) => fn B =>
  2001       @{map 3} (fn alive => fn A as TFree (_, S) => fn B =>
  2001           if alive then resort_tfree_or_tvar S B else A)
  2002           if alive then resort_tfree_or_tvar S B else A)
  2002         (liveness_of_fp_bnf num_As any_fp_bnf) As Bs0;
  2003         (liveness_of_fp_bnf num_As any_fp_bnf) As Bs0;
  2003 
  2004 
  2004     val B_ify_T = Term.typ_subst_atomic (As ~~ Bs);
  2005     val B_ify_T = Term.typ_subst_atomic (As ~~ Bs);
  2005 
  2006 
  2042 
  2043 
  2043         val maybe_conceal_def_binding = Thm.def_binding
  2044         val maybe_conceal_def_binding = Thm.def_binding
  2044           #> not (Config.get no_defs_lthy bnf_note_all) ? Binding.conceal;
  2045           #> not (Config.get no_defs_lthy bnf_note_all) ? Binding.conceal;
  2045 
  2046 
  2046         val ((raw_ctrs, raw_ctr_defs), (lthy', lthy)) = no_defs_lthy
  2047         val ((raw_ctrs, raw_ctr_defs), (lthy', lthy)) = no_defs_lthy
  2047           |> apfst split_list o fold_map3 (fn b => fn mx => fn rhs =>
  2048           |> apfst split_list o @{fold_map 3} (fn b => fn mx => fn rhs =>
  2048               Local_Theory.define ((b, mx), ((maybe_conceal_def_binding b, []), rhs)) #>> apsnd snd)
  2049               Local_Theory.define ((b, mx), ((maybe_conceal_def_binding b, []), rhs)) #>> apsnd snd)
  2049             ctr_bindings ctr_mixfixes ctr_rhss
  2050             ctr_bindings ctr_mixfixes ctr_rhss
  2050           ||> `Local_Theory.restore;
  2051           ||> `Local_Theory.restore;
  2051 
  2052 
  2052         val phi = Proof_Context.export_morphism lthy lthy';
  2053         val phi = Proof_Context.export_morphism lthy lthy';
  2101             val sel_default_lthy = fake_local_theory_for_sel_defaults sel_bTs lthy;
  2102             val sel_default_lthy = fake_local_theory_for_sel_defaults sel_bTs lthy;
  2102 
  2103 
  2103             val sel_default_eqs = map (prepare_term sel_default_lthy) raw_sel_default_eqs;
  2104             val sel_default_eqs = map (prepare_term sel_default_lthy) raw_sel_default_eqs;
  2104 
  2105 
  2105             fun ctr_spec_of disc_b ctr0 sel_bs = ((disc_b, ctr0), sel_bs);
  2106             fun ctr_spec_of disc_b ctr0 sel_bs = ((disc_b, ctr0), sel_bs);
  2106             val ctr_specs = map3 ctr_spec_of disc_bindings ctrs0 sel_bindingss;
  2107             val ctr_specs = @{map 3} ctr_spec_of disc_bindings ctrs0 sel_bindingss;
  2107 
  2108 
  2108             val (ctr_sugar as {case_cong, ...}, lthy') =
  2109             val (ctr_sugar as {case_cong, ...}, lthy') =
  2109               free_constructors tacss ((((plugins, discs_sels), standard_binding), ctr_specs),
  2110               free_constructors tacss ((((plugins, discs_sels), standard_binding), ctr_specs),
  2110                 sel_default_eqs) lthy
  2111                 sel_default_eqs) lthy
  2111 
  2112 
  2134          #> massage_res, lthy')
  2135          #> massage_res, lthy')
  2135       end;
  2136       end;
  2136 
  2137 
  2137     fun wrap_ctrs_derive_map_set_rel_thms_define_co_rec_for_types (wrap_one_etc, lthy) =
  2138     fun wrap_ctrs_derive_map_set_rel_thms_define_co_rec_for_types (wrap_one_etc, lthy) =
  2138       fold_map I wrap_one_etc lthy
  2139       fold_map I wrap_one_etc lthy
  2139       |>> apsnd split_list o apfst (apsnd split_list4 o apfst split_list15 o split_list)
  2140       |>> apsnd split_list o apfst (apsnd @{split_list 4} o apfst @{split_list 15} o split_list)
  2140         o split_list;
  2141         o split_list;
  2141 
  2142 
  2142     fun mk_simp_thms ({injects, distincts, case_thms, ...} : ctr_sugar) co_recs map_thms rel_injects
  2143     fun mk_simp_thms ({injects, distincts, case_thms, ...} : ctr_sugar) co_recs map_thms rel_injects
  2143         rel_distincts set_thmss =
  2144         rel_distincts set_thmss =
  2144       injects @ distincts @ case_thms @ co_recs @ map_thms @ rel_injects @ rel_distincts @
  2145       injects @ distincts @ case_thms @ co_recs @ map_thms @ rel_injects @ rel_distincts @
  2202               ((map single rel_induct_thms, single common_rel_induct_thm),
  2203               ((map single rel_induct_thms, single common_rel_induct_thm),
  2203                (rel_induct_attrs, rel_induct_attrs))
  2204                (rel_induct_attrs, rel_induct_attrs))
  2204             end;
  2205             end;
  2205 
  2206 
  2206         val simp_thmss =
  2207         val simp_thmss =
  2207           map6 mk_simp_thms ctr_sugars rec_thmss map_thmss rel_injectss rel_distinctss set_thmss;
  2208           @{map 6} mk_simp_thms ctr_sugars rec_thmss map_thmss rel_injectss rel_distinctss set_thmss;
  2208 
  2209 
  2209         val common_notes =
  2210         val common_notes =
  2210           (if nn > 1 then
  2211           (if nn > 1 then
  2211              [(inductN, [induct_thm], K induct_attrs),
  2212              [(inductN, [induct_thm], K induct_attrs),
  2212               (rel_inductN, common_rel_induct_thms, K common_rel_induct_attrs)]
  2213               (rel_inductN, common_rel_induct_thms, K common_rel_induct_attrs)]
  2313             (map #exhaust ctr_sugars) (flat pre_set_defss) (flat ctr_defss)
  2314             (map #exhaust ctr_sugars) (flat pre_set_defss) (flat ctr_defss)
  2314             dtor_ctors abs_inverses
  2315             dtor_ctors abs_inverses
  2315           |> split_list;
  2316           |> split_list;
  2316 
  2317 
  2317         val simp_thmss =
  2318         val simp_thmss =
  2318           map6 mk_simp_thms ctr_sugars
  2319           @{map 6} mk_simp_thms ctr_sugars
  2319             (map3 flat_corec_thms corec_disc_thmss corec_disc_iff_thmss corec_sel_thmss)
  2320             (@{map 3} flat_corec_thms corec_disc_thmss corec_disc_iff_thmss corec_sel_thmss)
  2320             map_thmss rel_injectss rel_distinctss set_thmss;
  2321             map_thmss rel_injectss rel_distinctss set_thmss;
  2321 
  2322 
  2322         val common_notes =
  2323         val common_notes =
  2323           (set_inductN, set_induct_thms, nth set_induct_attrss) ::
  2324           (set_inductN, set_induct_thms, nth set_induct_attrss) ::
  2324           (if nn > 1 then
  2325           (if nn > 1 then