8 Author: Stefan Berghofer, TU Muenchen |
8 Author: Stefan Berghofer, TU Muenchen |
9 *) |
9 *) |
10 |
10 |
11 signature BNF_LFP_COMPAT = |
11 signature BNF_LFP_COMPAT = |
12 sig |
12 sig |
13 datatype nesting_mode = Keep_Nesting | Unfold_Nesting_if_Possible | Always_Unfold_Nesting |
13 datatype nesting_preference = Keep_Nesting | Unfold_Nesting |
14 |
14 |
15 val get_all: theory -> nesting_mode -> Old_Datatype_Aux.info Symtab.table |
15 val get_all: theory -> nesting_preference -> Old_Datatype_Aux.info Symtab.table |
16 val get_info: theory -> nesting_mode -> string -> Old_Datatype_Aux.info option |
16 val get_info: theory -> nesting_preference -> string -> Old_Datatype_Aux.info option |
17 val the_info: theory -> nesting_mode -> string -> Old_Datatype_Aux.info |
17 val the_info: theory -> nesting_preference -> string -> Old_Datatype_Aux.info |
18 val the_spec: theory -> nesting_mode -> string -> (string * sort) list * (string * typ list) list |
18 val the_spec: theory -> nesting_preference -> string -> |
19 val the_descr: theory -> nesting_mode -> string list -> |
19 (string * sort) list * (string * typ list) list |
|
20 val the_descr: theory -> nesting_preference -> string list -> |
20 Old_Datatype_Aux.descr * (string * sort) list * string list * string |
21 Old_Datatype_Aux.descr * (string * sort) list * string list * string |
21 * (string list * string list) * (typ list * typ list) |
22 * (string list * string list) * (typ list * typ list) |
22 val get_constrs: theory -> nesting_mode -> string -> (string * typ) list option |
23 val get_constrs: theory -> nesting_preference -> string -> (string * typ) list option |
23 val interpretation: nesting_mode -> |
24 val interpretation: nesting_preference -> |
24 (Old_Datatype_Aux.config -> string list -> theory -> theory) -> theory -> theory |
25 (Old_Datatype_Aux.config -> string list -> theory -> theory) -> theory -> theory |
|
26 val datatype_compat: string list -> local_theory -> local_theory |
|
27 val datatype_compat_global: string list -> theory -> theory |
25 val datatype_compat_cmd: string list -> local_theory -> local_theory |
28 val datatype_compat_cmd: string list -> local_theory -> local_theory |
26 val add_datatype: nesting_mode -> Old_Datatype_Aux.spec list -> theory -> string list * theory |
29 val add_datatype: nesting_preference -> Old_Datatype_Aux.spec list -> theory -> |
|
30 string list * theory |
27 end; |
31 end; |
28 |
32 |
29 structure BNF_LFP_Compat : BNF_LFP_COMPAT = |
33 structure BNF_LFP_Compat : BNF_LFP_COMPAT = |
30 struct |
34 struct |
31 |
35 |
55 else |
59 else |
56 perm_kks ~~ |
60 perm_kks ~~ |
57 map (fn (_, (s, Ds, sDss)) => (s, map perm_dtyp Ds, map (apsnd (map perm_dtyp)) sDss)) desc |
61 map (fn (_, (s, Ds, sDss)) => (s, map perm_dtyp Ds, map (apsnd (map perm_dtyp)) sDss)) desc |
58 end; |
62 end; |
59 |
63 |
60 fun mk_infos_of_mutually_recursive_new_datatypes nesting_mode need_co_inducts_recs check_names |
64 fun mk_infos_of_mutually_recursive_new_datatypes nesting_pref need_co_inducts_recs check_names |
61 raw_fpT_names0 lthy = |
65 fpT_names0 lthy = |
62 let |
66 let |
63 val thy = Proof_Context.theory_of lthy; |
67 val thy = Proof_Context.theory_of lthy; |
64 |
68 |
65 fun not_datatype s = error (quote s ^ " is not a new-style datatype"); |
69 fun not_datatype s = error (quote s ^ " is not a new-style datatype"); |
66 fun not_mutually_recursive ss = |
70 fun not_mutually_recursive ss = |
67 error ("{" ^ commas ss ^ "} is not a complete set of mutually recursive new-style datatypes"); |
71 error ("{" ^ commas ss ^ "} is not a complete set of mutually recursive new-style datatypes"); |
68 |
|
69 val fpT_names0 = |
|
70 map (fst o dest_Type o Proof_Context.read_type_name {proper = true, strict = false} lthy) |
|
71 raw_fpT_names0; |
|
72 |
72 |
73 fun lfp_sugar_of s = |
73 fun lfp_sugar_of s = |
74 (case fp_sugar_of lthy s of |
74 (case fp_sugar_of lthy s of |
75 SOME (fp_sugar as {fp = Least_FP, ...}) => fp_sugar |
75 SOME (fp_sugar as {fp = Least_FP, ...}) => fp_sugar |
76 | _ => not_datatype s); |
76 | _ => not_datatype s); |
94 |
94 |
95 val fp_ctr_sugars = map (#ctr_sugar o lfp_sugar_of) fpT_names; |
95 val fp_ctr_sugars = map (#ctr_sugar o lfp_sugar_of) fpT_names; |
96 val orig_descr = map3 mk_typ_descr (0 upto nn_fp - 1) fpTs fp_ctr_sugars; |
96 val orig_descr = map3 mk_typ_descr (0 upto nn_fp - 1) fpTs fp_ctr_sugars; |
97 val all_infos = Old_Datatype_Data.get_all thy; |
97 val all_infos = Old_Datatype_Data.get_all thy; |
98 val (orig_descr' :: nested_descrs) = |
98 val (orig_descr' :: nested_descrs) = |
99 if nesting_mode = Keep_Nesting then |
99 if nesting_pref = Keep_Nesting then [orig_descr] |
100 [orig_descr] |
100 else fst (Old_Datatype_Aux.unfold_datatypes lthy orig_descr all_infos orig_descr nn_fp); |
101 else |
|
102 fst (Old_Datatype_Aux.unfold_datatypes lthy orig_descr all_infos orig_descr nn_fp); |
|
103 |
101 |
104 fun cliquify_descr [] = [] |
102 fun cliquify_descr [] = [] |
105 | cliquify_descr [entry] = [[entry]] |
103 | cliquify_descr [entry] = [[entry]] |
106 | cliquify_descr (full_descr as (_, (T_name1, _, _)) :: _) = |
104 | cliquify_descr (full_descr as (_, (T_name1, _, _)) :: _) = |
107 let |
105 let |
170 val infos = map_index mk_info (take nn_fp fp_sugars); |
168 val infos = map_index mk_info (take nn_fp fp_sugars); |
171 in |
169 in |
172 (nn, b_names, compat_b_names, lfp_sugar_thms, infos, lthy') |
170 (nn, b_names, compat_b_names, lfp_sugar_thms, infos, lthy') |
173 end; |
171 end; |
174 |
172 |
175 fun infos_of_new_datatype_mutual_cluster lthy nesting_mode raw_fpt_names01 = |
173 fun infos_of_new_datatype_mutual_cluster lthy nesting_pref fpT_name = |
176 mk_infos_of_mutually_recursive_new_datatypes nesting_mode false subset [raw_fpt_names01] lthy |
174 let |
177 |> #5; |
175 fun infos_of nesting_pref = |
178 |
176 #5 (mk_infos_of_mutually_recursive_new_datatypes nesting_pref false subset [fpT_name] lthy); |
179 fun get_all thy nesting_mode = |
177 in |
|
178 infos_of nesting_pref |
|
179 handle ERROR _ => if nesting_pref = Unfold_Nesting then infos_of Keep_Nesting else [] |
|
180 end; |
|
181 |
|
182 fun get_all thy nesting_pref = |
180 let |
183 let |
181 val lthy = Named_Target.theory_init thy; |
184 val lthy = Named_Target.theory_init thy; |
182 val old_info_tab = Old_Datatype_Data.get_all thy; |
185 val old_info_tab = Old_Datatype_Data.get_all thy; |
183 val new_T_names = BNF_FP_Def_Sugar.fp_sugars_of_global thy |
186 val new_T_names = BNF_FP_Def_Sugar.fp_sugars_of_global thy |
184 |> map_filter (try (fn {T = Type (s, _), fp_res_index = 0, ...} => s)); |
187 |> map_filter (try (fn {T = Type (s, _), fp_res_index = 0, ...} => s)); |
185 val new_infos = maps (infos_of_new_datatype_mutual_cluster lthy nesting_mode) new_T_names; |
188 val new_infos = maps (infos_of_new_datatype_mutual_cluster lthy nesting_pref) new_T_names; |
186 in |
189 in |
187 fold (if nesting_mode = Keep_Nesting then Symtab.update else Symtab.default) new_infos |
190 fold (if nesting_pref = Keep_Nesting then Symtab.update else Symtab.default) new_infos |
188 old_info_tab |
191 old_info_tab |
189 end; |
192 end; |
190 |
193 |
191 fun get_one get_old get_new thy nesting_mode x = |
194 fun get_one get_old get_new thy nesting_pref x = |
192 let |
195 let |
193 val (get_fst, get_snd) = |
196 val (get_fst, get_snd) = |
194 (get_old thy, get_new thy nesting_mode) |> nesting_mode = Keep_Nesting ? swap |
197 (get_old thy, get_new thy nesting_pref) |> nesting_pref = Keep_Nesting ? swap |
195 in |
198 in |
196 (case get_fst x of NONE => get_snd x | res => res) |
199 (case get_fst x of NONE => get_snd x | res => res) |
197 end; |
200 end; |
198 |
201 |
199 fun get_info_of_new_datatype thy nesting_mode T_name = |
202 fun get_info_of_new_datatype thy nesting_pref T_name = |
200 let val lthy = Named_Target.theory_init thy in |
203 let val lthy = Named_Target.theory_init thy in |
201 AList.lookup (op =) (infos_of_new_datatype_mutual_cluster lthy nesting_mode T_name) T_name |
204 AList.lookup (op =) (infos_of_new_datatype_mutual_cluster lthy nesting_pref T_name) T_name |
202 end; |
205 end; |
203 |
206 |
204 val get_info = get_one Old_Datatype_Data.get_info get_info_of_new_datatype; |
207 val get_info = get_one Old_Datatype_Data.get_info get_info_of_new_datatype; |
205 |
208 |
206 fun the_info thy nesting_mode T_name = |
209 fun the_info thy nesting_pref T_name = |
207 (case get_info thy nesting_mode T_name of |
210 (case get_info thy nesting_pref T_name of |
208 SOME info => info |
211 SOME info => info |
209 | NONE => error ("Unknown datatype " ^ quote T_name)); |
212 | NONE => error ("Unknown datatype " ^ quote T_name)); |
210 |
213 |
211 fun the_spec thy nesting_mode T_name = |
214 fun the_spec thy nesting_pref T_name = |
212 let |
215 let |
213 val {descr, index, ...} = the_info thy nesting_mode T_name; |
216 val {descr, index, ...} = the_info thy nesting_pref T_name; |
214 val (_, Ds, ctrs0) = the (AList.lookup (op =) descr index); |
217 val (_, Ds, ctrs0) = the (AList.lookup (op =) descr index); |
215 val Ts = map Old_Datatype_Aux.dest_DtTFree Ds; |
218 val Ts = map Old_Datatype_Aux.dest_DtTFree Ds; |
216 val ctrs = map (apsnd (map (Old_Datatype_Aux.typ_of_dtyp descr))) ctrs0; |
219 val ctrs = map (apsnd (map (Old_Datatype_Aux.typ_of_dtyp descr))) ctrs0; |
217 in (Ts, ctrs) end; |
220 in (Ts, ctrs) end; |
218 |
221 |
219 fun the_descr thy nesting_mode (T_names0 as T_name01 :: _) = |
222 fun the_descr thy nesting_pref (T_names0 as T_name01 :: _) = |
220 let |
223 let |
221 fun not_mutually_recursive ss = |
224 fun not_mutually_recursive ss = |
222 error ("{" ^ commas ss ^ "} is not a complete set of mutually recursive datatypes"); |
225 error ("{" ^ commas ss ^ "} is not a complete set of mutually recursive datatypes"); |
223 |
226 |
224 val info = the_info thy nesting_mode T_name01; |
227 val info = the_info thy nesting_pref T_name01; |
225 val descr = #descr info; |
228 val descr = #descr info; |
226 |
229 |
227 val (_, Ds, _) = the (AList.lookup (op =) descr (#index info)); |
230 val (_, Ds, _) = the (AList.lookup (op =) descr (#index info)); |
228 val vs = map Old_Datatype_Aux.dest_DtTFree Ds; |
231 val vs = map Old_Datatype_Aux.dest_DtTFree Ds; |
229 |
232 |
246 val prefix = space_implode "_" names; |
249 val prefix = space_implode "_" names; |
247 in |
250 in |
248 (descr, vs, T_names, prefix, (names, auxnames), (Ts, Us)) |
251 (descr, vs, T_names, prefix, (names, auxnames), (Ts, Us)) |
249 end; |
252 end; |
250 |
253 |
251 fun get_constrs thy nesting_mode T_name = |
254 fun get_constrs thy nesting_pref T_name = |
252 try (the_spec thy nesting_mode) T_name |
255 try (the_spec thy nesting_pref) T_name |
253 |> Option.map (fn (tfrees, ctrs) => |
256 |> Option.map (fn (tfrees, ctrs) => |
254 let |
257 let |
255 fun varify_tfree (s, S) = TVar ((s, 0), S); |
258 fun varify_tfree (s, S) = TVar ((s, 0), S); |
256 fun varify_typ (TFree x) = varify_tfree x |
259 fun varify_typ (TFree x) = varify_tfree x |
257 | varify_typ T = T; |
260 | varify_typ T = T; |
261 fun mk_ctr_typ Ts = map (Term.map_atyps varify_typ) Ts ---> dataT; |
264 fun mk_ctr_typ Ts = map (Term.map_atyps varify_typ) Ts ---> dataT; |
262 in |
265 in |
263 map (apsnd mk_ctr_typ) ctrs |
266 map (apsnd mk_ctr_typ) ctrs |
264 end); |
267 end); |
265 |
268 |
266 fun old_interpretation_of nesting_mode f config T_names thy = |
269 fun old_interpretation_of nesting_pref f config T_names thy = |
267 if nesting_mode <> Keep_Nesting orelse exists (is_none o fp_sugar_of_global thy) T_names then |
270 if nesting_pref = Unfold_Nesting orelse exists (is_none o fp_sugar_of_global thy) T_names then |
268 f config T_names thy |
271 f config T_names thy |
269 else |
272 else |
270 thy; |
273 thy; |
271 |
274 |
272 fun new_interpretation_of nesting_mode f fp_sugars thy = |
275 fun new_interpretation_of nesting_pref f fp_sugars thy = |
273 let val T_names = map (fst o dest_Type o #T) fp_sugars in |
276 let val T_names = map (fst o dest_Type o #T) fp_sugars in |
274 if nesting_mode = Keep_Nesting orelse |
277 if nesting_pref = Keep_Nesting orelse |
275 exists (is_none o Old_Datatype_Data.get_info thy) T_names then |
278 exists (is_none o Old_Datatype_Data.get_info thy) T_names then |
276 f Old_Datatype_Aux.default_config T_names thy |
279 f Old_Datatype_Aux.default_config T_names thy |
277 else |
280 else |
278 thy |
281 thy |
279 end; |
282 end; |
280 |
283 |
281 fun interpretation nesting_mode f = |
284 fun interpretation nesting_pref f = |
282 Old_Datatype_Data.interpretation (old_interpretation_of nesting_mode f) |
285 Old_Datatype_Data.interpretation (old_interpretation_of nesting_pref f) |
283 #> fp_sugar_interpretation (new_interpretation_of nesting_mode f); |
286 #> fp_sugar_interpretation (new_interpretation_of nesting_pref f); |
284 |
287 |
285 val code_nitpicksimp_simp_attrs = Code.add_default_eqn_attrib :: @{attributes [nitpick_simp, simp]}; |
288 val code_nitpicksimp_simp_attrs = Code.add_default_eqn_attrib :: @{attributes [nitpick_simp, simp]}; |
286 |
289 |
287 fun datatype_compat_cmd fpT_names lthy = |
290 fun datatype_compat fpT_names lthy = |
288 let |
291 let |
289 val (nn, b_names, compat_b_names, lfp_sugar_thms, infos, lthy') = |
292 val (nn, b_names, compat_b_names, lfp_sugar_thms, infos, lthy') = |
290 mk_infos_of_mutually_recursive_new_datatypes Unfold_Nesting_if_Possible true eq_set fpT_names |
293 mk_infos_of_mutually_recursive_new_datatypes Unfold_Nesting true eq_set fpT_names lthy; |
291 lthy; |
|
292 |
294 |
293 val all_notes = |
295 val all_notes = |
294 (case lfp_sugar_thms of |
296 (case lfp_sugar_thms of |
295 NONE => [] |
297 NONE => [] |
296 | SOME ((induct_thms, induct_thm, induct_attrs), (rec_thmss, _)) => |
298 | SOME ((induct_thms, induct_thm, induct_attrs), (rec_thmss, _)) => |
326 |> Local_Theory.raw_theory register_interpret |
328 |> Local_Theory.raw_theory register_interpret |
327 |> Local_Theory.notes all_notes |
329 |> Local_Theory.notes all_notes |
328 |> snd |
330 |> snd |
329 end; |
331 end; |
330 |
332 |
331 fun add_datatype nesting_mode old_specs thy = |
333 fun datatype_compat_global fpT_names = |
|
334 Named_Target.theory_init |
|
335 #> datatype_compat fpT_names |
|
336 #> Named_Target.exit; |
|
337 |
|
338 fun datatype_compat_cmd raw_fpT_names lthy = |
|
339 let |
|
340 val fpT_names = |
|
341 map (fst o dest_Type o Proof_Context.read_type_name {proper = true, strict = false} lthy) |
|
342 raw_fpT_names; |
|
343 in |
|
344 datatype_compat fpT_names lthy |
|
345 end; |
|
346 |
|
347 fun add_datatype nesting_pref old_specs thy = |
332 let |
348 let |
333 val fpT_names = map (Sign.full_name thy o #1 o fst) old_specs; |
349 val fpT_names = map (Sign.full_name thy o #1 o fst) old_specs; |
334 |
350 |
335 fun new_type_args_of (s, S) = (SOME Binding.empty, (TFree (s, @{sort type}), S)); |
351 fun new_type_args_of (s, S) = (SOME Binding.empty, (TFree (s, @{sort type}), S)); |
336 fun new_ctr_spec_of (b, Ts, mx) = (((Binding.empty, b), map (pair Binding.empty) Ts), mx); |
352 fun new_ctr_spec_of (b, Ts, mx) = (((Binding.empty, b), map (pair Binding.empty) Ts), mx); |