6 *) |
6 *) |
7 |
7 |
8 signature BNF_FP_DEF_SUGAR = |
8 signature BNF_FP_DEF_SUGAR = |
9 sig |
9 sig |
10 val datatypes: bool -> |
10 val datatypes: bool -> |
11 (mixfix list -> (string * sort) list option -> binding list -> binding list list -> |
11 (mixfix list -> (string * sort) list option -> binding list -> binding list -> |
12 typ list * typ list list -> BNF_Def.BNF list -> local_theory -> |
12 binding list list -> typ list * typ list list -> BNF_Def.BNF list -> local_theory -> |
13 BNF_FP.fp_result * local_theory) -> |
13 BNF_FP.fp_result * local_theory) -> |
14 (bool * bool) * (((((binding * typ) * sort) list * binding) * mixfix) * ((((binding * binding) * |
14 (bool * bool) * ((((binding * (binding * (typ * sort)) list) * binding) * mixfix) * |
15 (binding * typ) list) * (binding * term) list) * mixfix) list) list -> |
15 ((((binding * binding) * (binding * typ) list) * (binding * term) list) * |
|
16 mixfix) list) list -> |
16 local_theory -> local_theory |
17 local_theory -> local_theory |
17 val parse_datatype_cmd: bool -> |
18 val parse_datatype_cmd: bool -> |
18 (mixfix list -> (string * sort) list option -> binding list -> binding list list -> |
19 (mixfix list -> (string * sort) list option -> binding list -> binding list -> |
19 typ list * typ list list -> BNF_Def.BNF list -> local_theory -> |
20 binding list list -> typ list * typ list list -> BNF_Def.BNF list -> local_theory -> |
20 BNF_FP.fp_result * local_theory) -> |
21 BNF_FP.fp_result * local_theory) -> |
21 (local_theory -> local_theory) parser |
22 (local_theory -> local_theory) parser |
22 end; |
23 end; |
23 |
24 |
24 structure BNF_FP_Def_Sugar : BNF_FP_DEF_SUGAR = |
25 structure BNF_FP_Def_Sugar : BNF_FP_DEF_SUGAR = |
127 |
128 |
128 fun reassoc_conjs thm = |
129 fun reassoc_conjs thm = |
129 reassoc_conjs (thm RS @{thm conj_assoc[THEN iffD1]}) |
130 reassoc_conjs (thm RS @{thm conj_assoc[THEN iffD1]}) |
130 handle THM _ => thm; |
131 handle THM _ => thm; |
131 |
132 |
132 fun type_args_constrained_of (((cAs, _), _), _) = cAs; |
133 fun map_binding_of ((((b, _), _), _), _) = b; |
|
134 fun type_args_named_constrained_of ((((_, ncAs), _), _), _) = ncAs; |
133 fun type_binding_of (((_, b), _), _) = b; |
135 fun type_binding_of (((_, b), _), _) = b; |
134 fun mixfix_of ((_, mx), _) = mx; |
136 fun mixfix_of ((_, mx), _) = mx; |
135 fun ctr_specs_of (_, ctr_specs) = ctr_specs; |
137 fun ctr_specs_of (_, ctr_specs) = ctr_specs; |
136 |
138 |
137 fun disc_of ((((disc, _), _), _), _) = disc; |
139 fun disc_of ((((disc, _), _), _), _) = disc; |
154 |
156 |
155 val nn = length specs; |
157 val nn = length specs; |
156 val fp_bs = map type_binding_of specs; |
158 val fp_bs = map type_binding_of specs; |
157 val fp_b_names = map Binding.name_of fp_bs; |
159 val fp_b_names = map Binding.name_of fp_bs; |
158 val fp_common_name = mk_common_name fp_b_names; |
160 val fp_common_name = mk_common_name fp_b_names; |
159 |
161 val map_bs = map map_binding_of specs; |
160 fun prepare_type_arg ((_, ty), c) = |
162 |
|
163 fun prepare_type_arg (_, (ty, c)) = |
161 let val TFree (s, _) = prepare_typ no_defs_lthy0 ty in |
164 let val TFree (s, _) = prepare_typ no_defs_lthy0 ty in |
162 TFree (s, prepare_constraint no_defs_lthy0 c) |
165 TFree (s, prepare_constraint no_defs_lthy0 c) |
163 end; |
166 end; |
164 |
167 |
165 val Ass0 = map (map prepare_type_arg o type_args_constrained_of) specs; |
168 val Ass0 = map (map prepare_type_arg o type_args_named_constrained_of) specs; |
166 val unsorted_Ass0 = map (map (resort_tfree HOLogic.typeS)) Ass0; |
169 val unsorted_Ass0 = map (map (resort_tfree HOLogic.typeS)) Ass0; |
167 val unsorted_As = Library.foldr1 merge_type_args unsorted_Ass0; |
170 val unsorted_As = Library.foldr1 merge_type_args unsorted_Ass0; |
168 val set_bss = map (map (fst o fst) o type_args_constrained_of) specs; |
171 val set_bss = map (map fst o type_args_named_constrained_of) specs; |
169 |
172 |
170 val (((Bs0, Cs), Xs), no_defs_lthy) = |
173 val (((Bs0, Cs), Xs), no_defs_lthy) = |
171 no_defs_lthy0 |
174 no_defs_lthy0 |
172 |> fold (Variable.declare_typ o resort_tfree dummyS) unsorted_As |
175 |> fold (Variable.declare_typ o resort_tfree dummyS) unsorted_As |
173 |> mk_TFrees (length unsorted_As) |
176 |> mk_TFrees (length unsorted_As) |
178 (* TODO: cleaner handling of fake contexts, without "background_theory" *) |
181 (* TODO: cleaner handling of fake contexts, without "background_theory" *) |
179 (*the "perhaps o try" below helps gracefully handles the case where the new type is defined in a |
182 (*the "perhaps o try" below helps gracefully handles the case where the new type is defined in a |
180 locale and shadows an existing global type*) |
183 locale and shadows an existing global type*) |
181 val fake_thy = |
184 val fake_thy = |
182 Theory.copy #> fold (fn spec => perhaps (try (Sign.add_type no_defs_lthy |
185 Theory.copy #> fold (fn spec => perhaps (try (Sign.add_type no_defs_lthy |
183 (type_binding_of spec, length (type_args_constrained_of spec), mixfix_of spec)))) specs; |
186 (type_binding_of spec, length (type_args_named_constrained_of spec), mixfix_of spec)))) |
|
187 specs; |
184 val fake_lthy = Proof_Context.background_theory fake_thy no_defs_lthy; |
188 val fake_lthy = Proof_Context.background_theory fake_thy no_defs_lthy; |
185 |
189 |
186 fun mk_fake_T b = |
190 fun mk_fake_T b = |
187 Type (fst (Term.dest_Type (Proof_Context.read_type_name fake_lthy true (Binding.name_of b))), |
191 Type (fst (Term.dest_Type (Proof_Context.read_type_name fake_lthy true (Binding.name_of b))), |
188 unsorted_As); |
192 unsorted_As); |
238 |
242 |
239 (* TODO: clean up list *) |
243 (* TODO: clean up list *) |
240 val (pre_bnfs, ((fp_bnfs as any_fp_bnf :: _, dtors0, ctors0, fp_folds0, fp_recs0, fp_induct, |
244 val (pre_bnfs, ((fp_bnfs as any_fp_bnf :: _, dtors0, ctors0, fp_folds0, fp_recs0, fp_induct, |
241 fp_strong_induct, dtor_ctors, ctor_dtors, ctor_injects, fp_map_thms, fp_set_thmss, |
245 fp_strong_induct, dtor_ctors, ctor_dtors, ctor_injects, fp_map_thms, fp_set_thmss, |
242 fp_rel_thms, fp_fold_thms, fp_rec_thms), lthy)) = |
246 fp_rel_thms, fp_fold_thms, fp_rec_thms), lthy)) = |
243 fp_bnf construct_fp fp_bs mixfixes set_bss (map dest_TFree unsorted_As) fp_eqs no_defs_lthy0; |
247 fp_bnf construct_fp fp_bs mixfixes map_bs set_bss (map dest_TFree unsorted_As) fp_eqs |
|
248 no_defs_lthy0; |
244 |
249 |
245 val timer = time (Timer.startRealTimer ()); |
250 val timer = time (Timer.startRealTimer ()); |
246 |
251 |
247 fun build_map build_arg (Type (s, Ts)) (Type (_, Us)) = |
252 fun build_map build_arg (Type (s, Ts)) (Type (_, Us)) = |
248 let |
253 let |
1179 (Parse.typ >> pair Binding.empty); |
1184 (Parse.typ >> pair Binding.empty); |
1180 |
1185 |
1181 val parse_defaults = |
1186 val parse_defaults = |
1182 @{keyword "("} |-- @{keyword "defaults"} |-- Scan.repeat parse_bound_term --| @{keyword ")"}; |
1187 @{keyword "("} |-- @{keyword "defaults"} |-- Scan.repeat parse_bound_term --| @{keyword ")"}; |
1183 |
1188 |
1184 (* Identical to unexported function of the same name in "Pure/Isar/parse.ML" *) |
1189 val parse_type_arg_constrained = |
1185 fun parse_type_arguments arg = |
1190 Parse.type_ident -- Scan.option (@{keyword "::"} |-- Parse.!!! Parse.sort) |
1186 arg >> single || @{keyword "("} |-- Parse.!!! (Parse.list1 arg --| @{keyword ")"}) || |
1191 |
|
1192 val parse_type_arg_named_constrained = parse_opt_binding_colon -- parse_type_arg_constrained |
|
1193 |
|
1194 val parse_type_args_named_constrained = |
|
1195 parse_type_arg_constrained >> (single o pair Binding.empty) || |
|
1196 @{keyword "("} |-- Parse.!!! (Parse.list1 parse_type_arg_named_constrained --| @{keyword ")"}) || |
1187 Scan.succeed []; |
1197 Scan.succeed []; |
1188 |
1198 |
1189 val parse_type_arg_constrained = |
|
1190 parse_opt_binding_colon -- Parse.type_ident -- |
|
1191 Scan.option (@{keyword "::"} |-- Parse.!!! Parse.sort) |
|
1192 |
|
1193 val parse_type_args_constrained = parse_type_arguments parse_type_arg_constrained; |
|
1194 |
|
1195 val parse_single_spec = |
1199 val parse_single_spec = |
1196 parse_type_args_constrained -- Parse.binding -- Parse.opt_mixfix -- |
1200 parse_opt_binding_colon -- parse_type_args_named_constrained -- Parse.binding -- |
1197 (@{keyword "="} |-- Parse.enum1 "|" (parse_opt_binding_colon -- Parse.binding -- |
1201 Parse.opt_mixfix -- (@{keyword "="} |-- Parse.enum1 "|" (parse_opt_binding_colon -- |
1198 Scan.repeat parse_ctr_arg -- Scan.optional parse_defaults [] -- Parse.opt_mixfix)); |
1202 Parse.binding -- Scan.repeat parse_ctr_arg -- Scan.optional parse_defaults [] -- |
|
1203 Parse.opt_mixfix)); |
1199 |
1204 |
1200 val parse_datatype = parse_wrap_options -- Parse.and_list1 parse_single_spec; |
1205 val parse_datatype = parse_wrap_options -- Parse.and_list1 parse_single_spec; |
1201 |
1206 |
1202 fun parse_datatype_cmd lfp construct_fp = parse_datatype >> datatype_cmd lfp construct_fp; |
1207 fun parse_datatype_cmd lfp construct_fp = parse_datatype >> datatype_cmd lfp construct_fp; |
1203 |
1208 |