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 |