src/HOL/Tools/BNF/bnf_lfp_size.ML
author blanchet
Thu, 24 Jul 2014 00:24:00 +0200
changeset 57631 959caab43a3d
parent 57399 cfc19f0a6261
child 57890 1e13f63fb452
permissions -rw-r--r--
use the noted theorem whenever possible, also in 'BNF_Def'
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
56638
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
     1
(*  Title:      HOL/Tools/BNF/bnf_lfp_size.ML
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
     2
    Author:     Jasmin Blanchette, TU Muenchen
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
     3
    Copyright   2014
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
     4
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
     5
Generation of size functions for new-style datatypes.
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
     6
*)
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
     7
56642
15cd15f9b40c allow registration of custom size functions for BNF-based datatypes
blanchet
parents: 56640
diff changeset
     8
signature BNF_LFP_SIZE =
15cd15f9b40c allow registration of custom size functions for BNF-based datatypes
blanchet
parents: 56640
diff changeset
     9
sig
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    10
  val register_size: string -> string -> thm list -> thm list -> local_theory -> local_theory
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    11
  val register_size_global: string -> string -> thm list -> thm list -> theory -> theory
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    12
  val lookup_size: Proof.context -> string -> (string * (thm list * thm list)) option
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    13
  val lookup_size_global: theory -> string -> (string * (thm list * thm list)) option
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    14
  val generate_lfp_size: BNF_FP_Util.fp_sugar list -> local_theory -> local_theory
56642
15cd15f9b40c allow registration of custom size functions for BNF-based datatypes
blanchet
parents: 56640
diff changeset
    15
end;
15cd15f9b40c allow registration of custom size functions for BNF-based datatypes
blanchet
parents: 56640
diff changeset
    16
15cd15f9b40c allow registration of custom size functions for BNF-based datatypes
blanchet
parents: 56640
diff changeset
    17
structure BNF_LFP_Size : BNF_LFP_SIZE =
56638
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    18
struct
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    19
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    20
open BNF_Util
56640
0a35354137a5 generate 'rec_o_map' and 'size_o_map' in size extension
blanchet
parents: 56639
diff changeset
    21
open BNF_Tactics
56638
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    22
open BNF_Def
56650
1f9ab71d43a5 no need to make 'size' generation an interpretation -- overkill
blanchet
parents: 56647
diff changeset
    23
open BNF_FP_Util
56638
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    24
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    25
val size_N = "size_"
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    26
56640
0a35354137a5 generate 'rec_o_map' and 'size_o_map' in size extension
blanchet
parents: 56639
diff changeset
    27
val rec_o_mapN = "rec_o_map"
56638
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    28
val sizeN = "size"
56640
0a35354137a5 generate 'rec_o_map' and 'size_o_map' in size extension
blanchet
parents: 56639
diff changeset
    29
val size_o_mapN = "size_o_map"
56638
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    30
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    31
val nitpicksimp_attrs = @{attributes [nitpick_simp]};
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    32
val simp_attrs = @{attributes [simp]};
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    33
val code_nitpicksimp_simp_attrs = Code.add_default_eqn_attrib :: nitpicksimp_attrs @ simp_attrs;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    34
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    35
structure Data = Generic_Data
56638
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    36
(
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    37
  type T = (string * (thm list * thm list)) Symtab.table;
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    38
  val empty = Symtab.empty;
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    39
  val extend = I
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    40
  fun merge data = Symtab.merge (K true) data;
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    41
);
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    42
56642
15cd15f9b40c allow registration of custom size functions for BNF-based datatypes
blanchet
parents: 56640
diff changeset
    43
fun register_size T_name size_name size_simps size_o_maps =
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    44
  Context.proof_map (Data.map (Symtab.update (T_name, (size_name, (size_simps, size_o_maps)))));
