src/HOL/Tools/BNF/bnf_lfp_compat.ML
author blanchet
Mon, 17 Feb 2014 13:31:42 +0100
changeset 55531 601ca8efa000
parent 55486 8609527278f2
child 55539 0819931d652d
permissions -rw-r--r--
renamed 'datatype_new_compat' to 'datatype_compat'
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
55061
a0adf838e2d1 adjusted comments
blanchet
parents: 55060
diff changeset
     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
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
     3
    Copyright   2013
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
     4
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
     5
Compatibility layer with the old datatype package.
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
     6
*)
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
     7
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
     8
signature BNF_LFP_COMPAT =
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
     9
sig
55531
601ca8efa000 renamed 'datatype_new_compat' to 'datatype_compat'
blanchet
parents: 55486
diff changeset
    10
  val datatype_compat_cmd : string list -> local_theory -> local_theory
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    11
end;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    12
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    13
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
    14
struct
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    15
54006
9fe1bd54d437 renamed theory file
blanchet
parents: 54003
diff changeset
    16
open Ctr_Sugar
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    17
open BNF_Util
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    18
open BNF_FP_Util
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    19
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
    20
open BNF_FP_N2M_Sugar
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    21
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    22
val compatN = "compat_";
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    23
55479
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    24
val code_nitpicksimp_simp_attrs = Code.add_default_eqn_attrib :: @{attributes [nitpick_simp, simp]};
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    25
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    26
(* TODO: graceful failure for local datatypes -- perhaps by making the command global *)
55531
601ca8efa000 renamed 'datatype_new_compat' to 'datatype_compat'
blanchet
parents: 55486
diff changeset
    27
fun datatype_compat_cmd raw_fpT_names lthy =
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    28
  let
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    29
    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
    30
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    31
    fun not_datatype s = error (quote s ^ " is not a new-style datatype");
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    32
    fun not_mutually_recursive ss =
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    33
      error ("{" ^ commas ss ^ "} is not a complete set of mutually recursive new-style datatypes");
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    34
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    35
    val (fpT_names as fpT_name1 :: _) =
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    36
      map (fst o dest_Type o Proof_Context.read_type_name_proper lthy false) raw_fpT_names;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    37
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    38
    fun lfp_sugar_of s =
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    39
      (case fp_sugar_of lthy s of
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    40
        SOME (fp_sugar as {fp = Least_FP, ...}) => fp_sugar
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    41
      | _ => not_datatype s);
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    42
55485
bdfb607543f4 better handling of recursion through functions
blanchet
parents: 55481
diff changeset
    43
    val {ctr_sugars = fp_ctr_sugars, ...} = lfp_sugar_of fpT_name1;
