5 *) |
5 *) |
6 |
6 |
7 signature DATATYPE_DATA = |
7 signature DATATYPE_DATA = |
8 sig |
8 sig |
9 include DATATYPE_COMMON |
9 include DATATYPE_COMMON |
10 val derive_datatype_props : config -> string list -> string list option |
10 val derive_datatype_props : config -> string list -> descr list -> (string * sort) list -> |
11 -> descr list -> (string * sort) list -> thm -> thm list list -> thm list list |
11 thm -> thm list list -> thm list list -> theory -> string list * theory |
12 -> theory -> string list * theory |
12 val rep_datatype : config -> (string list -> Proof.context -> Proof.context) -> |
13 val rep_datatype : config -> (string list -> Proof.context -> Proof.context) |
13 term list -> theory -> Proof.state |
14 -> string list option -> term list -> theory -> Proof.state |
14 val rep_datatype_cmd : string list -> theory -> Proof.state |
15 val rep_datatype_cmd : string list option -> string list -> theory -> Proof.state |
|
16 val get_info : theory -> string -> info option |
15 val get_info : theory -> string -> info option |
17 val the_info : theory -> string -> info |
16 val the_info : theory -> string -> info |
18 val the_descr : theory -> string list |
17 val the_descr : theory -> string list -> |
19 -> descr * (string * sort) list * string list |
18 descr * (string * sort) list * string list * string * |
20 * string * (string list * string list) * (typ list * typ list) |
19 (string list * string list) * (typ list * typ list) |
21 val the_spec : theory -> string -> (string * sort) list * (string * typ list) list |
20 val the_spec : theory -> string -> (string * sort) list * (string * typ list) list |
22 val all_distincts : theory -> typ list -> thm list list |
21 val all_distincts : theory -> typ list -> thm list list |
23 val get_constrs : theory -> string -> (string * typ) list option |
22 val get_constrs : theory -> string -> (string * typ) list option |
24 val get_all : theory -> info Symtab.table |
23 val get_all : theory -> info Symtab.table |
25 val info_of_constr : theory -> string * typ -> info option |
24 val info_of_constr : theory -> string * typ -> info option |
142 error ("Type constructors " ^ commas_quote raw_tycos ^ |
141 error ("Type constructors " ^ commas_quote raw_tycos ^ |
143 " do not belong exhaustively to one mutual recursive datatype"); |
142 " do not belong exhaustively to one mutual recursive datatype"); |
144 |
143 |
145 val (Ts, Us) = (pairself o map) Type protoTs; |
144 val (Ts, Us) = (pairself o map) Type protoTs; |
146 |
145 |
147 val names = map Long_Name.base_name (the_default tycos (#alt_names info)); |
146 val names = map Long_Name.base_name tycos; |
148 val (auxnames, _) = |
147 val (auxnames, _) = |
149 Name.make_context names |
148 Name.make_context names |
150 |> fold_map (Name.variant o Datatype_Aux.name_of_typ) Us; |
149 |> fold_map (Name.variant o Datatype_Aux.name_of_typ) Us; |
151 val prefix = space_implode "_" names; |
150 val prefix = space_implode "_" names; |
152 |
151 |
282 type T = Datatype_Aux.config * string list; |
281 type T = Datatype_Aux.config * string list; |
283 val eq: T * T -> bool = eq_snd (op =); |
282 val eq: T * T -> bool = eq_snd (op =); |
284 ); |
283 ); |
285 fun interpretation f = Datatype_Interpretation.interpretation (uncurry f); |
284 fun interpretation f = Datatype_Interpretation.interpretation (uncurry f); |
286 |
285 |
287 fun make_dt_info alt_names descr sorts induct inducts rec_names rec_rewrites |
286 fun make_dt_info descr sorts induct inducts rec_names rec_rewrites |
288 (index, (((((((((((_, (tname, _, _))), inject), distinct), |
287 (index, (((((((((((_, (tname, _, _))), inject), distinct), |
289 exhaust), nchotomy), case_name), case_rewrites), case_cong), weak_case_cong), |
288 exhaust), nchotomy), case_name), case_rewrites), case_cong), weak_case_cong), |
290 (split, split_asm))) = |
289 (split, split_asm))) = |
291 (tname, |
290 (tname, |
292 {index = index, |
291 {index = index, |
293 alt_names = alt_names, |
|
294 descr = descr, |
292 descr = descr, |
295 sorts = sorts, |
293 sorts = sorts, |
296 inject = inject, |
294 inject = inject, |
297 distinct = distinct, |
295 distinct = distinct, |
298 induct = induct, |
296 induct = induct, |
306 case_cong = case_cong, |
304 case_cong = case_cong, |
307 weak_case_cong = weak_case_cong, |
305 weak_case_cong = weak_case_cong, |
308 split = split, |
306 split = split, |
309 split_asm = split_asm}); |
307 split_asm = split_asm}); |
310 |
308 |
311 fun derive_datatype_props config dt_names alt_names descr sorts |
309 fun derive_datatype_props config dt_names descr sorts |
312 induct inject distinct thy1 = |
310 induct inject distinct thy1 = |
313 let |
311 let |
314 val thy2 = thy1 |> Theory.checkpoint; |
312 val thy2 = thy1 |> Theory.checkpoint; |
315 val flat_descr = flat descr; |
313 val flat_descr = flat descr; |
316 val new_type_names = map Long_Name.base_name (the_default dt_names alt_names); |
314 val new_type_names = map Long_Name.base_name dt_names; |
317 val _ = |
315 val _ = |
318 Datatype_Aux.message config |
316 Datatype_Aux.message config |
319 ("Deriving properties for datatype(s) " ^ commas_quote new_type_names); |
317 ("Deriving properties for datatype(s) " ^ commas_quote new_type_names); |
320 |
318 |
321 val (exhaust, thy3) = |
319 val (exhaust, thy3) = |
341 Datatype_Abs_Proofs.prove_split_thms |
339 Datatype_Abs_Proofs.prove_split_thms |
342 config new_type_names descr sorts inject distinct exhaust case_rewrites thy8; |
340 config new_type_names descr sorts inject distinct exhaust case_rewrites thy8; |
343 |
341 |
344 val inducts = Project_Rule.projections (Proof_Context.init_global thy2) induct; |
342 val inducts = Project_Rule.projections (Proof_Context.init_global thy2) induct; |
345 val dt_infos = map_index |
343 val dt_infos = map_index |
346 (make_dt_info alt_names flat_descr sorts induct inducts rec_names rec_rewrites) |
344 (make_dt_info flat_descr sorts induct inducts rec_names rec_rewrites) |
347 (hd descr ~~ inject ~~ distinct ~~ exhaust ~~ nchotomys ~~ |
345 (hd descr ~~ inject ~~ distinct ~~ exhaust ~~ nchotomys ~~ |
348 case_names ~~ case_rewrites ~~ case_congs ~~ weak_case_congs ~~ splits); |
346 case_names ~~ case_rewrites ~~ case_congs ~~ weak_case_congs ~~ splits); |
349 val dt_names = map fst dt_infos; |
347 val dt_names = map fst dt_infos; |
350 val prfx = Binding.qualify true (space_implode "_" new_type_names); |
348 val prfx = Binding.qualify true (space_implode "_" new_type_names); |
351 val simps = flat (inject @ distinct @ case_rewrites) @ rec_rewrites; |
349 val simps = flat (inject @ distinct @ case_rewrites) @ rec_rewrites; |
378 |
376 |
379 |
377 |
380 |
378 |
381 (** declare existing type as datatype **) |
379 (** declare existing type as datatype **) |
382 |
380 |
383 fun prove_rep_datatype config dt_names alt_names descr sorts |
381 fun prove_rep_datatype config dt_names descr sorts raw_inject half_distinct raw_induct thy1 = |
384 raw_inject half_distinct raw_induct thy1 = |
|
385 let |
382 let |
386 val raw_distinct = (map o maps) (fn thm => [thm, thm RS not_sym]) half_distinct; |
383 val raw_distinct = (map o maps) (fn thm => [thm, thm RS not_sym]) half_distinct; |
387 val new_type_names = map Long_Name.base_name (the_default dt_names alt_names); |
384 val new_type_names = map Long_Name.base_name dt_names; |
388 val prfx = Binding.qualify true (space_implode "_" new_type_names); |
385 val prfx = Binding.qualify true (space_implode "_" new_type_names); |
389 val (((inject, distinct), [induct]), thy2) = |
386 val (((inject, distinct), [induct]), thy2) = |
390 thy1 |
387 thy1 |
391 |> Datatype_Aux.store_thmss "inject" new_type_names raw_inject |
388 |> Datatype_Aux.store_thmss "inject" new_type_names raw_inject |
392 ||>> Datatype_Aux.store_thmss "distinct" new_type_names raw_distinct |
389 ||>> Datatype_Aux.store_thmss "distinct" new_type_names raw_distinct |
393 ||>> Global_Theory.add_thms |
390 ||>> Global_Theory.add_thms |
394 [((prfx (Binding.name "induct"), raw_induct), |
391 [((prfx (Binding.name "induct"), raw_induct), |
395 [mk_case_names_induct descr])]; |
392 [mk_case_names_induct descr])]; |
396 in |
393 in |
397 thy2 |
394 thy2 |
398 |> derive_datatype_props config dt_names alt_names [descr] sorts |
395 |> derive_datatype_props config dt_names [descr] sorts induct inject distinct |
399 induct inject distinct |
|
400 end; |
396 end; |
401 |
397 |
402 fun gen_rep_datatype prep_term config after_qed alt_names raw_ts thy = |
398 fun gen_rep_datatype prep_term config after_qed raw_ts thy = |
403 let |
399 let |
404 val ctxt = Proof_Context.init_global thy; |
400 val ctxt = Proof_Context.init_global thy; |
405 |
401 |
406 fun constr_of_term (Const (c, T)) = (c, T) |
402 fun constr_of_term (Const (c, T)) = (c, T) |
407 | constr_of_term t = error ("Not a constant: " ^ Syntax.string_of_term ctxt t); |
403 | constr_of_term t = error ("Not a constant: " ^ Syntax.string_of_term ctxt t); |
459 val [[[raw_induct]], raw_inject, half_distinct] = |
455 val [[[raw_induct]], raw_inject, half_distinct] = |
460 unflat rules (map Drule.zero_var_indexes_list raw_thms); |
456 unflat rules (map Drule.zero_var_indexes_list raw_thms); |
461 (*FIXME somehow dubious*) |
457 (*FIXME somehow dubious*) |
462 in |
458 in |
463 Proof_Context.background_theory_result (* FIXME !? *) |
459 Proof_Context.background_theory_result (* FIXME !? *) |
464 (prove_rep_datatype config dt_names alt_names descr vs |
460 (prove_rep_datatype config dt_names descr vs raw_inject half_distinct raw_induct) |
465 raw_inject half_distinct raw_induct) |
|
466 #-> after_qed |
461 #-> after_qed |
467 end; |
462 end; |
468 in |
463 in |
469 ctxt |
464 ctxt |
470 |> Proof.theorem NONE after_qed' ((map o map) (rpair []) (flat rules)) |
465 |> Proof.theorem NONE after_qed' ((map o map) (rpair []) (flat rules)) |