src/HOL/Tools/BNF/bnf_lfp_size.ML
changeset 61786 6c42d55097c1
parent 61760 1647bb489522
child 62082 614ef6d7a6b6
equal deleted inserted replaced
61785:7a461602a218 61786:6c42d55097c1
    28 val size_neqN = "size_neq";
    28 val size_neqN = "size_neq";
    29 
    29 
    30 val nitpicksimp_attrs = @{attributes [nitpick_simp]};
    30 val nitpicksimp_attrs = @{attributes [nitpick_simp]};
    31 val simp_attrs = @{attributes [simp]};
    31 val simp_attrs = @{attributes [simp]};
    32 
    32 
       
    33 fun mk_plus_nat (t1, t2) = Const (@{const_name Groups.plus},
       
    34   HOLogic.natT --> HOLogic.natT --> HOLogic.natT) $ t1 $ t2;
       
    35 
       
    36 fun mk_to_natT T = T --> HOLogic.natT;
       
    37 
       
    38 fun mk_abs_zero_nat T = Term.absdummy T HOLogic.zero;
       
    39 
       
    40 fun mk_pointful ctxt thm = unfold_thms ctxt [o_apply] (thm RS fun_cong);
       
    41 
       
    42 fun mk_unabs_def_unused_0 n =
       
    43   funpow n (fn thm => thm RS @{thm fun_cong_unused_0} handle THM _ => thm RS fun_cong);
       
    44 
    33 structure Data = Generic_Data
    45 structure Data = Generic_Data
    34 (
    46 (
    35   type T = (string * (thm list * thm list)) Symtab.table;
    47   type T = (string * (thm list * thm list)) Symtab.table;
    36   val empty = Symtab.empty;
    48   val empty = Symtab.empty;
    37   val extend = I
    49   val extend = I
    38   fun merge data = Symtab.merge (K true) data;
    50   fun merge data = Symtab.merge (K true) data;
    39 );
    51 );
    40 
    52 
    41 fun register_size T_name size_name size_simps size_gen_o_maps =
    53 fun check_size_type thy T_name size_name =
    42   Context.proof_map (Data.map (Symtab.update (T_name, (size_name, (size_simps, size_gen_o_maps)))));
    54   let
    43 
    55     val n = Sign.arity_number thy T_name;
    44 fun register_size_global T_name size_name size_simps size_gen_o_maps =
    56     val As = map (fn s => TFree (s, @{sort type})) (Name.invent Name.context Name.aT n);
    45   Context.theory_map
    57     val T = Type (T_name, As);
    46     (Data.map (Symtab.update (T_name, (size_name, (size_simps, size_gen_o_maps)))));
    58     val size_T = map mk_to_natT As ---> mk_to_natT T;
       
    59     val size_const = Const (size_name, size_T);
       
    60   in
       
    61     can (Thm.global_cterm_of thy) size_const orelse
       
    62     error ("Constant " ^ quote size_name ^ " registered as size function for " ^ quote T_name ^
       
    63       " must have type\n" ^ quote (Syntax.string_of_typ_global thy size_T))
       
    64   end;
       
    65 
       
    66 fun register_size T_name size_name size_simps size_gen_o_maps lthy =
       
    67   (check_size_type (Proof_Context.theory_of lthy) T_name size_name;
       
    68    Context.proof_map (Data.map (Symtab.update (T_name, (size_name, (size_simps, size_gen_o_maps)))))
       
    69      lthy);
       
    70 
       
    71 fun register_size_global T_name size_name size_simps size_gen_o_maps thy =
       
    72   (check_size_type thy T_name size_name;
       
    73    Context.theory_map (Data.map (Symtab.update (T_name, (size_name, (size_simps,
       
    74      size_gen_o_maps))))) thy);
    47 
    75 
    48 val size_of = Symtab.lookup o Data.get o Context.Proof;
    76 val size_of = Symtab.lookup o Data.get o Context.Proof;
    49 val size_of_global = Symtab.lookup o Data.get o Context.Theory;
    77 val size_of_global = Symtab.lookup o Data.get o Context.Theory;
    50 
       
    51 fun mk_plus_nat (t1, t2) = Const (@{const_name Groups.plus},
       
    52   HOLogic.natT --> HOLogic.natT --> HOLogic.natT) $ t1 $ t2;
       
    53 
       
    54 fun mk_to_natT T = T --> HOLogic.natT;
       
    55 
       
    56 fun mk_abs_zero_nat T = Term.absdummy T HOLogic.zero;
       
    57 
       
    58 fun mk_pointful ctxt thm = unfold_thms ctxt [o_apply] (thm RS fun_cong);
       
    59 
       
    60 fun mk_unabs_def_unused_0 n =
       
    61   funpow n (fn thm => thm RS @{thm fun_cong_unused_0} handle THM _ => thm RS fun_cong);
       
    62 
    78 
    63 val size_gen_o_map_simps = @{thms inj_on_id snd_comp_apfst[unfolded apfst_def]};
    79 val size_gen_o_map_simps = @{thms inj_on_id snd_comp_apfst[unfolded apfst_def]};
    64 
    80 
    65 fun mk_size_gen_o_map_tac ctxt size_def rec_o_map inj_maps size_maps =
    81 fun mk_size_gen_o_map_tac ctxt size_def rec_o_map inj_maps size_maps =
    66   unfold_thms_tac ctxt [size_def] THEN
    82   unfold_thms_tac ctxt [size_def] THEN
   123           else if exists (exists_subtype_in (As @ Cs)) Ts then
   139           else if exists (exists_subtype_in (As @ Cs)) Ts then
   124             (case Symtab.lookup data s of
   140             (case Symtab.lookup data s of
   125               SOME (size_name, (_, size_gen_o_maps)) =>
   141               SOME (size_name, (_, size_gen_o_maps)) =>
   126               let
   142               let
   127                 val (args, size_gen_o_mapss') = fold_map mk_size_of_typ Ts [];
   143                 val (args, size_gen_o_mapss') = fold_map mk_size_of_typ Ts [];
   128                 val size_const = Const (size_name, map fastype_of args ---> mk_to_natT T);
   144                 val size_T = map fastype_of args ---> mk_to_natT T;
       
   145                 val size_const = Const (size_name, size_T);
   129               in
   146               in
   130                 append (size_gen_o_maps :: size_gen_o_mapss')
   147                 append (size_gen_o_maps :: size_gen_o_mapss')
   131                 #> pair (Term.list_comb (size_const, args))
   148                 #> pair (Term.list_comb (size_const, args))
   132               end
   149               end
   133             | _ => pair (mk_abs_zero_nat T))
   150             | _ => pair (mk_abs_zero_nat T))