56643
41d3596d8a64 move size hooks together, with new one preceding old one and sharing same theory data
blanchet
parents: 56642
diff changeset
    45
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    46
fun register_size_global T_name size_name size_simps size_o_maps =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    47
  Context.theory_map (Data.map (Symtab.update (T_name, (size_name, (size_simps, size_o_maps)))));
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    48
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    49
val lookup_size = Symtab.lookup o Data.get o Context.Proof;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    50
val lookup_size_global = Symtab.lookup o Data.get o Context.Theory;
56642
15cd15f9b40c allow registration of custom size functions for BNF-based datatypes
blanchet
parents: 56640
diff changeset
    51
56638
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    52
val zero_nat = @{const zero_class.zero (nat)};
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    53
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    54
fun mk_plus_nat (t1, t2) = Const (@{const_name Groups.plus},
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    55
  HOLogic.natT --> HOLogic.natT --> HOLogic.natT) $ t1 $ t2;
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    56
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    57
fun mk_to_natT T = T --> HOLogic.natT;
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    58
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    59
fun mk_abs_zero_nat T = Term.absdummy T zero_nat;
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    60
56640
0a35354137a5 generate 'rec_o_map' and 'size_o_map' in size extension
blanchet
parents: 56639
diff changeset
    61
fun pointfill ctxt th = unfold_thms ctxt [o_apply] (th RS fun_cong);
0a35354137a5 generate 'rec_o_map' and 'size_o_map' in size extension
blanchet
parents: 56639
diff changeset
    62
0a35354137a5 generate 'rec_o_map' and 'size_o_map' in size extension
blanchet
parents: 56639
diff changeset
    63
fun mk_unabs_def_unused_0 n =
0a35354137a5 generate 'rec_o_map' and 'size_o_map' in size extension
blanchet
parents: 56639
diff changeset
    64
  funpow n (fn thm => thm RS @{thm fun_cong_unused_0} handle THM _ => thm RS fun_cong);
0a35354137a5 generate 'rec_o_map' and 'size_o_map' in size extension
blanchet
parents: 56639
diff changeset
    65
0a35354137a5 generate 'rec_o_map' and 'size_o_map' in size extension
blanchet
parents: 56639
diff changeset
    66
val rec_o_map_simp_thms =
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    67
  @{thms o_def id_def case_prod_app case_sum_map_sum case_prod_map_prod BNF_Comp.id_bnf_comp_def};
56638
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    68
57399
cfc19f0a6261 compile
blanchet
parents: 57397
diff changeset
    69
fun mk_rec_o_map_tac ctxt rec_def pre_map_defs live_nesting_map_ident0s abs_inverses
cfc19f0a6261 compile
blanchet
parents: 57397
diff changeset
    70
    ctor_rec_o_map =
56640
0a35354137a5 generate 'rec_o_map' and 'size_o_map' in size extension
blanchet
parents: 56639
diff changeset
    71
  unfold_thms_tac ctxt [rec_def] THEN
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    72
  HEADGOAL (rtac (ctor_rec_o_map RS trans)) THEN
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    73
  PRIMITIVE (Conv.fconv_rule Thm.eta_long_conversion) THEN
57395
465ac4021146 repaired BNF 'size' generation tactic for datatypes mixng old- and new-style datatypes on the right-hand side
blanchet
parents: 57303
diff changeset
    74
  HEADGOAL (asm_simp_tac (ss_only (pre_map_defs @
57399
cfc19f0a6261 compile
blanchet
parents: 57397
diff changeset
    75
    distinct Thm.eq_thm_prop (live_nesting_map_ident0s @ abs_inverses) @ rec_o_map_simp_thms) ctxt));
56638
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    76
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    77
val size_o_map_simp_thms = @{thms prod_inj_map inj_on_id snd_comp_apfst[unfolded apfst_def]};
56640
0a35354137a5 generate 'rec_o_map' and 'size_o_map' in size extension
blanchet
parents: 56639
diff changeset
    78
0a35354137a5 generate 'rec_o_map' and 'size_o_map' in size extension
blanchet
parents: 56639
diff changeset
    79
fun mk_size_o_map_tac ctxt size_def rec_o_map inj_maps size_maps =
0a35354137a5 generate 'rec_o_map' and 'size_o_map' in size extension
blanchet
parents: 56639
diff changeset
    80
  unfold_thms_tac ctxt [size_def] THEN
