| author | wenzelm | 
| Mon, 08 Jun 2020 22:31:36 +0200 | |
| changeset 71928 | ae643fb4ca30 | 
| parent 70494 | 41108e3e9ca5 | 
| child 80634 | a90ab1ea6458 | 
| permissions | -rw-r--r-- | 
| 55061 | 1 | (* Title: HOL/Tools/BNF/bnf_lfp_compat.ML | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 2 | Author: Jasmin Blanchette, TU Muenchen | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 3 | Copyright 2013, 2014 | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 4 | |
| 58147 | 5 | Compatibility layer with the old datatype package. Partly based on | 
| 58119 | 6 | |
| 7 | Title: HOL/Tools/Old_Datatype/old_datatype_data.ML | |
| 8 | Author: Stefan Berghofer, TU Muenchen | |
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 9 | *) | 
| 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 10 | |
| 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 11 | signature BNF_LFP_COMPAT = | 
| 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 12 | sig | 
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 13 | datatype preference = Keep_Nesting | Include_GFPs | Kill_Type_Args | 
| 58123 
62765d39539f
implemented compatibility definition of datatype
 blanchet parents: 
58122diff
changeset | 14 | |
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 15 | val get_all: theory -> preference list -> Old_Datatype_Aux.info Symtab.table | 
| 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 16 | val get_info: theory -> preference list -> string -> Old_Datatype_Aux.info option | 
| 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 17 | val the_info: theory -> preference list -> string -> Old_Datatype_Aux.info | 
| 58129 
3ec65a7f2b50
ported Refute to use new datatypes when possible
 blanchet parents: 
58126diff
changeset | 18 | val the_spec: theory -> string -> (string * sort) list * (string * typ list) list | 
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 19 | val the_descr: theory -> preference list -> string list -> | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 20 | Old_Datatype_Aux.descr * (string * sort) list * string list * string | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 21 | * (string list * string list) * (typ list * typ list) | 
| 58129 
3ec65a7f2b50
ported Refute to use new datatypes when possible
 blanchet parents: 
58126diff
changeset | 22 | val get_constrs: theory -> string -> (string * typ) list option | 
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 23 | val interpretation: string -> preference list -> | 
| 58123 
62765d39539f
implemented compatibility definition of datatype
 blanchet parents: 
58122diff
changeset | 24 | (Old_Datatype_Aux.config -> string list -> theory -> theory) -> theory -> theory | 
| 58125 | 25 | val datatype_compat: string list -> local_theory -> local_theory | 
| 26 | val datatype_compat_global: string list -> theory -> theory | |
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 27 | val datatype_compat_cmd: string list -> local_theory -> local_theory | 
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 28 | val add_datatype: preference list -> Old_Datatype_Aux.spec list -> theory -> string list * theory | 
| 63064 
2f18172214c8
support 'assumes' in specifications, e.g. 'definition', 'inductive';
 wenzelm parents: 
63047diff
changeset | 29 | val primrec: (binding * typ option * mixfix) list -> Specification.multi_specs -> | 
| 58684 | 30 | local_theory -> (term list * thm list) * local_theory | 
| 60003 | 31 | val primrec_global: (binding * typ option * mixfix) list -> | 
| 63064 
2f18172214c8
support 'assumes' in specifications, e.g. 'definition', 'inductive';
 wenzelm parents: 
63047diff
changeset | 32 | Specification.multi_specs -> theory -> (term list * thm list) * theory | 
| 60003 | 33 | val primrec_overloaded: (string * (string * typ) * bool) list -> | 
| 63064 
2f18172214c8
support 'assumes' in specifications, e.g. 'definition', 'inductive';
 wenzelm parents: 
63047diff
changeset | 34 | (binding * typ option * mixfix) list -> Specification.multi_specs -> theory -> | 
| 58147 | 35 | (term list * thm list) * theory | 
| 60003 | 36 | val primrec_simple: ((binding * typ) * mixfix) list -> term list -> | 
| 58220 | 37 | local_theory -> (string list * (term list * thm list)) * local_theory | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 38 | end; | 
| 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 39 | |
| 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 40 | structure BNF_LFP_Compat : BNF_LFP_COMPAT = | 
| 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 41 | struct | 
| 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 42 | |
| 54006 | 43 | open Ctr_Sugar | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 44 | open BNF_Util | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 45 | open BNF_Tactics | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 46 | open BNF_FP_Util | 
| 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 47 | open BNF_FP_Def_Sugar | 
| 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 48 | open BNF_FP_N2M_Sugar | 
| 58123 
62765d39539f
implemented compatibility definition of datatype
 blanchet parents: 
58122diff
changeset | 49 | open BNF_LFP | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 50 | |
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 51 | val compat_N = "compat_"; | 
| 58213 | 52 | val rec_split_N = "rec_split_"; | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 53 | |
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 54 | datatype preference = Keep_Nesting | Include_GFPs | Kill_Type_Args; | 
| 58123 
62765d39539f
implemented compatibility definition of datatype
 blanchet parents: 
