16 val use_thy: string -> unit |
16 val use_thy: string -> unit |
17 val update_thy: string -> unit |
17 val update_thy: string -> unit |
18 val remove_thy: string -> unit |
18 val remove_thy: string -> unit |
19 val time_use_thy: string -> unit |
19 val time_use_thy: string -> unit |
20 val use_thy_only: string -> unit |
20 val use_thy_only: string -> unit |
|
21 val update_thy_only: string -> unit |
21 end; |
22 end; |
22 |
23 |
23 signature THY_INFO = |
24 signature THY_INFO = |
24 sig |
25 sig |
25 include BASIC_THY_INFO |
26 include BASIC_THY_INFO |
|
27 datatype action = Update | Outdate | Remove |
|
28 val str_of_action: action -> string |
|
29 val add_hook: (action -> string -> unit) -> unit |
26 val names: unit -> string list |
30 val names: unit -> string list |
27 val get_theory: string -> theory |
31 val get_theory: string -> theory |
28 val put_theory: theory -> unit |
|
29 val get_preds: string -> string list |
32 val get_preds: string -> string list |
30 val loaded_files: string -> (Path.T * File.info) list |
33 val loaded_files: string -> (Path.T * File.info) list |
|
34 val touch_all_thys: unit -> unit |
31 val load_file: bool -> Path.T -> unit |
35 val load_file: bool -> Path.T -> unit |
32 val use_path: Path.T -> unit |
36 val use_path: Path.T -> unit |
33 val use: string -> unit |
37 val use: string -> unit |
34 val begin_theory: string -> string list -> (Path.T * bool) list -> theory |
38 val begin_theory: string -> string list -> (Path.T * bool) list -> theory |
35 val end_theory: theory -> theory |
39 val end_theory: theory -> theory |
128 | _ => error (loader_msg "undefined theory entry for" [name])); |
146 | _ => error (loader_msg "undefined theory entry for" [name])); |
129 |
147 |
130 val theory_of_sign = get_theory o Sign.name_of; |
148 val theory_of_sign = get_theory o Sign.name_of; |
131 val theory_of_thm = theory_of_sign o Thm.sign_of_thm; |
149 val theory_of_thm = theory_of_sign o Thm.sign_of_thm; |
132 |
150 |
133 fun put_theory theory = |
151 fun put_theory name theory = change_thy name (fn (deps, _) => (deps, Some theory)); |
134 change_thy (PureThy.get_name theory) (fn (deps, _) => (deps, Some theory)); |
|
135 |
152 |
136 |
153 |
137 |
154 |
138 (** thy operations **) |
155 (** thy operations **) |
139 |
156 |
140 (* maintain 'outdated' flag *) |
157 (* maintain 'outdated' flag *) |
|
158 |
|
159 local |
141 |
160 |
142 fun is_outdated name = |
161 fun is_outdated name = |
143 (case lookup_deps name of |
162 (case lookup_deps name of |
144 Some (Some {outdated, ...}) => outdated |
163 Some (Some {outdated, ...}) => outdated |
145 | _ => false); |
164 | _ => false); |
146 |
165 |
147 fun outdate_thy name = |
166 fun outdate_thy name = |
148 if is_finished name then () |
167 if is_finished name orelse is_outdated name then () |
149 else change_deps name (apsome (fn {present, outdated = _, master, files} => |
168 else (change_deps name (apsome (fn {present, outdated = _, master, files} => |
150 make_deps present true master files)); |
169 make_deps present true master files)); perform Outdate name); |
|
170 |
|
171 in |
151 |
172 |
152 fun touch_thy name = |
173 fun touch_thy name = |
153 if is_outdated name then () |
174 if is_finished name then warning (loader_msg "tried to touch finished theory" [name]) |
154 else if is_finished name then warning (loader_msg "tried to touch finished theory" [name]) |
175 else seq outdate_thy (thy_graph Graph.all_succs [name]); |
155 else |
176 |
156 (case filter_out is_outdated (thy_graph Graph.all_succs [name]) \ name of |
177 fun touch_all_thys () = seq outdate_thy (get_names ()); |
157 [] => outdate_thy name |
178 |
158 | names => |
179 end; |
159 (warning (loader_msg "the following theories become out-of-date:" names); |
|
160 seq outdate_thy names; outdate_thy name)); |
|
161 |
|
162 val untouch_deps = apsome (fn {present, outdated = _, master, files}: deps => |
|
163 make_deps present false master files); |
|
164 |
|
165 |
|
166 (* load_thy *) |
|
167 |
|
168 fun required_by [] = "" |
|
169 | required_by initiators = " (required by " ^ show_path (rev initiators) ^ ")"; |
|
170 |
|
171 fun load_thy ml time initiators dir name parents = |
|
172 let |
|
173 val _ = if name mem_string initiators then error (cycle_msg name (rev initiators)) else (); |
|
174 val _ = writeln ("Loading theory " ^ quote name ^ required_by initiators); |
|
175 |
|
176 val _ = seq touch_thy (thy_graph Graph.all_succs [name]); |
|
177 val master = ThyLoad.load_thy dir name ml time; |
|
178 |
|
179 val files = get_files name; |
|
180 val missing_files = mapfilter (fn (path, None) => Some (Path.pack path) | _ => None) files; |
|
181 in |
|
182 if null missing_files then () |
|
183 else warning (loader_msg "unresolved dependencies of theory" [name] ^ |
|
184 "\nfile(s): " ^ commas_quote missing_files); |
|
185 change_deps name (fn _ => Some (make_deps true false master files)) |
|
186 end; |
|
187 |
180 |
188 |
181 |
189 (* load_file *) |
182 (* load_file *) |
190 |
183 |
191 fun run_file path = |
184 fun run_file path = |
216 val use_path = load_file false; |
209 val use_path = load_file false; |
217 val use = use_path o Path.unpack; |
210 val use = use_path o Path.unpack; |
218 val time_use = load_file true o Path.unpack; |
211 val time_use = load_file true o Path.unpack; |
219 |
212 |
220 |
213 |
|
214 (* load_thy *) |
|
215 |
|
216 fun required_by [] = "" |
|
217 | required_by initiators = " (required by " ^ show_path (rev initiators) ^ ")"; |
|
218 |
|
219 fun load_thy ml time initiators dir name parents = |
|
220 let |
|
221 val _ = if name mem_string initiators then error (cycle_msg name (rev initiators)) else (); |
|
222 val _ = writeln ("Loading theory " ^ quote name ^ required_by initiators); |
|
223 |
|
224 val _ = touch_thy name; |
|
225 val master = ThyLoad.load_thy dir name ml time; |
|
226 |
|
227 val files = get_files name; |
|
228 val missing_files = mapfilter (fn (path, None) => Some (Path.pack path) | _ => None) files; |
|
229 in |
|
230 if null missing_files then () |
|
231 else warning (loader_msg "unresolved dependencies of theory" [name] ^ |
|
232 "\nfile(s): " ^ commas_quote missing_files); |
|
233 change_deps name (fn _ => Some (make_deps true false master files)); |
|
234 perform Update name |
|
235 end; |
|
236 |
|
237 |
221 (* require_thy *) |
238 (* require_thy *) |
222 |
239 |
223 fun init_deps master files = Some (make_deps false false master (map (rpair None) files)); |
240 fun init_deps master files = Some (make_deps false true master (map (rpair None) files)); |
224 |
241 |
225 fun load_deps dir name ml = |
242 fun load_deps dir name ml = |
226 let val (master, (parents, files)) = ThyLoad.deps_thy dir name ml |
243 let val (master, (parents, files)) = ThyLoad.deps_thy dir name ml |
227 in (Some (init_deps master files), parents) end; |
244 in (Some (init_deps master files), parents) end; |
228 |
245 |
256 val dir = Path.append prfx (Path.dir path); |
273 val dir = Path.append prfx (Path.dir path); |
257 val req_parent = |
274 val req_parent = |
258 require_thy ml time (strict andalso keep_strict) keep_strict (name :: initiators) dir; |
275 require_thy ml time (strict andalso keep_strict) keep_strict (name :: initiators) dir; |
259 |
276 |
260 val (current, (new_deps, parents)) = current_deps ml strict dir name handle ERROR => |
277 val (current, (new_deps, parents)) = current_deps ml strict dir name handle ERROR => |
261 error (loader_msg "The error(s) above occurred while examining theory" [name] ^ |
278 error (loader_msg "the error(s) above occurred while examining theory" [name] ^ |
262 (if null initiators then "" else "\n" ^ required_by initiators)); |
279 (if null initiators then "" else "\n" ^ required_by initiators)); |
263 val (visited', parent_results) = foldl_map req_parent (name :: visited, parents); |
280 val (visited', parent_results) = foldl_map req_parent (name :: visited, parents); |
264 |
281 |
265 val result = |
282 val result = |
266 if current andalso forall #1 parent_results then true |
283 if current andalso forall #1 parent_results then true |
267 else |
284 else |
268 ((case new_deps of |
285 ((case new_deps of |
269 Some deps => change_thys (update_node name parents (untouch_deps deps, None)) |
286 Some deps => change_thys (update_node name parents (deps, None)) |
270 | None => ()); |
287 | None => ()); |
271 load_thy ml time initiators dir name parents; |
288 load_thy ml time initiators dir name parents; |
272 false); |
289 false); |
273 in (visited', (result, name)) end |
290 in (visited', (result, name)) end |
274 end; |
291 end; |
275 |
292 |
276 fun gen_use_thy req s = |
293 fun gen_use_thy req s = |
277 let val (_, (_, name)) = req [] Path.current ([], s) |
294 let val (_, (_, name)) = req [] Path.current ([], s) |
278 in Context.context (get_theory name) end; |
295 in Context.context (get_theory name) end; |
279 |
296 |
280 val weak_use_thy = gen_use_thy (require_thy true false false false); |
297 val weak_use_thy = gen_use_thy (require_thy true false false false); |
281 val use_thy = gen_use_thy (require_thy true false true false); |
298 val use_thy = gen_use_thy (require_thy true false true false); |
282 val update_thy = gen_use_thy (require_thy true false true true); |
299 val time_use_thy = gen_use_thy (require_thy true true true false); |
283 val time_use_thy = gen_use_thy (require_thy true true true false); |
300 val use_thy_only = gen_use_thy (require_thy false false true false); |
284 val use_thy_only = gen_use_thy (require_thy false false true false); |
301 val update_thy = gen_use_thy (require_thy true false true true); |
|
302 val update_thy_only = gen_use_thy (require_thy false false true true); |
285 |
303 |
286 |
304 |
287 (* remove_thy *) |
305 (* remove_thy *) |
288 |
306 |
289 fun remove_thy name = |
307 fun remove_thy name = |
290 if is_finished name then error (loader_msg "cannot remove finished theory" [name]) |
308 if is_finished name then error (loader_msg "cannot remove finished theory" [name]) |
291 else |
309 else |
292 let val succs = thy_graph Graph.all_succs [name] in |
310 let val succs = thy_graph Graph.all_succs [name] in |
293 writeln (loader_msg "removing" succs); |
311 writeln (loader_msg "removing" succs); |
294 change_thys (Graph.del_nodes succs) |
312 change_thys (Graph.del_nodes succs); |
|
313 seq (perform Remove) succs |
295 end; |
314 end; |
296 |
315 |
297 |
316 |
298 (* begin / end theory *) |
317 (* begin / end theory *) |
299 |
318 |
308 val _ = change_thys (update_node name parents (init_deps [] [], Some theory)); |
327 val _ = change_thys (update_node name parents (init_deps [] [], Some theory)); |
309 val use_paths = mapfilter (fn (x, true) => Some x | _ => None) paths; |
328 val use_paths = mapfilter (fn (x, true) => Some x | _ => None) paths; |
310 in Context.setmp (Some theory) (seq use_path) use_paths; theory end; |
329 in Context.setmp (Some theory) (seq use_path) use_paths; theory end; |
311 |
330 |
312 fun end_theory theory = |
331 fun end_theory theory = |
313 let val theory' = PureThy.end_theory theory |
332 let |
314 in put_theory theory'; theory' end; |
333 val theory' = PureThy.end_theory theory; |
|
334 val name = PureThy.get_name theory; |
|
335 in put_theory name theory'; theory' end; |
315 |
336 |
316 |
337 |
317 (* finish all theories *) |
338 (* finish all theories *) |
318 |
339 |
319 fun finish () = change_thys (Graph.map_nodes (fn (_, entry) => (None, entry))); |
340 fun finish () = change_thys (Graph.map_nodes (fn (_, entry) => (None, entry))); |
341 handle Graph.DUPLICATE _ => err "duplicate theory entry" []) |
362 handle Graph.DUPLICATE _ => err "duplicate theory entry" []) |
342 |> add_deps name parent_names; |
363 |> add_deps name parent_names; |
343 in |
364 in |
344 if not (null nonfinished) then err "non-finished parent theories" nonfinished |
365 if not (null nonfinished) then err "non-finished parent theories" nonfinished |
345 else if not (null variants) then err "different versions of parent theories" variants |
366 else if not (null variants) then err "different versions of parent theories" variants |
346 else change_thys register |
367 else (change_thys register; perform Update name) |
347 end; |
368 end; |
348 |
369 |
349 |
370 |
350 (*final declarations of this structure*) |
371 (*final declarations of this structure*) |
351 val theory = get_theory; |
372 val theory = get_theory; |