0a35354137a5 generate 'rec_o_map' and 'size_o_map' in size extension
blanchet
parents: 56639
diff changeset
    81
  HEADGOAL (rtac (rec_o_map RS trans) THEN'
56642
15cd15f9b40c allow registration of custom size functions for BNF-based datatypes
blanchet
parents: 56640
diff changeset
    82
    asm_simp_tac (ss_only (inj_maps @ size_maps @ size_o_map_simp_thms) ctxt)) THEN
56645
a16d294f7e3f prevent tactic failures by detecting and ignoring BNFs with no 'size' functions early
blanchet
parents: 56643
diff changeset
    83
  IF_UNSOLVED (unfold_thms_tac ctxt @{thms o_def} THEN HEADGOAL (rtac refl));
56638
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
    84
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    85
fun generate_lfp_size (fp_sugars as ({T = Type (_, As), BT = Type (_, Bs),
57397
5004aca20821 tuned variable names
blanchet
parents: 57395
diff changeset
    86
    fp_res = {bnfs = fp_bnfs, xtor_co_rec_o_map_thms = ctor_rec_o_maps, ...}, fp_nesting_bnfs,
5004aca20821 tuned variable names
blanchet
parents: 57395
diff changeset
    87
    live_nesting_bnfs, ...} : fp_sugar) :: _) lthy0 =
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    88
  let
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    89
    val data = Data.get (Context.Proof lthy0);
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    90
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    91
    val Ts = map #T fp_sugars
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    92
    val T_names = map (fst o dest_Type) Ts;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    93
    val nn = length Ts;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    94
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    95
    val B_ify = Term.typ_subst_atomic (As ~~ Bs);
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    96
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    97
    val recs = map #co_rec fp_sugars;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    98
    val rec_thmss = map #co_rec_thms fp_sugars;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
    99
    val rec_Ts as rec_T1 :: _ = map fastype_of recs;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   100
    val rec_arg_Ts = binder_fun_types rec_T1;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   101
    val Cs = map body_type rec_Ts;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   102
    val Cs_rho = map (rpair HOLogic.natT) Cs;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   103
    val substCnatT = Term.subst_atomic_types Cs_rho;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   104
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   105
    val f_Ts = map mk_to_natT As;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   106
    val f_TsB = map mk_to_natT Bs;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   107
    val num_As = length As;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   108
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   109
    fun variant_names n pre = fst (Variable.variant_fixes (replicate n pre) lthy0);
56640
0a35354137a5 generate 'rec_o_map' and 'size_o_map' in size extension
blanchet
parents: 56639
diff changeset
   110
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   111
    val f_names = variant_names num_As "f";
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   112
    val fs = map2 (curry Free) f_names f_Ts;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   113
    val fsB = map2 (curry Free) f_names f_TsB;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   114
    val As_fs = As ~~ fs;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   115
56654
54326fa7afe6 qualify name
blanchet
parents: 56651
diff changeset
   116
    val size_bs =
