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, nested_map_idents, nested_map_comps, |
138 val (missing_arg_Ts, perm0_kks, basic_lfp_sugars, nested_map_idents, nested_map_comps, |
139 induct_thm, 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 |
144 val indices = map #fp_res_index basic_lfp_sugars; |
144 val indices = map #fp_res_index basic_lfp_sugars; |
157 val perm_fun_arg_Tssss = map #fun_arg_Tsss perm_basic_lfp_sugars; |
157 val perm_fun_arg_Tssss = map #fun_arg_Tsss perm_basic_lfp_sugars; |
158 |
158 |
159 fun unpermute0 perm0_xs = permute_like_unique (op =) perm0_kks kks perm0_xs; |
159 fun unpermute0 perm0_xs = permute_like_unique (op =) perm0_kks kks perm0_xs; |
160 fun unpermute perm_xs = permute_like_unique (op =) perm_indices indices perm_xs; |
160 fun unpermute perm_xs = permute_like_unique (op =) perm_indices indices perm_xs; |
161 |
161 |
162 val induct_thms = unpermute0 (conj_dests nn induct_thm); |
162 val inducts = unpermute0 (conj_dests nn common_induct); |
163 |
163 |
164 val lfpTs = unpermute perm_lfpTs; |
164 val lfpTs = unpermute perm_lfpTs; |
165 val Cs = unpermute perm_Cs; |
165 val Cs = unpermute perm_Cs; |
166 val ctr_offsets = unpermute perm_ctr_offsets; |
166 val ctr_offsets = unpermute perm_ctr_offsets; |
167 |
167 |
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 nested_map_idents = nested_map_idents, nested_map_comps = nested_map_comps, |
198 nested_map_idents = nested_map_idents, nested_map_comps = nested_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, induct_thm, induct_thms), |
201 ((n2m, map2 mk_spec ctr_offsets basic_lfp_sugars, missing_arg_Ts, common_induct, inducts), lthy) |
202 lthy) |
|
203 end; |
202 end; |
204 |
203 |
205 val undef_const = Const (@{const_name undefined}, dummyT); |
204 val undef_const = Const (@{const_name undefined}, dummyT); |
206 |
205 |
207 type eqn_data = { |
206 type eqn_data = { |
450 val _ = if exists is_only_old_datatype arg_Ts then raise OLD_PRIMREC () else (); |
449 val _ = if exists is_only_old_datatype arg_Ts then raise OLD_PRIMREC () else (); |
451 val _ = (case filter_out (fn (_, T) => Sign.of_sort thy (T, @{sort type})) (bs ~~ res_Ts) of |
450 val _ = (case filter_out (fn (_, T) => Sign.of_sort thy (T, @{sort type})) (bs ~~ res_Ts) of |
452 [] => () |
451 [] => () |
453 | (b, _) :: _ => raise PRIMREC ("type of " ^ Binding.print b ^ " contains top sort", [])); |
452 | (b, _) :: _ => raise PRIMREC ("type of " ^ Binding.print b ^ " contains top sort", [])); |
454 |
453 |
455 val ((n2m, rec_specs, _, induct_thm, induct_thms), lthy) = |
454 val ((n2m, rec_specs, _, common_induct, inducts), lthy) = |
456 rec_specs_of bs arg_Ts res_Ts frees callssss lthy0; |
455 rec_specs_of bs arg_Ts res_Ts frees callssss lthy0; |
457 |
456 |
458 val actual_nn = length funs_data; |
457 val actual_nn = length funs_data; |
459 |
458 |
460 val ctrs = maps (map #ctr o #ctr_specs) rec_specs; |
459 val ctrs = maps (map #ctr o #ctr_specs) rec_specs; |
491 (js, simp_thms) |
490 (js, simp_thms) |
492 end; |
491 end; |
493 |
492 |
494 val notes = |
493 val notes = |
495 (if n2m then |
494 (if n2m then |
496 map2 (fn name => fn thm => (name, inductN, [thm], [])) fun_names |
495 map2 (fn name => fn thm => (name, inductN, [thm], [])) fun_names (take actual_nn inducts) |
497 (take actual_nn induct_thms) |
|
498 else |
496 else |
499 []) |
497 []) |
500 |> map (fn (prefix, thmN, thms, attrs) => |
498 |> map (fn (prefix, thmN, thms, attrs) => |
501 ((Binding.qualify true prefix (Binding.name thmN), attrs), [(thms, [])])); |
499 ((Binding.qualify true prefix (Binding.name thmN), attrs), [(thms, [])])); |
502 |
500 |
503 val common_name = mk_common_name fun_names; |
501 val common_name = mk_common_name fun_names; |
504 |
502 |
505 val common_notes = |
503 val common_notes = |
506 (if n2m then [(inductN, [induct_thm], [])] else []) |
504 (if n2m then [(inductN, [common_induct], [])] else []) |
507 |> map (fn (thmN, thms, attrs) => |
505 |> map (fn (thmN, thms, attrs) => |
508 ((Binding.qualify true common_name (Binding.name thmN), attrs), [(thms, [])])); |
506 ((Binding.qualify true common_name (Binding.name thmN), attrs), [(thms, [])])); |
509 in |
507 in |
510 (((fun_names, defs), |
508 (((fun_names, defs), |
511 fn lthy => fn defs => |
509 fn lthy => fn defs => |