319 weak_case_cong = weak_case_cong, |
319 weak_case_cong = weak_case_cong, |
320 split = split, |
320 split = split, |
321 split_asm = split_asm}); |
321 split_asm = split_asm}); |
322 |
322 |
323 fun derive_datatype_props config dt_names alt_names descr sorts |
323 fun derive_datatype_props config dt_names alt_names descr sorts |
324 induct inject (distinct_rules, distinct_rewrites) thy1 = |
324 induct inject distinct thy1 = |
325 let |
325 let |
326 val thy2 = thy1 |> Theory.checkpoint; |
326 val thy2 = thy1 |> Theory.checkpoint; |
327 val flat_descr = flat descr; |
327 val flat_descr = flat descr; |
328 val new_type_names = map Long_Name.base_name (the_default dt_names alt_names); |
328 val new_type_names = map Long_Name.base_name (the_default dt_names alt_names); |
329 val _ = message config ("Deriving properties for datatype(s) " ^ commas_quote new_type_names); |
329 val _ = message config ("Deriving properties for datatype(s) " ^ commas_quote new_type_names); |
332 descr sorts induct (mk_case_names_exhausts flat_descr dt_names) thy2; |
332 descr sorts induct (mk_case_names_exhausts flat_descr dt_names) thy2; |
333 val (nchotomys, thy4) = DatatypeAbsProofs.prove_nchotomys config new_type_names |
333 val (nchotomys, thy4) = DatatypeAbsProofs.prove_nchotomys config new_type_names |
334 descr sorts exhaust thy3; |
334 descr sorts exhaust thy3; |
335 val ((rec_names, rec_rewrites), thy5) = DatatypeAbsProofs.prove_primrec_thms |
335 val ((rec_names, rec_rewrites), thy5) = DatatypeAbsProofs.prove_primrec_thms |
336 config new_type_names descr sorts (#inject o the o Symtab.lookup (get_all thy4)) |
336 config new_type_names descr sorts (#inject o the o Symtab.lookup (get_all thy4)) |
337 inject distinct_rewrites (Simplifier.theory_context thy4 dist_ss) induct thy4; |
337 inject distinct (Simplifier.theory_context thy4 dist_ss) induct thy4; |
338 val ((case_rewrites, case_names), thy6) = DatatypeAbsProofs.prove_case_thms |
338 val ((case_rewrites, case_names), thy6) = DatatypeAbsProofs.prove_case_thms |
339 config new_type_names descr sorts rec_names rec_rewrites thy5; |
339 config new_type_names descr sorts rec_names rec_rewrites thy5; |
340 val (case_congs, thy7) = DatatypeAbsProofs.prove_case_congs new_type_names |
340 val (case_congs, thy7) = DatatypeAbsProofs.prove_case_congs new_type_names |
341 descr sorts nchotomys case_rewrites thy6; |
341 descr sorts nchotomys case_rewrites thy6; |
342 val (weak_case_congs, thy8) = DatatypeAbsProofs.prove_weak_case_congs new_type_names |
342 val (weak_case_congs, thy8) = DatatypeAbsProofs.prove_weak_case_congs new_type_names |
343 descr sorts thy7; |
343 descr sorts thy7; |
344 val (splits, thy9) = DatatypeAbsProofs.prove_split_thms |
344 val (splits, thy9) = DatatypeAbsProofs.prove_split_thms |
345 config new_type_names descr sorts inject distinct_rewrites exhaust case_rewrites thy8; |
345 config new_type_names descr sorts inject distinct exhaust case_rewrites thy8; |
346 |
346 |
347 val inducts = Project_Rule.projections (ProofContext.init thy2) induct; |
347 val inducts = Project_Rule.projections (ProofContext.init thy2) induct; |
348 val dt_infos = map_index (make_dt_info alt_names flat_descr sorts induct inducts rec_names rec_rewrites) |
348 val dt_infos = map_index (make_dt_info alt_names flat_descr sorts induct inducts rec_names rec_rewrites) |
349 (hd descr ~~ inject ~~ distinct_rules ~~ exhaust ~~ nchotomys ~~ |
349 (hd descr ~~ inject ~~ distinct ~~ exhaust ~~ nchotomys ~~ |
350 case_names ~~ case_rewrites ~~ case_congs ~~ weak_case_congs ~~ splits); |
350 case_names ~~ case_rewrites ~~ case_congs ~~ weak_case_congs ~~ splits); |
351 val dt_names = map fst dt_infos; |
351 val dt_names = map fst dt_infos; |
352 val prfx = Binding.qualify true (space_implode "_" new_type_names); |
352 val prfx = Binding.qualify true (space_implode "_" new_type_names); |
353 val simps = flat (inject @ distinct_rules @ case_rewrites) @ rec_rewrites; |
353 val simps = flat (inject @ distinct @ case_rewrites) @ rec_rewrites; |
354 val named_rules = flat (map_index (fn (index, tname) => |
354 val named_rules = flat (map_index (fn (index, tname) => |
355 [((Binding.empty, [nth inducts index]), [Induct.induct_type tname]), |
355 [((Binding.empty, [nth inducts index]), [Induct.induct_type tname]), |
356 ((Binding.empty, [nth exhaust index]), [Induct.cases_type tname])]) dt_names); |
356 ((Binding.empty, [nth exhaust index]), [Induct.cases_type tname])]) dt_names); |
357 val unnamed_rules = map (fn induct => |
357 val unnamed_rules = map (fn induct => |
358 ((Binding.empty, [induct]), [Thm.kind_internal, Induct.induct_type ""])) |
358 ((Binding.empty, [induct]), [Thm.kind_internal, Induct.induct_type ""])) |
360 in |
360 in |
361 thy9 |
361 thy9 |
362 |> PureThy.add_thmss ([((prfx (Binding.name "simps"), simps), []), |
362 |> PureThy.add_thmss ([((prfx (Binding.name "simps"), simps), []), |
363 ((prfx (Binding.name "inducts"), inducts), []), |
363 ((prfx (Binding.name "inducts"), inducts), []), |
364 ((prfx (Binding.name "splits"), maps (fn (x, y) => [x, y]) splits), []), |
364 ((prfx (Binding.name "splits"), maps (fn (x, y) => [x, y]) splits), []), |
365 ((Binding.empty, flat case_rewrites @ flat distinct_rules @ rec_rewrites), |
365 ((Binding.empty, flat case_rewrites @ flat distinct @ rec_rewrites), |
366 [Simplifier.simp_add]), |
366 [Simplifier.simp_add]), |
367 ((Binding.empty, rec_rewrites), [Code.add_default_eqn_attribute]), |
367 ((Binding.empty, rec_rewrites), [Code.add_default_eqn_attribute]), |
368 ((Binding.empty, flat inject), [iff_add]), |
368 ((Binding.empty, flat inject), [iff_add]), |
369 ((Binding.empty, map (fn th => th RS notE) (flat distinct_rules)), |
369 ((Binding.empty, map (fn th => th RS notE) (flat distinct)), |
370 [Classical.safe_elim NONE]), |
370 [Classical.safe_elim NONE]), |
371 ((Binding.empty, weak_case_congs), [Simplifier.attrib (op addcongs)])] |
371 ((Binding.empty, weak_case_congs), [Simplifier.attrib (op addcongs)])] |
372 @ named_rules @ unnamed_rules) |
372 @ named_rules @ unnamed_rules) |
373 |> snd |
373 |> snd |
374 |> add_case_tr' case_names |
374 |> add_case_tr' case_names |
392 ||>> PureThy.add_thms [((Binding.name "induct", raw_induct), [mk_case_names_induct descr])] |
392 ||>> PureThy.add_thms [((Binding.name "induct", raw_induct), [mk_case_names_induct descr])] |
393 ||> Sign.restore_naming thy1; |
393 ||> Sign.restore_naming thy1; |
394 in |
394 in |
395 thy2 |
395 thy2 |
396 |> derive_datatype_props config dt_names alt_names [descr] sorts |
396 |> derive_datatype_props config dt_names alt_names [descr] sorts |
397 induct inject (distinct, distinct) |
397 induct inject distinct |
398 end; |
398 end; |
399 |
399 |
400 fun gen_rep_datatype prep_term config after_qed alt_names raw_ts thy = |
400 fun gen_rep_datatype prep_term config after_qed alt_names raw_ts thy = |
401 let |
401 let |
402 fun constr_of_term (Const (c, T)) = (c, T) |
402 fun constr_of_term (Const (c, T)) = (c, T) |
529 val _ = check_nonempty descr handle (exn as Datatype_Empty s) => |
529 val _ = check_nonempty descr handle (exn as Datatype_Empty s) => |
530 if #strict config then error ("Nonemptiness check failed for datatype " ^ s) |
530 if #strict config then error ("Nonemptiness check failed for datatype " ^ s) |
531 else raise exn; |
531 else raise exn; |
532 |
532 |
533 val _ = message config ("Constructing datatype(s) " ^ commas_quote new_type_names); |
533 val _ = message config ("Constructing datatype(s) " ^ commas_quote new_type_names); |
534 val ((inject, (distinct_rules, distinct_rewrites), induct), thy') = thy |> |
534 val ((inject, distinct, induct), thy') = thy |> |
535 DatatypeRepProofs.representation_proofs config dt_info new_type_names descr sorts |
535 DatatypeRepProofs.representation_proofs config dt_info new_type_names descr sorts |
536 types_syntax constr_syntax (mk_case_names_induct (flat descr)); |
536 types_syntax constr_syntax (mk_case_names_induct (flat descr)); |
537 in |
537 in |
538 derive_datatype_props config dt_names (SOME new_type_names) descr sorts |
538 derive_datatype_props config dt_names (SOME new_type_names) descr sorts |
539 induct inject (distinct_rules, distinct_rewrites) thy' |
539 induct inject distinct thy' |
540 end; |
540 end; |
541 |
541 |
542 val add_datatype = gen_add_datatype cert_typ; |
542 val add_datatype = gen_add_datatype cert_typ; |
543 val datatype_cmd = snd ooo gen_add_datatype read_typ default_config; |
543 val datatype_cmd = snd ooo gen_add_datatype read_typ default_config; |
544 |
544 |