|
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; |