src/HOL/BNF/Tools/bnf_fp_n2m_sugar.ML
changeset 54256 4843082be7ef
parent 54255 4f7c016d5bc6
child 54265 3e1d230f1c00
equal deleted inserted replaced
54255:4f7c016d5bc6 54256:4843082be7ef
    35 open BNF_FP_Def_Sugar
    35 open BNF_FP_Def_Sugar
    36 open BNF_FP_N2M
    36 open BNF_FP_N2M
    37 
    37 
    38 val n2mN = "n2m_"
    38 val n2mN = "n2m_"
    39 
    39 
       
    40 type n2m_sugar = fp_sugar list * (lfp_sugar_thms option * gfp_sugar_thms option);
       
    41 
       
    42 structure Data = Generic_Data
       
    43 (
       
    44   type T = n2m_sugar Typtab.table;
       
    45   val empty = Typtab.empty;
       
    46   val extend = I;
       
    47   val merge = Typtab.merge (eq_fst (eq_list eq_fp_sugar));
       
    48 );
       
    49 
       
    50 fun morph_n2m_sugar phi (fp_sugars, (lfp_sugar_thms_opt, gfp_sugar_thms_opt)) =
       
    51   (map (morph_fp_sugar phi) fp_sugars,
       
    52    (Option.map (morph_lfp_sugar_thms phi) lfp_sugar_thms_opt,
       
    53     Option.map (morph_gfp_sugar_thms phi) gfp_sugar_thms_opt));
       
    54 
       
    55 val transfer_n2m_sugar =
       
    56   morph_n2m_sugar o Morphism.thm_morphism o Thm.transfer o Proof_Context.theory_of;
       
    57 
       
    58 fun n2m_sugar_of ctxt =
       
    59   Typtab.lookup (Data.get (Context.Proof ctxt))
       
    60   #> Option.map (transfer_n2m_sugar ctxt);
       
    61 
       
    62 fun register_n2m_sugar key n2m_sugar =
       
    63   Local_Theory.declaration {syntax = false, pervasive = false}
       
    64     (fn phi => Data.map (Typtab.default (key, morph_n2m_sugar phi n2m_sugar)));
       
    65 
    40 fun unfold_let (Const (@{const_name Let}, _) $ arg1 $ arg2) = unfold_let (betapply (arg2, arg1))
    66 fun unfold_let (Const (@{const_name Let}, _) $ arg1 $ arg2) = unfold_let (betapply (arg2, arg1))
    41   | unfold_let (Const (@{const_name prod_case}, _) $ t) =
    67   | unfold_let (Const (@{const_name prod_case}, _) $ t) =
    42     (case unfold_let t of
    68     (case unfold_let t of
    43       t' as Abs (s1, T1, Abs (s2, T2, _)) =>
    69       t' as Abs (s1, T1, Abs (s2, T2, _)) =>
    44       let
    70       let
    91 fun map_partition f xs =
   117 fun map_partition f xs =
    92   fold_rev (fn x => fn (ys, (good, bad)) =>
   118   fold_rev (fn x => fn (ys, (good, bad)) =>
    93       case f x of SOME y => (y :: ys, (x :: good, bad)) | NONE => (ys, (good, x :: bad)))
   119       case f x of SOME y => (y :: ys, (x :: good, bad)) | NONE => (ys, (good, x :: bad)))
    94     xs ([], ([], []));
   120     xs ([], ([], []));
    95 
   121 
       
   122 fun key_of_fp_eqs fp fpTs fp_eqs =
       
   123   Type (fp_case fp "l" "g", fpTs @ maps (fn (z, T) => [TFree z, T]) fp_eqs);
       
   124 
    96 (* TODO: test with sort constraints on As *)
   125 (* TODO: test with sort constraints on As *)
    97 (* TODO: use right sorting order for "fp_sort" w.r.t. original BNFs (?) -- treat new variables
   126 (* TODO: use right sorting order for "fp_sort" w.r.t. original BNFs (?) -- treat new variables
    98    as deads? *)
   127    as deads? *)
    99 fun mutualize_fp_sugars has_nested fp bs fpTs get_indices callssss fp_sugars0 no_defs_lthy0 =
   128 fun mutualize_fp_sugars has_nested fp bs fpTs get_indices callssss fp_sugars0 no_defs_lthy0 =
   100   if has_nested then
   129   if has_nested then
   166       val ns = map length ctr_Tsss;
   195       val ns = map length ctr_Tsss;
   167       val kss = map (fn n => 1 upto n) ns;
   196       val kss = map (fn n => 1 upto n) ns;
   168       val mss = map (map length) ctr_Tsss;
   197       val mss = map (map length) ctr_Tsss;
   169 
   198 
   170       val fp_eqs = map dest_TFree Xs ~~ ctrXs_sum_prod_Ts;
   199       val fp_eqs = map dest_TFree Xs ~~ ctrXs_sum_prod_Ts;
   171 
   200       val key = key_of_fp_eqs fp fpTs fp_eqs;
   172       val base_fp_names = Name.variant_list [] fp_b_names;
       
   173       val fp_bs = map2 (fn b_name => fn base_fp_name =>
       
   174           Binding.qualify true b_name (Binding.name (n2mN ^ base_fp_name)))
       
   175         b_names base_fp_names;
       
   176 
       
   177       val (pre_bnfs, (fp_res as {xtor_co_iterss = xtor_co_iterss0, xtor_co_induct,
       
   178              dtor_injects, dtor_ctors, xtor_co_iter_thmss, ...}, lthy)) =
       
   179         fp_bnf (construct_mutualized_fp fp fpTs fp_sugars0) fp_bs As' fp_eqs no_defs_lthy;
       
   180 
       
   181       val nesting_bnfs = nesty_bnfs lthy ctrXs_Tsss As;
       
   182       val nested_bnfs = nesty_bnfs lthy ctrXs_Tsss Xs;
       
   183 
       
   184       val ((xtor_co_iterss, iters_args_types, coiters_args_types), _) =
       
   185         mk_co_iters_prelims fp ctr_Tsss fpTs Cs ns mss xtor_co_iterss0 lthy;
       
   186 
       
   187       fun mk_binding b suf = Binding.suffix_name ("_" ^ suf) b;
       
   188 
       
   189       val ((co_iterss, co_iter_defss), lthy) =
       
   190         fold_map2 (fn b =>
       
   191           (if fp = Least_FP then define_iters [foldN, recN] (the iters_args_types)
       
   192            else define_coiters [unfoldN, corecN] (the coiters_args_types))
       
   193             (mk_binding b) fpTs Cs) fp_bs xtor_co_iterss lthy
       
   194         |>> split_list;
       
   195 
       
   196       val rho = tvar_subst thy Ts fpTs;
       
   197       val ctr_sugar_phi =
       
   198         Morphism.compose (Morphism.typ_morphism (Term.typ_subst_TVars rho))
       
   199           (Morphism.term_morphism (Term.subst_TVars rho));
       
   200       val inst_ctr_sugar = morph_ctr_sugar ctr_sugar_phi;
       
   201 
       
   202       val ctr_sugars = map inst_ctr_sugar ctr_sugars0;
       
   203 
       
   204       val ((co_inducts, un_fold_thmss, co_rec_thmss, disc_unfold_thmss, disc_corec_thmss,
       
   205             sel_unfold_thmsss, sel_corec_thmsss), fp_sugar_thms) =
       
   206         if fp = Least_FP then
       
   207           derive_induct_iters_thms_for_types pre_bnfs (the iters_args_types) xtor_co_induct
       
   208             xtor_co_iter_thmss nesting_bnfs nested_bnfs fpTs Cs Xs ctrXs_Tsss ctrss ctr_defss
       
   209             co_iterss co_iter_defss lthy
       
   210           |> `(fn ((_, induct, _), (fold_thmss, rec_thmss, _)) =>
       
   211             ([induct], fold_thmss, rec_thmss, [], [], [], []))
       
   212           ||> (fn info => (SOME info, NONE))
       
   213         else
       
   214           derive_coinduct_coiters_thms_for_types pre_bnfs (the coiters_args_types) xtor_co_induct
       
   215             dtor_injects dtor_ctors xtor_co_iter_thmss nesting_bnfs fpTs Cs Xs ctrXs_Tsss kss mss ns
       
   216             ctr_defss ctr_sugars co_iterss co_iter_defss (Proof_Context.export lthy no_defs_lthy)
       
   217             lthy
       
   218           |> `(fn ((coinduct_thms_pairs, _), (unfold_thmss, corec_thmss, _),
       
   219                   (disc_unfold_thmss, disc_corec_thmss, _), _,
       
   220                   (sel_unfold_thmsss, sel_corec_thmsss, _)) =>
       
   221             (map snd coinduct_thms_pairs, unfold_thmss, corec_thmss, disc_unfold_thmss,
       
   222              disc_corec_thmss, sel_unfold_thmsss, sel_corec_thmsss))
       
   223           ||> (fn info => (NONE, SOME info));
       
   224 
       
   225       val phi = Proof_Context.export_morphism no_defs_lthy no_defs_lthy0;
       
   226 
       
   227       fun mk_target_fp_sugar (kk, T) =
       
   228         {T = T, fp = fp, index = kk, pre_bnfs = pre_bnfs, nested_bnfs = nested_bnfs,
       
   229          nesting_bnfs = nesting_bnfs, fp_res = fp_res, ctr_defss = ctr_defss,
       
   230          ctr_sugars = ctr_sugars, co_iterss = co_iterss, mapss = mapss, co_inducts = co_inducts,
       
   231          co_iter_thmsss = transpose [un_fold_thmss, co_rec_thmss],
       
   232          disc_co_itersss = transpose [disc_unfold_thmss, disc_corec_thmss],
       
   233          sel_co_iterssss = transpose [sel_unfold_thmsss, sel_corec_thmsss]}
       
   234         |> morph_fp_sugar phi;
       
   235     in
   201     in
   236       ((map_index mk_target_fp_sugar fpTs, fp_sugar_thms), lthy)
   202       (case n2m_sugar_of no_defs_lthy key of
       
   203         SOME n2m_sugar => (n2m_sugar, no_defs_lthy)
       
   204       | NONE =>
       
   205         let
       
   206           val base_fp_names = Name.variant_list [] fp_b_names;
       
   207           val fp_bs = map2 (fn b_name => fn base_fp_name =>
       
   208               Binding.qualify true b_name (Binding.name (n2mN ^ base_fp_name)))
       
   209             b_names base_fp_names;
       
   210 
       
   211           val (pre_bnfs, (fp_res as {xtor_co_iterss = xtor_co_iterss0, xtor_co_induct,
       
   212                  dtor_injects, dtor_ctors, xtor_co_iter_thmss, ...}, lthy)) =
       
   213             fp_bnf (construct_mutualized_fp fp fpTs fp_sugars0) fp_bs As' fp_eqs no_defs_lthy;
       
   214 
       
   215           val nesting_bnfs = nesty_bnfs lthy ctrXs_Tsss As;
       
   216           val nested_bnfs = nesty_bnfs lthy ctrXs_Tsss Xs;
       
   217 
       
   218           val ((xtor_co_iterss, iters_args_types, coiters_args_types), _) =
       
   219             mk_co_iters_prelims fp ctr_Tsss fpTs Cs ns mss xtor_co_iterss0 lthy;
       
   220 
       
   221           fun mk_binding b suf = Binding.suffix_name ("_" ^ suf) b;
       
   222 
       
   223           val ((co_iterss, co_iter_defss), lthy) =
       
   224             fold_map2 (fn b =>
       
   225               (if fp = Least_FP then define_iters [foldN, recN] (the iters_args_types)
       
   226                else define_coiters [unfoldN, corecN] (the coiters_args_types))
       
   227                 (mk_binding b) fpTs Cs) fp_bs xtor_co_iterss lthy
       
   228             |>> split_list;
       
   229 
       
   230           val rho = tvar_subst thy Ts fpTs;
       
   231           val ctr_sugar_phi =
       
   232             Morphism.compose (Morphism.typ_morphism (Term.typ_subst_TVars rho))
       
   233               (Morphism.term_morphism (Term.subst_TVars rho));
       
   234           val inst_ctr_sugar = morph_ctr_sugar ctr_sugar_phi;
       
   235 
       
   236           val ctr_sugars = map inst_ctr_sugar ctr_sugars0;
       
   237 
       
   238           val ((co_inducts, un_fold_thmss, co_rec_thmss, disc_unfold_thmss, disc_corec_thmss,
       
   239                 sel_unfold_thmsss, sel_corec_thmsss), fp_sugar_thms) =
       
   240             if fp = Least_FP then
       
   241               derive_induct_iters_thms_for_types pre_bnfs (the iters_args_types) xtor_co_induct
       
   242                 xtor_co_iter_thmss nesting_bnfs nested_bnfs fpTs Cs Xs ctrXs_Tsss ctrss ctr_defss
       
   243                 co_iterss co_iter_defss lthy
       
   244               |> `(fn ((_, induct, _), (fold_thmss, rec_thmss, _)) =>
       
   245                 ([induct], fold_thmss, rec_thmss, [], [], [], []))
       
   246               ||> (fn info => (SOME info, NONE))
       
   247             else
       
   248               derive_coinduct_coiters_thms_for_types pre_bnfs (the coiters_args_types)
       
   249                 xtor_co_induct dtor_injects dtor_ctors xtor_co_iter_thmss nesting_bnfs fpTs Cs Xs
       
   250                 ctrXs_Tsss kss mss ns ctr_defss ctr_sugars co_iterss co_iter_defss
       
   251                 (Proof_Context.export lthy no_defs_lthy) lthy
       
   252               |> `(fn ((coinduct_thms_pairs, _), (unfold_thmss, corec_thmss, _),
       
   253                       (disc_unfold_thmss, disc_corec_thmss, _), _,
       
   254                       (sel_unfold_thmsss, sel_corec_thmsss, _)) =>
       
   255                 (map snd coinduct_thms_pairs, unfold_thmss, corec_thmss, disc_unfold_thmss,
       
   256                  disc_corec_thmss, sel_unfold_thmsss, sel_corec_thmsss))
       
   257               ||> (fn info => (NONE, SOME info));
       
   258 
       
   259           val phi = Proof_Context.export_morphism no_defs_lthy no_defs_lthy0;
       
   260 
       
   261           fun mk_target_fp_sugar (kk, T) =
       
   262             {T = T, fp = fp, index = kk, pre_bnfs = pre_bnfs, nested_bnfs = nested_bnfs,
       
   263              nesting_bnfs = nesting_bnfs, fp_res = fp_res, ctr_defss = ctr_defss,
       
   264              ctr_sugars = ctr_sugars, co_iterss = co_iterss, mapss = mapss, co_inducts = co_inducts,
       
   265              co_iter_thmsss = transpose [un_fold_thmss, co_rec_thmss],
       
   266              disc_co_itersss = transpose [disc_unfold_thmss, disc_corec_thmss],
       
   267              sel_co_iterssss = transpose [sel_unfold_thmsss, sel_corec_thmsss]}
       
   268             |> morph_fp_sugar phi;
       
   269 
       
   270           val n2m_sugar = (map_index mk_target_fp_sugar fpTs, fp_sugar_thms);
       
   271         in
       
   272           (n2m_sugar, lthy |> register_n2m_sugar key n2m_sugar)
       
   273         end)
   237     end
   274     end
   238   else
   275   else
   239     (* TODO: reorder hypotheses and predicates in (co)induction rules? *)
       
   240     ((fp_sugars0, (NONE, NONE)), no_defs_lthy0);
   276     ((fp_sugars0, (NONE, NONE)), no_defs_lthy0);
   241 
   277 
   242 fun indexify_callsss fp_sugar callsss =
   278 fun indexify_callsss fp_sugar callsss =
   243   let
   279   let
   244     val {ctrs, ...} = of_fp_sugar #ctr_sugars fp_sugar;
   280     val {ctrs, ...} = of_fp_sugar #ctr_sugars fp_sugar;
   297     val perm_Ts = check_enrich_with_mutuals [] perm_actual_Ts;
   333     val perm_Ts = check_enrich_with_mutuals [] perm_actual_Ts;
   298     val missing_Ts = perm_Ts |> subtract (op =) actual_Ts;
   334     val missing_Ts = perm_Ts |> subtract (op =) actual_Ts;
   299     val Ts = actual_Ts @ missing_Ts;
   335     val Ts = actual_Ts @ missing_Ts;
   300 
   336 
   301     fun generalize_simple_type T (seen, lthy) =
   337     fun generalize_simple_type T (seen, lthy) =
   302       mk_TFrees 1 lthy |> (fn ([U], lthy) => (U, ((T, U) :: seen, lthy)));
   338       variant_tfrees ["aa"] lthy |> (fn ([U], lthy) => (U, ((T, U) :: seen, lthy)));
   303 
   339 
   304     fun generalize_type T (seen_lthy as (seen, _)) =
   340     fun generalize_type T (seen_lthy as (seen, _)) =
   305       (case AList.lookup (op =) seen T of
   341       (case AList.lookup (op =) seen T of
   306         SOME U => (U, seen_lthy)
   342         SOME U => (U, seen_lthy)
   307       | NONE =>
   343       | NONE =>