src/Tools/profiling.ML
changeset 78314 1588bec693c2
child 78315 addecc8de2c4
equal deleted inserted replaced
78313:7315ee1deaf3 78314:1588bec693c2
       
     1 (*  Author:     Makarius
       
     2     LICENSE:    Isabelle (BSD-3)
       
     3 
       
     4 Statistics for theory content.
       
     5 *)
       
     6 
       
     7 type theory_statistics =
       
     8  {theory: string,
       
     9   locales: int,
       
    10   locale_thms: int,
       
    11   global_thms: int};
       
    12 
       
    13 type session_statistics =
       
    14  {sizeof_thys_id: int,
       
    15   sizeof_thms_id: int,
       
    16   sizeof_terms: int,
       
    17   sizeof_types: int,
       
    18   sizeof_spaces: int};
       
    19 
       
    20 structure Statistics:
       
    21 sig
       
    22   val locale_names: theory -> string list
       
    23   val locale_thms: theory -> string -> thm list
       
    24   val global_thms: theory -> thm list
       
    25   val all_thms: theory -> thm list
       
    26   val statistics: string list -> theory_statistics list * session_statistics
       
    27   val main: unit -> unit
       
    28 end =
       
    29 struct
       
    30 
       
    31 (* theory content *)
       
    32 
       
    33 fun locale_names thy =
       
    34   let
       
    35     val parent_spaces = map Locale.locale_space (Theory.parents_of thy);
       
    36     fun add name =
       
    37       if exists (fn space => Name_Space.declared space name) parent_spaces then I
       
    38       else cons name;
       
    39   in fold add (Locale.get_locales thy) [] end;
       
    40 
       
    41 fun proper_thm thm = not (Thm.eq_thm_prop (Drule.dummy_thm, thm));
       
    42 
       
    43 fun locale_thms thy loc =
       
    44   (Locale.locale_notes thy loc, []) |->
       
    45     (fold (#2 #> fold (#2 #> (fold (#1 #> fold (fn thm => proper_thm thm ? cons thm ))))));
       
    46 
       
    47 fun global_thms thy =
       
    48   Facts.dest_static true
       
    49     (map Global_Theory.facts_of (Theory.parents_of thy)) (Global_Theory.facts_of thy)
       
    50   |> maps #2;
       
    51 
       
    52 fun all_thms thy =
       
    53   let val locales = locale_names thy
       
    54   in maps (locale_thms thy) locales @ global_thms thy end;
       
    55 
       
    56 
       
    57 (* session content *)
       
    58 
       
    59 fun theories_content thys =
       
    60   let
       
    61     val thms = maps all_thms thys;
       
    62     val thys_id = map Context.theory_id thys;
       
    63     val thms_id = map Thm.theory_id thms;
       
    64     val terms = (fold o Thm.fold_terms {hyps = true}) cons thms [];
       
    65     val types = (fold o fold_types) cons terms [];
       
    66     val spaces =
       
    67       maps (fn f => map f thys)
       
    68        [Sign.class_space,
       
    69         Sign.type_space,
       
    70         Sign.const_space,
       
    71         Theory.axiom_space,
       
    72         Thm.oracle_space,
       
    73         Global_Theory.fact_space,
       
    74         Locale.locale_space,
       
    75         Attrib.attribute_space o Context.Theory,
       
    76         Method.method_space o Context.Theory];
       
    77   in {thys_id = thys_id, thms_id = thms_id, terms = terms, types = types, spaces = spaces} end;
       
    78 
       
    79 fun sizeof_diff (a, b) = ML_Heap.sizeof a - ML_Heap.sizeof b;
       
    80 
       
    81 
       
    82 (* collect statistics *)
       
    83 
       
    84 fun theory_statistics thy : theory_statistics =
       
    85   let
       
    86     val locales = locale_names thy;
       
    87   in
       
    88    {theory = Context.theory_long_name thy,
       
    89     locales = length locales,
       
    90     locale_thms = length (maps (locale_thms thy) locales),
       
    91     global_thms = length (global_thms thy)}
       
    92   end;
       
    93 
       
    94 fun statistics theories =
       
    95   let
       
    96     val theories_member = Symtab.defined (Symtab.make_set theories) o Context.theory_long_name;
       
    97 
       
    98     val context_thys =
       
    99       #contexts (Context.finish_tracing ())
       
   100       |> map_filter (fn (Context.Theory thy, _) => SOME thy | _ => NONE);
       
   101 
       
   102     val loader_thys = map Thy_Info.get_theory (Thy_Info.get_names ());
       
   103     val loaded_thys = filter theories_member loader_thys;
       
   104 
       
   105     val all_thys = loader_thys @ context_thys;
       
   106     val base_thys = filter theories_member all_thys;
       
   107 
       
   108     val {thys_id = all_thys_id, thms_id = all_thms_id, terms = all_terms,
       
   109           types = all_types, spaces = all_spaces} = theories_content all_thys;
       
   110     val {thys_id = base_thys_id, thms_id = base_thms_id, terms = base_terms,
       
   111           types = base_types, spaces = base_spaces} = theories_content base_thys;
       
   112     val session_statistics =
       
   113       {sizeof_thys_id = sizeof_diff (all_thys_id, base_thys_id),
       
   114        sizeof_thms_id = sizeof_diff (all_thms_id, base_thms_id),
       
   115        sizeof_terms = sizeof_diff (all_terms, base_terms),
       
   116        sizeof_types = sizeof_diff (all_types, base_types),
       
   117        sizeof_spaces = sizeof_diff (all_spaces, base_spaces)};
       
   118   in (map theory_statistics loaded_thys, session_statistics) end;
       
   119 
       
   120 
       
   121 (* main entry point for "isabelle process" *)
       
   122 
       
   123 local
       
   124 
       
   125 val decode_args : string list XML.Decode.T =
       
   126   let open XML.Decode in list string end;
       
   127 
       
   128 val encode_theories_result : theory_statistics list XML.Encode.T =
       
   129   map (fn {theory = a, locales = b, locale_thms = c, global_thms = d} => (a, (b, (c, d))))
       
   130   #> let open XML.Encode in list (pair string (pair int (pair int int))) end;
       
   131 
       
   132 val encode_session_result : session_statistics XML.Encode.T =
       
   133   (fn {sizeof_thys_id = a,
       
   134        sizeof_thms_id = b,
       
   135        sizeof_terms = c,
       
   136        sizeof_types = d,
       
   137        sizeof_spaces = e} => (a, (b, (c, (d, e)))))
       
   138   #> let open XML.Encode in pair int (pair int (pair int (pair int int))) end;
       
   139 
       
   140 val encode_result = let open XML.Encode in pair encode_theories_result encode_session_result end;
       
   141 
       
   142 in
       
   143 
       
   144 fun main () =
       
   145   (case getenv "AUTOCORRES_STATISTICS" of
       
   146     "" => ()
       
   147   | dir_name =>
       
   148       let
       
   149         val dir = Path.explode dir_name;
       
   150         val args = decode_args (YXML.parse_body (File.read (dir + \<^path>\<open>args.yxml\<close>)));
       
   151         val result = statistics args;
       
   152       in File.write (dir + \<^path>\<open>result.yxml\<close>) (YXML.string_of_body (encode_result result)) end);
       
   153 
       
   154 end;
       
   155 
       
   156 end;