src/HOL/Tools/BNF/bnf_lfp_rec_sugar.ML
changeset 57399 cfc19f0a6261
parent 57397 5004aca20821
child 57527 1b07ca054327
equal deleted inserted replaced
57398:882091eb1e9a 57399:cfc19f0a6261
    77    calls: rec_call list,
    77    calls: rec_call list,
    78    rec_thm: thm};
    78    rec_thm: thm};
    79 
    79 
    80 type rec_spec =
    80 type rec_spec =
    81   {recx: term,
    81   {recx: term,
    82    fp_nesting_map_idents: thm list,
    82    fp_nesting_map_ident0s: thm list,
    83    fp_nesting_map_comps: thm list,
    83    fp_nesting_map_comps: thm list,
    84    ctr_specs: rec_ctr_spec list};
    84    ctr_specs: rec_ctr_spec list};
    85 
    85 
    86 type basic_lfp_sugar =
    86 type basic_lfp_sugar =
    87   {T: typ,
    87   {T: typ,
   133 
   133 
   134 fun rec_specs_of bs arg_Ts res_Ts callers callssss0 lthy0 =
   134 fun rec_specs_of bs arg_Ts res_Ts callers callssss0 lthy0 =
   135   let
   135   let
   136     val thy = Proof_Context.theory_of lthy0;
   136     val thy = Proof_Context.theory_of lthy0;
   137 
   137 
   138     val (missing_arg_Ts, perm0_kks, basic_lfp_sugars, fp_nesting_map_idents, fp_nesting_map_comps,
   138     val (missing_arg_Ts, perm0_kks, basic_lfp_sugars, fp_nesting_map_ident0s, fp_nesting_map_comps,
   139          common_induct, n2m, lthy) =
   139          common_induct, n2m, lthy) =
   140       get_basic_lfp_sugars bs arg_Ts callers callssss0 lthy0;
   140       get_basic_lfp_sugars bs arg_Ts callers callssss0 lthy0;
   141 
   141 
   142     val perm_basic_lfp_sugars = sort (int_ord o pairself #fp_res_index) basic_lfp_sugars;
   142     val perm_basic_lfp_sugars = sort (int_ord o pairself #fp_res_index) basic_lfp_sugars;
   143 
   143 
   193         rec_thms;
   193         rec_thms;
   194 
   194 
   195     fun mk_spec ctr_offset
   195     fun mk_spec ctr_offset
   196         ({T, fp_res_index, ctr_sugar = {ctrs, ...}, recx, rec_thms, ...} : basic_lfp_sugar) =
   196         ({T, fp_res_index, ctr_sugar = {ctrs, ...}, recx, rec_thms, ...} : basic_lfp_sugar) =
   197       {recx = mk_co_rec thy Least_FP (substAT T) perm_Cs' recx,
   197       {recx = mk_co_rec thy Least_FP (substAT T) perm_Cs' recx,
   198        fp_nesting_map_idents = fp_nesting_map_idents, fp_nesting_map_comps = fp_nesting_map_comps,
   198        fp_nesting_map_ident0s = fp_nesting_map_ident0s, fp_nesting_map_comps = fp_nesting_map_comps,
   199        ctr_specs = mk_ctr_specs fp_res_index ctr_offset ctrs rec_thms};
   199        ctr_specs = mk_ctr_specs fp_res_index ctr_offset ctrs rec_thms};
   200   in
   200   in
   201     ((n2m, map2 mk_spec ctr_offsets basic_lfp_sugars, missing_arg_Ts, common_induct, inducts), lthy)
   201     ((n2m, map2 mk_spec ctr_offsets basic_lfp_sugars, missing_arg_Ts, common_induct, inducts), lthy)
   202   end;
   202   end;
   203 
   203 
   413   in
   413   in
   414     map (find [] rhs_term) ctr_args
   414     map (find [] rhs_term) ctr_args
   415     |> (fn [] => NONE | callss => SOME (ctr, callss))
   415     |> (fn [] => NONE | callss => SOME (ctr, callss))
   416   end;
   416   end;
   417 
   417 
   418 fun mk_primrec_tac ctxt num_extra_args map_idents map_comps fun_defs recx =
   418 fun mk_primrec_tac ctxt num_extra_args map_ident0s map_comps fun_defs recx =
   419   unfold_thms_tac ctxt fun_defs THEN
   419   unfold_thms_tac ctxt fun_defs THEN
   420   HEADGOAL (rtac (funpow num_extra_args (fn thm => thm RS fun_cong) recx RS trans)) THEN
   420   HEADGOAL (rtac (funpow num_extra_args (fn thm => thm RS fun_cong) recx RS trans)) THEN
   421   unfold_thms_tac ctxt (nested_simps ctxt @ map_comps @ map_idents) THEN
   421   unfold_thms_tac ctxt (nested_simps ctxt @ map_ident0s @ map_comps) THEN
   422   HEADGOAL (rtac refl);
   422   HEADGOAL (rtac refl);
   423 
   423 
   424 fun prepare_primrec nonexhaustive fixes specs lthy0 =
   424 fun prepare_primrec nonexhaustive fixes specs lthy0 =
   425   let
   425   let
   426     val thy = Proof_Context.theory_of lthy0;
   426     val thy = Proof_Context.theory_of lthy0;
   462         raise PRIMREC ("argument " ^ quote (Syntax.string_of_term lthy ctr) ^
   462         raise PRIMREC ("argument " ^ quote (Syntax.string_of_term lthy ctr) ^
   463           " is not a constructor in left-hand side", [user_eqn])) eqns_data;
   463           " is not a constructor in left-hand side", [user_eqn])) eqns_data;
   464 
   464 
   465     val defs = build_defs lthy nonexhaustive bs mxs funs_data rec_specs has_call;
   465     val defs = build_defs lthy nonexhaustive bs mxs funs_data rec_specs has_call;
   466 
   466 
   467     fun prove lthy' def_thms' ({ctr_specs, fp_nesting_map_idents, fp_nesting_map_comps, ...}
   467     fun prove lthy' def_thms' ({ctr_specs, fp_nesting_map_ident0s, fp_nesting_map_comps, ...}
   468         : rec_spec) (fun_data : eqn_data list) =
   468         : rec_spec) (fun_data : eqn_data list) =
   469       let
   469       let
   470         val js =
   470         val js =
   471           find_indices (op = o pairself (fn {fun_name, ctr, ...} => (fun_name, ctr)))
   471           find_indices (op = o pairself (fn {fun_name, ctr, ...} => (fun_name, ctr)))
   472             fun_data eqns_data;
   472             fun_data eqns_data;
   475         val simp_thms = finds (fn (x, y) => #ctr x = #ctr y) fun_data ctr_specs
   475         val simp_thms = finds (fn (x, y) => #ctr x = #ctr y) fun_data ctr_specs
   476           |> fst
   476           |> fst
   477           |> map_filter (try (fn (x, [y]) =>
   477           |> map_filter (try (fn (x, [y]) =>
   478             (#fun_name x, #user_eqn x, length (#left_args x) + length (#right_args x), #rec_thm y)))
   478             (#fun_name x, #user_eqn x, length (#left_args x) + length (#right_args x), #rec_thm y)))
   479           |> map2 (fn j => fn (fun_name, user_eqn, num_extra_args, rec_thm) =>
   479           |> map2 (fn j => fn (fun_name, user_eqn, num_extra_args, rec_thm) =>
   480               mk_primrec_tac lthy' num_extra_args fp_nesting_map_idents fp_nesting_map_comps
   480               mk_primrec_tac lthy' num_extra_args fp_nesting_map_ident0s fp_nesting_map_comps
   481                 def_thms rec_thm
   481                 def_thms rec_thm
   482               |> K |> Goal.prove_sorry lthy' [] [] user_eqn
   482               |> K |> Goal.prove_sorry lthy' [] [] user_eqn
   483               (* for code extraction from proof terms: *)
   483               (* for code extraction from proof terms: *)
   484               |> singleton (Proof_Context.export lthy' lthy)
   484               |> singleton (Proof_Context.export lthy' lthy)
   485               |> Thm.name_derivation (Sign.full_name thy (Binding.name fun_name) ^
   485               |> Thm.name_derivation (Sign.full_name thy (Binding.name fun_name) ^