54326fa7afe6 qualify name
blanchet
parents: 56651
diff changeset
   117
      map ((fn base => Binding.qualify false base (Binding.name (prefix size_N base))) o
54326fa7afe6 qualify name
blanchet
parents: 56651
diff changeset
   118
        Long_Name.base_name) T_names;
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   119
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   120
    fun is_pair_C @{type_name prod} [_, T'] = member (op =) Cs T'
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   121
      | is_pair_C _ _ = false;
56640
0a35354137a5 generate 'rec_o_map' and 'size_o_map' in size extension
blanchet
parents: 56639
diff changeset
   122
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   123
    fun mk_size_of_typ (T as TFree _) =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   124
        pair (case AList.lookup (op =) As_fs T of
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   125
            SOME f => f
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   126
          | NONE => if member (op =) Cs T then Term.absdummy T (Bound 0) else mk_abs_zero_nat T)
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   127
      | mk_size_of_typ (T as Type (s, Ts)) =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   128
        if is_pair_C s Ts then
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   129
          pair (snd_const T)
56737
e4f363e16bdc use right set of variables for recursive check
blanchet
parents: 56684
diff changeset
   130
        else if exists (exists_subtype_in (As @ Cs)) Ts then
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   131
          (case Symtab.lookup data s of
56966
01637dd1260c more aggressive nested size handling in the absence of 'size_o_map' theorems (+ unrelated pattern matching fix)
blanchet
parents: 56737
diff changeset
   132
            SOME (size_name, (_, size_o_maps)) =>
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   133
            let
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   134
              val (args, size_o_mapss') = split_list (map (fn T => mk_size_of_typ T []) Ts);
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   135
              val size_const = Const (size_name, map fastype_of args ---> mk_to_natT T);
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   136
            in
57151
c16a6264c1d8 removed some spurious warnings in new (co)datatype package
blanchet
parents: 56966
diff changeset
   137
              fold (union Thm.eq_thm_prop) (size_o_maps :: size_o_mapss')
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   138
              #> pair (Term.list_comb (size_const, args))
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   139
            end
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   140
          | _ => pair (mk_abs_zero_nat T))
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   141
        else
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   142
          pair (mk_abs_zero_nat T);
56638
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
   143
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   144
    fun mk_size_of_arg t =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   145
      mk_size_of_typ (fastype_of t) #>> (fn s => substCnatT (betapply (s, t)));
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   146
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   147
    fun mk_size_arg rec_arg_T size_o_maps =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   148
      let
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   149
        val x_Ts = binder_types rec_arg_T;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   150
        val m = length x_Ts;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   151
        val x_names = variant_names m "x";
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   152
        val xs = map2 (curry Free) x_names x_Ts;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   153
        val (summands, size_o_maps') =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   154
          fold_map mk_size_of_arg xs size_o_maps
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   155
          |>> remove (op =) zero_nat;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   156
        val sum =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   157
          if null summands then HOLogic.zero
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   158
          else foldl1 mk_plus_nat (summands @ [HOLogic.Suc_zero]);
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   159
      in
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   160
        (fold_rev Term.lambda (map substCnatT xs) sum, size_o_maps')
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   161
      end;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   162
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   163
    fun mk_size_rhs recx size_o_maps =
56966
01637dd1260c more aggressive nested size handling in the absence of 'size_o_map' theorems (+ unrelated pattern matching fix)
blanchet
parents: 56737
diff changeset
   164
      fold_map mk_size_arg rec_arg_Ts size_o_maps
01637dd1260c more aggressive nested size handling in the absence of 'size_o_map' theorems (+ unrelated pattern matching fix)
blanchet
parents: 56737
diff changeset
   165
      |>> (fn args => fold_rev Term.lambda fs (Term.list_comb (substCnatT recx, args)));
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   166
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   167
    val maybe_conceal_def_binding = Thm.def_binding
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   168
      #> Config.get lthy0 bnf_note_all = false ? Binding.conceal;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   169
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   170
    val (size_rhss, nested_size_o_maps) = fold_map mk_size_rhs recs [];
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   171
    val size_Ts = map fastype_of size_rhss;
56638
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
   172
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   173
    val ((raw_size_consts, raw_size_defs), (lthy1', lthy1)) = lthy0
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   174
      |> apfst split_list o fold_map2 (fn b => fn rhs =>
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   175
          Local_Theory.define ((b, NoSyn), ((maybe_conceal_def_binding b, []), rhs)) #>> apsnd snd)
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   176
        size_bs size_rhss
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   177
      ||> `Local_Theory.restore;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   178
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   179
    val phi = Proof_Context.export_morphism lthy1 lthy1';
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   180
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   181
    val size_defs = map (Morphism.thm phi) raw_size_defs;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   182
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   183
    val size_consts0 = map (Morphism.term phi) raw_size_consts;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   184
    val size_consts = map2 retype_const_or_free size_Ts size_consts0;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   185
    val size_constsB = map (Term.map_types B_ify) size_consts;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   186
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   187
    val zeros = map mk_abs_zero_nat As;
56638
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
   188
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   189
    val overloaded_size_rhss = map (fn c => Term.list_comb (c, zeros)) size_consts;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   190
    val overloaded_size_Ts = map fastype_of overloaded_size_rhss;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   191
    val overloaded_size_consts = map (curry Const @{const_name size}) overloaded_size_Ts;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   192
    val overloaded_size_def_bs =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   193
      map (maybe_conceal_def_binding o Binding.suffix_name "_overloaded") size_bs;
56638
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
   194
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   195
    fun define_overloaded_size def_b lhs0 rhs lthy =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   196
      let
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   197
        val Free (c, _) = Syntax.check_term lthy lhs0;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   198
        val (thm, lthy') = lthy
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   199
          |> Local_Theory.define ((Binding.name c, NoSyn), ((def_b, []), rhs))
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   200
          |-> (fn (t, (_, thm)) => Spec_Rules.add Spec_Rules.Equational ([t], [thm]) #> pair thm);
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   201
        val ctxt_thy = Proof_Context.init_global (Proof_Context.theory_of lthy');
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   202
        val thm' = singleton (Proof_Context.export lthy' ctxt_thy) thm;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   203
      in (thm', lthy') end;
56638
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
   204
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   205
    val (overloaded_size_defs, lthy2) = lthy1
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   206
      |> Local_Theory.background_theory_result
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   207
        (Class.instantiation (T_names, map dest_TFree As, [HOLogic.class_size])
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   208
         #> fold_map3 define_overloaded_size overloaded_size_def_bs overloaded_size_consts
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   209
           overloaded_size_rhss
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   210
         ##> Class.prove_instantiation_instance (K (Class.intro_classes_tac []))
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   211
         ##> Local_Theory.exit_global);
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   212
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   213
    val size_defs' =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   214
      map (mk_unabs_def (num_As + 1) o (fn thm => thm RS meta_eq_to_obj_eq)) size_defs;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   215
    val size_defs_unused_0 =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   216
      map (mk_unabs_def_unused_0 (num_As + 1) o (fn thm => thm RS meta_eq_to_obj_eq)) size_defs;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   217
    val overloaded_size_defs' =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   218
      map (mk_unabs_def 1 o (fn thm => thm RS meta_eq_to_obj_eq)) overloaded_size_defs;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   219
56684
d8f32f55e463 more unfolding and more folding in size equations, to look more natural in the nested case
blanchet
parents: 56682
diff changeset
   220
    val all_overloaded_size_defs = overloaded_size_defs @
d8f32f55e463 more unfolding and more folding in size equations, to look more natural in the nested case
blanchet
parents: 56682
diff changeset
   221
      (Spec_Rules.retrieve lthy0 @{const size ('a)}
56966
01637dd1260c more aggressive nested size handling in the absence of 'size_o_map' theorems (+ unrelated pattern matching fix)
blanchet
parents: 56737
diff changeset
   222
       |> map_filter (try (fn (Spec_Rules.Equational, (_, [thm])) => thm)));
56684
d8f32f55e463 more unfolding and more folding in size equations, to look more natural in the nested case
blanchet
parents: 56682
diff changeset
   223
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   224
    val nested_size_maps = map (pointfill lthy2) nested_size_o_maps @ nested_size_o_maps;
57397
5004aca20821 tuned variable names
blanchet
parents: 57395
diff changeset
   225
    val all_inj_maps = map inj_map_of_bnf (fp_bnfs @ fp_nesting_bnfs @ live_nesting_bnfs)
57151
c16a6264c1d8 removed some spurious warnings in new (co)datatype package
blanchet
parents: 56966
diff changeset
   226
      |> distinct Thm.eq_thm_prop;
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   227
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   228
    fun derive_size_simp size_def' simp0 =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   229
      (trans OF [size_def', simp0])
56684
d8f32f55e463 more unfolding and more folding in size equations, to look more natural in the nested case
blanchet
parents: 56682
diff changeset
   230
      |> Simplifier.asm_full_simplify (ss_only (@{thms inj_on_convol_ident id_def o_def snd_conv} @
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   231
        all_inj_maps @ nested_size_maps) lthy2)
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   232
      |> fold_thms lthy2 size_defs_unused_0;
56684
d8f32f55e463 more unfolding and more folding in size equations, to look more natural in the nested case
blanchet
parents: 56682
diff changeset
   233
d8f32f55e463 more unfolding and more folding in size equations, to look more natural in the nested case
blanchet
parents: 56682
diff changeset
   234
    fun derive_overloaded_size_simp overloaded_size_def' simp0 =
d8f32f55e463 more unfolding and more folding in size equations, to look more natural in the nested case
blanchet
parents: 56682
diff changeset
   235
      (trans OF [overloaded_size_def', simp0])
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   236
      |> unfold_thms lthy2 @{thms add_0_left add_0_right}
56684
d8f32f55e463 more unfolding and more folding in size equations, to look more natural in the nested case
blanchet
parents: 56682
diff changeset
   237
      |> fold_thms lthy2 all_overloaded_size_defs;
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   238
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   239
    val size_simpss = map2 (map o derive_size_simp) size_defs' rec_thmss;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   240
    val size_simps = flat size_simpss;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   241
    val overloaded_size_simpss =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   242
      map2 (map o derive_overloaded_size_simp) overloaded_size_defs' size_simpss;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   243
    val size_thmss = map2 append size_simpss overloaded_size_simpss;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   244
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   245
    val ABs = As ~~ Bs;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   246
    val g_names = variant_names num_As "g";
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   247
    val gs = map2 (curry Free) g_names (map (op -->) ABs);
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   248
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   249
    val liveness = map (op <>) ABs;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   250
    val live_gs = AList.find (op =) (gs ~~ liveness) true;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   251
    val live = length live_gs;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   252
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   253
    val maps0 = map map_of_bnf fp_bnfs;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   254
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   255
    val (rec_o_map_thmss, size_o_map_thmss) =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   256
      if live = 0 then
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   257
        `I (replicate nn [])
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   258
      else
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   259
        let
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   260
          val pre_bnfs = map #pre_bnf fp_sugars;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   261
          val pre_map_defs = map map_def_of_bnf pre_bnfs;
57399
cfc19f0a6261 compile
blanchet
parents: 57397
diff changeset
   262
          val live_nesting_map_ident0s = map map_ident0_of_bnf live_nesting_bnfs;
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   263
          val abs_inverses = map (#abs_inverse o #absT_info) fp_sugars;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   264
          val rec_defs = map #co_rec_def fp_sugars;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   265
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   266
          val gmaps = map (fn map0 => Term.list_comb (mk_map live As Bs map0, live_gs)) maps0;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   267
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   268
          val num_rec_args = length rec_arg_Ts;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   269
          val h_Ts = map B_ify rec_arg_Ts;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   270
          val h_names = variant_names num_rec_args "h";
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   271
          val hs = map2 (curry Free) h_names h_Ts;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   272
          val hrecs = map (fn recx => Term.list_comb (Term.map_types B_ify recx, hs)) recs;
56638
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
   273
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   274
          val rec_o_map_lhss = map2 (curry HOLogic.mk_comp) hrecs gmaps;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   275
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   276
          val ABgs = ABs ~~ gs;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   277
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   278
          fun mk_rec_arg_arg (x as Free (_, T)) =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   279
            let val U = B_ify T in
57303
498a62e65f5f tune the implementation of 'rel_coinduct'
desharna
parents: 57151
diff changeset
   280
              if T = U then x else build_map lthy2 [] (the o AList.lookup (op =) ABgs) (T, U) $ x
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   281
            end;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   282
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   283
          fun mk_rec_o_map_arg rec_arg_T h =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   284
            let
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   285
              val x_Ts = binder_types rec_arg_T;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   286
              val m = length x_Ts;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   287
              val x_names = variant_names m "x";
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   288
              val xs = map2 (curry Free) x_names x_Ts;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   289
              val xs' = map mk_rec_arg_arg xs;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   290
            in
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   291
              fold_rev Term.lambda xs (Term.list_comb (h, xs'))
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   292
            end;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   293
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   294
          fun mk_rec_o_map_rhs recx =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   295
            let val args = map2 mk_rec_o_map_arg rec_arg_Ts hs in
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   296
              Term.list_comb (recx, args)
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   297
            end;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   298
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   299
          val rec_o_map_rhss = map mk_rec_o_map_rhs recs;
56638
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
   300
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   301
          val rec_o_map_goals =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   302
            map2 (fold_rev (fold_rev Logic.all) [gs, hs] o HOLogic.mk_Trueprop oo
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   303
              curry HOLogic.mk_eq) rec_o_map_lhss rec_o_map_rhss;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   304
          val rec_o_map_thms =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   305
            map3 (fn goal => fn rec_def => fn ctor_rec_o_map =>
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   306
                Goal.prove lthy2 [] [] goal (fn {context = ctxt, ...} =>
57399
cfc19f0a6261 compile
blanchet
parents: 57397
diff changeset
   307
                  mk_rec_o_map_tac ctxt rec_def pre_map_defs live_nesting_map_ident0s abs_inverses
57395
465ac4021146 repaired BNF 'size' generation tactic for datatypes mixng old- and new-style datatypes on the right-hand side
blanchet
parents: 57303
diff changeset
   308
                    ctor_rec_o_map)
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   309
                |> Thm.close_derivation)
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   310
              rec_o_map_goals rec_defs ctor_rec_o_maps;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   311
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   312
          val size_o_map_conds =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   313
            if exists (can Logic.dest_implies o Thm.prop_of) nested_size_o_maps then
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   314
              map (HOLogic.mk_Trueprop o mk_inj) live_gs
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   315
            else
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   316
              [];
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   317
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   318
          val fsizes = map (fn size_constB => Term.list_comb (size_constB, fsB)) size_constsB;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   319
          val size_o_map_lhss = map2 (curry HOLogic.mk_comp) fsizes gmaps;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   320
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   321
          val fgs = map2 (fn fB => fn g as Free (_, Type (_, [A, B])) =>
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   322
            if A = B then fB else HOLogic.mk_comp (fB, g)) fsB gs;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   323
          val size_o_map_rhss = map (fn c => Term.list_comb (c, fgs)) size_consts;
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   324
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   325
          val size_o_map_goals =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   326
            map2 (fold_rev (fold_rev Logic.all) [fsB, gs] o
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   327
              curry Logic.list_implies size_o_map_conds o HOLogic.mk_Trueprop oo
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   328
              curry HOLogic.mk_eq) size_o_map_lhss size_o_map_rhss;
56966
01637dd1260c more aggressive nested size handling in the absence of 'size_o_map' theorems (+ unrelated pattern matching fix)
blanchet
parents: 56737
diff changeset
   329
01637dd1260c more aggressive nested size handling in the absence of 'size_o_map' theorems (+ unrelated pattern matching fix)
blanchet
parents: 56737
diff changeset
   330
          (* The "size o map" theorem generation will fail if 'nested_size_maps' is incomplete,
01637dd1260c more aggressive nested size handling in the absence of 'size_o_map' theorems (+ unrelated pattern matching fix)
blanchet
parents: 56737
diff changeset
   331
             which occurs when there is recursion through non-datatypes. In this case, we simply
01637dd1260c more aggressive nested size handling in the absence of 'size_o_map' theorems (+ unrelated pattern matching fix)
blanchet
parents: 56737
diff changeset
   332
             avoid generating the theorem. The resulting characteristic lemmas are then expressed
01637dd1260c more aggressive nested size handling in the absence of 'size_o_map' theorems (+ unrelated pattern matching fix)
blanchet
parents: 56737
diff changeset
   333
             in terms of "map", which is not the end of the world. *)
01637dd1260c more aggressive nested size handling in the absence of 'size_o_map' theorems (+ unrelated pattern matching fix)
blanchet
parents: 56737
diff changeset
   334
          val size_o_map_thmss =
01637dd1260c more aggressive nested size handling in the absence of 'size_o_map' theorems (+ unrelated pattern matching fix)
blanchet
parents: 56737
diff changeset
   335
            map3 (fn goal => fn size_def => the_list o try (fn rec_o_map =>
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   336
                Goal.prove lthy2 [] [] goal (fn {context = ctxt, ...} =>
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   337
                  mk_size_o_map_tac ctxt size_def rec_o_map all_inj_maps nested_size_maps)
56966
01637dd1260c more aggressive nested size handling in the absence of 'size_o_map' theorems (+ unrelated pattern matching fix)
blanchet
parents: 56737
diff changeset
   338
                |> Thm.close_derivation))
01637dd1260c more aggressive nested size handling in the absence of 'size_o_map' theorems (+ unrelated pattern matching fix)
blanchet
parents: 56737
diff changeset
   339
              size_o_map_goals size_defs rec_o_map_thms
56640
0a35354137a5 generate 'rec_o_map' and 'size_o_map' in size extension
blanchet
parents: 56639
diff changeset
   340
        in
56966
01637dd1260c more aggressive nested size handling in the absence of 'size_o_map' theorems (+ unrelated pattern matching fix)
blanchet
parents: 56737
diff changeset
   341
          (map single rec_o_map_thms, size_o_map_thmss)
56640
0a35354137a5 generate 'rec_o_map' and 'size_o_map' in size extension
blanchet
parents: 56639
diff changeset
   342
        end;
0a35354137a5 generate 'rec_o_map' and 'size_o_map' in size extension
blanchet
parents: 56639
diff changeset
   343
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   344
    val massage_multi_notes =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   345
      maps (fn (thmN, thmss, attrs) =>
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   346
        map2 (fn T_name => fn thms =>
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   347
            ((Binding.qualify true (Long_Name.base_name T_name) (Binding.name thmN), attrs),
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   348
             [(thms, [])]))
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   349
          T_names thmss)
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   350
      #> filter_out (null o fst o hd o snd);
56638
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
   351
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   352
    val notes =
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   353
      [(rec_o_mapN, rec_o_map_thmss, []),
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   354
       (sizeN, size_thmss, code_nitpicksimp_simp_attrs),
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   355
       (size_o_mapN, size_o_map_thmss, [])]
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   356
      |> massage_multi_notes;
57631
959caab43a3d use the noted theorem whenever possible, also in 'BNF_Def'
blanchet
parents: 57399
diff changeset
   357
959caab43a3d use the noted theorem whenever possible, also in 'BNF_Def'
blanchet
parents: 57399
diff changeset
   358
    val (noted, lthy3) =
959caab43a3d use the noted theorem whenever possible, also in 'BNF_Def'
blanchet
parents: 57399
diff changeset
   359
      lthy2
959caab43a3d use the noted theorem whenever possible, also in 'BNF_Def'
blanchet
parents: 57399
diff changeset
   360
      |> Spec_Rules.add Spec_Rules.Equational (size_consts, size_simps)
959caab43a3d use the noted theorem whenever possible, also in 'BNF_Def'
blanchet
parents: 57399
diff changeset
   361
      |> Local_Theory.notes notes;
959caab43a3d use the noted theorem whenever possible, also in 'BNF_Def'
blanchet
parents: 57399
diff changeset
   362
959caab43a3d use the noted theorem whenever possible, also in 'BNF_Def'
blanchet
parents: 57399
diff changeset
   363
    val phi0 = substitute_noted_thm noted;
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   364
  in
57631
959caab43a3d use the noted theorem whenever possible, also in 'BNF_Def'
blanchet
parents: 57399
diff changeset
   365
    lthy3
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   366
    |> Local_Theory.declaration {syntax = false, pervasive = true}
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   367
      (fn phi => Data.map (fold2 (fn T_name => fn Const (size_name, _) =>
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   368
           Symtab.update (T_name, (size_name,
57631
959caab43a3d use the noted theorem whenever possible, also in 'BNF_Def'
blanchet
parents: 57399
diff changeset
   369
             pairself (map (Morphism.thm (phi0 $> phi))) (size_simps, flat size_o_map_thmss))))
56651
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   370
         T_names size_consts))
fc105315822a localize new size function generation code
blanchet
parents: 56650
diff changeset
   371
  end;
56638
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
   372
092a306bcc3d generate size instances for new-style datatypes
blanchet
parents:
diff changeset
   373
end;