58122diff
changeset | 55 | |
| 58213 | 56 | fun mk_split_rec_rhs ctxt fpTs Cs (recs as rec1 :: _) = | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 57 | let | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 58 | fun repair_rec_arg_args [] [] = [] | 
| 69593 | 59 | | repair_rec_arg_args ((g_T as Type (\<^type_name>\<open>fun\<close>, _)) :: g_Ts) (g :: gs) = | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 60 | let | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 61 | val (x_Ts, body_T) = strip_type g_T; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 62 | in | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 63 | (case try HOLogic.dest_prodT body_T of | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 64 | NONE => [g] | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 65 | | SOME (fst_T, _) => | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 66 | if member (op =) fpTs fst_T then | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 67 | let val (xs, _) = mk_Frees "x" x_Ts ctxt in | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 68 | map (fn mk_proj => fold_rev Term.lambda xs (mk_proj (Term.list_comb (g, xs)))) | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 69 | [HOLogic.mk_fst, HOLogic.mk_snd] | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 70 | end | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 71 | else | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 72 | [g]) | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 73 | :: repair_rec_arg_args g_Ts gs | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 74 | end | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 75 | | repair_rec_arg_args (g_T :: g_Ts) (g :: gs) = | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 76 | if member (op =) fpTs g_T then | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 77 | let | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 78 | val j = find_index (member (op =) Cs) g_Ts; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 79 | val h = nth gs j; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 80 | val g_Ts' = nth_drop j g_Ts; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 81 | val gs' = nth_drop j gs; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 82 | in | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 83 | [g, h] :: repair_rec_arg_args g_Ts' gs' | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 84 | end | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 85 | else | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 86 | [g] :: repair_rec_arg_args g_Ts gs; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 87 | |
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 88 | fun repair_back_rec_arg f_T f' = | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 89 | let | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 90 | val g_Ts = Term.binder_types f_T; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 91 | val (gs, _) = mk_Frees "g" g_Ts ctxt; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 92 | in | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 93 | fold_rev Term.lambda gs (Term.list_comb (f', | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 94 | flat_rec_arg_args (repair_rec_arg_args g_Ts gs))) | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 95 | end; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 96 | |
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 97 | val f_Ts = binder_fun_types (fastype_of rec1); | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 98 | val (fs', _) = mk_Frees "f" (replicate (length f_Ts) Term.dummyT) ctxt; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 99 | |
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 100 | fun mk_rec' recx = | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 101 | fold_rev Term.lambda fs' (Term.list_comb (recx, map2 repair_back_rec_arg f_Ts fs')) | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 102 | |> Syntax.check_term ctxt; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 103 | in | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 104 | map mk_rec' recs | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 105 | end; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 106 | |
| 58213 | 107 | fun define_split_recs fpTs Cs recs lthy = | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 108 | let | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 109 | val b_names = Name.variant_list [] (map base_name_of_typ fpTs); | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 110 | |
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 111 | fun mk_binding b_name = | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 112 | Binding.qualify true (compat_N ^ b_name) | 
| 58213 | 113 | (Binding.prefix_name rec_split_N (Binding.name b_name)); | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 114 | |
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 115 | val bs = map mk_binding b_names; | 
| 58213 | 116 | val rhss = mk_split_rec_rhs lthy fpTs Cs recs; | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 117 | in | 
| 58634 
9f10d82e8188
added parameterized ML antiquotations @{map N}, @{fold N}, @{fold_map N}, @{split_list N};
 wenzelm parents: 
58461diff
changeset | 118 |     @{fold_map 3} (define_co_rec_as Least_FP Cs) fpTs bs rhss lthy
 | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 119 | end; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 120 | |
| 58218 
a92acec845a7
no type-based lookup -- these fail in the general, ambiguous case
 blanchet parents: 
58217diff
changeset | 121 | fun mk_split_rec_thmss ctxt Xs ctrXs_Tsss ctrss rec0_thmss (recs as rec1 :: _) rec_defs = | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 122 | let | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 123 | val f_Ts = binder_fun_types (fastype_of rec1); | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 124 | val (fs, _) = mk_Frees "f" f_Ts ctxt; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 125 | val frecs = map (fn recx => Term.list_comb (recx, fs)) recs; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 126 | |
| 58218 
a92acec845a7
no type-based lookup -- these fail in the general, ambiguous case
 blanchet parents: 
58217diff
changeset | 127 | val Xs_frecs = Xs ~~ frecs; | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 128 | val fss = unflat ctrss fs; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 129 | |
| 69593 | 130 | fun mk_rec_call g n (Type (\<^type_name>\<open>fun\<close>, [_, ran_T])) = | 
| 63047 
2146553e96c6
generalize code to avoid making assumptions about type variable names
 blanchet parents: 
62497diff
changeset | 131 | Abs (Name.uu, Term.dummyT, mk_rec_call g (n + 1) ran_T) | 
| 58218 
a92acec845a7
no type-based lookup -- these fail in the general, ambiguous case
 blanchet parents: 
58217diff
changeset | 132 | | mk_rec_call g n X = | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 133 | let | 
| 58218 
a92acec845a7
no type-based lookup -- these fail in the general, ambiguous case
 blanchet parents: 
58217diff
changeset | 134 | val frec = the (AList.lookup (op =) Xs_frecs X); | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 135 | val xg = Term.list_comb (g, map Bound (n - 1 downto 0)); | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 136 | in frec $ xg end; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 137 | |
| 58218 
a92acec845a7
no type-based lookup -- these fail in the general, ambiguous case
 blanchet parents: 
58217diff
changeset | 138 | fun mk_rec_arg_arg ctrXs_T g = | 
| 
a92acec845a7
no type-based lookup -- these fail in the general, ambiguous case
 blanchet parents: 
58217diff
changeset | 139 | g :: (if member (op =) Xs (body_type ctrXs_T) then [mk_rec_call g 0 ctrXs_T] else []); | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 140 | |
| 58218 
a92acec845a7
no type-based lookup -- these fail in the general, ambiguous case
 blanchet parents: 
58217diff
changeset | 141 | fun mk_goal frec ctrXs_Ts ctr f = | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 142 | let | 
| 58218 
a92acec845a7
no type-based lookup -- these fail in the general, ambiguous case
 blanchet parents: 
58217diff
changeset | 143 | val ctr_Ts = binder_types (fastype_of ctr); | 
| 58217 | 144 | val (gs, _) = mk_Frees "g" ctr_Ts ctxt; | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 145 | val gctr = Term.list_comb (ctr, gs); | 
| 58218 
a92acec845a7
no type-based lookup -- these fail in the general, ambiguous case
 blanchet parents: 
58217diff
changeset | 146 | val fgs = flat_rec_arg_args (map2 mk_rec_arg_arg ctrXs_Ts gs); | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 147 | in | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 148 | fold_rev (fold_rev Logic.all) [fs, gs] | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 149 | (mk_Trueprop_eq (frec $ gctr, Term.list_comb (f, fgs))) | 
| 63047 
2146553e96c6
generalize code to avoid making assumptions about type variable names
 blanchet parents: 
62497diff
changeset | 150 | |> Syntax.check_term ctxt | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 151 | end; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 152 | |
| 58634 
9f10d82e8188
added parameterized ML antiquotations @{map N}, @{fold N}, @{fold_map N}, @{split_list N};
 wenzelm parents: 
58461diff
changeset | 153 |     val goalss = @{map 4} (@{map 3} o mk_goal) frecs ctrXs_Tsss ctrss fss;
 | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 154 | |
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 155 | fun tac ctxt = | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 156 |       unfold_thms_tac ctxt (@{thms o_apply fst_conv snd_conv} @ rec_defs @ flat rec0_thmss) THEN
 | 
| 60728 | 157 | HEADGOAL (rtac ctxt refl); | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 158 | |
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 159 | fun prove goal = | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 160 | Goal.prove_sorry ctxt [] [] goal (tac o #context) | 
| 70494 | 161 | |> Thm.close_derivation \<^here>; | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 162 | in | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 163 | map (map prove) goalss | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 164 | end; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 165 | |
| 58218 
a92acec845a7
no type-based lookup -- these fail in the general, ambiguous case
 blanchet parents: 
58217diff
changeset | 166 | fun define_split_rec_derive_induct_rec_thms Xs fpTs ctrXs_Tsss ctrss inducts induct recs0 rec_thmss | 
| 58217 | 167 | lthy = | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 168 | let | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 169 | val thy = Proof_Context.theory_of lthy; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 170 | |
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 171 | (* imperfect: will not yield the expected theorem for functions taking a large number of | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 172 | arguments *) | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 173 |     val repair_induct = unfold_thms lthy @{thms all_mem_range};
 | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 174 | |
| 58214 | 175 | val inducts' = map repair_induct inducts; | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 176 | val induct' = repair_induct induct; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 177 | |
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 178 | val Cs = map ((fn TVar ((s, _), S) => TFree (s, S)) o body_type o fastype_of) recs0; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 179 | val recs = map2 (mk_co_rec thy Least_FP Cs) fpTs recs0; | 
| 58213 | 180 | val ((recs', rec'_defs), lthy') = define_split_recs fpTs Cs recs lthy |>> split_list; | 
| 58218 
a92acec845a7
no type-based lookup -- these fail in the general, ambiguous case
 blanchet parents: 
58217diff
changeset | 181 | val rec'_thmss = mk_split_rec_thmss lthy' Xs ctrXs_Tsss ctrss rec_thmss recs' rec'_defs; | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 182 | in | 
| 58214 | 183 | ((inducts', induct', recs', rec'_thmss), lthy') | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 184 | end; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 185 | |
| 58219 
61b852f90161
improved 'datatype_compat' further for recursion through functions
 blanchet parents: 
58218diff
changeset | 186 | fun body_rec_indices (Old_Datatype_Aux.DtRec kk) = [kk] | 
| 69593 | 187 | | body_rec_indices (Old_Datatype_Aux.DtType (\<^type_name>\<open>fun\<close>, [_, D])) = body_rec_indices D | 
| 58219 
61b852f90161
improved 'datatype_compat' further for recursion through functions
 blanchet parents: 
58218diff
changeset | 188 | | body_rec_indices _ = []; | 
| 
61b852f90161
improved 'datatype_compat' further for recursion through functions
 blanchet parents: 
58218diff
changeset | 189 | |
| 56453 
00548d372f02
support deeply nested datatypes in 'datatype_compat'
 blanchet parents: 
56452diff
changeset | 190 | fun reindex_desc desc = | 
| 
00548d372f02
support deeply nested datatypes in 'datatype_compat'
 blanchet parents: 
56452diff
changeset | 191 | let | 
| 
00548d372f02
support deeply nested datatypes in 'datatype_compat'
 blanchet parents: 
56452diff
changeset | 192 | val kks = map fst desc; | 
| 
00548d372f02
support deeply nested datatypes in 'datatype_compat'
 blanchet parents: 
56452diff
changeset | 193 | val perm_kks = sort int_ord kks; | 
| 
00548d372f02
support deeply nested datatypes in 'datatype_compat'
 blanchet parents: 
56452diff
changeset | 194 | |
| 58112 
8081087096ad
renamed modules defining old datatypes, as a step towards having 'datatype_new' take 'datatype's place
 blanchet parents: 
57983diff
changeset | 195 | fun perm_dtyp (Old_Datatype_Aux.DtType (s, Ds)) = Old_Datatype_Aux.DtType (s, map perm_dtyp Ds) | 
| 
8081087096ad
renamed modules defining old datatypes, as a step towards having 'datatype_new' take 'datatype's place
 blanchet parents: 
57983diff
changeset | 196 | | perm_dtyp (Old_Datatype_Aux.DtRec kk) = | 
| 
8081087096ad
renamed modules defining old datatypes, as a step towards having 'datatype_new' take 'datatype's place
 blanchet parents: 
57983diff
changeset | 197 | Old_Datatype_Aux.DtRec (find_index (curry (op =) kk) kks) | 
| 58113 | 198 | | perm_dtyp D = D; | 
| 56453 
00548d372f02
support deeply nested datatypes in 'datatype_compat'
 blanchet parents: 
56452diff
changeset | 199 | in | 
| 
00548d372f02
support deeply nested datatypes in 'datatype_compat'
 blanchet parents: 
56452diff
changeset | 200 | if perm_kks = kks then | 
| 
00548d372f02
support deeply nested datatypes in 'datatype_compat'
 blanchet parents: 
56452diff
changeset | 201 | desc | 
| 
00548d372f02
support deeply nested datatypes in 'datatype_compat'
 blanchet parents: 
56452diff
changeset | 202 | else | 
| 
00548d372f02
support deeply nested datatypes in 'datatype_compat'
 blanchet parents: 
56452diff
changeset | 203 | perm_kks ~~ | 
| 
00548d372f02
support deeply nested datatypes in 'datatype_compat'
 blanchet parents: 
56452diff
changeset | 204 | map (fn (_, (s, Ds, sDss)) => (s, map perm_dtyp Ds, map (apsnd (map perm_dtyp)) sDss)) desc | 
| 58113 | 205 | end; | 
| 56453 
00548d372f02
support deeply nested datatypes in 'datatype_compat'
 blanchet parents: 
56452diff
changeset | 206 | |
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 207 | fun mk_infos_of_mutually_recursive_new_datatypes prefs check_names fpT_names0 lthy = | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 208 | let | 
| 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 209 | val thy = Proof_Context.theory_of lthy; | 
| 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 210 | |
| 64705 
7596b0736ab9
more uniform errors in '(prim)(co)rec(ursive)' variants
 blanchet parents: 
64674diff
changeset | 211 | fun not_datatype_name s = | 
| 
7596b0736ab9
more uniform errors in '(prim)(co)rec(ursive)' variants
 blanchet parents: 
64674diff
changeset | 212 | error (quote s ^ " is not a datatype"); | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 213 | fun not_mutually_recursive ss = | 
| 58315 | 214 |       error ("{" ^ commas ss ^ "} is not a complete set of mutually recursive datatypes");
 | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 215 | |
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 216 | fun checked_fp_sugar_of s = | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 217 | (case fp_sugar_of lthy s of | 
| 63859 
dca6fabd8060
make (co)induct component of 'fp_sugar' optional, for the benefit of nonuniform (co)datatypes and other similar extensions
 blanchet parents: 
63732diff
changeset | 218 |         SOME (fp_sugar as {fp, fp_co_induct_sugar = SOME _, ...}) =>
 | 
| 64705 
7596b0736ab9
more uniform errors in '(prim)(co)rec(ursive)' variants
 blanchet parents: 
64674diff
changeset | 219 | if member (op =) prefs Include_GFPs orelse fp = Least_FP then fp_sugar | 
| 
7596b0736ab9
more uniform errors in '(prim)(co)rec(ursive)' variants
 blanchet parents: 
64674diff
changeset | 220 | else not_datatype_name s | 
| 
7596b0736ab9
more uniform errors in '(prim)(co)rec(ursive)' variants
 blanchet parents: 
64674diff
changeset | 221 | | _ => not_datatype_name s); | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 222 | |
| 58229 | 223 | val fpTs0 as Type (_, var_As) :: _ = | 
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 224 | map (#T o checked_fp_sugar_of o fst o dest_Type) | 
| 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 225 | (#Ts (#fp_res (checked_fp_sugar_of (hd fpT_names0)))); | 
| 63732 | 226 | val fpT_names as fpT_name1 :: _ = map (fst o dest_Type) fpTs0; | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 227 | |
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 228 | val _ = check_names (op =) (fpT_names0, fpT_names) orelse not_mutually_recursive fpT_names0; | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 229 | |
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 230 | val (As_names, _) = Variable.variant_fixes (map (fn TVar ((s, _), _) => s) var_As) lthy; | 
| 56452 
0c98c9118407
preserve user type variable names to avoid mismatches/confusion
 blanchet parents: 
56002diff
changeset | 231 | val As = map2 (fn s => fn TVar (_, S) => TFree (s, S)) As_names var_As; | 
| 56455 
1ff66e72628b
allow arguments to 'datatype_compat' in disorder
 blanchet parents: 
56453diff
changeset | 232 | val fpTs = map (fn s => Type (s, As)) fpT_names; | 
| 56453 
00548d372f02
support deeply nested datatypes in 'datatype_compat'
 blanchet parents: 
56452diff
changeset | 233 | |
| 
00548d372f02
support deeply nested datatypes in 'datatype_compat'
 blanchet parents: 
56452diff
changeset | 234 | val nn_fp = length fpTs; | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 235 | |
| 58112 
8081087096ad
renamed modules defining old datatypes, as a step towards having 'datatype_new' take 'datatype's place
 blanchet parents: 
57983diff
changeset | 236 | val mk_dtyp = Old_Datatype_Aux.dtyp_of_typ (map (apsnd (map Term.dest_TFree) o dest_Type) fpTs); | 
| 56453 
00548d372f02
support deeply nested datatypes in 'datatype_compat'
 blanchet parents: 
56452diff
changeset | 237 | |
| 
00548d372f02
support deeply nested datatypes in 'datatype_compat'
 blanchet parents: 
56452diff
changeset | 238 | fun mk_ctr_descr Ts = mk_ctr Ts #> dest_Const ##> (binder_types #> map mk_dtyp); | 
| 
00548d372f02
support deeply nested datatypes in 'datatype_compat'
 blanchet parents: 
56452diff
changeset | 239 |     fun mk_typ_descr index (Type (T_name, Ts)) ({ctrs, ...} : ctr_sugar) =
 | 
| 
00548d372f02
support deeply nested datatypes in 'datatype_compat'
 blanchet parents: 
56452diff
changeset | 240 | (index, (T_name, map mk_dtyp Ts, map (mk_ctr_descr Ts) ctrs)); | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 241 | |
| 63732 | 242 |     val fp_sugars as {fp, ...} :: _ = map checked_fp_sugar_of fpT_names;
 | 
| 243 | val fp_ctr_sugars = map (#ctr_sugar o #fp_ctr_sugar) fp_sugars; | |
| 58634 
9f10d82e8188
added parameterized ML antiquotations @{map N}, @{fold N}, @{fold_map N}, @{split_list N};
 wenzelm parents: 
58461diff
changeset | 244 |     val orig_descr = @{map 3} mk_typ_descr (0 upto nn_fp - 1) fpTs fp_ctr_sugars;
 | 
| 58112 
8081087096ad
renamed modules defining old datatypes, as a step towards having 'datatype_new' take 'datatype's place
 blanchet parents: 
57983diff
changeset | 245 | val all_infos = Old_Datatype_Data.get_all thy; | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 246 | val (orig_descr' :: nested_descrs) = | 
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 247 | if member (op =) prefs Keep_Nesting then [orig_descr] | 
| 58125 | 248 | else fst (Old_Datatype_Aux.unfold_datatypes lthy orig_descr all_infos orig_descr nn_fp); | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 249 | |
| 57798 | 250 | fun cliquify_descr [] = [] | 
| 251 | | cliquify_descr [entry] = [[entry]] | |
| 252 | | cliquify_descr (full_descr as (_, (T_name1, _, _)) :: _) = | |
| 253 | let | |
| 254 | val nn = | |
| 255 | if member (op =) fpT_names T_name1 then | |
| 256 | nn_fp | |
| 257 | else | |
| 258 | (case Symtab.lookup all_infos T_name1 of | |
| 259 |                 SOME {descr, ...} =>
 | |
| 58112 
8081087096ad
renamed modules defining old datatypes, as a step towards having 'datatype_new' take 'datatype's place
 blanchet parents: 
57983diff
changeset | 260 | length (filter_out (exists Old_Datatype_Aux.is_rec_type o #2 o snd) descr) | 
| 57798 | 261 | | NONE => raise Fail "unknown old-style datatype"); | 
| 262 | in | |
| 263 | chop nn full_descr ||> cliquify_descr |> op :: | |
| 264 | end; | |
| 265 | ||
| 56453 
00548d372f02
support deeply nested datatypes in 'datatype_compat'
 blanchet parents: 
56452diff
changeset | 266 | (* put nested types before the types that nest them, as needed for N2M *) | 
| 56484 | 267 | val descrs = burrow reindex_desc (orig_descr' :: rev nested_descrs); | 
| 58340 | 268 | val (mutual_cliques, descr) = | 
| 57798 | 269 | split_list (flat (map_index (fn (i, descr) => map (pair i) descr) | 
| 270 | (maps cliquify_descr descrs))); | |
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 271 | |
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 272 | val fpTs' = Old_Datatype_Aux.get_rec_types descr; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 273 | val nn = length fpTs'; | 
| 55485 | 274 | |
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 275 | val fp_sugars = map (checked_fp_sugar_of o fst o dest_Type) fpTs'; | 
| 58219 
61b852f90161
improved 'datatype_compat' further for recursion through functions
 blanchet parents: 
58218diff
changeset | 276 | val ctr_Tsss = map (map (map (Old_Datatype_Aux.typ_of_dtyp descr) o snd) o #3 o snd) descr; | 
| 
61b852f90161
improved 'datatype_compat' further for recursion through functions
 blanchet parents: 
58218diff
changeset | 277 | val kkssss = map (map (map body_rec_indices o snd) o #3 o snd) descr; | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 278 | |
| 69593 | 279 | val callers = map (fn kk => Var ((Name.uu, kk), \<^typ>\<open>unit => unit\<close>)) (0 upto nn - 1); | 
| 55772 
367ec44763fd
correct most general type for mutual recursion when several identical types are involved
 blanchet parents: 
55571diff
changeset | 280 | |
| 
367ec44763fd
correct most general type for mutual recursion when several identical types are involved
 blanchet parents: 
55571diff
changeset | 281 | fun apply_comps n kk = | 
| 55966 | 282 | mk_partial_compN n (replicate n HOLogic.unitT ---> HOLogic.unitT) (nth callers kk); | 
| 55772 
367ec44763fd
correct most general type for mutual recursion when several identical types are involved
 blanchet parents: 
55571diff
changeset | 283 | |
| 58219 
61b852f90161
improved 'datatype_compat' further for recursion through functions
 blanchet parents: 
58218diff
changeset | 284 | val callssss = map2 (map2 (map2 (map o apply_comps o num_binder_types))) ctr_Tsss kkssss; | 
| 56453 
00548d372f02
support deeply nested datatypes in 'datatype_compat'
 blanchet parents: 
56452diff
changeset | 285 | |
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 286 | val b_names = Name.variant_list [] (map base_name_of_typ fpTs'); | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 287 | val compat_b_names = map (prefix compat_N) b_names; | 
| 56453 
00548d372f02
support deeply nested datatypes in 'datatype_compat'
 blanchet parents: 
56452diff
changeset | 288 | val compat_bs = map Binding.name compat_b_names; | 
| 55772 
367ec44763fd
correct most general type for mutual recursion when several identical types are involved
 blanchet parents: 
55571diff
changeset | 289 | |
| 58217 | 290 | val ((fp_sugars', (lfp_sugar_thms', _)), lthy') = | 
| 54286 
22616f65d4ea
properly detect when to perform n2m -- e.g. handle the case of two independent functions on irrelevant types being defined in parallel
 blanchet parents: 
54267diff
changeset | 291 | if nn > nn_fp then | 
| 58340 | 292 | mutualize_fp_sugars (K true) Least_FP mutual_cliques compat_bs fpTs' callers callssss | 
| 293 | fp_sugars lthy | |
| 54286 
22616f65d4ea
properly detect when to perform n2m -- e.g. handle the case of two independent functions on irrelevant types being defined in parallel
 blanchet parents: 
54267diff
changeset | 294 | else | 
| 58217 | 295 | ((fp_sugars, (NONE, NONE)), lthy); | 
| 296 | ||
| 58460 | 297 |     fun mk_ctr_of ({fp_ctr_sugar = {ctr_sugar = {ctrs, ...}, ...}, ...} : fp_sugar) (Type (_, Ts)) =
 | 
| 298 | map (mk_ctr Ts) ctrs; | |
| 58218 
a92acec845a7
no type-based lookup -- these fail in the general, ambiguous case
 blanchet parents: 
58217diff
changeset | 299 | val substAT = Term.typ_subst_atomic (var_As ~~ As); | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 300 | |
| 58217 | 301 | val Xs' = map #X fp_sugars'; | 
| 58460 | 302 | val ctrXs_Tsss' = map (map (map substAT) o #ctrXs_Tss o #fp_ctr_sugar) fp_sugars'; | 
| 58217 | 303 | val ctrss' = map2 mk_ctr_of fp_sugars' fpTs'; | 
| 63859 
dca6fabd8060
make (co)induct component of 'fp_sugar' optional, for the benefit of nonuniform (co)datatypes and other similar extensions
 blanchet parents: 
63732diff
changeset | 304 |     val {fp_co_induct_sugar = SOME {common_co_inducts = induct :: _, ...}, ...} :: _ = fp_sugars';
 | 
| 
dca6fabd8060
make (co)induct component of 'fp_sugar' optional, for the benefit of nonuniform (co)datatypes and other similar extensions
 blanchet parents: 
63732diff
changeset | 305 | val inducts = map (hd o #co_inducts o the o #fp_co_induct_sugar) fp_sugars'; | 
| 
dca6fabd8060
make (co)induct component of 'fp_sugar' optional, for the benefit of nonuniform (co)datatypes and other similar extensions
 blanchet parents: 
63732diff
changeset | 306 | val recs = map (#co_rec o the o #fp_co_induct_sugar) fp_sugars'; | 
| 
dca6fabd8060
make (co)induct component of 'fp_sugar' optional, for the benefit of nonuniform (co)datatypes and other similar extensions
 blanchet parents: 
63732diff
changeset | 307 | val rec_thmss = map (#co_rec_thms o the o #fp_co_induct_sugar) fp_sugars'; | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 308 | |
| 69593 | 309 | fun is_nested_rec_type (Type (\<^type_name>\<open>fun\<close>, [_, T])) = member (op =) Xs' (body_type T) | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 310 | | is_nested_rec_type _ = false; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 311 | |
| 58217 | 312 | val ((lfp_sugar_thms'', (inducts', induct', recs', rec'_thmss)), lthy'') = | 
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 313 | if member (op =) prefs Keep_Nesting orelse | 
| 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 314 | not (exists (exists (exists is_nested_rec_type)) ctrXs_Tsss') then | 
| 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 315 | ((lfp_sugar_thms', (inducts, induct, recs, rec_thmss)), lthy') | 
| 63732 | 316 | else if fp = Least_FP then | 
| 58218 
a92acec845a7
no type-based lookup -- these fail in the general, ambiguous case
 blanchet parents: 
58217diff
changeset | 317 | define_split_rec_derive_induct_rec_thms Xs' fpTs' ctrXs_Tsss' ctrss' inducts induct recs | 
| 58217 | 318 | rec_thmss lthy' | 
| 58214 | 319 | |>> `(fn (inducts', induct', _, rec'_thmss) => | 
| 63732 | 320 | SOME ((inducts', induct', mk_induct_attrs ctrss'), (rec'_thmss, []))) | 
| 321 | else | |
| 64705 
7596b0736ab9
more uniform errors in '(prim)(co)rec(ursive)' variants
 blanchet parents: 
64674diff
changeset | 322 | not_datatype_name fpT_name1; | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 323 | |
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 324 | val rec'_names = map (fst o dest_Const) recs'; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 325 | val rec'_thms = flat rec'_thmss; | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 326 | |
| 58460 | 327 |     fun mk_info (kk, {T = Type (T_name0, _), fp_ctr_sugar = {ctr_sugar = {casex, exhaust, nchotomy,
 | 
| 328 | injects, distincts, case_thms, case_cong, case_cong_weak, split, | |
| 329 | split_asm, ...}, ...}, ...} : fp_sugar) = | |
| 55539 
0819931d652d
simplified data structure by reducing the incidence of clumsy indices
 blanchet parents: 
55531diff
changeset | 330 | (T_name0, | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 331 |        {index = kk, descr = descr, inject = injects, distinct = distincts, induct = induct',
 | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 332 | inducts = inducts', exhaust = exhaust, nchotomy = nchotomy, rec_names = rec'_names, | 
| 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 333 | rec_rewrites = rec'_thms, case_name = fst (dest_Const casex), case_rewrites = case_thms, | 
| 57983 
6edc3529bb4e
reordered some (co)datatype property names for more consistency
 blanchet parents: 
57807diff
changeset | 334 | case_cong = case_cong, case_cong_weak = case_cong_weak, split = split, | 
| 57794 | 335 | split_asm = split_asm}); | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 336 | |
| 58217 | 337 | val infos = map_index mk_info (take nn_fp fp_sugars'); | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 338 | in | 
| 58217 | 339 | (nn, b_names, compat_b_names, lfp_sugar_thms'', infos, lthy'') | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 340 | end; | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 341 | |
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 342 | fun infos_of_new_datatype_mutual_cluster lthy prefs fpT_name = | 
| 58358 | 343 | let | 
| 344 | fun get prefs = | |
| 345 | #5 (mk_infos_of_mutually_recursive_new_datatypes prefs subset [fpT_name] lthy) | |
| 346 | handle ERROR _ => []; | |
| 347 | in | |
| 348 | (case get prefs of | |
| 349 | [] => if member (op =) prefs Keep_Nesting then [] else get (Keep_Nesting :: prefs) | |
| 350 | | infos => infos) | |
| 351 | end; | |
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 352 | |
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 353 | fun get_all thy prefs = | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 354 | let | 
| 59644 | 355 | val ctxt = Proof_Context.init_global thy; | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 356 | val old_info_tab = Old_Datatype_Data.get_all thy; | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 357 | val new_T_names = BNF_FP_Def_Sugar.fp_sugars_of_global thy | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 358 |       |> map_filter (try (fn {T = Type (s, _), fp_res_index = 0, ...} => s));
 | 
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 359 | val new_infos = | 
| 59644 | 360 | maps (infos_of_new_datatype_mutual_cluster ctxt (insert (op =) Keep_Nesting prefs)) | 
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 361 | new_T_names; | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 362 | in | 
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 363 | fold (if member (op =) prefs Keep_Nesting then Symtab.update else Symtab.default) new_infos | 
| 58123 
62765d39539f
implemented compatibility definition of datatype
 blanchet parents: 
58122diff
changeset | 364 | old_info_tab | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 365 | end; | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 366 | |
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 367 | fun get_one get_old get_new thy prefs x = | 
| 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 368 | let | 
| 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 369 | val (get_fst, get_snd) = (get_old thy, get_new thy) |> member (op =) prefs Keep_Nesting ? swap; | 
| 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 370 | in | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 371 | (case get_fst x of NONE => get_snd x | res => res) | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 372 | end; | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 373 | |
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 374 | fun get_info_of_new_datatype prefs thy T_name = | 
| 59644 | 375 | let val ctxt = Proof_Context.init_global thy in | 
| 376 | AList.lookup (op =) (infos_of_new_datatype_mutual_cluster ctxt prefs T_name) T_name | |
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 377 | end; | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 378 | |
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 379 | fun get_info thy prefs = | 
| 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 380 | get_one Old_Datatype_Data.get_info (get_info_of_new_datatype prefs) thy prefs; | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 381 | |
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 382 | fun the_info thy prefs T_name = | 
| 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 383 | (case get_info thy prefs T_name of | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 384 | SOME info => info | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 385 |   | NONE => error ("Unknown datatype " ^ quote T_name));
 | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 386 | |
| 58129 
3ec65a7f2b50
ported Refute to use new datatypes when possible
 blanchet parents: 
58126diff
changeset | 387 | fun the_spec thy T_name = | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 388 | let | 
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 389 |     val {descr, index, ...} = the_info thy [Keep_Nesting, Include_GFPs] T_name;
 | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 390 | val (_, Ds, ctrs0) = the (AList.lookup (op =) descr index); | 
| 58129 
3ec65a7f2b50
ported Refute to use new datatypes when possible
 blanchet parents: 
58126diff
changeset | 391 | val tfrees = map Old_Datatype_Aux.dest_DtTFree Ds; | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 392 | val ctrs = map (apsnd (map (Old_Datatype_Aux.typ_of_dtyp descr))) ctrs0; | 
| 58129 
3ec65a7f2b50
ported Refute to use new datatypes when possible
 blanchet parents: 
58126diff
changeset | 393 | in (tfrees, ctrs) end; | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 394 | |
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 395 | fun the_descr thy prefs (T_names0 as T_name01 :: _) = | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 396 | let | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 397 | fun not_mutually_recursive ss = | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 398 |       error ("{" ^ commas ss ^ "} is not a complete set of mutually recursive datatypes");
 | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 399 | |
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 400 | val info = the_info thy prefs T_name01; | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 401 | val descr = #descr info; | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 402 | |
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 403 | val (_, Ds, _) = the (AList.lookup (op =) descr (#index info)); | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 404 | val vs = map Old_Datatype_Aux.dest_DtTFree Ds; | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 405 | |
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 406 | fun is_DtTFree (Old_Datatype_Aux.DtTFree _) = true | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 407 | | is_DtTFree _ = false; | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 408 | |
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 409 | val k = find_index (fn (_, (_, dTs, _)) => not (forall is_DtTFree dTs)) descr; | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 410 | val protoTs as (dataTs, _) = chop k descr | 
| 59058 
a78612c67ec0
renamed "pairself" to "apply2", in accordance to @{apply 2};
 wenzelm parents: 
58684diff
changeset | 411 | |> (apply2 o map) | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 412 | (fn (_, (T_name, Ds, _)) => (T_name, map (Old_Datatype_Aux.typ_of_dtyp descr) Ds)); | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 413 | |
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 414 | val T_names = map fst dataTs; | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 415 | val _ = eq_set (op =) (T_names, T_names0) orelse not_mutually_recursive T_names0 | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 416 | |
| 59058 
a78612c67ec0
renamed "pairself" to "apply2", in accordance to @{apply 2};
 wenzelm parents: 
58684diff
changeset | 417 | val (Ts, Us) = apply2 (map Type) protoTs; | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 418 | |
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 419 | val names = map Long_Name.base_name T_names; | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 420 | val (auxnames, _) = Name.make_context names | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 421 | |> fold_map (Name.variant o Old_Datatype_Aux.name_of_typ) Us; | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 422 | val prefix = space_implode "_" names; | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 423 | in | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 424 | (descr, vs, T_names, prefix, (names, auxnames), (Ts, Us)) | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 425 | end; | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 426 | |
| 58129 
3ec65a7f2b50
ported Refute to use new datatypes when possible
 blanchet parents: 
58126diff
changeset | 427 | fun get_constrs thy T_name = | 
| 
3ec65a7f2b50
ported Refute to use new datatypes when possible
 blanchet parents: 
58126diff
changeset | 428 | try (the_spec thy) T_name | 
| 58119 | 429 | |> Option.map (fn (tfrees, ctrs) => | 
| 430 | let | |
| 431 | fun varify_tfree (s, S) = TVar ((s, 0), S); | |
| 432 | fun varify_typ (TFree x) = varify_tfree x | |
| 433 | | varify_typ T = T; | |
| 434 | ||
| 435 | val dataT = Type (T_name, map varify_tfree tfrees); | |
| 436 | ||
| 437 | fun mk_ctr_typ Ts = map (Term.map_atyps varify_typ) Ts ---> dataT; | |
| 438 | in | |
| 439 | map (apsnd mk_ctr_typ) ctrs | |
| 440 | end); | |
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 441 | |
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 442 | fun old_interpretation_of prefs f config T_names thy = | 
| 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 443 | if not (member (op =) prefs Keep_Nesting) orelse | 
| 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 444 | exists (is_none o fp_sugar_of_global thy) T_names then | 
| 58122 | 445 | f config T_names thy | 
| 446 | else | |
| 447 | thy; | |
| 448 | ||
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 449 | fun new_interpretation_of prefs f (fp_sugars : fp_sugar list) thy = | 
| 58122 | 450 | let val T_names = map (fst o dest_Type o #T) fp_sugars in | 
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 451 | if (member (op =) prefs Include_GFPs orelse forall (curry (op =) Least_FP o #fp) fp_sugars) | 
| 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 452 | andalso (member (op =) prefs Keep_Nesting orelse | 
| 58146 | 453 | exists (is_none o Old_Datatype_Data.get_info thy) T_names) then | 
| 58123 
62765d39539f
implemented compatibility definition of datatype
 blanchet parents: 
58122diff
changeset | 454 | f Old_Datatype_Aux.default_config T_names thy | 
| 58122 | 455 | else | 
| 456 | thy | |
| 457 | end; | |
| 458 | ||
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 459 | fun interpretation name prefs f = | 
| 58659 
6c9821c32dd5
Local_Interpretation is superseded by Plugin with formal Plugin_Name management, avoiding undeclared strings;
 wenzelm parents: 
58634diff
changeset | 460 | Old_Datatype_Data.interpretation (old_interpretation_of prefs f) | 
| 
6c9821c32dd5
Local_Interpretation is superseded by Plugin with formal Plugin_Name management, avoiding undeclared strings;
 wenzelm parents: 
58634diff
changeset | 461 | #> fp_sugars_interpretation name (Local_Theory.background_theory o new_interpretation_of prefs f); | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 462 | |
| 66251 
cd935b7cb3fb
proper concept of code declaration wrt. atomicity and Isar declarations
 haftmann parents: 
64705diff
changeset | 463 | val nitpicksimp_simp_attrs = @{attributes [nitpick_simp, simp]};
 | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 464 | |
| 58125 | 465 | fun datatype_compat fpT_names lthy = | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 466 | let | 
| 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 467 | val (nn, b_names, compat_b_names, lfp_sugar_thms, infos, lthy') = | 
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 468 | mk_infos_of_mutually_recursive_new_datatypes [] eq_set fpT_names lthy; | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 469 | |
| 66251 
cd935b7cb3fb
proper concept of code declaration wrt. atomicity and Isar declarations
 haftmann parents: 
64705diff
changeset | 470 | val (all_notes, rec_thmss) = | 
| 53746 
bd038e48526d
have "datatype_new_compat" register induction and recursion theorems in nested case
 blanchet parents: 
53309diff
changeset | 471 | (case lfp_sugar_thms of | 
| 66251 
cd935b7cb3fb
proper concept of code declaration wrt. atomicity and Isar declarations
 haftmann parents: 
64705diff
changeset | 472 | NONE => ([], []) | 
| 58214 | 473 | | SOME ((inducts, induct, induct_attrs), (rec_thmss, _)) => | 
| 53746 
bd038e48526d
have "datatype_new_compat" register induction and recursion theorems in nested case
 blanchet parents: 
53309diff
changeset | 474 | let | 
| 58211 
c1f3fa32d322
extended 'datatype_compat' to generate the expected, old-style recursor in the presence of recursion through functions
 blanchet parents: 
58189diff
changeset | 475 | val common_name = compat_N ^ mk_common_name b_names; | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 476 | |
| 53746 
bd038e48526d
have "datatype_new_compat" register induction and recursion theorems in nested case
 blanchet parents: 
53309diff
changeset | 477 | val common_notes = | 
| 58214 | 478 | (if nn > 1 then [(inductN, [induct], induct_attrs)] else []) | 
| 53746 
bd038e48526d
have "datatype_new_compat" register induction and recursion theorems in nested case
 blanchet parents: 
53309diff
changeset | 479 | |> filter_out (null o #2) | 
| 
bd038e48526d
have "datatype_new_compat" register induction and recursion theorems in nested case
 blanchet parents: 
53309diff
changeset | 480 | |> map (fn (thmN, thms, attrs) => | 
| 
bd038e48526d
have "datatype_new_compat" register induction and recursion theorems in nested case
 blanchet parents: 
53309diff
changeset | 481 | ((Binding.qualify true common_name (Binding.name thmN), attrs), [(thms, [])])); | 
| 
bd038e48526d
have "datatype_new_compat" register induction and recursion theorems in nested case
 blanchet parents: 
53309diff
changeset | 482 | |
| 
bd038e48526d
have "datatype_new_compat" register induction and recursion theorems in nested case
 blanchet parents: 
53309diff
changeset | 483 | val notes = | 
| 58214 | 484 | [(inductN, map single inducts, induct_attrs), | 
| 66251 
cd935b7cb3fb
proper concept of code declaration wrt. atomicity and Isar declarations
 haftmann parents: 
64705diff
changeset | 485 | (recN, rec_thmss, nitpicksimp_simp_attrs)] | 
| 53746 
bd038e48526d
have "datatype_new_compat" register induction and recursion theorems in nested case
 blanchet parents: 
53309diff
changeset | 486 | |> filter_out (null o #2) | 
| 
bd038e48526d
have "datatype_new_compat" register induction and recursion theorems in nested case
 blanchet parents: 
53309diff
changeset | 487 | |> maps (fn (thmN, thmss, attrs) => | 
| 
bd038e48526d
have "datatype_new_compat" register induction and recursion theorems in nested case
 blanchet parents: 
53309diff
changeset | 488 | if forall null thmss then | 
| 
bd038e48526d
have "datatype_new_compat" register induction and recursion theorems in nested case
 blanchet parents: 
53309diff
changeset | 489 | [] | 
| 
bd038e48526d
have "datatype_new_compat" register induction and recursion theorems in nested case
 blanchet parents: 
53309diff
changeset | 490 | else | 
| 
bd038e48526d
have "datatype_new_compat" register induction and recursion theorems in nested case
 blanchet parents: 
53309diff
changeset | 491 | map2 (fn b_name => fn thms => | 
| 
bd038e48526d
have "datatype_new_compat" register induction and recursion theorems in nested case
 blanchet parents: 
53309diff
changeset | 492 | ((Binding.qualify true b_name (Binding.name thmN), attrs), [(thms, [])])) | 
| 
bd038e48526d
have "datatype_new_compat" register induction and recursion theorems in nested case
 blanchet parents: 
53309diff
changeset | 493 | compat_b_names thmss); | 
| 
bd038e48526d
have "datatype_new_compat" register induction and recursion theorems in nested case
 blanchet parents: 
53309diff
changeset | 494 | in | 
| 66251 
cd935b7cb3fb
proper concept of code declaration wrt. atomicity and Isar declarations
 haftmann parents: 
64705diff
changeset | 495 | (common_notes @ notes, rec_thmss) | 
| 53746 
bd038e48526d
have "datatype_new_compat" register induction and recursion theorems in nested case
 blanchet parents: 
53309diff
changeset | 496 | end); | 
| 
bd038e48526d
have "datatype_new_compat" register induction and recursion theorems in nested case
 blanchet parents: 
53309diff
changeset | 497 | |
| 
bd038e48526d
have "datatype_new_compat" register induction and recursion theorems in nested case
 blanchet parents: 
53309diff
changeset | 498 | val register_interpret = | 
| 58112 
8081087096ad
renamed modules defining old datatypes, as a step towards having 'datatype_new' take 'datatype's place
 blanchet parents: 
57983diff
changeset | 499 | Old_Datatype_Data.register infos | 
| 58113 | 500 | #> Old_Datatype_Data.interpretation_data (Old_Datatype_Aux.default_config, map fst infos); | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 501 | in | 
| 58117 
9608028d8f43
more compatibility between old- and new-style datatypes
 blanchet parents: 
58113diff
changeset | 502 | lthy' | 
| 53746 
bd038e48526d
have "datatype_new_compat" register induction and recursion theorems in nested case
 blanchet parents: 
53309diff
changeset | 503 | |> Local_Theory.raw_theory register_interpret | 
| 57633 | 504 | |> Local_Theory.notes all_notes | 
| 505 | |> snd | |
| 66251 
cd935b7cb3fb
proper concept of code declaration wrt. atomicity and Isar declarations
 haftmann parents: 
64705diff
changeset | 506 | |> Code.declare_default_eqns (map (rpair true) (flat rec_thmss)) | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 507 | end; | 
| 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 508 | |
| 58665 | 509 | val datatype_compat_global = Named_Target.theory_map o datatype_compat; | 
| 58125 | 510 | |
| 511 | fun datatype_compat_cmd raw_fpT_names lthy = | |
| 512 | let | |
| 513 | val fpT_names = | |
| 514 |       map (fst o dest_Type o Proof_Context.read_type_name {proper = true, strict = false} lthy)
 | |
| 515 | raw_fpT_names; | |
| 516 | in | |
| 517 | datatype_compat fpT_names lthy | |
| 518 | end; | |
| 519 | ||
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 520 | fun add_datatype prefs old_specs thy = | 
| 58123 
62765d39539f
implemented compatibility definition of datatype
 blanchet parents: 
58122diff
changeset | 521 | let | 
| 
62765d39539f
implemented compatibility definition of datatype
 blanchet parents: 
58122diff
changeset | 522 | val fpT_names = map (Sign.full_name thy o #1 o fst) old_specs; | 
| 
62765d39539f
implemented compatibility definition of datatype
 blanchet parents: 
58122diff
changeset | 523 | |
| 58300 | 524 | fun new_type_args_of (s, S) = | 
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 525 | (if member (op =) prefs Kill_Type_Args then NONE else SOME Binding.empty, | 
| 69593 | 526 | (TFree (s, \<^sort>\<open>type\<close>), S)); | 
| 58123 
62765d39539f
implemented compatibility definition of datatype
 blanchet parents: 
58122diff
changeset | 527 | fun new_ctr_spec_of (b, Ts, mx) = (((Binding.empty, b), map (pair Binding.empty) Ts), mx); | 
| 
62765d39539f
implemented compatibility definition of datatype
 blanchet parents: 
58122diff
changeset | 528 | |
| 
62765d39539f
implemented compatibility definition of datatype
 blanchet parents: 
58122diff
changeset | 529 | fun new_spec_of ((b, old_tyargs, mx), old_ctr_specs) = | 
| 
62765d39539f
implemented compatibility definition of datatype
 blanchet parents: 
58122diff
changeset | 530 | (((((map new_type_args_of old_tyargs, b), mx), map new_ctr_spec_of old_ctr_specs), | 
| 62324 | 531 | (Binding.empty, Binding.empty, Binding.empty)), []); | 
| 58123 
62765d39539f
implemented compatibility definition of datatype
 blanchet parents: 
58122diff
changeset | 532 | |
| 
62765d39539f
implemented compatibility definition of datatype
 blanchet parents: 
58122diff
changeset | 533 | val new_specs = map new_spec_of old_specs; | 
| 
62765d39539f
implemented compatibility definition of datatype
 blanchet parents: 
58122diff
changeset | 534 | in | 
| 
62765d39539f
implemented compatibility definition of datatype
 blanchet parents: 
58122diff
changeset | 535 | (fpT_names, | 
| 
62765d39539f
implemented compatibility definition of datatype
 blanchet parents: 
58122diff
changeset | 536 | thy | 
| 58665 | 537 | |> Named_Target.theory_map | 
| 538 | (co_datatypes Least_FP construct_lfp (default_ctr_options, new_specs)) | |
| 58354 
04ac60da613e
support (finite values of) codatatypes in Quickcheck
 blanchet parents: 
58340diff
changeset | 539 | |> not (member (op =) prefs Keep_Nesting) ? perhaps (try (datatype_compat_global fpT_names))) | 
| 58123 
62765d39539f
implemented compatibility definition of datatype
 blanchet parents: 
58122diff
changeset | 540 | end; | 
| 
62765d39539f
implemented compatibility definition of datatype
 blanchet parents: 
58122diff
changeset | 541 | |
| 60004 | 542 | fun old_of_new f (ts, _, simpss) = (ts, f simpss); | 
| 543 | ||
| 64674 
ef0a5fd30f3b
print constants in 'primrec', 'primcorec(ursive)', 'corec(ursive)', like in 'definition' and 'fun(ction)'
 blanchet parents: 
63859diff
changeset | 544 | val primrec = apfst (old_of_new flat) ooo BNF_LFP_Rec_Sugar.primrec false []; | 
| 
ef0a5fd30f3b
print constants in 'primrec', 'primcorec(ursive)', 'corec(ursive)', like in 'definition' and 'fun(ction)'
 blanchet parents: 
63859diff
changeset | 545 | val primrec_global = apfst (old_of_new flat) ooo BNF_LFP_Rec_Sugar.primrec_global false []; | 
| 
ef0a5fd30f3b
print constants in 'primrec', 'primcorec(ursive)', 'corec(ursive)', like in 'definition' and 'fun(ction)'
 blanchet parents: 
63859diff
changeset | 546 | val primrec_overloaded = apfst (old_of_new flat) oooo BNF_LFP_Rec_Sugar.primrec_overloaded false []; | 
| 62497 
5b5b704f4811
respect qualification when noting theorems in prim(co)rec
 traytel parents: 
62324diff
changeset | 547 | val primrec_simple = apfst (apfst fst o apsnd (old_of_new (flat o snd))) ooo | 
| 64674 
ef0a5fd30f3b
print constants in 'primrec', 'primcorec(ursive)', 'corec(ursive)', like in 'definition' and 'fun(ction)'
 blanchet parents: 
63859diff
changeset | 548 | BNF_LFP_Rec_Sugar.primrec_simple false; | 
| 58126 | 549 | |
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 550 | val _ = | 
| 69593 | 551 | Outer_Syntax.local_theory \<^command_keyword>\<open>datatype_compat\<close> | 
| 58315 | 552 | "register datatypes as old-style datatypes and derive old-style properties" | 
| 55531 
601ca8efa000
renamed 'datatype_new_compat' to 'datatype_compat'
 blanchet parents: 
55486diff
changeset | 553 | (Scan.repeat1 Parse.type_const >> datatype_compat_cmd); | 
| 53303 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 554 | |
| 
ae49b835ca01
moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
 blanchet parents: diff
changeset | 555 | end; |