src/HOL/Tools/BNF/bnf_fp_def_sugar.ML
changeset 55862 b458558cbcc2
parent 55861 0a8200e31474
child 55863 fa3a1ec69a1b
equal deleted inserted replaced
55861:0a8200e31474 55862:b458558cbcc2
    55 
    55 
    56   val morph_gfp_sugar_thms: morphism -> gfp_sugar_thms -> gfp_sugar_thms
    56   val morph_gfp_sugar_thms: morphism -> gfp_sugar_thms -> gfp_sugar_thms
    57   val transfer_gfp_sugar_thms: Proof.context -> gfp_sugar_thms -> gfp_sugar_thms
    57   val transfer_gfp_sugar_thms: Proof.context -> gfp_sugar_thms -> gfp_sugar_thms
    58 
    58 
    59   val mk_co_iters_prelims: BNF_Util.fp_kind -> typ list list list -> typ list -> typ list ->
    59   val mk_co_iters_prelims: BNF_Util.fp_kind -> typ list list list -> typ list -> typ list ->
    60     typ list -> typ list -> int list -> int list list -> term list list -> Proof.context ->
    60      typ list -> typ list -> int list -> int list list -> term list list -> Proof.context ->
    61     (term list list
    61      (term list list * (typ list list * typ list list list list * term list list
    62      * (typ list list * typ list list list list * term list list
    62         * term list list list list) option
    63         * term list list list list) list option
    63       * (string * term list * term list list
    64      * (string * term list * term list list
    64         * ((term list list * term list list list) * typ list)) option)
    65         * ((term list list * term list list list) * typ list) list) option)
    65      * Proof.context
    66     * Proof.context
       
    67   val repair_nullary_single_ctr: typ list list -> typ list list
    66   val repair_nullary_single_ctr: typ list list -> typ list list
    68   val mk_coiter_p_pred_types: typ list -> int list -> typ list list
    67   val mk_coiter_p_pred_types: typ list -> int list -> typ list list
    69   val mk_coiter_fun_arg_types: typ list list list -> typ list -> typ list -> typ list -> int list ->
    68   val mk_coiter_fun_arg_types: typ list list list -> typ list -> typ list -> typ list -> int list ->
    70     int list list -> term ->
    69     int list list -> term ->
    71     typ list list
    70     typ list list
    72     * (typ list list list list * typ list list list * typ list list list list * typ list)
    71     * (typ list list list list * typ list list list * typ list list list list * typ list)
    73   val define_iters: string list ->
    72   val define_iter:
    74     (typ list list * typ list list list list * term list list * term list list list list) list ->
    73     (typ list list * typ list list list list * term list list * term list list list list) option ->
    75     (string -> binding) -> typ list -> typ list -> term list -> term list -> Proof.context ->
    74     (string -> binding) -> typ list -> typ list -> term list -> term -> Proof.context ->
    76     (term list * thm list) * Proof.context
    75     (term list * thm list) * Proof.context
    77   val define_coiters: string list -> string * term list * term list list
    76   val define_coiter: 'a * term list * term list list
    78     * ((term list list * term list list list) * typ list) list ->
    77       * ((term list list * term list list list) * typ list) -> (string -> binding) -> 'b list ->
    79     (string -> binding) -> typ list -> typ list -> term list -> term list -> Proof.context ->
    78     typ list -> term list -> term -> Proof.context -> (term list * thm list) * local_theory
    80     (term list * thm list) * Proof.context
       
    81   val derive_induct_iters_thms_for_types: BNF_Def.bnf list ->
    79   val derive_induct_iters_thms_for_types: BNF_Def.bnf list ->
    82     (typ list list * typ list list list list * term list list * term list list list list) list ->
    80      ('a * typ list list list list * term list list * 'b) option -> thm -> thm list list ->
    83     thm -> thm list list -> BNF_Def.bnf list -> BNF_Def.bnf list -> typ list -> typ list ->
    81      BNF_Def.bnf list -> BNF_Def.bnf list -> typ list -> typ list -> typ list ->
    84     typ list -> typ list list list -> thm list -> thm list -> thm list -> term list list ->
    82      typ list list list -> thm list -> thm list -> thm list -> term list list -> thm list list ->
    85     thm list list -> term list list -> thm list list -> local_theory -> lfp_sugar_thms
    83      term list list -> thm list list -> Proof.context -> lfp_sugar_thms
    86   val derive_coinduct_coiters_thms_for_types: BNF_Def.bnf list ->
    84   val derive_coinduct_coiters_thms_for_types: BNF_Def.bnf list ->
    87     string * term list * term list list * ((term list list * term list list list)
    85     string * term list * term list list * ((term list list * term list list list) * typ list) ->
    88       * typ list) list ->
       
    89     thm -> thm list -> thm list -> thm list list -> BNF_Def.bnf list -> typ list -> typ list ->
    86     thm -> thm list -> thm list -> thm list list -> BNF_Def.bnf list -> typ list -> typ list ->
    90     typ list -> typ list list list -> int list list -> int list list -> int list -> thm list ->
    87     typ list -> typ list list list -> int list list -> int list list -> int list -> thm list ->
    91     thm list -> (thm -> thm) -> thm list list -> Ctr_Sugar.ctr_sugar list -> term list list ->
    88     thm list -> (thm -> thm) -> thm list list -> Ctr_Sugar.ctr_sugar list -> term list list ->
    92     thm list list -> (thm list -> thm list) -> local_theory -> gfp_sugar_thms
    89     thm list list -> (thm list -> thm list) -> local_theory -> gfp_sugar_thms
    93 
    90 
   379     val (zssss_tl, lthy) =
   376     val (zssss_tl, lthy) =
   380       lthy
   377       lthy
   381       |> mk_Freessss "y" (map (map (map tl)) z_Tssss);
   378       |> mk_Freessss "y" (map (map (map tl)) z_Tssss);
   382     val zssss = map2 (map2 (map2 cons)) zssss_hd zssss_tl;
   379     val zssss = map2 (map2 (map2 cons)) zssss_hd zssss_tl;
   383   in
   380   in
   384     ([(h_Tss, z_Tssss, hss, zssss)], lthy)
   381     ((h_Tss, z_Tssss, hss, zssss), lthy)
   385   end;
   382   end;
   386 
   383 
   387 (*avoid "'a itself" arguments in coiterators*)
   384 (*avoid "'a itself" arguments in coiterators*)
   388 fun repair_nullary_single_ctr [[]] = [[@{typ unit}]]
   385 fun repair_nullary_single_ctr [[]] = [[@{typ unit}]]
   389   | repair_nullary_single_ctr Tss = Tss;
   386   | repair_nullary_single_ctr Tss = Tss;
   447         val cqfsss = map3 (map3 (map3 build_dtor_coiter_arg)) f_Tsss cqssss cfssss;
   444         val cqfsss = map3 (map3 (map3 build_dtor_coiter_arg)) f_Tsss cqssss cfssss;
   448       in (pfss, cqfsss) end;
   445       in (pfss, cqfsss) end;
   449 
   446 
   450     val corec_args = mk_args sssss hssss h_Tsss;
   447     val corec_args = mk_args sssss hssss h_Tsss;
   451   in
   448   in
   452     ((z, cs, cpss, [(corec_args, corec_types)]), lthy)
   449     ((z, cs, cpss, (corec_args, corec_types)), lthy)
   453   end;
   450   end;
   454 
   451 
   455 fun mk_co_iters_prelims fp ctr_Tsss fpTs Cs absTs repTs ns mss xtor_co_iterss0 lthy =
   452 fun mk_co_iters_prelims fp ctr_Tsss fpTs Cs absTs repTs ns mss xtor_co_iterss0 lthy =
   456   let
   453   let
   457     val thy = Proof_Context.theory_of lthy;
   454     val thy = Proof_Context.theory_of lthy;
       
   455     val nn = length fpTs;
   458 
   456 
   459     val (xtor_co_iter_fun_Tss, xtor_co_iterss) =
   457     val (xtor_co_iter_fun_Tss, xtor_co_iterss) =
   460       map (mk_co_iters thy fp fpTs Cs #> `(binder_fun_types o fastype_of o hd))
   458       map (mk_co_iters thy fp fpTs Cs #> `(binder_fun_types o fastype_of o hd))
   461         (transpose xtor_co_iterss0)
   459         (transpose xtor_co_iterss0)
   462       |> apsnd transpose o apfst transpose o split_list;
   460       |> apsnd transpose o apfst transpose o split_list;
   463 
   461 
   464     val ((iters_args_types, coiters_args_types), lthy') =
   462     val ((iters_args_types, coiters_args_types), lthy') =
   465       if fp = Least_FP then
   463       if fp = Least_FP then
   466         mk_iters_args_types ctr_Tsss Cs absTs repTs ns mss xtor_co_iter_fun_Tss lthy
   464         if nn = 1 andalso forall (forall (forall (not o exists_subtype_in fpTs))) ctr_Tsss then
   467         |>> (rpair NONE o SOME)
   465           ((NONE, NONE), lthy)
       
   466         else
       
   467           mk_iters_args_types ctr_Tsss Cs absTs repTs ns mss xtor_co_iter_fun_Tss lthy
       
   468           |>> (rpair NONE o SOME)
   468       else
   469       else
   469         mk_coiters_args_types ctr_Tsss Cs absTs repTs ns mss xtor_co_iter_fun_Tss lthy
   470         mk_coiters_args_types ctr_Tsss Cs absTs repTs ns mss xtor_co_iter_fun_Tss lthy
   470         |>> (pair NONE o SOME);
   471         |>> (pair NONE o SOME);
   471   in
   472   in
   472     ((xtor_co_iterss, iters_args_types, coiters_args_types), lthy')
   473     ((xtor_co_iterss, iters_args_types, coiters_args_types), lthy')
   499     val defs' = map (Morphism.thm phi) defs;
   500     val defs' = map (Morphism.thm phi) defs;
   500   in
   501   in
   501     ((csts', defs'), lthy')
   502     ((csts', defs'), lthy')
   502   end;
   503   end;
   503 
   504 
   504 fun define_iters iterNs iter_args_typess' mk_binding fpTs Cs reps ctor_iters lthy =
   505 fun define_iter NONE _ _ _ _ _ lthy = (([], []), lthy)
   505   let
   506   | define_iter (SOME (_, _, fss, xssss)) mk_binding fpTs Cs reps ctor_iter lthy =
   506     val nn = length fpTs;
   507     let
   507     val fpT = domain_type (snd (strip_typeN nn (fastype_of (co_rec_of ctor_iters))));
   508       val nn = length fpTs;
   508 
   509       val (ctor_iter_absTs, fpT) = strip_typeN nn (fastype_of ctor_iter)
   509     fun generate_iter pre (_, _, fss, xssss) ctor_iter =
   510         |>> map domain_type ||> domain_type;
   510       let val ctor_iter_absTs = map domain_type (fst (strip_typeN nn (fastype_of ctor_iter))) in
   511 
   511         (mk_binding pre,
   512       val binding_spec =
       
   513         (mk_binding recN,
   512          fold_rev (fold_rev Term.lambda) fss (Term.list_comb (ctor_iter,
   514          fold_rev (fold_rev Term.lambda) fss (Term.list_comb (ctor_iter,
   513            map4 (fn ctor_iter_absT => fn rep => fn fs => fn xsss =>
   515            map4 (fn ctor_iter_absT => fn rep => fn fs => fn xsss =>
   514                mk_case_absumprod ctor_iter_absT rep fs
   516                mk_case_absumprod ctor_iter_absT rep fs
   515                  (map (HOLogic.mk_tuple o map HOLogic.mk_tuple) xsss) (map flat_rec_arg_args xsss))
   517                  (map (HOLogic.mk_tuple o map HOLogic.mk_tuple) xsss) (map flat_rec_arg_args xsss))
   516              ctor_iter_absTs reps fss xssss)))
   518              ctor_iter_absTs reps fss xssss)));
   517       end;
   519     in
   518   in
   520       define_co_iters Least_FP fpT Cs [binding_spec] lthy
   519     define_co_iters Least_FP fpT Cs (map3 generate_iter iterNs iter_args_typess' ctor_iters) lthy
   521     end;
   520   end;
   522 
   521 
   523 fun define_coiter (_, cs, cpss, ((pfss, cqfsss), f_absTs)) mk_binding fpTs Cs abss dtor_coiter lthy =
   522 fun define_coiters coiterNs (_, cs, cpss, coiter_args_typess') mk_binding fpTs Cs abss dtor_coiters
       
   523     lthy =
       
   524   let
   524   let
   525     val nn = length fpTs;
   525     val nn = length fpTs;
   526     val fpT = range_type (snd (strip_typeN nn (fastype_of (co_rec_of dtor_coiters))));
   526     val fpT = range_type (snd (strip_typeN nn (fastype_of dtor_coiter)));
   527 
   527 
   528     fun generate_coiter pre ((pfss, cqfsss), f_absTs) dtor_coiter =
   528     fun generate_coiter dtor_coiter =
   529       (mk_binding pre,
   529       (mk_binding corecN,
   530        fold_rev (fold_rev Term.lambda) pfss (Term.list_comb (dtor_coiter,
   530        fold_rev (fold_rev Term.lambda) pfss (Term.list_comb (dtor_coiter,
   531          map5 mk_preds_getterss_join cs cpss f_absTs abss cqfsss)));
   531          map5 mk_preds_getterss_join cs cpss f_absTs abss cqfsss)));
   532   in
   532   in
   533     define_co_iters Greatest_FP fpT Cs
   533     define_co_iters Greatest_FP fpT Cs [generate_coiter dtor_coiter] lthy
   534       (map3 generate_coiter coiterNs coiter_args_typess' dtor_coiters) lthy
       
   535   end;
   534   end;
   536 
   535 
   537 fun derive_induct_iters_thms_for_types pre_bnfs [rec_args_types] ctor_induct ctor_iter_thmss
   536 fun derive_induct_iters_thms_for_types pre_bnfs rec_args_typess ctor_induct ctor_iter_thmss
   538     nesting_bnfs nested_bnfs fpTs Cs Xs ctrXs_Tsss fp_abs_inverses fp_type_definitions abs_inverses
   537     nesting_bnfs nested_bnfs fpTs Cs Xs ctrXs_Tsss fp_abs_inverses fp_type_definitions abs_inverses
   539     ctrss ctr_defss iterss iter_defss lthy =
   538     ctrss ctr_defss iterss iter_defss lthy =
   540   let
   539   let
   541     val iterss' = transpose iterss;
   540     val iterss' = transpose iterss;
   542     val iter_defss' = transpose iter_defss;
   541     val iter_defss' = transpose iter_defss;
   543 
       
   544     val [recs] = iterss';
       
   545     val [rec_defs] = iter_defss';
       
   546 
   542 
   547     val ctr_Tsss = map (map (binder_types o fastype_of)) ctrss;
   543     val ctr_Tsss = map (map (binder_types o fastype_of)) ctrss;
   548 
   544 
   549     val nn = length pre_bnfs;
   545     val nn = length pre_bnfs;
   550     val ns = map length ctr_Tsss;
   546     val ns = map length ctr_Tsss;
   687           |> Thm.close_derivation;
   683           |> Thm.close_derivation;
   688       in
   684       in
   689         map2 (map2 prove) goalss tacss
   685         map2 (map2 prove) goalss tacss
   690       end;
   686       end;
   691 
   687 
   692     val rec_thmss = mk_iter_thmss rec_args_types recs rec_defs (map co_rec_of ctor_iter_thmss);
   688     val rec_thmss =
       
   689       (case rec_args_typess of
       
   690         SOME types =>
       
   691         mk_iter_thmss types (the_single iterss') (the_single iter_defss')
       
   692           (map co_rec_of ctor_iter_thmss)
       
   693       | NONE => replicate nn []);
   693   in
   694   in
   694     ((induct_thms, induct_thm, [induct_case_names_attr]),
   695     ((induct_thms, induct_thm, [induct_case_names_attr]),
   695      (rec_thmss, code_nitpicksimp_attrs @ simp_attrs))
   696      (rec_thmss, code_nitpicksimp_attrs @ simp_attrs))
   696   end;
   697   end;
   697 
   698 
   698 fun derive_coinduct_coiters_thms_for_types pre_bnfs (z, cs, cpss,
   699 fun derive_coinduct_coiters_thms_for_types pre_bnfs (z, cs, cpss,
   699       coiters_args_types as [((phss, cshsss), _)])
   700       coiters_args_types as ((phss, cshsss), _))
   700     dtor_coinduct dtor_injects dtor_ctors dtor_coiter_thmss nesting_bnfs fpTs Cs Xs ctrXs_Tsss kss
   701     dtor_coinduct dtor_injects dtor_ctors dtor_coiter_thmss nesting_bnfs fpTs Cs Xs ctrXs_Tsss kss
   701     mss ns fp_abs_inverses abs_inverses mk_vimage2p ctr_defss (ctr_sugars : ctr_sugar list)
   702     mss ns fp_abs_inverses abs_inverses mk_vimage2p ctr_defss (ctr_sugars : ctr_sugar list)
   702     coiterss coiter_defss export_args lthy =
   703     coiterss coiter_defss export_args lthy =
   703   let
   704   let
   704     fun mk_ctor_dtor_coiter_thm dtor_inject dtor_ctor coiter =
   705     fun mk_ctor_dtor_coiter_thm dtor_inject dtor_ctor coiter =
   823       map3 (quasi_unambiguous_case_names ooo mk_coinduct_concls) mss discss ctrss;
   824       map3 (quasi_unambiguous_case_names ooo mk_coinduct_concls) mss discss ctrss;
   824 
   825 
   825     fun mk_maybe_not pos = not pos ? HOLogic.mk_not;
   826     fun mk_maybe_not pos = not pos ? HOLogic.mk_not;
   826 
   827 
   827     val fcoiterss' as [hcorecs] =
   828     val fcoiterss' as [hcorecs] =
   828       map2 (fn (pfss, _) => map (lists_bmoc pfss)) (map fst coiters_args_types) coiterss';
   829       map2 (fn (pfss, _) => map (lists_bmoc pfss)) [fst coiters_args_types] coiterss';
   829 
   830 
   830     val corec_thmss =
   831     val corec_thmss =
   831       let
   832       let
   832         fun mk_goal pfss c cps fcoiter n k ctr m cfs' =
   833         fun mk_goal pfss c cps fcoiter n k ctr m cfs' =
   833           fold_rev (fold_rev Logic.all) ([c] :: pfss)
   834           fold_rev (fold_rev Logic.all) ([c] :: pfss)
  1335           (((maps_sets_rels, (ctrs, xss, ctr_defs, ctr_sugar)), co_iter_res), lthy);
  1336           (((maps_sets_rels, (ctrs, xss, ctr_defs, ctr_sugar)), co_iter_res), lthy);
  1336       in
  1337       in
  1337         (wrap_ctrs
  1338         (wrap_ctrs
  1338          #> derive_maps_sets_rels
  1339          #> derive_maps_sets_rels
  1339          ##>>
  1340          ##>>
  1340            (if fp = Least_FP then define_iters [recN] (the iters_args_types) mk_binding fpTs Cs reps
  1341            (if fp = Least_FP then define_iter iters_args_types mk_binding fpTs Cs reps
  1341            else define_coiters [corecN] (the coiters_args_types) mk_binding fpTs Cs abss)
  1342            else define_coiter (the coiters_args_types) mk_binding fpTs Cs abss)
  1342              [co_rec_of xtor_co_iters]
  1343              (co_rec_of xtor_co_iters)
  1343          #> massage_res, lthy')
  1344          #> massage_res, lthy')
  1344       end;
  1345       end;
  1345 
  1346 
  1346     fun wrap_types_etc (wrap_types_etcs, lthy) =
  1347     fun wrap_types_etc (wrap_types_etcs, lthy) =
  1347       fold_map I wrap_types_etcs lthy
  1348       fold_map I wrap_types_etcs lthy
  1355     fun derive_note_induct_iters_thms_for_types
  1356     fun derive_note_induct_iters_thms_for_types
  1356         ((((mapss, rel_injects, rel_distincts, setss), (ctrss, _, ctr_defss, ctr_sugars)),
  1357         ((((mapss, rel_injects, rel_distincts, setss), (ctrss, _, ctr_defss, ctr_sugars)),
  1357           (iterss, iter_defss)), lthy) =
  1358           (iterss, iter_defss)), lthy) =
  1358       let
  1359       let
  1359         val ((induct_thms, induct_thm, induct_attrs), (rec_thmss, iter_attrs)) =
  1360         val ((induct_thms, induct_thm, induct_attrs), (rec_thmss, iter_attrs)) =
  1360           derive_induct_iters_thms_for_types pre_bnfs (the iters_args_types) xtor_co_induct
  1361           derive_induct_iters_thms_for_types pre_bnfs iters_args_types xtor_co_induct
  1361             xtor_co_iter_thmss nesting_bnfs nested_bnfs fpTs Cs Xs ctrXs_Tsss abs_inverses
  1362             xtor_co_iter_thmss nesting_bnfs nested_bnfs fpTs Cs Xs ctrXs_Tsss abs_inverses
  1362             type_definitions abs_inverses ctrss ctr_defss iterss iter_defss lthy;
  1363             type_definitions abs_inverses ctrss ctr_defss iterss iter_defss lthy;
  1363 
  1364 
  1364         val induct_type_attr = Attrib.internal o K o Induct.induct_type;
  1365         val induct_type_attr = Attrib.internal o K o Induct.induct_type;
       
  1366 
       
  1367         val (iterss', rec_thmss') =
       
  1368           if iterss = [[]] then ([map #casex ctr_sugars], map #case_thms ctr_sugars)
       
  1369           else (iterss, rec_thmss);
  1365 
  1370 
  1366         val simp_thmss =
  1371         val simp_thmss =
  1367           map6 mk_simp_thms ctr_sugars rec_thmss mapss rel_injects rel_distincts setss;
  1372           map6 mk_simp_thms ctr_sugars rec_thmss mapss rel_injects rel_distincts setss;
  1368 
  1373 
  1369         val common_notes =
  1374         val common_notes =
  1375            (recN, rec_thmss, K iter_attrs),
  1380            (recN, rec_thmss, K iter_attrs),
  1376            (simpsN, simp_thmss, K [])]
  1381            (simpsN, simp_thmss, K [])]
  1377           |> massage_multi_notes;
  1382           |> massage_multi_notes;
  1378       in
  1383       in
  1379         lthy
  1384         lthy
  1380         |> Spec_Rules.add Spec_Rules.Equational (map co_rec_of iterss, flat rec_thmss)
  1385         |> (if is_some iters_args_types then
       
  1386               Spec_Rules.add Spec_Rules.Equational (map co_rec_of iterss, flat rec_thmss)
       
  1387             else
       
  1388               I)
  1381         |> Local_Theory.notes (common_notes @ notes) |> snd
  1389         |> Local_Theory.notes (common_notes @ notes) |> snd
  1382         |> register_fp_sugars Xs Least_FP pre_bnfs absT_infos nested_bnfs nesting_bnfs fp_res
  1390         |> register_fp_sugars Xs Least_FP pre_bnfs absT_infos nested_bnfs nesting_bnfs fp_res
  1383           ctrXs_Tsss ctr_defss ctr_sugars iterss mapss [induct_thm] (map single induct_thms)
  1391           ctrXs_Tsss ctr_defss ctr_sugars iterss' mapss [induct_thm] (map single induct_thms)
  1384           (map single rec_thmss) (replicate nn []) (replicate nn [])
  1392           (map single rec_thmss') (replicate nn []) (replicate nn [])
  1385       end;
  1393       end;
  1386 
  1394 
  1387     fun derive_note_coinduct_coiters_thms_for_types
  1395     fun derive_note_coinduct_coiters_thms_for_types
  1388         ((((mapss, rel_injects, rel_distincts, setss), (_, _, ctr_defss, ctr_sugars)),
  1396         ((((mapss, rel_injects, rel_distincts, setss), (_, _, ctr_defss, ctr_sugars)),
  1389           (coiterss, coiter_defss)), lthy) =
  1397           (coiterss, coiter_defss)), lthy) =