src/HOL/Tools/BNF/bnf_fp_def_sugar.ML
changeset 56641 029997d3b5d8
parent 56640 0a35354137a5
child 56648 2ffa440b3074
equal deleted inserted replaced
56640:0a35354137a5 56641:029997d3b5d8
    73   val mk_corec_fun_arg_types: typ list list list -> typ list -> typ list -> typ list -> int list ->
    73   val mk_corec_fun_arg_types: typ list list list -> typ list -> typ list -> typ list -> int list ->
    74     int list list -> term ->
    74     int list list -> term ->
    75     typ list list
    75     typ list list
    76     * (typ list list list list * typ list list list * typ list list list list * typ list)
    76     * (typ list list list list * typ list list list * typ list list list list * typ list)
    77   val define_rec:
    77   val define_rec:
    78     (typ list list * typ list list list list * term list list * term list list list list) option ->
    78     typ list list * typ list list list list * term list list * term list list list list ->
    79     (string -> binding) -> typ list -> typ list -> term list -> term -> Proof.context ->
    79     (string -> binding) -> typ list -> typ list -> term list -> term -> Proof.context ->
    80     (term * thm) * Proof.context
    80     (term * thm) * Proof.context
    81   val define_corec: 'a * term list * term list list
    81   val define_corec: 'a * term list * term list list
    82       * ((term list list * term list list list) * typ list) -> (string -> binding) -> 'b list ->
    82       * ((term list list * term list list list) * typ list) -> (string -> binding) -> 'b list ->
    83     typ list -> term list -> term -> local_theory -> (term * thm) * local_theory
    83     typ list -> term list -> term -> local_theory -> (term * thm) * local_theory
   456     val (xtor_co_rec_fun_Ts, xtor_co_recs) =
   456     val (xtor_co_rec_fun_Ts, xtor_co_recs) =
   457       mk_xtor_co_recs thy fp fpTs Cs xtor_co_recs0 |> `(binder_fun_types o fastype_of o hd);
   457       mk_xtor_co_recs thy fp fpTs Cs xtor_co_recs0 |> `(binder_fun_types o fastype_of o hd);
   458 
   458 
   459     val ((recs_args_types, corecs_args_types), lthy') =
   459     val ((recs_args_types, corecs_args_types), lthy') =
   460       if fp = Least_FP then
   460       if fp = Least_FP then
   461         if nn = 1 andalso forall (forall (forall (not o exists_subtype_in fpTs))) ctr_Tsss then
   461         mk_recs_args_types ctr_Tsss Cs absTs repTs ns mss xtor_co_rec_fun_Ts lthy
   462           ((NONE, NONE), lthy)
   462         |>> (rpair NONE o SOME)
   463         else
       
   464           mk_recs_args_types ctr_Tsss Cs absTs repTs ns mss xtor_co_rec_fun_Ts lthy
       
   465           |>> (rpair NONE o SOME)
       
   466       else
   463       else
   467         mk_corecs_args_types ctr_Tsss Cs absTs repTs ns mss xtor_co_rec_fun_Ts lthy
   464         mk_corecs_args_types ctr_Tsss Cs absTs repTs ns mss xtor_co_rec_fun_Ts lthy
   468         |>> (pair NONE o SOME);
   465         |>> (pair NONE o SOME);
   469   in
   466   in
   470     ((xtor_co_recs, recs_args_types, corecs_args_types), lthy')
   467     ((xtor_co_recs, recs_args_types, corecs_args_types), lthy')
   495     val def' = Morphism.thm phi def;
   492     val def' = Morphism.thm phi def;
   496   in
   493   in
   497     ((cst', def'), lthy')
   494     ((cst', def'), lthy')
   498   end;
   495   end;
   499 
   496 
   500 fun define_rec NONE _ _ _ _ _ = pair (Term.dummy, refl)
   497 fun define_rec (_, _, fss, xssss) mk_binding fpTs Cs reps ctor_rec =
   501   | define_rec (SOME (_, _, fss, xssss)) mk_binding fpTs Cs reps ctor_rec =
   498   let
   502     let
   499     val nn = length fpTs;
   503       val nn = length fpTs;
   500     val (ctor_rec_absTs, fpT) = strip_typeN nn (fastype_of ctor_rec)
   504       val (ctor_rec_absTs, fpT) = strip_typeN nn (fastype_of ctor_rec)
   501       |>> map domain_type ||> domain_type;
   505         |>> map domain_type ||> domain_type;
   502   in
   506     in
   503     define_co_rec Least_FP fpT Cs (mk_binding recN)
   507       define_co_rec Least_FP fpT Cs (mk_binding recN)
   504       (fold_rev (fold_rev Term.lambda) fss (Term.list_comb (ctor_rec,
   508         (fold_rev (fold_rev Term.lambda) fss (Term.list_comb (ctor_rec,
   505          map4 (fn ctor_rec_absT => fn rep => fn fs => fn xsss =>
   509            map4 (fn ctor_rec_absT => fn rep => fn fs => fn xsss =>
   506              mk_case_absumprod ctor_rec_absT rep fs (map (map HOLogic.mk_tuple) xsss)
   510                mk_case_absumprod ctor_rec_absT rep fs (map (map HOLogic.mk_tuple) xsss)
   507                (map flat_rec_arg_args xsss))
   511                  (map flat_rec_arg_args xsss))
   508            ctor_rec_absTs reps fss xssss)))
   512              ctor_rec_absTs reps fss xssss)))
   509   end;
   513     end;
       
   514 
   510 
   515 fun define_corec (_, cs, cpss, ((pgss, cqgsss), f_absTs)) mk_binding fpTs Cs abss dtor_corec =
   511 fun define_corec (_, cs, cpss, ((pgss, cqgsss), f_absTs)) mk_binding fpTs Cs abss dtor_corec =
   516   let
   512   let
   517     val nn = length fpTs;
   513     val nn = length fpTs;
   518     val fpT = range_type (snd (strip_typeN nn (fastype_of dtor_corec)));
   514     val fpT = range_type (snd (strip_typeN nn (fastype_of dtor_corec)));
   668           |> Thm.close_derivation;
   664           |> Thm.close_derivation;
   669       in
   665       in
   670         map2 (map2 prove) goalss tacss
   666         map2 (map2 prove) goalss tacss
   671       end;
   667       end;
   672 
   668 
   673     val rec_thmss =
   669     val rec_thmss = mk_rec_thmss (the rec_args_typess) recs rec_defs ctor_rec_thms;
   674       (case rec_args_typess of
       
   675         SOME types => mk_rec_thmss types recs rec_defs ctor_rec_thms
       
   676       | NONE => replicate nn []);
       
   677   in
   670   in
   678     ((induct_thms, induct_thm, [induct_case_names_attr]),
   671     ((induct_thms, induct_thm, [induct_case_names_attr]),
   679      (rec_thmss, code_nitpicksimp_attrs @ simp_attrs))
   672      (rec_thmss, code_nitpicksimp_attrs @ simp_attrs))
   680   end;
   673   end;
   681 
   674 
  1310           (((maps_sets_rels, (ctrs, xss, ctr_defs, ctr_sugar)), co_rec_res), lthy);
  1303           (((maps_sets_rels, (ctrs, xss, ctr_defs, ctr_sugar)), co_rec_res), lthy);
  1311       in
  1304       in
  1312         (wrap_ctrs
  1305         (wrap_ctrs
  1313          #> derive_maps_sets_rels
  1306          #> derive_maps_sets_rels
  1314          ##>>
  1307          ##>>
  1315            (if fp = Least_FP then define_rec recs_args_types mk_binding fpTs Cs reps
  1308            (if fp = Least_FP then define_rec (the recs_args_types) mk_binding fpTs Cs reps
  1316            else define_corec (the corecs_args_types) mk_binding fpTs Cs abss) xtor_co_rec
  1309            else define_corec (the corecs_args_types) mk_binding fpTs Cs abss) xtor_co_rec
  1317          #> massage_res, lthy')
  1310          #> massage_res, lthy')
  1318       end;
  1311       end;
  1319 
  1312 
  1320     fun wrap_types_etc (wrap_types_etcs, lthy) =
  1313     fun wrap_types_etc (wrap_types_etcs, lthy) =
  1335             nesting_bnfs nested_bnfs fpTs Cs Xs ctrXs_Tsss abs_inverses type_definitions
  1328             nesting_bnfs nested_bnfs fpTs Cs Xs ctrXs_Tsss abs_inverses type_definitions
  1336             abs_inverses ctrss ctr_defss recs rec_defs lthy;
  1329             abs_inverses ctrss ctr_defss recs rec_defs lthy;
  1337 
  1330 
  1338         val induct_type_attr = Attrib.internal o K o Induct.induct_type;
  1331         val induct_type_attr = Attrib.internal o K o Induct.induct_type;
  1339 
  1332 
  1340         val (recs', rec_thmss') =
       
  1341           if is_some recs_args_types then (recs, rec_thmss)
       
  1342           else (map #casex ctr_sugars, map #case_thms ctr_sugars);
       
  1343 
       
  1344         val simp_thmss =
  1333         val simp_thmss =
  1345           map6 mk_simp_thms ctr_sugars rec_thmss mapss rel_injects rel_distincts setss;
  1334           map6 mk_simp_thms ctr_sugars rec_thmss mapss rel_injects rel_distincts setss;
  1346 
  1335 
  1347         val common_notes =
  1336         val common_notes =
  1348           (if nn > 1 then [(inductN, [induct_thm], induct_attrs)] else [])
  1337           (if nn > 1 then [(inductN, [induct_thm], induct_attrs)] else [])
  1353            (recN, rec_thmss, K rec_attrs),
  1342            (recN, rec_thmss, K rec_attrs),
  1354            (simpsN, simp_thmss, K [])]
  1343            (simpsN, simp_thmss, K [])]
  1355           |> massage_multi_notes;
  1344           |> massage_multi_notes;
  1356       in
  1345       in
  1357         lthy
  1346         lthy
  1358         |> (if is_some recs_args_types then
  1347         |> Spec_Rules.add Spec_Rules.Equational (recs, flat rec_thmss)
  1359               Spec_Rules.add Spec_Rules.Equational (recs, flat rec_thmss)
       
  1360             else
       
  1361               I)
       
  1362         |> Local_Theory.notes (common_notes @ notes) |> snd
  1348         |> Local_Theory.notes (common_notes @ notes) |> snd
  1363         |> register_as_fp_sugars Xs Least_FP pre_bnfs absT_infos nested_bnfs nesting_bnfs fp_res
  1349         |> register_as_fp_sugars Xs Least_FP pre_bnfs absT_infos nested_bnfs nesting_bnfs fp_res
  1364           ctrXs_Tsss ctr_defss ctr_sugars recs' mapss [induct_thm] (map single induct_thms)
  1350           ctrXs_Tsss ctr_defss ctr_sugars recs mapss [induct_thm] (map single induct_thms)
  1365           rec_thmss' (replicate nn []) (replicate nn []) rel_injects
  1351           rec_thmss (replicate nn []) (replicate nn []) rel_injects
  1366       end;
  1352       end;
  1367 
  1353 
  1368     fun derive_note_coinduct_corecs_thms_for_types
  1354     fun derive_note_coinduct_corecs_thms_for_types
  1369         ((((mapss, rel_injects, rel_distincts, setss), (_, _, ctr_defss, ctr_sugars)),
  1355         ((((mapss, rel_injects, rel_distincts, setss), (_, _, ctr_defss, ctr_sugars)),
  1370           (corecs, corec_defs)), lthy) =
  1356           (corecs, corec_defs)), lthy) =