src/HOL/Tools/primrec_package.ML
changeset 8480 50266d517b0c
parent 8432 daf6b3961ed4
child 8973 ac448cd43452
equal deleted inserted replaced
8479:5d327a46dc61 8480:50266d517b0c
     7 *)
     7 *)
     8 
     8 
     9 signature PRIMREC_PACKAGE =
     9 signature PRIMREC_PACKAGE =
    10 sig
    10 sig
    11   val quiet_mode: bool ref
    11   val quiet_mode: bool ref
       
    12   val print_primrecs: theory -> unit
       
    13   val get_primrec: theory -> string -> (string * thm list) list option
    12   val add_primrec: string -> ((bstring * string) * Args.src list) list
    14   val add_primrec: string -> ((bstring * string) * Args.src list) list
    13     -> theory -> theory * thm list
    15     -> theory -> theory * thm list
    14   val add_primrec_i: string -> ((bstring * term) * theory attribute list) list
    16   val add_primrec_i: string -> ((bstring * term) * theory attribute list) list
    15     -> theory -> theory * thm list
    17     -> theory -> theory * thm list
       
    18   val setup: (theory -> theory) list
    16 end;
    19 end;
    17 
    20 
    18 structure PrimrecPackage : PRIMREC_PACKAGE =
    21 structure PrimrecPackage : PRIMREC_PACKAGE =
    19 struct
    22 struct
    20 
    23 
    29 
    32 
    30 (* messages *)
    33 (* messages *)
    31 
    34 
    32 val quiet_mode = ref false;
    35 val quiet_mode = ref false;
    33 fun message s = if ! quiet_mode then () else writeln s;
    36 fun message s = if ! quiet_mode then () else writeln s;
       
    37 
       
    38 
       
    39 (** theory data **)
       
    40 
       
    41 (* data kind 'HOL/primrec' *)
       
    42 
       
    43 structure PrimrecArgs =
       
    44 struct
       
    45   val name = "HOL/primrec";
       
    46   type T = (string * thm list) list Symtab.table;
       
    47 
       
    48   val empty = Symtab.empty;
       
    49   val copy = I;
       
    50   val prep_ext = I;
       
    51   val merge: T * T -> T = Symtab.merge (K true);
       
    52 
       
    53   fun print sg tab =
       
    54     Pretty.writeln (Pretty.strs ("primrecs:" ::
       
    55       map #1 (Sign.cond_extern_table sg Sign.constK tab)));
       
    56 end;
       
    57 
       
    58 structure PrimrecData = TheoryDataFun(PrimrecArgs);
       
    59 val print_primrecs = PrimrecData.print;
       
    60 
       
    61 
       
    62 (* get and put data *)
       
    63 
       
    64 fun get_primrec thy name = Symtab.lookup (PrimrecData.get thy, name);
       
    65 
       
    66 fun put_primrec name info thy =
       
    67   let val tab = PrimrecData.get thy
       
    68   in 
       
    69     PrimrecData.put (case Symtab.lookup (tab, name) of
       
    70        None => Symtab.update_new ((name, [info]), tab)
       
    71      | Some infos => Symtab.update ((name, info::infos), tab)) thy end;
    34 
    72 
    35 
    73 
    36 (* preprocessing of equations *)
    74 (* preprocessing of equations *)
    37 
    75 
    38 fun process_eqn sign (eq, rec_fns) = 
    76 fun process_eqn sign (eq, rec_fns) = 
   255       (if eq_set (names1, names2) then (PureThy.add_defs_i o map Thm.no_attributes) defs'
   293       (if eq_set (names1, names2) then (PureThy.add_defs_i o map Thm.no_attributes) defs'
   256        else primrec_err ("functions " ^ commas_quote names2 ^
   294        else primrec_err ("functions " ^ commas_quote names2 ^
   257          "\nare not mutually recursive"));
   295          "\nare not mutually recursive"));
   258     val rewrites = o_def :: (map mk_meta_eq rec_rewrites) @ defs_thms';
   296     val rewrites = o_def :: (map mk_meta_eq rec_rewrites) @ defs_thms';
   259     val _ = message ("Proving equations for primrec function(s) " ^ commas_quote names1 ^ " ...");
   297     val _ = message ("Proving equations for primrec function(s) " ^ commas_quote names1 ^ " ...");
   260     val char_thms = map (fn (_, t) => prove_goalw_cterm rewrites (cterm_of (Theory.sign_of thy') t)
   298     val simps = map (fn (_, t) => prove_goalw_cterm rewrites (cterm_of (Theory.sign_of thy') t)
   261         (fn _ => [rtac refl 1])) eqns;
   299         (fn _ => [rtac refl 1])) eqns;
   262     val simps = char_thms;
   300     val (thy'', [simps']) = thy'
   263 
   301       |> PureThy.add_thmss [(("simps", simps), [Simplifier.simp_add_global])]
   264     val thy'' =
   302       |>> (#1 o PureThy.add_thms ((map fst eqns ~~ simps) ~~ atts))
   265       thy'
   303       |>> (#1 o PureThy.add_thms [(("induct", prepare_induct (#2 (hd dts)) rec_eqns), [])])
   266       |> (#1 o PureThy.add_thmss [(("simps", simps), [Simplifier.simp_add_global])])
   304       |>> Theory.parent_path
   267       |> (#1 o PureThy.add_thms ((map fst eqns ~~ simps) ~~ atts))
   305   in
   268       |> (#1 o PureThy.add_thms [(("induct", prepare_induct (#2 (hd dts)) rec_eqns), [])])
   306     (foldl (fn (thy, (fname, _, _, tname)) =>
   269       |> Theory.parent_path;
   307        put_primrec fname (tname, simps') thy) (thy'', defs), simps')
   270   in (thy'', char_thms) end;
   308   end;
   271 
   309 
   272 
   310 
   273 fun add_primrec alt_name eqns thy =
   311 fun add_primrec alt_name eqns thy =
   274   let
   312   let
   275     val sign = Theory.sign_of thy;
   313     val sign = Theory.sign_of thy;
   282   in
   320   in
   283     add_primrec_i alt_name (names ~~ eqn_ts' ~~ atts) thy
   321     add_primrec_i alt_name (names ~~ eqn_ts' ~~ atts) thy
   284   end;
   322   end;
   285 
   323 
   286 
   324 
       
   325 (** package setup **)
       
   326 
       
   327 val setup = [PrimrecData.init];
       
   328 
   287 (* outer syntax *)
   329 (* outer syntax *)
   288 
   330 
   289 local structure P = OuterParse and K = OuterSyntax.Keyword in
   331 local structure P = OuterParse and K = OuterSyntax.Keyword in
   290 
   332 
   291 val primrec_decl =
   333 val primrec_decl =