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) ^ |