src/HOL/Tools/BNF/bnf_fp_def_sugar.ML
changeset 57471 11cd462e31ec
parent 57399 cfc19f0a6261
child 57489 8f0ba9f2d10f
equal deleted inserted replaced
57455:d3eac6fd0bd6 57471:11cd462e31ec
   241 fun merge_type_arg fp T T' = if T = T' then T else cannot_merge_types fp;
   241 fun merge_type_arg fp T T' = if T = T' then T else cannot_merge_types fp;
   242 
   242 
   243 fun merge_type_args fp (As, As') =
   243 fun merge_type_args fp (As, As') =
   244   if length As = length As' then map2 (merge_type_arg fp) As As' else cannot_merge_types fp;
   244   if length As = length As' then map2 (merge_type_arg fp) As As' else cannot_merge_types fp;
   245 
   245 
   246 fun reassoc_conjs thm =
       
   247   reassoc_conjs (thm RS @{thm conj_assoc[THEN iffD1]})
       
   248   handle THM _ => thm;
       
   249 
       
   250 fun type_args_named_constrained_of_spec (((((ncAs, _), _), _), _), _) = ncAs;
   246 fun type_args_named_constrained_of_spec (((((ncAs, _), _), _), _), _) = ncAs;
   251 fun type_binding_of_spec (((((_, b), _), _), _), _) = b;
   247 fun type_binding_of_spec (((((_, b), _), _), _), _) = b;
   252 fun mixfix_of_spec ((((_, mx), _), _), _) = mx;
   248 fun mixfix_of_spec ((((_, mx), _), _), _) = mx;
   253 fun mixfixed_ctr_specs_of_spec (((_, mx_ctr_specs), _), _) = mx_ctr_specs;
   249 fun mixfixed_ctr_specs_of_spec (((_, mx_ctr_specs), _), _) = mx_ctr_specs;
   254 fun map_binding_of_spec ((_, (b, _)), _) = b;
   250 fun map_binding_of_spec ((_, (b, _)), _) = b;
   440     val fpT = range_type (snd (strip_typeN nn (fastype_of dtor_corec)));
   436     val fpT = range_type (snd (strip_typeN nn (fastype_of dtor_corec)));
   441   in
   437   in
   442     define_co_rec Greatest_FP fpT Cs (mk_binding corecN)
   438     define_co_rec Greatest_FP fpT Cs (mk_binding corecN)
   443       (fold_rev (fold_rev Term.lambda) pgss (Term.list_comb (dtor_corec,
   439       (fold_rev (fold_rev Term.lambda) pgss (Term.list_comb (dtor_corec,
   444          map5 mk_preds_getterss_join cs cpss f_absTs abss cqgsss)))
   440          map5 mk_preds_getterss_join cs cpss f_absTs abss cqgsss)))
       
   441   end;
       
   442 
       
   443 fun postproc_co_induct lthy nn prop prop_conj =
       
   444   Drule.zero_var_indexes
       
   445   #> `(conj_dests nn)
       
   446   #>> map (fn thm => Thm.permute_prems 0 (~1) (thm RS prop))
       
   447   ##> (fn thm => Thm.permute_prems 0 (~nn)
       
   448     (if nn = 1 then thm RS prop
       
   449      else funpow nn (fn thm => Local_Defs.unfold lthy @{thms conj_assoc} (thm RS prop_conj)) thm));
       
   450 
       
   451 fun mk_induct_attrs ctrss =
       
   452   let
       
   453     val induct_cases = quasi_unambiguous_case_names (maps (map name_of_ctr) ctrss);
       
   454     val induct_case_names_attr = Attrib.internal (K (Rule_Cases.case_names induct_cases));
       
   455   in
       
   456     [induct_case_names_attr]
       
   457   end;
       
   458 
       
   459 fun derive_rel_induct_thm_for_types lthy fpA_Ts ns As Bs mss ctrAss ctrAs_Tsss ctr_sugars
       
   460     ctor_rel_induct ctor_defss ctor_injects pre_rel_defs abs_inverses live_nesting_rel_eqs =
       
   461   let
       
   462     val B_ify = typ_subst_nonatomic (As ~~ Bs)
       
   463     val fpB_Ts = map B_ify fpA_Ts;
       
   464     val ctrBs_Tsss = map (map (map B_ify)) ctrAs_Tsss;
       
   465     val ctrBss = map (map (subst_nonatomic_types (As ~~ Bs))) ctrAss;
       
   466 
       
   467     val ((((Rs, IRs), ctrAsss), ctrBsss), names_lthy) = lthy
       
   468       |> mk_Frees "R" (map2 mk_pred2T As Bs)
       
   469       ||>> mk_Frees "IR" (map2 mk_pred2T fpA_Ts fpB_Ts)
       
   470       ||>> mk_Freesss "a" ctrAs_Tsss
       
   471       ||>> mk_Freesss "b" ctrBs_Tsss;
       
   472 
       
   473     fun choose_relator AB = the (find_first
       
   474       (fastype_of #> binder_types #> (fn [T1, T2] => AB = (T1, T2))) (Rs @ IRs));
       
   475 
       
   476     val premises =
       
   477       let
       
   478         fun build_the_rel A B = build_rel lthy fpA_Ts choose_relator (A, B);
       
   479         fun build_rel_app a b = build_the_rel (fastype_of a) (fastype_of b) $ a $ b;
       
   480 
       
   481         fun mk_prem ctrA ctrB argAs argBs =
       
   482           fold_rev Logic.all (argAs @ argBs) (fold_rev (curry Logic.mk_implies)
       
   483             (map2 (HOLogic.mk_Trueprop oo build_rel_app) argAs argBs)
       
   484             (HOLogic.mk_Trueprop
       
   485               (build_rel_app (Term.list_comb (ctrA, argAs)) (Term.list_comb (ctrB, argBs)))));
       
   486       in
       
   487         flat (map4 (map4 mk_prem) ctrAss ctrBss ctrAsss ctrBsss)
       
   488       end;
       
   489 
       
   490     val goal = HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
       
   491       (map2 mk_leq (map (build_rel lthy [] choose_relator) (fpA_Ts ~~ fpB_Ts)) IRs));
       
   492 
       
   493     val rel_induct0_thm = Goal.prove_sorry lthy [] premises goal
       
   494       (fn {context = ctxt, prems = prems} =>
       
   495           mk_rel_induct0_tac ctxt ctor_rel_induct prems (map (certify ctxt) IRs)
       
   496             (map #exhaust ctr_sugars) ctor_defss ctor_injects pre_rel_defs abs_inverses
       
   497             live_nesting_rel_eqs)
       
   498       |> singleton (Proof_Context.export names_lthy lthy)
       
   499       |> Thm.close_derivation;
       
   500   in
       
   501     (postproc_co_induct lthy (length fpA_Ts) @{thm predicate2D} @{thm predicate2D_conj}
       
   502        rel_induct0_thm,
       
   503      mk_induct_attrs ctrAss)
   445   end;
   504   end;
   446 
   505 
   447 fun derive_induct_recs_thms_for_types pre_bnfs rec_args_typess ctor_induct ctor_rec_thms
   506 fun derive_induct_recs_thms_for_types pre_bnfs rec_args_typess ctor_induct ctor_rec_thms
   448     live_nesting_bnfs fp_nesting_bnfs fpTs Cs Xs ctrXs_Tsss fp_abs_inverses fp_type_definitions
   507     live_nesting_bnfs fp_nesting_bnfs fpTs Cs Xs ctrXs_Tsss fp_abs_inverses fp_type_definitions
   449     abs_inverses ctrss ctr_defss recs rec_defs lthy =
   508     abs_inverses ctrss ctr_defss recs rec_defs lthy =
   550             inductN);
   609             inductN);
   551       in
   610       in
   552         `(conj_dests nn) thm
   611         `(conj_dests nn) thm
   553       end;
   612       end;
   554 
   613 
   555     val induct_cases = quasi_unambiguous_case_names (maps (map name_of_ctr) ctrss);
       
   556     val induct_case_names_attr = Attrib.internal (K (Rule_Cases.case_names induct_cases));
       
   557 
       
   558     val xctrss = map2 (map2 (curry Term.list_comb)) ctrss xsss;
   614     val xctrss = map2 (map2 (curry Term.list_comb)) ctrss xsss;
   559 
   615 
   560     fun mk_rec_thmss (_, x_Tssss, fss, _) recs rec_defs ctor_rec_thms =
   616     fun mk_rec_thmss (_, x_Tssss, fss, _) recs rec_defs ctor_rec_thms =
   561       let
   617       let
   562         val frecs = map (lists_bmoc fss) recs;
   618         val frecs = map (lists_bmoc fss) recs;
   592         map2 (map2 prove) goalss tacss
   648         map2 (map2 prove) goalss tacss
   593       end;
   649       end;
   594 
   650 
   595     val rec_thmss = mk_rec_thmss (the rec_args_typess) recs rec_defs ctor_rec_thms;
   651     val rec_thmss = mk_rec_thmss (the rec_args_typess) recs rec_defs ctor_rec_thms;
   596   in
   652   in
   597     ((induct_thms, induct_thm, [induct_case_names_attr]),
   653     ((induct_thms, induct_thm, mk_induct_attrs ctrss),
   598      (rec_thmss, code_nitpicksimp_attrs @ simp_attrs))
   654      (rec_thmss, code_nitpicksimp_attrs @ simp_attrs))
   599   end;
   655   end;
   600 
   656 
   601 fun coinduct_attrs fpTs ctr_sugars mss =
   657 fun mk_coinduct_attrs fpTs ctr_sugars mss =
   602   let
   658   let
   603     val nn = length fpTs;
   659     val nn = length fpTs;
   604     val fp_b_names = map base_name_of_typ fpTs;
   660     val fp_b_names = map base_name_of_typ fpTs;
   605     val ctrss = map #ctrs ctr_sugars;
   661     val ctrss = map #ctrs ctr_sugars;
   606     val discss = map #discs ctr_sugars;
   662     val discss = map #discs ctr_sugars;
   633       coinduct_consumes_attr :: coinduct_case_names_attr :: coinduct_case_concl_attrs;
   689       coinduct_consumes_attr :: coinduct_case_names_attr :: coinduct_case_concl_attrs;
   634   in
   690   in
   635     (coinduct_attrs, common_coinduct_attrs)
   691     (coinduct_attrs, common_coinduct_attrs)
   636   end;
   692   end;
   637 
   693 
   638 fun postproc_coinduct nn prop prop_conj =
   694 fun derive_rel_coinduct_thm_for_types lthy fpA_Ts ns As Bs mss ctr_sugars abs_inverses abs_injects
   639   Drule.zero_var_indexes
   695   ctor_injects dtor_ctors rel_pre_defs ctor_defss dtor_rel_coinduct live_nesting_rel_eqs =
   640   #> `(conj_dests nn)
       
   641   #>> map (fn thm => Thm.permute_prems 0 nn (thm RS prop))
       
   642   ##> (fn thm => Thm.permute_prems 0 nn
       
   643     (if nn = 1 then thm RS prop
       
   644      else funpow nn (fn thm => reassoc_conjs (thm RS prop_conj)) thm));
       
   645 
       
   646 fun derive_rel_coinduct0_thm_for_types lthy fpA_Ts ns As Bs mss ctr_sugars abs_inverses abs_injects
       
   647   ctor_injects dtor_ctors rel_pre_defs ctor_defss dtor_rel_coinduct =
       
   648   let
   696   let
   649     val fpB_Ts = map (typ_subst_nonatomic (As ~~ Bs)) fpA_Ts;
   697     val fpB_Ts = map (typ_subst_nonatomic (As ~~ Bs)) fpA_Ts;
   650 
   698 
   651     val (Rs, IRs, fpAs, fpBs, names_lthy) =
   699     val (Rs, IRs, fpAs, fpBs, names_lthy) =
   652       let
   700       let
   711     val rel_coinduct0_thm = Goal.prove_sorry lthy [] premises goal
   759     val rel_coinduct0_thm = Goal.prove_sorry lthy [] premises goal
   712       (fn {context = ctxt, prems = prems} =>
   760       (fn {context = ctxt, prems = prems} =>
   713           mk_rel_coinduct0_tac ctxt dtor_rel_coinduct (map (certify ctxt) IRs) prems
   761           mk_rel_coinduct0_tac ctxt dtor_rel_coinduct (map (certify ctxt) IRs) prems
   714             (map #exhaust ctr_sugars) (map (flat o #disc_thmss) ctr_sugars)
   762             (map #exhaust ctr_sugars) (map (flat o #disc_thmss) ctr_sugars)
   715             (map (flat o #sel_thmss) ctr_sugars) ctor_defss dtor_ctors ctor_injects abs_injects
   763             (map (flat o #sel_thmss) ctr_sugars) ctor_defss dtor_ctors ctor_injects abs_injects
   716             rel_pre_defs abs_inverses)
   764             rel_pre_defs abs_inverses live_nesting_rel_eqs)
   717       |> singleton (Proof_Context.export names_lthy lthy)
   765       |> singleton (Proof_Context.export names_lthy lthy)
   718       |> Thm.close_derivation;
   766       |> Thm.close_derivation;
   719   in
   767   in
   720     (postproc_coinduct (length fpA_Ts) @{thm predicate2D} @{thm predicate2D_conj} rel_coinduct0_thm,
   768     (postproc_co_induct lthy (length fpA_Ts) @{thm predicate2D} @{thm predicate2D_conj}
   721      coinduct_attrs fpA_Ts ctr_sugars mss)
   769        rel_coinduct0_thm,
       
   770      mk_coinduct_attrs fpA_Ts ctr_sugars mss)
   722   end;
   771   end;
   723 
   772 
   724 fun derive_coinduct_corecs_thms_for_types pre_bnfs (x, cs, cpss, ((pgss, cqgsss), _))
   773 fun derive_coinduct_corecs_thms_for_types pre_bnfs (x, cs, cpss, ((pgss, cqgsss), _))
   725     dtor_coinduct dtor_injects dtor_ctors dtor_corec_thms live_nesting_bnfs fpTs Cs Xs ctrXs_Tsss
   774     dtor_coinduct dtor_injects dtor_ctors dtor_corec_thms live_nesting_bnfs fpTs Cs Xs ctrXs_Tsss
   726     kss mss ns fp_abs_inverses abs_inverses mk_vimage2p ctr_defss (ctr_sugars : ctr_sugar list)
   775     kss mss ns fp_abs_inverses abs_inverses mk_vimage2p ctr_defss (ctr_sugars : ctr_sugar list)
   815         val rel_eqs = map rel_eq_of_bnf pre_bnfs;
   864         val rel_eqs = map rel_eq_of_bnf pre_bnfs;
   816         val rel_monos = map rel_mono_of_bnf pre_bnfs;
   865         val rel_monos = map rel_mono_of_bnf pre_bnfs;
   817         val dtor_coinducts =
   866         val dtor_coinducts =
   818           [dtor_coinduct, mk_strong_coinduct_thm dtor_coinduct rel_eqs rel_monos mk_vimage2p lthy]
   867           [dtor_coinduct, mk_strong_coinduct_thm dtor_coinduct rel_eqs rel_monos mk_vimage2p lthy]
   819       in
   868       in
   820         map2 (postproc_coinduct nn mp mp_conj oo prove) dtor_coinducts goals
   869         map2 (postproc_co_induct lthy nn mp mp_conj oo prove) dtor_coinducts goals
   821       end;
   870       end;
   822 
   871 
   823     fun mk_maybe_not pos = not pos ? HOLogic.mk_not;
   872     fun mk_maybe_not pos = not pos ? HOLogic.mk_not;
   824 
   873 
   825     val gcorecs = map (lists_bmoc pgss) corecs;
   874     val gcorecs = map (lists_bmoc pgss) corecs;
   910     fun mk_sel_corec_thms corec_thmss =
   959     fun mk_sel_corec_thms corec_thmss =
   911       map3 (map3 (map2 o mk_sel_corec_thm)) corec_thmss selsss sel_thmsss;
   960       map3 (map3 (map2 o mk_sel_corec_thm)) corec_thmss selsss sel_thmsss;
   912 
   961 
   913     val sel_corec_thmsss = mk_sel_corec_thms corec_thmss;
   962     val sel_corec_thmsss = mk_sel_corec_thms corec_thmss;
   914   in
   963   in
   915     ((coinduct_thms_pairs, coinduct_attrs fpTs ctr_sugars mss),
   964     ((coinduct_thms_pairs, mk_coinduct_attrs fpTs ctr_sugars mss),
   916      (corec_thmss, code_nitpicksimp_attrs),
   965      (corec_thmss, code_nitpicksimp_attrs),
   917      (disc_corec_thmss, []),
   966      (disc_corec_thmss, []),
   918      (disc_corec_iff_thmss, simp_attrs),
   967      (disc_corec_iff_thmss, simp_attrs),
   919      (sel_corec_thmsss, simp_attrs))
   968      (sel_corec_thmsss, simp_attrs))
   920   end;
   969   end;
  1529           derive_induct_recs_thms_for_types pre_bnfs recs_args_types xtor_co_induct xtor_co_rec_thms
  1578           derive_induct_recs_thms_for_types pre_bnfs recs_args_types xtor_co_induct xtor_co_rec_thms
  1530             live_nesting_bnfs fp_nesting_bnfs fpTs Cs Xs ctrXs_Tsss abs_inverses type_definitions
  1579             live_nesting_bnfs fp_nesting_bnfs fpTs Cs Xs ctrXs_Tsss abs_inverses type_definitions
  1531             abs_inverses ctrss ctr_defss recs rec_defs lthy;
  1580             abs_inverses ctrss ctr_defss recs rec_defs lthy;
  1532 
  1581 
  1533         val induct_type_attr = Attrib.internal o K o Induct.induct_type;
  1582         val induct_type_attr = Attrib.internal o K o Induct.induct_type;
       
  1583         val induct_pred_attr = Attrib.internal o K o Induct.induct_pred;
       
  1584 
       
  1585         val ((rel_induct_thmss, common_rel_induct_thms),
       
  1586              (rel_induct_attrs, common_rel_induct_attrs)) =
       
  1587           if live = 0 then
       
  1588             ((replicate nn [], []), ([], []))
       
  1589           else
       
  1590             let
       
  1591               val ((rel_induct_thms, common_rel_induct_thm), rel_induct_attrs) =
       
  1592                 derive_rel_induct_thm_for_types lthy fpTs ns As Bs mss ctrss ctr_Tsss ctr_sugars
       
  1593                   rel_xtor_co_induct_thm ctr_defss ctor_injects pre_rel_defs abs_inverses
       
  1594                   (map rel_eq_of_bnf live_nesting_bnfs);
       
  1595             in
       
  1596               ((map single rel_induct_thms, single common_rel_induct_thm),
       
  1597                (rel_induct_attrs, rel_induct_attrs))
       
  1598             end;
  1534 
  1599 
  1535         val simp_thmss =
  1600         val simp_thmss =
  1536           map6 mk_simp_thms ctr_sugars rec_thmss mapss rel_injectss rel_distinctss setss;
  1601           map6 mk_simp_thms ctr_sugars rec_thmss mapss rel_injectss rel_distinctss setss;
  1537 
  1602 
  1538         val common_notes =
  1603         val common_notes =
  1539           (if nn > 1 then [(inductN, [induct_thm], induct_attrs)] else [])
  1604           (if nn > 1 then
       
  1605              [(inductN, [induct_thm], induct_attrs),
       
  1606               (rel_inductN, common_rel_induct_thms, common_rel_induct_attrs)]
       
  1607            else [])
  1540           |> massage_simple_notes fp_common_name;
  1608           |> massage_simple_notes fp_common_name;
  1541 
  1609 
  1542         val notes =
  1610         val notes =
  1543           [(inductN, map single induct_thms, fn T_name => induct_attrs @ [induct_type_attr T_name]),
  1611           [(inductN, map single induct_thms, fn T_name => induct_attrs @ [induct_type_attr T_name]),
  1544            (recN, rec_thmss, K rec_attrs),
  1612            (recN, rec_thmss, K rec_attrs),
       
  1613            (rel_inductN, rel_induct_thmss, K (rel_induct_attrs @ [induct_pred_attr ""])),
  1545            (simpsN, simp_thmss, K [])]
  1614            (simpsN, simp_thmss, K [])]
  1546           |> massage_multi_notes;
  1615           |> massage_multi_notes;
  1547       in
  1616       in
  1548         lthy
  1617         lthy
  1549         |> Spec_Rules.add Spec_Rules.Equational (recs, flat rec_thmss)
  1618         |> Spec_Rules.add Spec_Rules.Equational (recs, flat rec_thmss)
  1565           derive_coinduct_corecs_thms_for_types pre_bnfs (the corecs_args_types) xtor_co_induct
  1634           derive_coinduct_corecs_thms_for_types pre_bnfs (the corecs_args_types) xtor_co_induct
  1566             dtor_injects dtor_ctors xtor_co_rec_thms live_nesting_bnfs fpTs Cs Xs ctrXs_Tsss kss mss
  1635             dtor_injects dtor_ctors xtor_co_rec_thms live_nesting_bnfs fpTs Cs Xs ctrXs_Tsss kss mss
  1567             ns abs_inverses abs_inverses I ctr_defss ctr_sugars corecs corec_defs
  1636             ns abs_inverses abs_inverses I ctr_defss ctr_sugars corecs corec_defs
  1568             (Proof_Context.export lthy' no_defs_lthy) lthy;
  1637             (Proof_Context.export lthy' no_defs_lthy) lthy;
  1569 
  1638 
  1570         val ((rel_coinduct_thms, rel_coinduct_thm),
       
  1571              (rel_coinduct_attrs, common_rel_coinduct_attrs)) =
       
  1572           derive_rel_coinduct0_thm_for_types lthy fpTs ns As Bs mss ctr_sugars abs_inverses
       
  1573             abs_injects ctor_injects dtor_ctors pre_rel_defs ctr_defss rel_xtor_co_induct_thm;
       
  1574 
       
  1575         val sel_corec_thmss = map flat sel_corec_thmsss;
  1639         val sel_corec_thmss = map flat sel_corec_thmsss;
  1576 
  1640 
  1577         val coinduct_type_attr = Attrib.internal o K o Induct.coinduct_type;
  1641         val coinduct_type_attr = Attrib.internal o K o Induct.coinduct_type;
  1578         val coinduct_pred_attr = Attrib.internal o K o Induct.coinduct_pred;
  1642         val coinduct_pred_attr = Attrib.internal o K o Induct.coinduct_pred;
  1579 
  1643 
  1580         val flat_corec_thms = append oo append;
  1644         val flat_corec_thms = append oo append;
       
  1645 
       
  1646         val ((rel_coinduct_thmss, common_rel_coinduct_thms),
       
  1647              (rel_coinduct_attrs, common_rel_coinduct_attrs)) =
       
  1648           if live = 0 then
       
  1649             ((replicate nn [], []), ([], []))
       
  1650           else
       
  1651             let
       
  1652               val ((rel_coinduct_thms, common_rel_coinduct_thm),
       
  1653                    (rel_coinduct_attrs, common_rel_coinduct_attrs)) =
       
  1654                 derive_rel_coinduct_thm_for_types lthy fpTs ns As Bs mss ctr_sugars abs_inverses
       
  1655                   abs_injects ctor_injects dtor_ctors pre_rel_defs ctr_defss rel_xtor_co_induct_thm
       
  1656                   (map rel_eq_of_bnf live_nesting_bnfs)
       
  1657             in
       
  1658               ((map single rel_coinduct_thms, single common_rel_coinduct_thm),
       
  1659                (rel_coinduct_attrs, common_rel_coinduct_attrs))
       
  1660             end;
  1581 
  1661 
  1582         val simp_thmss =
  1662         val simp_thmss =
  1583           map6 mk_simp_thms ctr_sugars
  1663           map6 mk_simp_thms ctr_sugars
  1584             (map3 flat_corec_thms disc_corec_thmss disc_corec_iff_thmss sel_corec_thmss)
  1664             (map3 flat_corec_thms disc_corec_thmss disc_corec_iff_thmss sel_corec_thmss)
  1585             mapss rel_injectss rel_distinctss setss;
  1665             mapss rel_injectss rel_distinctss setss;
  1586 
  1666 
  1587         val common_notes =
  1667         val common_notes =
  1588           (if nn > 1 then
  1668           (if nn > 1 then
  1589             [(rel_coinductN, [rel_coinduct_thm], common_rel_coinduct_attrs),
  1669             [(coinductN, [coinduct_thm], common_coinduct_attrs),
  1590              (coinductN, [coinduct_thm], common_coinduct_attrs),
  1670              (rel_coinductN, common_rel_coinduct_thms, common_rel_coinduct_attrs),
  1591              (strong_coinductN, [strong_coinduct_thm], common_coinduct_attrs)]
  1671              (strong_coinductN, [strong_coinduct_thm], common_coinduct_attrs)]
  1592           else
  1672           else [])
  1593             [])
       
  1594           |> massage_simple_notes fp_common_name;
  1673           |> massage_simple_notes fp_common_name;
  1595 
  1674 
  1596         val notes =
  1675         val notes =
  1597           [(coinductN, map single coinduct_thms,
  1676           [(coinductN, map single coinduct_thms,
  1598             fn T_name => coinduct_attrs @ [coinduct_type_attr T_name]),
  1677             fn T_name => coinduct_attrs @ [coinduct_type_attr T_name]),
  1599            (rel_coinductN, map single rel_coinduct_thms,
       
  1600             K (rel_coinduct_attrs @ [coinduct_pred_attr ""])),
       
  1601            (corecN, corec_thmss, K corec_attrs),
  1678            (corecN, corec_thmss, K corec_attrs),
  1602            (disc_corecN, disc_corec_thmss, K disc_corec_attrs),
  1679            (disc_corecN, disc_corec_thmss, K disc_corec_attrs),
  1603            (disc_corec_iffN, disc_corec_iff_thmss, K disc_corec_iff_attrs),
  1680            (disc_corec_iffN, disc_corec_iff_thmss, K disc_corec_iff_attrs),
       
  1681            (rel_coinductN, rel_coinduct_thmss, K (rel_coinduct_attrs @ [coinduct_pred_attr ""])),
  1604            (sel_corecN, sel_corec_thmss, K sel_corec_attrs),
  1682            (sel_corecN, sel_corec_thmss, K sel_corec_attrs),
  1605            (simpsN, simp_thmss, K []),
  1683            (simpsN, simp_thmss, K []),
  1606            (strong_coinductN, map single strong_coinduct_thms, K coinduct_attrs)]
  1684            (strong_coinductN, map single strong_coinduct_thms, K coinduct_attrs)]
  1607           |> massage_multi_notes;
  1685           |> massage_multi_notes;
  1608       in
  1686       in