bdfb607543f4 better handling of recursion through functions
blanchet
parents: 55481
diff changeset
    44
    val fpTs0 as Type (_, var_As) :: _ = map (body_type o fastype_of o hd o #ctrs) fp_ctr_sugars;
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    45
    val fpT_names' = map (fst o dest_Type) fpTs0;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    46
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    47
    val _ = eq_set (op =) (fpT_names, fpT_names') orelse not_mutually_recursive fpT_names;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    48
54950
f00012c20344 made 'datatype_new_compat' work with sort constraints
blanchet
parents: 54435
diff changeset
    49
    val (unsorted_As, _) = lthy |> mk_TFrees (length var_As);
f00012c20344 made 'datatype_new_compat' work with sort constraints
blanchet
parents: 54435
diff changeset
    50
    val As = map2 (resort_tfree o Type.sort_of_atyp) var_As unsorted_As;
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    51
    val fpTs as fpT1 :: _ = map (fn s => Type (s, As)) fpT_names';
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    52
55486
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
    53
    fun nested_Tparentss_indicessss_of parent_Tkks (T as Type (s, _)) kk =
55479
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    54
      (case try lfp_sugar_of s of
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    55
        SOME ({T = T0, fp_res = {Ts = mutual_Ts0, ...}, ctr_sugars, ...}) =>
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    56
        let
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    57
          val rho = Vartab.fold (cons o apsnd snd) (Sign.typ_match thy (T0, T) Vartab.empty) [];
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    58
          val substT = Term.typ_subst_TVars rho;
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    59
          val mutual_Ts = map substT mutual_Ts0;
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    60
          val mutual_nn = length mutual_Ts;
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    61
          val mutual_kks = kk upto kk + mutual_nn - 1;
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    62
          val mutual_Tkks = mutual_Ts ~~ mutual_kks;
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    63
55486
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
    64
          fun indices_of_ctr_arg parent_Tkks (U as Type (s, Us)) (accum as (Tparents_ksss, kk')) =
55479
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    65
              if s = @{type_name fun} then
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    66
                if exists_subtype_in mutual_Ts U then
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    67
                  (warning "Incomplete support for recursion through functions -- \
55485
bdfb607543f4 better handling of recursion through functions
blanchet
parents: 55481
diff changeset
    68
                     \the old 'primrec' will fail";
55486
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
    69
                   indices_of_ctr_arg parent_Tkks (range_type U) accum)
55479
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    70
                else
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    71
                  ([], accum)
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    72
              else
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    73
                (case AList.lookup (op =) (parent_Tkks @ mutual_Tkks) U of
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    74
                  SOME kk => ([kk], accum)
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    75
                | NONE =>
55486
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
    76
                  if exists (exists_strict_subtype_in mutual_Ts) Us then
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
    77
                    error "Deeply nested recursion not supported"
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
    78
                  else if exists (member (op =) mutual_Ts) Us then
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
    79
                    ([kk'],
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
    80
                     nested_Tparentss_indicessss_of parent_Tkks U kk' |>> append Tparents_ksss)
55479
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    81
                  else
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    82
                    ([], accum))
55486
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
    83
            | indices_of_ctr_arg _ _ accum = ([], accum);
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    84
55486
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
    85
          fun Tparents_indicesss_of_mutual_type T kk ctr_Tss =
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
    86
            let val parent_Tkks' = (T, kk) :: parent_Tkks in
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
    87
              fold_map (fold_map (indices_of_ctr_arg parent_Tkks')) ctr_Tss
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
    88
              #>> pair parent_Tkks'
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
    89
            end;
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
    90
55479
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    91
          val ctrss = map #ctrs ctr_sugars;
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    92
          val ctr_Tsss = map (map (binder_types o substT o fastype_of)) ctrss;
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    93
        in
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    94
          ([], kk + mutual_nn)
55486
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
    95
          |> fold_map3 Tparents_indicesss_of_mutual_type mutual_Ts mutual_kks ctr_Tsss
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
    96
          |> (fn (Tparentss_kkssss, (Tparentss_kkssss', kk)) =>
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
    97
            (Tparentss_kkssss @ Tparentss_kkssss', kk))
55479
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    98
        end
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
    99
      | NONE => error ("Unsupported recursion via type constructor " ^ quote s ^
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
   100
          " not corresponding to new-style datatype (cf. \"datatype_new\")"));
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
   101
55485
bdfb607543f4 better handling of recursion through functions
blanchet
parents: 55481
diff changeset
   102
    fun get_indices (Var ((_, kk), _)) = [kk];
55479
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
   103
55486
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
   104
    val (Tparentss_kkssss, _) = nested_Tparentss_indicessss_of [] fpT1 0;
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
   105
    val Tparentss = map fst Tparentss_kkssss;
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
   106
    val Ts = map (fst o hd) Tparentss;
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
   107
    val kkssss = map snd Tparentss_kkssss;
55485
bdfb607543f4 better handling of recursion through functions
blanchet
parents: 55481
diff changeset
   108
bdfb607543f4 better handling of recursion through functions
blanchet
parents: 55481
diff changeset
   109
    val fp_sugars0 = map (lfp_sugar_of o fst o dest_Type) Ts;
bdfb607543f4 better handling of recursion through functions
blanchet
parents: 55481
diff changeset
   110
    val ctrss0 = map (#ctrs o of_fp_sugar #ctr_sugars) fp_sugars0;
bdfb607543f4 better handling of recursion through functions
blanchet
parents: 55481
diff changeset
   111
    val ctr_Tsss0 = map (map (binder_types o fastype_of)) ctrss0;
bdfb607543f4 better handling of recursion through functions
blanchet
parents: 55481
diff changeset
   112
bdfb607543f4 better handling of recursion through functions
blanchet
parents: 55481
diff changeset
   113
    fun apply_comps n kk =
bdfb607543f4 better handling of recursion through functions
blanchet
parents: 55481
diff changeset
   114
      mk_partial_compN n (replicate n @{typ unit} ---> @{typ unit})
bdfb607543f4 better handling of recursion through functions
blanchet
parents: 55481
diff changeset
   115
        (Var ((Name.uu, kk), @{typ "unit => unit"}));
bdfb607543f4 better handling of recursion through functions
blanchet
parents: 55481
diff changeset
   116
bdfb607543f4 better handling of recursion through functions
blanchet
parents: 55481
diff changeset
   117
    val callssss =
55486
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
   118
      map2 (map2 (map2 (fn kks => fn ctr_T => map (apply_comps (num_binder_types ctr_T)) kks)))
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
   119
        kkssss ctr_Tsss0;
55479
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
   120
55481
a8b83356e869 generate unique names
blanchet
parents: 55480
diff changeset
   121
    val b_names = Name.variant_list [] (map base_name_of_typ Ts);
53746
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   122
    val compat_b_names = map (prefix compatN) b_names;
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   123
    val compat_bs = map Binding.name compat_b_names;
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   124
    val common_name = compatN ^ mk_common_name b_names;
55486
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
   125
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   126
    val nn_fp = length fpTs;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   127
    val nn = length Ts;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   128
53746
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   129
    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: 54267
diff changeset
   130
      if nn > nn_fp then
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: 54267
diff changeset
   131
        mutualize_fp_sugars Least_FP compat_bs Ts get_indices callssss fp_sugars0 lthy
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: 54267
diff changeset
   132
      else
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: 54267
diff changeset
   133
        ((fp_sugars0, (NONE, NONE)), lthy);
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   134
55409
b74248961819 made 'ctr_sugar' more friendly to the 'datatype_realizer'
blanchet
parents: 55061
diff changeset
   135
    val {ctr_sugars, co_inducts = [induct], co_inductss = inductss, co_iterss,
b74248961819 made 'ctr_sugar' more friendly to the 'datatype_realizer'
blanchet
parents: 55061
diff changeset
   136
      co_iter_thmsss = iter_thmsss, ...} :: _ = fp_sugars;
b74248961819 made 'ctr_sugar' more friendly to the 'datatype_realizer'
blanchet
parents: 55061
diff changeset
   137
    val inducts = map the_single inductss;
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   138
55486
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
   139
    fun mk_dtyp [] (TFree a) = Datatype_Aux.DtTFree a
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
   140
      | mk_dtyp [] (Type (s, Ts)) = Datatype_Aux.DtType (s, map (mk_dtyp []) Ts)
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
   141
      | mk_dtyp [kk] (Type (@{type_name fun}, [T, T'])) =
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
   142
        Datatype_Aux.DtType (@{type_name fun}, [mk_dtyp [] T, mk_dtyp [kk] T'])
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
   143
      | mk_dtyp [kk] T = if nth Ts kk = T then Datatype_Aux.DtRec kk else mk_dtyp [] T;
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   144
55486
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
   145
    fun mk_ctr_descr Ts kkss ctr0 =
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
   146
      mk_ctr Ts ctr0 |> (fn Const (s, T) => (s, map2 mk_dtyp kkss (binder_types T)));
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
   147
    fun mk_typ_descr kksss ((Type (T_name, Ts), kk) :: parents) ctrs0 =
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
   148
      (kk, (T_name, map (mk_dtyp (map snd (take 1 parents))) Ts, map2 (mk_ctr_descr Ts) kksss ctrs0));
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   149
55486
8609527278f2 generate proper 'DtRec' indices in 'datatype_new_compat' for the case where some types are duplicated
blanchet
parents: 55485
diff changeset
   150
    val descr = map3 mk_typ_descr kkssss Tparentss ctrss0;
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   151
    val recs = map (fst o dest_Const o co_rec_of) co_iterss;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   152
    val rec_thms = flat (map co_rec_of iter_thmsss);
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   153
54003
c4343c31f86d made SML/NJ happy
blanchet
parents: 53901
diff changeset
   154
    fun mk_info ({T = Type (T_name0, _), index, ...} : fp_sugar) =
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   155
      let
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   156
        val {casex, exhaust, nchotomy, injects, distincts, case_thms, case_cong, weak_case_cong,
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   157
          split, split_asm, ...} = nth ctr_sugars index;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   158
      in
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   159
        (T_name0,
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   160
         {index = index, descr = descr, inject = injects, distinct = distincts, induct = induct,
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   161
         inducts = inducts, exhaust = exhaust, nchotomy = nchotomy, rec_names = recs,
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   162
         rec_rewrites = rec_thms, case_name = fst (dest_Const casex), case_rewrites = case_thms,
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   163
         case_cong = case_cong, weak_case_cong = weak_case_cong, split = split,
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   164
         split_asm = split_asm})
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   165
      end;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   166
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   167
    val infos = map mk_info (take nn_fp fp_sugars);
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   168
53746
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   169
    val all_notes =
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   170
      (case lfp_sugar_thms of
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   171
        NONE => []
53808
b3e2022530e3 register codatatypes with Nitpick
blanchet
parents: 53747
diff changeset
   172
      | SOME ((induct_thms, induct_thm, induct_attrs), (fold_thmss, rec_thmss, _)) =>
53746
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   173
        let
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   174
          val common_notes =
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   175
            (if nn > 1 then [(inductN, [induct_thm], induct_attrs)] else [])
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   176
            |> filter_out (null o #2)
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   177
            |> map (fn (thmN, thms, attrs) =>
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   178
              ((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: 53309
diff changeset
   179
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   180
          val notes =
53747
a8253329ebe9 took out spurious attributes (no need for several code equations / simps for thesame constants)
blanchet
parents: 53746
diff changeset
   181
            [(foldN, fold_thmss, []),
53746
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   182
             (inductN, map single induct_thms, induct_attrs),
55479
ece4910c3ea0 improved 'datatype_new_compat': generate more fixpoint equations for types like 'datatype_new x = C (x list) (x list)' (here, one equation for each x list instead of a single for both), for higher compatibility + code generation attributes on the recursor
blanchet
parents: 55409
diff changeset
   183
             (recN, rec_thmss, code_nitpicksimp_simp_attrs)]
53746
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   184
            |> filter_out (null o #2)
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   185
            |> maps (fn (thmN, thmss, attrs) =>
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   186
              if forall null thmss then
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   187
                []
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   188
              else
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   189
                map2 (fn b_name => fn thms =>
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   190
                    ((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: 53309
diff changeset
   191
                  compat_b_names thmss);
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   192
        in
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   193
          common_notes @ notes
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   194
        end);
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   195
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   196
    val register_interpret =
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   197
      Datatype_Data.register infos
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   198
      #> Datatype_Data.interpretation_data (Datatype_Aux.default_config, map fst infos)
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   199
  in
53746
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   200
    lthy
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   201
    |> Local_Theory.raw_theory register_interpret
bd038e48526d have "datatype_new_compat" register induction and recursion theorems in nested case
blanchet
parents: 53309
diff changeset
   202
    |> Local_Theory.notes all_notes |> snd
53303
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   203
  end;
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   204
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   205
val _ =
55531
601ca8efa000 renamed 'datatype_new_compat' to 'datatype_compat'
blanchet
parents: 55486
diff changeset
   206
  Outer_Syntax.local_theory @{command_spec "datatype_compat"}
54025
70bc41e7a91e tuned command descriptions
blanchet
parents: 54009
diff changeset
   207
    "register new-style datatypes as old-style datatypes"
55531
601ca8efa000 renamed 'datatype_new_compat' to 'datatype_compat'
blanchet
parents: 55486
diff changeset
   208
    (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
   209
ae49b835ca01 moved files related to "primrec_new", "primcorec", and "datatype_compat" from bitbucket co-rec repository
blanchet
parents:
diff changeset
   210
end;