src/HOL/BNF/Tools/bnf_fp_n2m_sugar.ML
changeset 54009 f138452e8265
parent 54006 9fe1bd54d437
child 54030 732b53d9b720
equal deleted inserted replaced
54008:b15cfc2864de 54009:f138452e8265
     5 Suggared flattening of nested to mutual (co)recursion.
     5 Suggared flattening of nested to mutual (co)recursion.
     6 *)
     6 *)
     7 
     7 
     8 signature BNF_FP_N2M_SUGAR =
     8 signature BNF_FP_N2M_SUGAR =
     9 sig
     9 sig
    10   val mutualize_fp_sugars: bool -> bool -> BNF_FP_Util.fp_kind -> binding list -> typ list ->
    10   val mutualize_fp_sugars: bool -> BNF_FP_Util.fp_kind -> binding list -> typ list ->
    11     (term -> int list) -> term list list list list -> BNF_FP_Def_Sugar.fp_sugar list ->
    11     (term -> int list) -> term list list list list -> BNF_FP_Def_Sugar.fp_sugar list ->
    12     local_theory ->
    12     local_theory ->
    13     (BNF_FP_Def_Sugar.fp_sugar list
    13     (BNF_FP_Def_Sugar.fp_sugar list
    14      * (BNF_FP_Def_Sugar.lfp_sugar_thms option * BNF_FP_Def_Sugar.gfp_sugar_thms option))
    14      * (BNF_FP_Def_Sugar.lfp_sugar_thms option * BNF_FP_Def_Sugar.gfp_sugar_thms option))
    15     * local_theory
    15     * local_theory
    16   val pad_and_indexify_calls: BNF_FP_Def_Sugar.fp_sugar list -> int ->
    16   val pad_and_indexify_calls: BNF_FP_Def_Sugar.fp_sugar list -> int ->
    17     (term * term list list) list list -> term list list list list
    17     (term * term list list) list list -> term list list list list
    18   val nested_to_mutual_fps: bool -> BNF_FP_Util.fp_kind -> binding list -> typ list ->
    18   val nested_to_mutual_fps: BNF_FP_Util.fp_kind -> binding list -> typ list -> (term -> int list) ->
    19     (term -> int list) -> ((term * term list list) list) list -> local_theory ->
    19     (term * term list list) list list -> local_theory ->
    20     (typ list * int list * BNF_FP_Def_Sugar.fp_sugar list
    20     (typ list * int list * BNF_FP_Def_Sugar.fp_sugar list
    21      * (BNF_FP_Def_Sugar.lfp_sugar_thms option * BNF_FP_Def_Sugar.gfp_sugar_thms option))
    21      * (BNF_FP_Def_Sugar.lfp_sugar_thms option * BNF_FP_Def_Sugar.gfp_sugar_thms option))
    22     * local_theory
    22     * local_theory
    23 end;
    23 end;
    24 
    24 
    35 val n2mN = "n2m_"
    35 val n2mN = "n2m_"
    36 
    36 
    37 (* TODO: test with sort constraints on As *)
    37 (* TODO: test with sort constraints on As *)
    38 (* TODO: use right sorting order for "fp_sort" w.r.t. original BNFs (?) -- treat new variables
    38 (* TODO: use right sorting order for "fp_sort" w.r.t. original BNFs (?) -- treat new variables
    39    as deads? *)
    39    as deads? *)
    40 fun mutualize_fp_sugars lose_co_rec mutualize fp bs fpTs get_indices callssss fp_sugars0
    40 fun mutualize_fp_sugars mutualize fp bs fpTs get_indices callssss fp_sugars0 no_defs_lthy0 =
    41     no_defs_lthy0 =
       
    42   (* TODO: Also check whether there's any lost recursion? *)
       
    43   if mutualize orelse has_duplicates (op =) fpTs then
    41   if mutualize orelse has_duplicates (op =) fpTs then
    44     let
    42     let
    45       val thy = Proof_Context.theory_of no_defs_lthy0;
    43       val thy = Proof_Context.theory_of no_defs_lthy0;
    46 
    44 
    47       val qsotm = quote o Syntax.string_of_term no_defs_lthy0;
    45       val qsotm = quote o Syntax.string_of_term no_defs_lthy0;
    77         no_defs_lthy0
    75         no_defs_lthy0
    78         |> fold Variable.declare_typ As
    76         |> fold Variable.declare_typ As
    79         |> mk_TFrees nn
    77         |> mk_TFrees nn
    80         ||>> variant_tfrees fp_b_names;
    78         ||>> variant_tfrees fp_b_names;
    81 
    79 
    82       (* If "lose_co_rec" is "true", the function "null" on "'a list" gives rise to
       
    83            'list = unit + 'a list
       
    84          instead of
       
    85            'list = unit + 'list
       
    86          resulting in a simpler (co)induction rule and (co)recursor. *)
       
    87       fun freeze_fp_default (T as Type (s, Ts)) =
    80       fun freeze_fp_default (T as Type (s, Ts)) =
    88           (case find_index (curry (op =) T) fpTs of
    81           (case find_index (curry (op =) T) fpTs of
    89             ~1 => Type (s, map freeze_fp_default Ts)
    82             ~1 => Type (s, map freeze_fp_default Ts)
    90           | kk => nth Xs kk)
    83           | kk => nth Xs kk)
    91         | freeze_fp_default T = T;
    84         | freeze_fp_default T = T;
    98       fun freeze_fp calls (T as Type (s, Ts)) =
    91       fun freeze_fp calls (T as Type (s, Ts)) =
    99           (case map_filter (try (snd o dest_map no_defs_lthy s)) calls of
    92           (case map_filter (try (snd o dest_map no_defs_lthy s)) calls of
   100             [] =>
    93             [] =>
   101             (case union (op = o pairself fst)
    94             (case union (op = o pairself fst)
   102                 (maps (fn call => map (rpair call) (get_indices_checked call)) calls) [] of
    95                 (maps (fn call => map (rpair call) (get_indices_checked call)) calls) [] of
   103               [] => T |> not lose_co_rec ? freeze_fp_default
    96               [] => freeze_fp_default T
   104             | [(kk, _)] => nth Xs kk
    97             | [(kk, _)] => nth Xs kk
   105             | (_, call1) :: (_, call2) :: _ => incompatible_calls call1 call2)
    98             | (_, call1) :: (_, call2) :: _ => incompatible_calls call1 call2)
   106           | callss =>
    99           | callss =>
   107             Type (s, map2 freeze_fp (flatten_type_args_of_bnf (the (bnf_of no_defs_lthy s)) []
   100             Type (s, map2 freeze_fp (flatten_type_args_of_bnf (the (bnf_of no_defs_lthy s)) []
   108               (transpose callss)) Ts))
   101               (transpose callss)) Ts))
   199     map do_ctr ctrs
   192     map do_ctr ctrs
   200   end;
   193   end;
   201 
   194 
   202 fun pad_and_indexify_calls fp_sugars0 = map2 indexify_callsss fp_sugars0 oo pad_list [];
   195 fun pad_and_indexify_calls fp_sugars0 = map2 indexify_callsss fp_sugars0 oo pad_list [];
   203 
   196 
   204 fun nested_to_mutual_fps lose_co_rec fp actual_bs actual_Ts get_indices actual_callssss0 lthy =
   197 fun nested_to_mutual_fps fp actual_bs actual_Ts get_indices actual_callssss0 lthy =
   205   let
   198   let
   206     val qsoty = quote o Syntax.string_of_typ lthy;
   199     val qsoty = quote o Syntax.string_of_typ lthy;
   207     val qsotys = space_implode " or " o map qsoty;
   200     val qsotys = space_implode " or " o map qsoty;
   208 
   201 
   209     fun not_co_datatype0 T = error (qsoty T ^ " is not a " ^ co_prefix fp ^ "datatype");
   202     fun not_co_datatype0 T = error (qsoty T ^ " is not a " ^ co_prefix fp ^ "datatype");
   262     val perm_callssss = pad_and_indexify_calls perm_fp_sugars0 nn actual_callssss0;
   255     val perm_callssss = pad_and_indexify_calls perm_fp_sugars0 nn actual_callssss0;
   263 
   256 
   264     val get_perm_indices = map (fn kk => find_index (curry (op =) kk) perm_kks) o get_indices;
   257     val get_perm_indices = map (fn kk => find_index (curry (op =) kk) perm_kks) o get_indices;
   265 
   258 
   266     val ((perm_fp_sugars, fp_sugar_thms), lthy) =
   259     val ((perm_fp_sugars, fp_sugar_thms), lthy) =
   267       mutualize_fp_sugars lose_co_rec mutualize fp perm_bs perm_Ts get_perm_indices perm_callssss
   260       mutualize_fp_sugars mutualize fp perm_bs perm_Ts get_perm_indices perm_callssss
   268         perm_fp_sugars0 lthy;
   261         perm_fp_sugars0 lthy;
   269 
   262 
   270     val fp_sugars = unpermute perm_fp_sugars;
   263     val fp_sugars = unpermute perm_fp_sugars;
   271   in
   264   in
   272     ((missing_Ts, perm_kks, fp_sugars, fp_sugar_thms), lthy)
   265     ((missing_Ts, perm_kks, fp_sugars, fp_sugar_thms), lthy)