src/HOL/Tools/BNF/bnf_lfp_rec_sugar.ML
changeset 62326 3cf7a067599c
parent 62323 8c3eec5812d8
child 62497 5b5b704f4811
equal deleted inserted replaced
62325:7e4d31eefe60 62326:3cf7a067599c
    26 
    26 
    27   type rec_spec =
    27   type rec_spec =
    28     {recx: term,
    28     {recx: term,
    29      fp_nesting_map_ident0s: thm list,
    29      fp_nesting_map_ident0s: thm list,
    30      fp_nesting_map_comps: thm list,
    30      fp_nesting_map_comps: thm list,
       
    31      fp_nesting_pred_maps: thm list,
    31      ctr_specs: rec_ctr_spec list}
    32      ctr_specs: rec_ctr_spec list}
    32 
    33 
    33   type basic_lfp_sugar =
    34   type basic_lfp_sugar =
    34     {T: typ,
    35     {T: typ,
    35      fp_res_index: int,
    36      fp_res_index: int,
    42   type lfp_rec_extension =
    43   type lfp_rec_extension =
    43     {nested_simps: thm list,
    44     {nested_simps: thm list,
    44      is_new_datatype: Proof.context -> string -> bool,
    45      is_new_datatype: Proof.context -> string -> bool,
    45      basic_lfp_sugars_of: binding list -> typ list -> term list ->
    46      basic_lfp_sugars_of: binding list -> typ list -> term list ->
    46        (term * term list list) list list -> local_theory ->
    47        (term * term list list) list list -> local_theory ->
    47        typ list * int list * basic_lfp_sugar list * thm list * thm list * thm * Token.src list
    48        typ list * int list * basic_lfp_sugar list * thm list * thm list * thm list * thm
    48        * bool * local_theory,
    49        * Token.src list * bool * local_theory,
    49      rewrite_nested_rec_call: (Proof.context -> (term -> bool) -> (string -> int) -> typ list ->
    50      rewrite_nested_rec_call: (Proof.context -> (term -> bool) -> (string -> int) -> typ list ->
    50        term -> term -> term -> term) option};
    51        term -> term -> term -> term) option};
    51 
    52 
    52   val register_lfp_rec_extension: lfp_rec_extension -> theory -> theory
    53   val register_lfp_rec_extension: lfp_rec_extension -> theory -> theory
    53   val default_basic_lfp_sugars_of: binding list -> typ list -> term list ->
    54   val default_basic_lfp_sugars_of: binding list -> typ list -> term list ->
    54     (term * term list list) list list -> local_theory ->
    55     (term * term list list) list list -> local_theory ->
    55     typ list * int list * basic_lfp_sugar list * thm list * thm list * thm * Token.src list * bool
    56     typ list * int list * basic_lfp_sugar list * thm list * thm list * thm list * thm
    56     * local_theory
    57     * Token.src list * bool * local_theory
    57   val rec_specs_of: binding list -> typ list -> typ list -> term list ->
    58   val rec_specs_of: binding list -> typ list -> typ list -> term list ->
    58     (term * term list list) list list -> local_theory ->
    59     (term * term list list) list list -> local_theory ->
    59     (bool * rec_spec list * typ list * thm * thm list * Token.src list * typ list) * local_theory
    60     (bool * rec_spec list * typ list * thm * thm list * Token.src list * typ list) * local_theory
    60 
    61 
    61   val lfp_rec_sugar_interpretation: string ->
    62   val lfp_rec_sugar_interpretation: string ->
   115 
   116 
   116 type rec_spec =
   117 type rec_spec =
   117   {recx: term,
   118   {recx: term,
   118    fp_nesting_map_ident0s: thm list,
   119    fp_nesting_map_ident0s: thm list,
   119    fp_nesting_map_comps: thm list,
   120    fp_nesting_map_comps: thm list,
       
   121    fp_nesting_pred_maps: thm list,
   120    ctr_specs: rec_ctr_spec list};
   122    ctr_specs: rec_ctr_spec list};
   121 
   123 
   122 type basic_lfp_sugar =
   124 type basic_lfp_sugar =
   123   {T: typ,
   125   {T: typ,
   124    fp_res_index: int,
   126    fp_res_index: int,
   131 type lfp_rec_extension =
   133 type lfp_rec_extension =
   132   {nested_simps: thm list,
   134   {nested_simps: thm list,
   133    is_new_datatype: Proof.context -> string -> bool,
   135    is_new_datatype: Proof.context -> string -> bool,
   134    basic_lfp_sugars_of: binding list -> typ list -> term list ->
   136    basic_lfp_sugars_of: binding list -> typ list -> term list ->
   135      (term * term list list) list list -> local_theory ->
   137      (term * term list list) list list -> local_theory ->
   136      typ list * int list * basic_lfp_sugar list * thm list * thm list * thm * Token.src list * bool
   138      typ list * int list * basic_lfp_sugar list * thm list * thm list * thm list * thm
   137      * local_theory,
   139      * Token.src list * bool * local_theory,
   138    rewrite_nested_rec_call: (Proof.context -> (term -> bool) -> (string -> int) -> typ list ->
   140    rewrite_nested_rec_call: (Proof.context -> (term -> bool) -> (string -> int) -> typ list ->
   139      term -> term -> term -> term) option};
   141      term -> term -> term -> term) option};
   140 
   142 
   141 structure Data = Theory_Data
   143 structure Data = Theory_Data
   142 (
   144 (
   170 
   172 
   171       val basic_lfp_sugar =
   173       val basic_lfp_sugar =
   172         {T = T, fp_res_index = 0, C = C, fun_arg_Tsss = fun_arg_Tsss, ctr_sugar = ctr_sugar,
   174         {T = T, fp_res_index = 0, C = C, fun_arg_Tsss = fun_arg_Tsss, ctr_sugar = ctr_sugar,
   173          recx = casex, rec_thms = case_thms};
   175          recx = casex, rec_thms = case_thms};
   174     in
   176     in
   175       ([], [0], [basic_lfp_sugar], [], [], TrueI, [], false, ctxt)
   177       ([], [0], [basic_lfp_sugar], [], [], [], TrueI (*dummy*), [], false, ctxt)
   176     end
   178     end
   177   | default_basic_lfp_sugars_of _ _ _ _ _ = error "Unsupported mutual recursion at this stage";
   179   | default_basic_lfp_sugars_of _ _ _ _ _ = error "Unsupported mutual recursion at this stage";
   178 
   180 
   179 fun basic_lfp_sugars_of bs arg_Ts callers callssss lthy =
   181 fun basic_lfp_sugars_of bs arg_Ts callers callssss lthy =
   180   (case Data.get (Proof_Context.theory_of lthy) of
   182   (case Data.get (Proof_Context.theory_of lthy) of
   197 fun rec_specs_of bs arg_Ts res_Ts callers callssss0 lthy0 =
   199 fun rec_specs_of bs arg_Ts res_Ts callers callssss0 lthy0 =
   198   let
   200   let
   199     val thy = Proof_Context.theory_of lthy0;
   201     val thy = Proof_Context.theory_of lthy0;
   200 
   202 
   201     val (missing_arg_Ts, perm0_kks, basic_lfp_sugars, fp_nesting_map_ident0s, fp_nesting_map_comps,
   203     val (missing_arg_Ts, perm0_kks, basic_lfp_sugars, fp_nesting_map_ident0s, fp_nesting_map_comps,
   202          common_induct, induct_attrs, n2m, lthy) =
   204          fp_nesting_pred_maps, common_induct, induct_attrs, n2m, lthy) =
   203       basic_lfp_sugars_of bs arg_Ts callers callssss0 lthy0;
   205       basic_lfp_sugars_of bs arg_Ts callers callssss0 lthy0;
   204 
   206 
   205     val perm_basic_lfp_sugars = sort (int_ord o apply2 #fp_res_index) basic_lfp_sugars;
   207     val perm_basic_lfp_sugars = sort (int_ord o apply2 #fp_res_index) basic_lfp_sugars;
   206 
   208 
   207     val indices = map #fp_res_index basic_lfp_sugars;
   209     val indices = map #fp_res_index basic_lfp_sugars;
   257 
   259 
   258     fun mk_spec ctr_offset
   260     fun mk_spec ctr_offset
   259         ({T, fp_res_index, ctr_sugar = {ctrs, ...}, recx, rec_thms, ...} : basic_lfp_sugar) =
   261         ({T, fp_res_index, ctr_sugar = {ctrs, ...}, recx, rec_thms, ...} : basic_lfp_sugar) =
   260       {recx = mk_co_rec thy Least_FP perm_Cs' (substAT T) recx,
   262       {recx = mk_co_rec thy Least_FP perm_Cs' (substAT T) recx,
   261        fp_nesting_map_ident0s = fp_nesting_map_ident0s, fp_nesting_map_comps = fp_nesting_map_comps,
   263        fp_nesting_map_ident0s = fp_nesting_map_ident0s, fp_nesting_map_comps = fp_nesting_map_comps,
       
   264        fp_nesting_pred_maps = fp_nesting_pred_maps,
   262        ctr_specs = mk_ctr_specs fp_res_index ctr_offset ctrs rec_thms};
   265        ctr_specs = mk_ctr_specs fp_res_index ctr_offset ctrs rec_thms};
   263   in
   266   in
   264     ((n2m, map2 mk_spec ctr_offsets basic_lfp_sugars, missing_arg_Ts, common_induct, inducts,
   267     ((n2m, map2 mk_spec ctr_offsets basic_lfp_sugars, missing_arg_Ts, common_induct, inducts,
   265       induct_attrs, map #T basic_lfp_sugars), lthy)
   268       induct_attrs, map #T basic_lfp_sugars), lthy)
   266   end;
   269   end;
   490   in
   493   in
   491     map (find [] rhs_term) ctr_args
   494     map (find [] rhs_term) ctr_args
   492     |> (fn [] => NONE | callss => SOME (ctr, callss))
   495     |> (fn [] => NONE | callss => SOME (ctr, callss))
   493   end;
   496   end;
   494 
   497 
   495 fun mk_primrec_tac ctxt num_extra_args map_ident0s map_comps fun_defs recx =
   498 fun mk_primrec_tac ctxt num_extra_args fp_nesting_map_ident0s fp_nesting_map_comps
       
   499     fp_nesting_pred_maps fun_defs recx =
   496   unfold_thms_tac ctxt fun_defs THEN
   500   unfold_thms_tac ctxt fun_defs THEN
   497   HEADGOAL (rtac ctxt (funpow num_extra_args (fn thm => thm RS fun_cong) recx RS trans)) THEN
   501   HEADGOAL (rtac ctxt (funpow num_extra_args (fn thm => thm RS fun_cong) recx RS trans)) THEN
   498   unfold_thms_tac ctxt (nested_simps ctxt @ map_ident0s @ map_comps) THEN
   502   unfold_thms_tac ctxt (nested_simps ctxt @ fp_nesting_map_ident0s @ fp_nesting_map_comps @
       
   503     fp_nesting_pred_maps) THEN
   499   HEADGOAL (rtac ctxt refl);
   504   HEADGOAL (rtac ctxt refl);
   500 
   505 
   501 fun prepare_primrec plugins nonexhaustives transfers fixes specs lthy0 =
   506 fun prepare_primrec plugins nonexhaustives transfers fixes specs lthy0 =
   502   let
   507   let
   503     val thy = Proof_Context.theory_of lthy0;
   508     val thy = Proof_Context.theory_of lthy0;
   539         error_at lthy0 [user_eqn] ("Argument " ^ quote (Syntax.string_of_term lthy ctr) ^
   544         error_at lthy0 [user_eqn] ("Argument " ^ quote (Syntax.string_of_term lthy ctr) ^
   540           " is not a constructor in left-hand side")) eqns_data;
   545           " is not a constructor in left-hand side")) eqns_data;
   541 
   546 
   542     val defs = build_defs lthy nonexhaustives bs mxs funs_data rec_specs has_call;
   547     val defs = build_defs lthy nonexhaustives bs mxs funs_data rec_specs has_call;
   543 
   548 
   544     fun prove def_thms ({ctr_specs, fp_nesting_map_ident0s, fp_nesting_map_comps, ...} : rec_spec)
   549     fun prove def_thms ({ctr_specs, fp_nesting_map_ident0s, fp_nesting_map_comps,
   545         (fun_data : eqn_data list) lthy' =
   550         fp_nesting_pred_maps, ...} : rec_spec) (fun_data : eqn_data list) lthy' =
   546       let
   551       let
   547         val js =
   552         val js =
   548           find_indices (op = o apply2 (fn {fun_name, ctr, ...} => (fun_name, ctr)))
   553           find_indices (op = o apply2 (fn {fun_name, ctr, ...} => (fun_name, ctr)))
   549             fun_data eqns_data;
   554             fun_data eqns_data;
   550 
   555 
   554             (#user_eqn x, length (#left_args x) + length (#right_args x), #rec_thm y)))
   559             (#user_eqn x, length (#left_args x) + length (#right_args x), #rec_thm y)))
   555           |> map (fn (user_eqn, num_extra_args, rec_thm) =>
   560           |> map (fn (user_eqn, num_extra_args, rec_thm) =>
   556               Goal.prove_sorry lthy' [] [] user_eqn
   561               Goal.prove_sorry lthy' [] [] user_eqn
   557                 (fn {context = ctxt, prems = _} =>
   562                 (fn {context = ctxt, prems = _} =>
   558                   mk_primrec_tac ctxt num_extra_args fp_nesting_map_ident0s fp_nesting_map_comps
   563                   mk_primrec_tac ctxt num_extra_args fp_nesting_map_ident0s fp_nesting_map_comps
   559                     def_thms rec_thm)
   564                     fp_nesting_pred_maps def_thms rec_thm)
   560               |> Thm.close_derivation);
   565               |> Thm.close_derivation);
   561       in
   566       in
   562         ((js, simps), lthy')
   567         ((js, simps), lthy')
   563       end;
   568       end;
   564 
   569