179 local |
179 local |
180 |
180 |
181 fun prep_var (Var (ixn, _), SOME x) = SOME (ixn, x) |
181 fun prep_var (Var (ixn, _), SOME x) = SOME (ixn, x) |
182 | prep_var _ = NONE; |
182 | prep_var _ = NONE; |
183 |
183 |
184 fun prep_inst (concl, xs) = (*exception Library.UnequalLengths *) |
184 fun prep_inst (concl, xs) = (*exception Library.UnequalLengths*) |
185 let val vs = InductAttrib.vars_of concl |
185 let val vs = InductAttrib.vars_of concl |
186 in List.mapPartial prep_var (Library.drop (length vs - length xs, vs) ~~ xs) end; |
186 in map_filter prep_var (Library.drop (length vs - length xs, vs) ~~ xs) end; |
187 |
187 |
188 in |
188 in |
189 |
189 |
190 fun gen_induct_tac inst_tac (varss, opt_rule) i state = |
190 fun gen_induct_tac inst_tac (varss, opt_rule) i state = |
191 SUBGOAL (fn (Bi,_) => |
191 SUBGOAL (fn (Bi,_) => |
192 let |
192 let |
193 val (rule, rule_name) = |
193 val (rule, rule_name) = |
194 case opt_rule of |
194 case opt_rule of |
195 SOME r => (r, "Induction rule") |
195 SOME r => (r, "Induction rule") |
196 | NONE => |
196 | NONE => |
197 let val tn = find_tname (hd (List.mapPartial I (List.concat varss))) Bi |
197 let val tn = find_tname (hd (map_filter I (flat varss))) Bi |
198 val {sign, ...} = Thm.rep_thm state |
198 val {sign, ...} = Thm.rep_thm state |
199 in (#induction (the_datatype sign tn), "Induction rule for type " ^ tn) |
199 in (#induction (the_datatype sign tn), "Induction rule for type " ^ tn) |
200 end |
200 end |
201 val concls = HOLogic.dest_concls (Thm.concl_of rule); |
201 val concls = HOLogic.dest_concls (Thm.concl_of rule); |
202 val insts = List.concat (map prep_inst (concls ~~ varss)) handle Library.UnequalLengths => |
202 val insts = maps prep_inst (concls ~~ varss) handle Library.UnequalLengths => |
203 error (rule_name ^ " has different numbers of variables"); |
203 error (rule_name ^ " has different numbers of variables"); |
204 in occs_in_prems (inst_tac insts rule) (map #2 insts) i end) |
204 in occs_in_prems (inst_tac insts rule) (map #2 insts) i end) |
205 i state; |
205 i state; |
206 |
206 |
207 fun induct_tac s = |
207 fun induct_tac s = |
208 gen_induct_tac Tactic.res_inst_tac' |
208 gen_induct_tac Tactic.res_inst_tac' |
209 (map (Library.single o SOME) (Syntax.read_idents s), NONE); |
209 (map (single o SOME) (Syntax.read_idents s), NONE); |
210 |
210 |
211 fun induct_thm_tac th s = |
211 fun induct_thm_tac th s = |
212 gen_induct_tac Tactic.res_inst_tac' |
212 gen_induct_tac Tactic.res_inst_tac' |
213 ([map SOME (Syntax.read_idents s)], SOME th); |
213 ([map SOME (Syntax.read_idents s)], SOME th); |
214 |
214 |
271 (* case names *) |
271 (* case names *) |
272 |
272 |
273 local |
273 local |
274 |
274 |
275 fun dt_recs (DtTFree _) = [] |
275 fun dt_recs (DtTFree _) = [] |
276 | dt_recs (DtType (_, dts)) = List.concat (map dt_recs dts) |
276 | dt_recs (DtType (_, dts)) = maps dt_recs dts |
277 | dt_recs (DtRec i) = [i]; |
277 | dt_recs (DtRec i) = [i]; |
278 |
278 |
279 fun dt_cases (descr: descr) (_, args, constrs) = |
279 fun dt_cases (descr: descr) (_, args, constrs) = |
280 let |
280 let |
281 fun the_bname i = Sign.base_name (#1 (valOf (AList.lookup (op =) descr i))); |
281 fun the_bname i = Sign.base_name (#1 (the (AList.lookup (op =) descr i))); |
282 val bnames = map the_bname (distinct (op =) (List.concat (map dt_recs args))); |
282 val bnames = map the_bname (distinct (op =) (maps dt_recs args)); |
283 in map (fn (c, _) => space_implode "_" (Sign.base_name c :: bnames)) constrs end; |
283 in map (fn (c, _) => space_implode "_" (Sign.base_name c :: bnames)) constrs end; |
284 |
284 |
285 |
285 |
286 fun induct_cases descr = |
286 fun induct_cases descr = |
287 DatatypeProp.indexify_names (List.concat (map (dt_cases descr) (map #2 descr))); |
287 DatatypeProp.indexify_names (maps (dt_cases descr) (map #2 descr)); |
288 |
288 |
289 fun exhaust_cases descr i = dt_cases descr (valOf (AList.lookup (op =) descr i)); |
289 fun exhaust_cases descr i = dt_cases descr (the (AList.lookup (op =) descr i)); |
290 |
290 |
291 in |
291 in |
292 |
292 |
293 fun mk_case_names_induct descr = RuleCases.case_names (induct_cases descr); |
293 fun mk_case_names_induct descr = RuleCases.case_names (induct_cases descr); |
294 |
294 |
295 fun mk_case_names_exhausts descr new = |
295 fun mk_case_names_exhausts descr new = |
296 map (RuleCases.case_names o exhaust_cases descr o #1) |
296 map (RuleCases.case_names o exhaust_cases descr o #1) |
297 (List.filter (fn ((_, (name, _, _))) => name mem_string new) descr); |
297 (filter (fn ((_, (name, _, _))) => member (op =) new name) descr); |
298 |
298 |
299 end; |
299 end; |
300 |
300 |
301 (*Name management for ATP linkup. The suffix here must agree with the one given |
301 (*Name management for ATP linkup. The suffix here must agree with the one given |
302 for notE in Clasimp.addIff*) |
302 for notE in Clasimp.addIff*) |
304 Thm.name_thm (Thm.name_of_thm th ^ "_iff1", th RS notE); |
304 Thm.name_thm (Thm.name_of_thm th ^ "_iff1", th RS notE); |
305 |
305 |
306 fun add_rules simps case_thms size_thms rec_thms inject distinct |
306 fun add_rules simps case_thms size_thms rec_thms inject distinct |
307 weak_case_congs cong_att = |
307 weak_case_congs cong_att = |
308 (snd o PureThy.add_thmss [(("simps", simps), []), |
308 (snd o PureThy.add_thmss [(("simps", simps), []), |
309 (("", List.concat case_thms @ size_thms @ |
309 (("", flat case_thms @ size_thms @ |
310 List.concat distinct @ rec_thms), [Simplifier.simp_add]), |
310 flat distinct @ rec_thms), [Simplifier.simp_add]), |
311 (("", size_thms @ rec_thms), [setmp CodegenData.strict_functyp false (RecfunCodegen.add NONE)]), |
311 (("", size_thms @ rec_thms), [setmp CodegenData.strict_functyp false (RecfunCodegen.add NONE)]), |
312 (("", List.concat inject), [iff_add]), |
312 (("", flat inject), [iff_add]), |
313 (("", map name_notE (List.concat distinct)), [Classical.safe_elim NONE]), |
313 (("", map name_notE (flat distinct)), [Classical.safe_elim NONE]), |
314 (("", weak_case_congs), [cong_att])]); |
314 (("", weak_case_congs), [cong_att])]); |
315 |
315 |
316 |
316 |
317 (* add_cases_induct *) |
317 (* add_cases_induct *) |
318 |
318 |
413 val cases as ((cname, _), _) :: _ = map dest_case1 (dest_case2 u); |
411 val cases as ((cname, _), _) :: _ = map dest_case1 (dest_case2 u); |
414 val tab = Symtab.dest (get_datatypes thy); |
412 val tab = Symtab.dest (get_datatypes thy); |
415 val (cases', default) = (case split_last cases of |
413 val (cases', default) = (case split_last cases of |
416 (cases', (("dummy_pattern", []), t)) => (cases', SOME t) |
414 (cases', (("dummy_pattern", []), t)) => (cases', SOME t) |
417 | _ => (cases, NONE)) |
415 | _ => (cases, NONE)) |
418 fun abstr (Free (x, T), body) = Term.absfree (x, T, body) |
416 fun abstr (Free (x, T)) body = Term.absfree (x, T, body) |
419 | abstr (Const ("_constrain", _) $ Free (x, T) $ tT, body) = |
417 | abstr (Const ("_constrain", _) $ Free (x, T) $ tT) body = |
420 Syntax.const Syntax.constrainAbsC $ Term.absfree (x, T, body) $ tT |
418 Syntax.const Syntax.constrainAbsC $ Term.absfree (x, T, body) $ tT |
421 | abstr (Const ("Pair", _) $ x $ y, body) = |
419 | abstr (Const ("Pair", _) $ x $ y) body = |
422 Syntax.const "split" $ abstr (x, abstr (y, body)) |
420 Syntax.const "split" $ (abstr x o abstr y) body |
423 | abstr (t, _) = case_error "Illegal pattern" NONE [t]; |
421 | abstr t _ = case_error "Illegal pattern" NONE [t]; |
424 in case find_first (fn (_, {descr, index, ...}) => |
422 in case find_first (fn (_, {descr, index, ...}) => |
425 exists (equal cname o fst) (#3 (snd (List.nth (descr, index))))) tab of |
423 exists (equal cname o fst) (#3 (snd (nth descr index)))) tab of |
426 NONE => case_error ("Not a datatype constructor: " ^ cname) NONE [u] |
424 NONE => case_error ("Not a datatype constructor: " ^ cname) NONE [u] |
427 | SOME (tname, {descr, sorts, case_name, index, ...}) => |
425 | SOME (tname, {descr, sorts, case_name, index, ...}) => |
428 let |
426 let |
429 val _ = if exists (equal "dummy_pattern" o fst o fst) cases' then |
427 val _ = if exists (equal "dummy_pattern" o fst o fst) cases' then |
430 case_error "Illegal occurrence of '_' dummy pattern" (SOME tname) [u] else (); |
428 case_error "Illegal occurrence of '_' dummy pattern" (SOME tname) [u] else (); |
431 val (_, (_, dts, constrs)) = List.nth (descr, index); |
429 val (_, (_, dts, constrs)) = nth descr index; |
432 fun find_case (cases, (s, dt)) = |
430 fun find_case (s, dt) cases = |
433 (case find_first (equal s o fst o fst) cases' of |
431 (case find_first (equal s o fst o fst) cases' of |
434 NONE => (cases, list_abs (map (rpair dummyT) |
432 NONE => (list_abs (map (rpair dummyT) |
435 (DatatypeProp.make_tnames (map (typ_of_dtyp descr sorts) dt)), |
433 (DatatypeProp.make_tnames (map (typ_of_dtyp descr sorts) dt)), |
436 case default of |
434 case default of |
437 NONE => (warning ("No clause for constructor " ^ s ^ |
435 NONE => (warning ("No clause for constructor " ^ s ^ |
438 " in case expression"); Const ("undefined", dummyT)) |
436 " in case expression"); Const ("undefined", dummyT)) |
439 | SOME t => t)) |
437 | SOME t => t), cases) |
440 | SOME (c as ((_, vs), t)) => |
438 | SOME (c as ((_, vs), t)) => |
441 if length dt <> length vs then |
439 if length dt <> length vs then |
442 case_error ("Wrong number of arguments for constructor " ^ s) |
440 case_error ("Wrong number of arguments for constructor " ^ s) |
443 (SOME tname) vs |
441 (SOME tname) vs |
444 else (cases \ c, foldr abstr t vs)) |
442 else (fold_rev abstr vs t, remove (op =) c cases)) |
445 val (cases'', fs) = foldl_map find_case (cases', constrs) |
443 val (fs, cases'') = fold_map find_case constrs cases' |
446 in case (cases'', length constrs = length cases', default) of |
444 in case (cases'', length constrs = length cases', default) of |
447 ([], true, SOME _) => |
445 ([], true, SOME _) => |
448 case_error "Extra '_' dummy pattern" (SOME tname) [u] |
446 case_error "Extra '_' dummy pattern" (SOME tname) [u] |
449 | (_ :: _, _, _) => |
447 | (_ :: _, _, _) => |
450 let val extra = distinct (op =) (map (fst o fst) cases'') |
448 let val extra = distinct (op =) (map (fst o fst) cases'') |
476 end; |
474 end; |
477 val cases = map (fn ((cname, dts), t) => |
475 val cases = map (fn ((cname, dts), t) => |
478 (Sign.extern_const (Context.theory_of context) cname, |
476 (Sign.extern_const (Context.theory_of context) cname, |
479 strip_abs (length dts) t, is_dependent (length dts) t)) |
477 strip_abs (length dts) t, is_dependent (length dts) t)) |
480 (constrs ~~ fs); |
478 (constrs ~~ fs); |
481 fun count_cases (cs, (_, _, true)) = cs |
479 fun count_cases (_, _, true) = I |
482 | count_cases (cs, (cname, (_, body), false)) = |
480 | count_cases (cname, (_, body), false) = |
483 case AList.lookup (op = : term * term -> bool) cs body |
481 AList.map_default (op = : term * term -> bool) |
484 of NONE => (body, [cname]) :: cs |
482 (body, []) (cons cname) |
485 | SOME cnames => AList.update (op =) (body, cnames @ [cname]) cs; |
483 val cases' = sort (int_ord o swap o pairself (length o snd)) |
486 val cases' = sort (int_ord o Library.swap o pairself (length o snd)) |
484 (fold_rev count_cases cases []); |
487 (Library.foldl count_cases ([], cases)); |
|
488 fun mk_case1 (cname, (vs, body), _) = Syntax.const "_case1" $ |
485 fun mk_case1 (cname, (vs, body), _) = Syntax.const "_case1" $ |
489 list_comb (Syntax.const cname, vs) $ body; |
486 list_comb (Syntax.const cname, vs) $ body; |
490 fun is_undefined (Const ("undefined", _)) = true |
487 fun is_undefined (Const ("undefined", _)) = true |
491 | is_undefined _ = false; |
488 | is_undefined _ = false; |
492 in |
489 in |
501 | (default, cnames) :: _ => |
498 | (default, cnames) :: _ => |
502 if length cnames = 1 then cases |
499 if length cnames = 1 then cases |
503 else if length cnames = length constrs then |
500 else if length cnames = length constrs then |
504 [hd cases, ("dummy_pattern", ([], default), false)] |
501 [hd cases, ("dummy_pattern", ([], default), false)] |
505 else |
502 else |
506 filter_out (fn (cname, _, _) => cname mem cnames) cases @ |
503 filter_out (fn (cname, _, _) => member (op =) cnames cname) cases @ |
507 [("dummy_pattern", ([], default), false)])) |
504 [("dummy_pattern", ([], default), false)])) |
508 end; |
505 end; |
509 |
506 |
510 fun make_case_tr' case_names descr = List.concat (map |
507 fun make_case_tr' case_names descr = maps |
511 (fn ((_, (_, _, constrs)), case_name) => map (rpair (case_tr' constrs)) |
508 (fn ((_, (_, _, constrs)), case_name) => |
512 (NameSpace.accesses' case_name)) (descr ~~ case_names)); |
509 map (rpair (case_tr' constrs)) (NameSpace.accesses' case_name)) |
|
510 (descr ~~ case_names); |
513 |
511 |
514 val trfun_setup = |
512 val trfun_setup = |
515 Theory.add_advanced_trfuns ([], [("_case_syntax", case_tr)], [], []); |
513 Theory.add_advanced_trfuns ([], [("_case_syntax", case_tr)], [], []); |
516 |
514 |
517 |
515 |
597 end; |
595 end; |
598 |
596 |
599 fun add_datatype_axm flat_names new_type_names descr sorts types_syntax constr_syntax dt_info |
597 fun add_datatype_axm flat_names new_type_names descr sorts types_syntax constr_syntax dt_info |
600 case_names_induct case_names_exhausts thy = |
598 case_names_induct case_names_exhausts thy = |
601 let |
599 let |
602 val descr' = List.concat descr; |
600 val descr' = flat descr; |
603 val recTs = get_rec_types descr' sorts; |
601 val recTs = get_rec_types descr' sorts; |
604 val used = foldr add_typ_tfree_names [] recTs; |
602 val used = map fst (fold Term.add_tfreesT recTs []); |
605 val newTs = Library.take (length (hd descr), recTs); |
603 val newTs = Library.take (length (hd descr), recTs); |
606 |
604 |
607 val no_size = exists (fn (_, (_, _, constrs)) => exists (fn (_, cargs) => exists |
605 val no_size = exists (fn (_, (_, _, constrs)) => exists (fn (_, cargs) => exists |
608 (fn dt => is_rec_type dt andalso not (null (fst (strip_dtyp dt)))) |
606 (fn dt => is_rec_type dt andalso not (null (fst (strip_dtyp dt)))) |
609 cargs) constrs) descr'; |
607 cargs) constrs) descr'; |
633 let val Ts = map (typ_of_dtyp descr' sorts) cargs |
631 let val Ts = map (typ_of_dtyp descr' sorts) cargs |
634 in Ts ---> freeT end) constrs) (hd descr); |
632 in Ts ---> freeT end) constrs) (hd descr); |
635 |
633 |
636 val case_names = map (fn s => (s ^ "_case")) new_type_names; |
634 val case_names = map (fn s => (s ^ "_case")) new_type_names; |
637 |
635 |
638 val thy2' = thy |> |
636 val thy2' = thy |
639 |
637 |
640 (** new types **) |
638 (** new types **) |
641 |
639 |> fold (fn ((name, mx), tvs) => TypedefPackage.add_typedecls [(name, tvs, mx)]) |
642 curry (Library.foldr (fn (((name, mx), tvs), thy') => thy' |> |
640 (types_syntax ~~ tyvars) |
643 TypedefPackage.add_typedecls [(name, tvs, mx)])) |
641 |> add_path flat_names (space_implode "_" new_type_names) |
644 (types_syntax ~~ tyvars) |> |
|
645 add_path flat_names (space_implode "_" new_type_names) |> |
|
646 |
642 |
647 (** primrec combinators **) |
643 (** primrec combinators **) |
648 |
644 |
649 specify_consts (map (fn ((name, T), T') => |
645 |> specify_consts (map (fn ((name, T), T') => |
650 (name, reccomb_fn_Ts @ [T] ---> T', NoSyn)) (reccomb_names ~~ recTs ~~ rec_result_Ts)) |> |
646 (name, reccomb_fn_Ts @ [T] ---> T', NoSyn)) (reccomb_names ~~ recTs ~~ rec_result_Ts)) |
651 |
647 |
652 (** case combinators **) |
648 (** case combinators **) |
653 |
649 |
654 specify_consts (map (fn ((name, T), Ts) => |
650 |> specify_consts (map (fn ((name, T), Ts) => |
655 (name, Ts @ [T] ---> freeT, NoSyn)) (case_names ~~ newTs ~~ case_fn_Ts)); |
651 (name, Ts @ [T] ---> freeT, NoSyn)) (case_names ~~ newTs ~~ case_fn_Ts)); |
656 |
652 |
657 val reccomb_names' = map (Sign.full_name thy2') reccomb_names; |
653 val reccomb_names' = map (Sign.full_name thy2') reccomb_names; |
658 val case_names' = map (Sign.full_name thy2') case_names; |
654 val case_names' = map (Sign.full_name thy2') case_names; |
659 |
655 |
660 val thy2 = thy2' |> |
656 val thy2 = thy2' |
661 |
657 |
662 (** size functions **) |
658 (** size functions **) |
663 |
659 |
664 (if no_size then I else specify_consts (map (fn (s, T) => |
660 |> (if no_size then I else specify_consts (map (fn (s, T) => |
665 (Sign.base_name s, T --> HOLogic.natT, NoSyn)) |
661 (Sign.base_name s, T --> HOLogic.natT, NoSyn)) |
666 (size_names ~~ Library.drop (length (hd descr), recTs)))) |> |
662 (size_names ~~ Library.drop (length (hd descr), recTs)))) |
667 |
663 |
668 (** constructors **) |
664 (** constructors **) |
669 |
665 |
670 parent_path flat_names |> |
666 |> parent_path flat_names |
671 curry (Library.foldr (fn (((((_, (_, _, constrs)), T), tname), |
667 |> fold (fn ((((_, (_, _, constrs)), T), tname), |
672 constr_syntax'), thy') => thy' |> |
668 constr_syntax') => |
673 add_path flat_names tname |> |
669 add_path flat_names tname #> |
674 specify_consts (map (fn ((_, cargs), (cname, mx)) => |
670 specify_consts (map (fn ((_, cargs), (cname, mx)) => |
675 (cname, map (typ_of_dtyp descr' sorts) cargs ---> T, mx)) |
671 (cname, map (typ_of_dtyp descr' sorts) cargs ---> T, mx)) |
676 (constrs ~~ constr_syntax')) |> |
672 (constrs ~~ constr_syntax')) #> |
677 parent_path flat_names)) |
673 parent_path flat_names) |
678 (hd descr ~~ newTs ~~ new_type_names ~~ constr_syntax); |
674 (hd descr ~~ newTs ~~ new_type_names ~~ constr_syntax); |
679 |
675 |
680 (**** introduction of axioms ****) |
676 (**** introduction of axioms ****) |
681 |
677 |
682 val rec_axs = DatatypeProp.make_primrecs new_type_names descr sorts thy2; |
678 val rec_axs = DatatypeProp.make_primrecs new_type_names descr sorts thy2; |
773 val (weak_case_congs, thy10) = DatatypeAbsProofs.prove_weak_case_congs new_type_names |
769 val (weak_case_congs, thy10) = DatatypeAbsProofs.prove_weak_case_congs new_type_names |
774 descr sorts thy9; |
770 descr sorts thy9; |
775 val (size_thms, thy11) = DatatypeAbsProofs.prove_size_thms flat_names new_type_names |
771 val (size_thms, thy11) = DatatypeAbsProofs.prove_size_thms flat_names new_type_names |
776 descr sorts reccomb_names rec_thms thy10; |
772 descr sorts reccomb_names rec_thms thy10; |
777 |
773 |
778 val dt_infos = map (make_dt_info (List.concat descr) sorts induct reccomb_names rec_thms) |
774 val dt_infos = map (make_dt_info (flat descr) sorts induct reccomb_names rec_thms) |
779 ((0 upto length (hd descr) - 1) ~~ (hd descr) ~~ case_names ~~ case_thms ~~ |
775 ((0 upto length (hd descr) - 1) ~~ (hd descr) ~~ case_names ~~ case_thms ~~ |
780 casedist_thms ~~ simproc_dists ~~ inject ~~ nchotomys ~~ case_congs ~~ weak_case_congs); |
776 casedist_thms ~~ simproc_dists ~~ inject ~~ nchotomys ~~ case_congs ~~ weak_case_congs); |
781 |
777 |
782 val simps = List.concat (distinct @ inject @ case_thms) @ size_thms @ rec_thms; |
778 val simps = flat (distinct @ inject @ case_thms) @ size_thms @ rec_thms; |
783 |
779 |
784 val thy12 = |
780 val thy12 = |
785 thy11 |
781 thy11 |
786 |> Theory.add_advanced_trfuns ([], [], make_case_tr' case_names (hd descr), []) |
782 |> Theory.add_advanced_trfuns ([], [], make_case_tr' case_names (hd descr), []) |
787 |> Theory.add_path (space_implode "_" new_type_names) |
783 |> Theory.add_path (space_implode "_" new_type_names) |
850 val dt_info = get_datatypes thy1; |
846 val dt_info = get_datatypes thy1; |
851 |
847 |
852 val (case_names_induct, case_names_exhausts) = case RuleCases.get induction |
848 val (case_names_induct, case_names_exhausts) = case RuleCases.get induction |
853 of (("1", _) :: _, _) => (mk_case_names_induct descr, mk_case_names_exhausts descr (map #1 dtnames)) |
849 of (("1", _) :: _, _) => (mk_case_names_induct descr, mk_case_names_exhausts descr (map #1 dtnames)) |
854 | (cases, _) => (RuleCases.case_names (map fst cases), |
850 | (cases, _) => (RuleCases.case_names (map fst cases), |
855 replicate (length ((List.filter (fn ((_, (name, _, _))) => member (op =) |
851 replicate (length ((filter (fn ((_, (name, _, _))) => member (op =) |
856 (map #1 dtnames) name) descr))) |
852 (map #1 dtnames) name) descr))) |
857 (RuleCases.case_names (map fst cases))); |
853 (RuleCases.case_names (map fst cases))); |
858 |
854 |
859 |
855 |
860 val _ = message ("Proofs for datatype(s) " ^ commas_quote new_type_names); |
856 val _ = message ("Proofs for datatype(s) " ^ commas_quote new_type_names); |
947 end) dts); |
943 end) dts); |
948 |
944 |
949 val _ = (case duplicates (op =) (map fst new_dts) @ duplicates (op =) new_type_names of |
945 val _ = (case duplicates (op =) (map fst new_dts) @ duplicates (op =) new_type_names of |
950 [] => () | dups => error ("Duplicate datatypes: " ^ commas dups)); |
946 [] => () | dups => error ("Duplicate datatypes: " ^ commas dups)); |
951 |
947 |
952 fun prep_dt_spec ((dts', constr_syntax, sorts, i), (tvs, tname, mx, constrs)) = |
948 fun prep_dt_spec (tvs, tname, mx, constrs) (dts', constr_syntax, sorts, i) = |
953 let |
949 let |
954 fun prep_constr ((constrs, constr_syntax', sorts'), (cname, cargs, mx')) = |
950 fun prep_constr (cname, cargs, mx') (constrs, constr_syntax', sorts') = |
955 let |
951 let |
956 val (cargs', sorts'') = Library.foldl (prep_typ tmp_thy) (([], sorts'), cargs); |
952 val (cargs', sorts'') = Library.foldl (prep_typ tmp_thy) (([], sorts'), cargs); |
957 val _ = (case foldr add_typ_tfree_names [] cargs' \\ tvs of |
953 val _ = (case fold (curry add_typ_tfree_names) cargs' [] \\ tvs of |
958 [] => () |
954 [] => () |
959 | vs => error ("Extra type variables on rhs: " ^ commas vs)) |
955 | vs => error ("Extra type variables on rhs: " ^ commas vs)) |
960 in (constrs @ [((if flat_names then Sign.full_name tmp_thy else |
956 in (constrs @ [((if flat_names then Sign.full_name tmp_thy else |
961 Sign.full_name_path tmp_thy tname) (Syntax.const_name cname mx'), |
957 Sign.full_name_path tmp_thy tname) (Syntax.const_name cname mx'), |
962 map (dtyp_of_typ new_dts) cargs')], |
958 map (dtyp_of_typ new_dts) cargs')], |
976 constr_syntax @ [constr_syntax'], sorts', i + 1) |
972 constr_syntax @ [constr_syntax'], sorts', i + 1) |
977 | dups => error ("Duplicate constructors " ^ commas dups ^ |
973 | dups => error ("Duplicate constructors " ^ commas dups ^ |
978 " in datatype " ^ tname) |
974 " in datatype " ^ tname) |
979 end; |
975 end; |
980 |
976 |
981 val (dts', constr_syntax, sorts', i) = Library.foldl prep_dt_spec (([], [], [], 0), dts); |
977 val (dts', constr_syntax, sorts', i) = fold prep_dt_spec dts ([], [], [], 0); |
982 val sorts = sorts' @ (map (rpair (Sign.defaultS tmp_thy)) (tyvars \\ map fst sorts')); |
978 val sorts = sorts' @ (map (rpair (Sign.defaultS tmp_thy)) (tyvars \\ map fst sorts')); |
983 val dt_info = get_datatypes thy; |
979 val dt_info = get_datatypes thy; |
984 val (descr, _) = unfold_datatypes tmp_thy dts' sorts dt_info dts' i; |
980 val (descr, _) = unfold_datatypes tmp_thy dts' sorts dt_info dts' i; |
985 val _ = check_nonempty descr handle (exn as Datatype_Empty s) => |
981 val _ = check_nonempty descr handle (exn as Datatype_Empty s) => |
986 if err then error ("Nonemptiness check failed for datatype " ^ s) |
982 if err then error ("Nonemptiness check failed for datatype " ^ s) |
987 else raise exn; |
983 else raise exn; |
988 |
984 |
989 val descr' = List.concat descr; |
985 val descr' = flat descr; |
990 val case_names_induct = mk_case_names_induct descr'; |
986 val case_names_induct = mk_case_names_induct descr'; |
991 val case_names_exhausts = mk_case_names_exhausts descr' (map #1 new_dts); |
987 val case_names_exhausts = mk_case_names_exhausts descr' (map #1 new_dts); |
992 in |
988 in |
993 (if (!quick_and_dirty) then add_datatype_axm else add_datatype_def) |
989 (if (!quick_and_dirty) then add_datatype_axm else add_datatype_def) |
994 flat_names new_type_names descr sorts types_syntax constr_syntax dt_info |
990 flat_names new_type_names descr sorts types_syntax constr_syntax dt_info |