5 Suggared flattening of nested to mutual (co)recursion. |
5 Suggared flattening of nested to mutual (co)recursion. |
6 *) |
6 *) |
7 |
7 |
8 signature BNF_FP_N2M_SUGAR = |
8 signature BNF_FP_N2M_SUGAR = |
9 sig |
9 sig |
10 val mutualize_fp_sugars: bool -> bool -> BNF_FP_Util.fp_kind -> binding list -> typ list -> |
10 val mutualize_fp_sugars: bool -> BNF_FP_Util.fp_kind -> binding list -> typ list -> |
11 (term -> int list) -> term list list list list -> BNF_FP_Def_Sugar.fp_sugar list -> |
11 (term -> int list) -> term list list list list -> BNF_FP_Def_Sugar.fp_sugar list -> |
12 local_theory -> |
12 local_theory -> |
13 (BNF_FP_Def_Sugar.fp_sugar list |
13 (BNF_FP_Def_Sugar.fp_sugar list |
14 * (BNF_FP_Def_Sugar.lfp_sugar_thms option * BNF_FP_Def_Sugar.gfp_sugar_thms option)) |
14 * (BNF_FP_Def_Sugar.lfp_sugar_thms option * BNF_FP_Def_Sugar.gfp_sugar_thms option)) |
15 * local_theory |
15 * local_theory |
16 val pad_and_indexify_calls: BNF_FP_Def_Sugar.fp_sugar list -> int -> |
16 val pad_and_indexify_calls: BNF_FP_Def_Sugar.fp_sugar list -> int -> |
17 (term * term list list) list list -> term list list list list |
17 (term * term list list) list list -> term list list list list |
18 val nested_to_mutual_fps: bool -> BNF_FP_Util.fp_kind -> binding list -> typ list -> |
18 val nested_to_mutual_fps: BNF_FP_Util.fp_kind -> binding list -> typ list -> (term -> int list) -> |
19 (term -> int list) -> ((term * term list list) list) list -> local_theory -> |
19 (term * term list list) list list -> local_theory -> |
20 (typ list * int list * BNF_FP_Def_Sugar.fp_sugar list |
20 (typ list * int list * BNF_FP_Def_Sugar.fp_sugar list |
21 * (BNF_FP_Def_Sugar.lfp_sugar_thms option * BNF_FP_Def_Sugar.gfp_sugar_thms option)) |
21 * (BNF_FP_Def_Sugar.lfp_sugar_thms option * BNF_FP_Def_Sugar.gfp_sugar_thms option)) |
22 * local_theory |
22 * local_theory |
23 end; |
23 end; |
24 |
24 |
35 val n2mN = "n2m_" |
35 val n2mN = "n2m_" |
36 |
36 |
37 (* TODO: test with sort constraints on As *) |
37 (* TODO: test with sort constraints on As *) |
38 (* TODO: use right sorting order for "fp_sort" w.r.t. original BNFs (?) -- treat new variables |
38 (* TODO: use right sorting order for "fp_sort" w.r.t. original BNFs (?) -- treat new variables |
39 as deads? *) |
39 as deads? *) |
40 fun mutualize_fp_sugars lose_co_rec mutualize fp bs fpTs get_indices callssss fp_sugars0 |
40 fun mutualize_fp_sugars mutualize fp bs fpTs get_indices callssss fp_sugars0 no_defs_lthy0 = |
41 no_defs_lthy0 = |
|
42 (* TODO: Also check whether there's any lost recursion? *) |
|
43 if mutualize orelse has_duplicates (op =) fpTs then |
41 if mutualize orelse has_duplicates (op =) fpTs then |
44 let |
42 let |
45 val thy = Proof_Context.theory_of no_defs_lthy0; |
43 val thy = Proof_Context.theory_of no_defs_lthy0; |
46 |
44 |
47 val qsotm = quote o Syntax.string_of_term no_defs_lthy0; |
45 val qsotm = quote o Syntax.string_of_term no_defs_lthy0; |
77 no_defs_lthy0 |
75 no_defs_lthy0 |
78 |> fold Variable.declare_typ As |
76 |> fold Variable.declare_typ As |
79 |> mk_TFrees nn |
77 |> mk_TFrees nn |
80 ||>> variant_tfrees fp_b_names; |
78 ||>> variant_tfrees fp_b_names; |
81 |
79 |
82 (* If "lose_co_rec" is "true", the function "null" on "'a list" gives rise to |
|
83 'list = unit + 'a list |
|
84 instead of |
|
85 'list = unit + 'list |
|
86 resulting in a simpler (co)induction rule and (co)recursor. *) |
|
87 fun freeze_fp_default (T as Type (s, Ts)) = |
80 fun freeze_fp_default (T as Type (s, Ts)) = |
88 (case find_index (curry (op =) T) fpTs of |
81 (case find_index (curry (op =) T) fpTs of |
89 ~1 => Type (s, map freeze_fp_default Ts) |
82 ~1 => Type (s, map freeze_fp_default Ts) |
90 | kk => nth Xs kk) |
83 | kk => nth Xs kk) |
91 | freeze_fp_default T = T; |
84 | freeze_fp_default T = T; |
98 fun freeze_fp calls (T as Type (s, Ts)) = |
91 fun freeze_fp calls (T as Type (s, Ts)) = |
99 (case map_filter (try (snd o dest_map no_defs_lthy s)) calls of |
92 (case map_filter (try (snd o dest_map no_defs_lthy s)) calls of |
100 [] => |
93 [] => |
101 (case union (op = o pairself fst) |
94 (case union (op = o pairself fst) |
102 (maps (fn call => map (rpair call) (get_indices_checked call)) calls) [] of |
95 (maps (fn call => map (rpair call) (get_indices_checked call)) calls) [] of |
103 [] => T |> not lose_co_rec ? freeze_fp_default |
96 [] => freeze_fp_default T |
104 | [(kk, _)] => nth Xs kk |
97 | [(kk, _)] => nth Xs kk |
105 | (_, call1) :: (_, call2) :: _ => incompatible_calls call1 call2) |
98 | (_, call1) :: (_, call2) :: _ => incompatible_calls call1 call2) |
106 | callss => |
99 | callss => |
107 Type (s, map2 freeze_fp (flatten_type_args_of_bnf (the (bnf_of no_defs_lthy s)) [] |
100 Type (s, map2 freeze_fp (flatten_type_args_of_bnf (the (bnf_of no_defs_lthy s)) [] |
108 (transpose callss)) Ts)) |
101 (transpose callss)) Ts)) |
199 map do_ctr ctrs |
192 map do_ctr ctrs |
200 end; |
193 end; |
201 |
194 |
202 fun pad_and_indexify_calls fp_sugars0 = map2 indexify_callsss fp_sugars0 oo pad_list []; |
195 fun pad_and_indexify_calls fp_sugars0 = map2 indexify_callsss fp_sugars0 oo pad_list []; |
203 |
196 |
204 fun nested_to_mutual_fps lose_co_rec fp actual_bs actual_Ts get_indices actual_callssss0 lthy = |
197 fun nested_to_mutual_fps fp actual_bs actual_Ts get_indices actual_callssss0 lthy = |
205 let |
198 let |
206 val qsoty = quote o Syntax.string_of_typ lthy; |
199 val qsoty = quote o Syntax.string_of_typ lthy; |
207 val qsotys = space_implode " or " o map qsoty; |
200 val qsotys = space_implode " or " o map qsoty; |
208 |
201 |
209 fun not_co_datatype0 T = error (qsoty T ^ " is not a " ^ co_prefix fp ^ "datatype"); |
202 fun not_co_datatype0 T = error (qsoty T ^ " is not a " ^ co_prefix fp ^ "datatype"); |
262 val perm_callssss = pad_and_indexify_calls perm_fp_sugars0 nn actual_callssss0; |
255 val perm_callssss = pad_and_indexify_calls perm_fp_sugars0 nn actual_callssss0; |
263 |
256 |
264 val get_perm_indices = map (fn kk => find_index (curry (op =) kk) perm_kks) o get_indices; |
257 val get_perm_indices = map (fn kk => find_index (curry (op =) kk) perm_kks) o get_indices; |
265 |
258 |
266 val ((perm_fp_sugars, fp_sugar_thms), lthy) = |
259 val ((perm_fp_sugars, fp_sugar_thms), lthy) = |
267 mutualize_fp_sugars lose_co_rec mutualize fp perm_bs perm_Ts get_perm_indices perm_callssss |
260 mutualize_fp_sugars mutualize fp perm_bs perm_Ts get_perm_indices perm_callssss |
268 perm_fp_sugars0 lthy; |
261 perm_fp_sugars0 lthy; |
269 |
262 |
270 val fp_sugars = unpermute perm_fp_sugars; |
263 val fp_sugars = unpermute perm_fp_sugars; |
271 in |
264 in |
272 ((missing_Ts, perm_kks, fp_sugars, fp_sugar_thms), lthy) |
265 ((missing_Ts, perm_kks, fp_sugars, fp_sugar_thms), lthy) |