54 datatype preference = Keep_Nesting | Include_GFPs | Kill_Type_Args; |
54 datatype preference = Keep_Nesting | Include_GFPs | Kill_Type_Args; |
55 |
55 |
56 fun mk_split_rec_rhs ctxt fpTs Cs (recs as rec1 :: _) = |
56 fun mk_split_rec_rhs ctxt fpTs Cs (recs as rec1 :: _) = |
57 let |
57 let |
58 fun repair_rec_arg_args [] [] = [] |
58 fun repair_rec_arg_args [] [] = [] |
59 | repair_rec_arg_args ((g_T as Type (@{type_name fun}, _)) :: g_Ts) (g :: gs) = |
59 | repair_rec_arg_args ((g_T as Type (\<^type_name>\<open>fun\<close>, _)) :: g_Ts) (g :: gs) = |
60 let |
60 let |
61 val (x_Ts, body_T) = strip_type g_T; |
61 val (x_Ts, body_T) = strip_type g_T; |
62 in |
62 in |
63 (case try HOLogic.dest_prodT body_T of |
63 (case try HOLogic.dest_prodT body_T of |
64 NONE => [g] |
64 NONE => [g] |
125 val frecs = map (fn recx => Term.list_comb (recx, fs)) recs; |
125 val frecs = map (fn recx => Term.list_comb (recx, fs)) recs; |
126 |
126 |
127 val Xs_frecs = Xs ~~ frecs; |
127 val Xs_frecs = Xs ~~ frecs; |
128 val fss = unflat ctrss fs; |
128 val fss = unflat ctrss fs; |
129 |
129 |
130 fun mk_rec_call g n (Type (@{type_name fun}, [_, ran_T])) = |
130 fun mk_rec_call g n (Type (\<^type_name>\<open>fun\<close>, [_, ran_T])) = |
131 Abs (Name.uu, Term.dummyT, mk_rec_call g (n + 1) ran_T) |
131 Abs (Name.uu, Term.dummyT, mk_rec_call g (n + 1) ran_T) |
132 | mk_rec_call g n X = |
132 | mk_rec_call g n X = |
133 let |
133 let |
134 val frec = the (AList.lookup (op =) Xs_frecs X); |
134 val frec = the (AList.lookup (op =) Xs_frecs X); |
135 val xg = Term.list_comb (g, map Bound (n - 1 downto 0)); |
135 val xg = Term.list_comb (g, map Bound (n - 1 downto 0)); |
182 in |
182 in |
183 ((inducts', induct', recs', rec'_thmss), lthy') |
183 ((inducts', induct', recs', rec'_thmss), lthy') |
184 end; |
184 end; |
185 |
185 |
186 fun body_rec_indices (Old_Datatype_Aux.DtRec kk) = [kk] |
186 fun body_rec_indices (Old_Datatype_Aux.DtRec kk) = [kk] |
187 | body_rec_indices (Old_Datatype_Aux.DtType (@{type_name fun}, [_, D])) = body_rec_indices D |
187 | body_rec_indices (Old_Datatype_Aux.DtType (\<^type_name>\<open>fun\<close>, [_, D])) = body_rec_indices D |
188 | body_rec_indices _ = []; |
188 | body_rec_indices _ = []; |
189 |
189 |
190 fun reindex_desc desc = |
190 fun reindex_desc desc = |
191 let |
191 let |
192 val kks = map fst desc; |
192 val kks = map fst desc; |
274 |
274 |
275 val fp_sugars = map (checked_fp_sugar_of o fst o dest_Type) fpTs'; |
275 val fp_sugars = map (checked_fp_sugar_of o fst o dest_Type) fpTs'; |
276 val ctr_Tsss = map (map (map (Old_Datatype_Aux.typ_of_dtyp descr) o snd) o #3 o snd) descr; |
276 val ctr_Tsss = map (map (map (Old_Datatype_Aux.typ_of_dtyp descr) o snd) o #3 o snd) descr; |
277 val kkssss = map (map (map body_rec_indices o snd) o #3 o snd) descr; |
277 val kkssss = map (map (map body_rec_indices o snd) o #3 o snd) descr; |
278 |
278 |
279 val callers = map (fn kk => Var ((Name.uu, kk), @{typ "unit => unit"})) (0 upto nn - 1); |
279 val callers = map (fn kk => Var ((Name.uu, kk), \<^typ>\<open>unit => unit\<close>)) (0 upto nn - 1); |
280 |
280 |
281 fun apply_comps n kk = |
281 fun apply_comps n kk = |
282 mk_partial_compN n (replicate n HOLogic.unitT ---> HOLogic.unitT) (nth callers kk); |
282 mk_partial_compN n (replicate n HOLogic.unitT ---> HOLogic.unitT) (nth callers kk); |
283 |
283 |
284 val callssss = map2 (map2 (map2 (map o apply_comps o num_binder_types))) ctr_Tsss kkssss; |
284 val callssss = map2 (map2 (map2 (map o apply_comps o num_binder_types))) ctr_Tsss kkssss; |
304 val {fp_co_induct_sugar = SOME {common_co_inducts = induct :: _, ...}, ...} :: _ = fp_sugars'; |
304 val {fp_co_induct_sugar = SOME {common_co_inducts = induct :: _, ...}, ...} :: _ = fp_sugars'; |
305 val inducts = map (hd o #co_inducts o the o #fp_co_induct_sugar) fp_sugars'; |
305 val inducts = map (hd o #co_inducts o the o #fp_co_induct_sugar) fp_sugars'; |
306 val recs = map (#co_rec o the o #fp_co_induct_sugar) fp_sugars'; |
306 val recs = map (#co_rec o the o #fp_co_induct_sugar) fp_sugars'; |
307 val rec_thmss = map (#co_rec_thms o the o #fp_co_induct_sugar) fp_sugars'; |
307 val rec_thmss = map (#co_rec_thms o the o #fp_co_induct_sugar) fp_sugars'; |
308 |
308 |
309 fun is_nested_rec_type (Type (@{type_name fun}, [_, T])) = member (op =) Xs' (body_type T) |
309 fun is_nested_rec_type (Type (\<^type_name>\<open>fun\<close>, [_, T])) = member (op =) Xs' (body_type T) |
310 | is_nested_rec_type _ = false; |
310 | is_nested_rec_type _ = false; |
311 |
311 |
312 val ((lfp_sugar_thms'', (inducts', induct', recs', rec'_thmss)), lthy'') = |
312 val ((lfp_sugar_thms'', (inducts', induct', recs', rec'_thmss)), lthy'') = |
313 if member (op =) prefs Keep_Nesting orelse |
313 if member (op =) prefs Keep_Nesting orelse |
314 not (exists (exists (exists is_nested_rec_type)) ctrXs_Tsss') then |
314 not (exists (exists (exists is_nested_rec_type)) ctrXs_Tsss') then |
521 let |
521 let |
522 val fpT_names = map (Sign.full_name thy o #1 o fst) old_specs; |
522 val fpT_names = map (Sign.full_name thy o #1 o fst) old_specs; |
523 |
523 |
524 fun new_type_args_of (s, S) = |
524 fun new_type_args_of (s, S) = |
525 (if member (op =) prefs Kill_Type_Args then NONE else SOME Binding.empty, |
525 (if member (op =) prefs Kill_Type_Args then NONE else SOME Binding.empty, |
526 (TFree (s, @{sort type}), S)); |
526 (TFree (s, \<^sort>\<open>type\<close>), S)); |
527 fun new_ctr_spec_of (b, Ts, mx) = (((Binding.empty, b), map (pair Binding.empty) Ts), mx); |
527 fun new_ctr_spec_of (b, Ts, mx) = (((Binding.empty, b), map (pair Binding.empty) Ts), mx); |
528 |
528 |
529 fun new_spec_of ((b, old_tyargs, mx), old_ctr_specs) = |
529 fun new_spec_of ((b, old_tyargs, mx), old_ctr_specs) = |
530 (((((map new_type_args_of old_tyargs, b), mx), map new_ctr_spec_of old_ctr_specs), |
530 (((((map new_type_args_of old_tyargs, b), mx), map new_ctr_spec_of old_ctr_specs), |
531 (Binding.empty, Binding.empty, Binding.empty)), []); |
531 (Binding.empty, Binding.empty, Binding.empty)), []); |
546 val primrec_overloaded = apfst (old_of_new flat) oooo BNF_LFP_Rec_Sugar.primrec_overloaded false []; |
546 val primrec_overloaded = apfst (old_of_new flat) oooo BNF_LFP_Rec_Sugar.primrec_overloaded false []; |
547 val primrec_simple = apfst (apfst fst o apsnd (old_of_new (flat o snd))) ooo |
547 val primrec_simple = apfst (apfst fst o apsnd (old_of_new (flat o snd))) ooo |
548 BNF_LFP_Rec_Sugar.primrec_simple false; |
548 BNF_LFP_Rec_Sugar.primrec_simple false; |
549 |
549 |
550 val _ = |
550 val _ = |
551 Outer_Syntax.local_theory @{command_keyword datatype_compat} |
551 Outer_Syntax.local_theory \<^command_keyword>\<open>datatype_compat\<close> |
552 "register datatypes as old-style datatypes and derive old-style properties" |
552 "register datatypes as old-style datatypes and derive old-style properties" |
553 (Scan.repeat1 Parse.type_const >> datatype_compat_cmd); |
553 (Scan.repeat1 Parse.type_const >> datatype_compat_cmd); |
554 |
554 |
555 end; |
555 end; |