69 ThyInfo {path = "", |
70 ThyInfo {path = "", |
70 children = ["Pure", "CPure"], |
71 children = ["Pure", "CPure"], |
71 thy_time = Some "", ml_time = Some "", |
72 thy_time = Some "", ml_time = Some "", |
72 theory = Some proto_pure_thy, |
73 theory = Some proto_pure_thy, |
73 thms = Symtab.null, |
74 thms = Symtab.null, |
74 thy_simps = [], ml_simps = []}), |
75 thy_ss = None, simpset = None}), |
75 ("Pure", ThyInfo {path = "", children = [], |
76 ("Pure", ThyInfo {path = "", children = [], |
76 thy_time = Some "", ml_time = Some "", |
77 thy_time = Some "", ml_time = Some "", |
77 theory = Some pure_thy, |
78 theory = Some pure_thy, |
78 thms = Symtab.null, |
79 thms = Symtab.null, |
79 thy_simps = [], ml_simps = []}), |
80 thy_ss = None, simpset = None}), |
80 ("CPure", ThyInfo {path = "", |
81 ("CPure", ThyInfo {path = "", |
81 children = [], |
82 children = [], |
82 thy_time = Some "", ml_time = Some "", |
83 thy_time = Some "", ml_time = Some "", |
83 theory = Some cpure_thy, |
84 theory = Some cpure_thy, |
84 thms = Symtab.null, |
85 thms = Symtab.null, |
85 thy_simps = [], ml_simps = []})]); |
86 thy_ss = None, simpset = None}) |
|
87 ]); |
86 |
88 |
87 val loadpath = ref ["."]; (*default search path for theory files *) |
89 val loadpath = ref ["."]; (*default search path for theory files *) |
88 |
90 |
89 val delete_tmpfiles = ref true; (*remove temporary files after use *) |
91 val delete_tmpfiles = ref true; (*remove temporary files after use *) |
90 |
92 |
211 end; |
218 end; |
212 |
219 |
213 (*Remove theory from all child lists in loaded_thys *) |
220 (*Remove theory from all child lists in loaded_thys *) |
214 fun unlink_thy tname = |
221 fun unlink_thy tname = |
215 let fun remove (ThyInfo {path, children, thy_time, ml_time, theory, thms, |
222 let fun remove (ThyInfo {path, children, thy_time, ml_time, theory, thms, |
216 thy_simps, ml_simps}) = |
223 thy_ss, simpset}) = |
217 ThyInfo {path = path, children = children \ tname, |
224 ThyInfo {path = path, children = children \ tname, |
218 thy_time = thy_time, ml_time = ml_time, theory = theory, |
225 thy_time = thy_time, ml_time = ml_time, theory = theory, |
219 thms = thms, thy_simps = thy_simps, ml_simps = ml_simps} |
226 thms = thms, thy_ss = thy_ss, simpset = simpset} |
220 in loaded_thys := Symtab.map remove (!loaded_thys) end; |
227 in loaded_thys := Symtab.map remove (!loaded_thys) end; |
221 |
228 |
222 (*Remove a theory from loaded_thys *) |
229 (*Remove a theory from loaded_thys *) |
223 fun remove_thy tname = |
230 fun remove_thy tname = |
224 loaded_thys := Symtab.make (filter_out (fn (id, _) => id = tname) |
231 loaded_thys := Symtab.make (filter_out (fn (id, _) => id = tname) |
225 (Symtab.dest (!loaded_thys))); |
232 (Symtab.dest (!loaded_thys))); |
226 |
233 |
227 (*Change thy_time and ml_time for an existent item *) |
234 (*Change thy_time and ml_time for an existent item *) |
228 fun set_info thy_time ml_time tname = |
235 fun set_info tname thy_time ml_time = |
229 let val ThyInfo {path, children, theory, thms, thy_simps, ml_simps, ...} = |
236 let val tinfo = case Symtab.lookup (!loaded_thys, tname) of |
230 the (Symtab.lookup (!loaded_thys, tname)); |
237 Some (ThyInfo {path, children, theory, thms, thy_ss, simpset,...}) => |
231 in loaded_thys := Symtab.update |
238 ThyInfo {path = path, children = children, |
232 ((tname, |
239 thy_time = thy_time, ml_time = ml_time, |
233 ThyInfo {path = path, children = children, thy_time = thy_time, |
240 theory = theory, thms = thms, |
234 ml_time = ml_time, theory = theory, thms = thms, |
241 thy_ss = thy_ss, simpset = simpset} |
235 thy_simps = thy_simps, ml_simps = ml_simps}), |
242 | None => ThyInfo {path = "", children = [], |
236 !loaded_thys) |
243 thy_time = thy_time, ml_time = ml_time, |
|
244 theory = None, thms = Symtab.null, |
|
245 thy_ss = None, simpset = None}; |
|
246 in loaded_thys := Symtab.update ((tname, tinfo), !loaded_thys) |
237 end; |
247 end; |
238 |
248 |
239 (*Mark theory as changed since last read if it has been completly read *) |
249 (*Mark theory as changed since last read if it has been completly read *) |
240 fun mark_outdated tname = |
250 fun mark_outdated tname = |
241 let val t = get_thyinfo tname; |
251 let val t = get_thyinfo tname; |
242 in if is_none t then () |
252 in if is_none t then () |
243 else let val ThyInfo {thy_time, ml_time, ...} = the t |
253 else let val ThyInfo {thy_time, ml_time, ...} = the t |
244 in set_info (if is_none thy_time then None else Some "") |
254 in set_info tname |
|
255 (if is_none thy_time then None else Some "") |
245 (if is_none ml_time then None else Some "") |
256 (if is_none ml_time then None else Some "") |
246 tname |
257 |
247 end |
258 end |
248 end; |
259 end; |
249 |
260 |
250 (*Read .thy and .ML files that haven't been read yet or have changed since |
261 (*Read .thy and .ML files that haven't been read yet or have changed since |
251 they were last read; |
262 they were last read; |
257 val (path, tname) = split_filename name; |
268 val (path, tname) = split_filename name; |
258 val (thy_file, ml_file) = get_filenames path tname; |
269 val (thy_file, ml_file) = get_filenames path tname; |
259 val (abs_path, _) = if thy_file = "" then split_filename ml_file |
270 val (abs_path, _) = if thy_file = "" then split_filename ml_file |
260 else split_filename thy_file; |
271 else split_filename thy_file; |
261 val (thy_uptodate, ml_uptodate) = thy_unchanged tname thy_file ml_file; |
272 val (thy_uptodate, ml_uptodate) = thy_unchanged tname thy_file ml_file; |
262 val (thy_simps, ml_simps) = get_simps tname; |
|
263 val old_simps = ref []; |
|
264 |
273 |
265 (*Set absolute path for loaded theory *) |
274 (*Set absolute path for loaded theory *) |
266 fun set_path () = |
275 fun set_path () = |
267 let val ThyInfo {children, thy_time, ml_time, theory, thms, |
276 let val ThyInfo {children, thy_time, ml_time, theory, thms, thy_ss, |
268 thy_simps, ml_simps, ...} = |
277 simpset, ...} = |
269 the (Symtab.lookup (!loaded_thys, tname)); |
278 the (Symtab.lookup (!loaded_thys, tname)); |
270 in loaded_thys := Symtab.update ((tname, |
279 in loaded_thys := Symtab.update ((tname, |
271 ThyInfo {path = abs_path, children = children, |
280 ThyInfo {path = abs_path, children = children, |
272 thy_time = thy_time, ml_time = ml_time, |
281 thy_time = thy_time, ml_time = ml_time, |
273 theory = theory, thms = thms, |
282 theory = theory, thms = thms, |
274 thy_simps = thy_simps, |
283 thy_ss = thy_ss, simpset = simpset}), |
275 ml_simps = ml_simps}), |
|
276 !loaded_thys) |
284 !loaded_thys) |
277 end; |
285 end; |
278 |
286 |
279 (*Mark all direct descendants of a theory as changed *) |
287 (*Mark all direct descendants of a theory as changed *) |
280 fun mark_children thy = |
288 fun mark_children thy = |
291 |
299 |
292 (*Remove theorems associated with a theory*) |
300 (*Remove theorems associated with a theory*) |
293 fun delete_thms () = |
301 fun delete_thms () = |
294 let |
302 let |
295 val tinfo = case get_thyinfo tname of |
303 val tinfo = case get_thyinfo tname of |
296 Some (ThyInfo {path, children, thy_time, ml_time, theory, |
304 Some (ThyInfo {path, children, thy_time, ml_time, theory, thy_ss, |
297 thy_simps, ml_simps, ...}) => |
305 simpset, ...}) => |
298 ThyInfo {path = path, children = children, |
306 ThyInfo {path = path, children = children, |
299 thy_time = thy_time, ml_time = ml_time, |
307 thy_time = thy_time, ml_time = ml_time, |
300 theory = theory, thms = Symtab.null, |
308 theory = theory, thms = Symtab.null, |
301 thy_simps = thy_simps, ml_simps = ml_simps} |
309 thy_ss = thy_ss, simpset = simpset} |
302 | None => ThyInfo {path = "", children = [], |
310 | None => ThyInfo {path = "", children = [], |
303 thy_time = None, ml_time = None, |
311 thy_time = None, ml_time = None, |
304 theory = None, thms = Symtab.null, |
312 theory = None, thms = Symtab.null, |
305 thy_simps = [], ml_simps = []}; |
313 thy_ss = None, simpset = None}; |
306 in loaded_thys := Symtab.update ((tname, tinfo), !loaded_thys) end; |
314 |
307 |
315 val ThyInfo {theory, ...} = tinfo; |
308 fun update_simps (new_thy_simps, new_ml_simps) = |
316 in loaded_thys := Symtab.update ((tname, tinfo), !loaded_thys); |
|
317 case theory of |
|
318 Some t => delete_thm_db t |
|
319 | None => () |
|
320 end; |
|
321 |
|
322 fun save_thy_ss () = |
309 let val ThyInfo {path, children, thy_time, ml_time, theory, thms, |
323 let val ThyInfo {path, children, thy_time, ml_time, theory, thms, |
310 thy_simps, ml_simps} = the (get_thyinfo tname); |
324 simpset, ...} = the (get_thyinfo tname); |
311 |
325 in loaded_thys := Symtab.update |
312 val (thy_simps', ml_simps') = |
326 ((tname, ThyInfo {path = path, children = children, |
313 (if is_none new_thy_simps then thy_simps else the new_thy_simps, |
327 thy_time = thy_time, ml_time = ml_time, |
314 if is_none new_ml_simps then ml_simps else the new_ml_simps); |
328 theory = theory, thms = thms, |
315 in loaded_thys := Symtab.update ((tname, |
329 thy_ss = Some (!Simplifier.simpset), |
316 ThyInfo {path = path, children = children, |
330 simpset = simpset}), |
317 thy_time = thy_time, ml_time = ml_time, theory = theory, |
331 !loaded_thys) |
318 thms = thms, thy_simps = thy_simps', |
332 end; |
319 ml_simps = ml_simps'}), !loaded_thys) |
333 |
|
334 fun save_simpset () = |
|
335 let val ThyInfo {path, children, thy_time, ml_time, theory, thms, |
|
336 thy_ss, ...} = the (get_thyinfo tname); |
|
337 in loaded_thys := Symtab.update |
|
338 ((tname, ThyInfo {path = path, children = children, |
|
339 thy_time = thy_time, ml_time = ml_time, |
|
340 theory = theory, thms = thms, |
|
341 thy_ss = thy_ss, |
|
342 simpset = Some (!Simplifier.simpset)}), |
|
343 !loaded_thys) |
320 end; |
344 end; |
321 |
345 |
322 in if thy_uptodate andalso ml_uptodate then () |
346 in if thy_uptodate andalso ml_uptodate then () |
323 else |
347 else |
324 ( |
348 ( |
325 delete_thms (); |
349 if thy_file = "" then () |
326 |
350 else if thy_uptodate then |
327 if thy_uptodate orelse thy_file = "" then |
351 simpset := let val ThyInfo {thy_ss, ...} = the (get_thyinfo tname); |
328 (Delsimps ml_simps; |
352 in the thy_ss end |
329 old_simps := #simps(rep_ss (!simpset)); |
|
330 update_simps (None, Some [])) |
|
331 else |
353 else |
332 (writeln ("Reading \"" ^ name ^ ".thy\""); |
354 (writeln ("Reading \"" ^ name ^ ".thy\""); |
333 Delsimps (thy_simps @ ml_simps); |
355 delete_thms (); |
334 old_simps := #simps(rep_ss (!simpset)); |
|
335 update_simps (Some [], Some []); (*clear simp lists in case use_thy |
|
336 encounters an EROR exception*) |
|
337 read_thy tname thy_file; |
356 read_thy tname thy_file; |
338 use (out_name tname); |
357 use (out_name tname); |
|
358 save_thy_ss (); |
339 |
359 |
340 if not (!delete_tmpfiles) then () |
360 if not (!delete_tmpfiles) then () |
341 else delete_file (out_name tname); |
361 else delete_file (out_name tname) |
342 |
|
343 update_simps |
|
344 (Some (gen_rems same_thm (#simps(rep_ss (!simpset)), !old_simps)), |
|
345 None); |
|
346 old_simps := #simps(rep_ss (!simpset)) |
|
347 ); |
362 ); |
348 |
363 |
349 set_info (Some (file_info thy_file)) None tname; |
364 set_info tname (Some (file_info thy_file)) None; |
350 (*mark thy_file as successfully loaded*) |
365 (*mark thy_file as successfully loaded*) |
351 |
366 |
352 if ml_file = "" then () |
367 if ml_file = "" then () |
353 else |
368 else (writeln ("Reading \"" ^ name ^ ".ML\""); |
354 (writeln ("Reading \"" ^ name ^ ".ML\""); |
369 use ml_file); |
355 use ml_file; |
370 save_simpset (); |
356 |
371 |
357 update_simps (None, |
372 (*Store theory again because it could have been redefined*) |
358 Some (gen_rems same_thm (#simps(rep_ss (!simpset)), !old_simps))) |
373 use_string |
359 ); |
374 ["val _ = store_theory (" ^ tname ^ ".thy, " ^ quote tname ^ ");"]; |
360 |
375 |
361 use_string |
376 (*Store axioms of theory |
362 ["val _ = (store_theory (" ^ tname ^ ".thy, " ^ quote tname ^ ");\ |
377 (but only if it's not a copy of an older theory)*) |
363 \map store_thm_db (axioms_of " ^ tname ^ ".thy));"]; |
378 let val parents = get_parents tname; |
364 (*Store theory again because it could have been redefined*) |
379 val fst_thy = get_theory (hd parents); |
|
380 val this_thy = get_theory tname; |
|
381 val axioms = |
|
382 if length parents = 1 |
|
383 andalso Sign.eq_sg (sign_of fst_thy, sign_of this_thy) then [] |
|
384 else axioms_of this_thy; |
|
385 in map store_thm_db axioms end; |
365 |
386 |
366 (*Now set the correct info*) |
387 (*Now set the correct info*) |
367 set_info (Some (file_info thy_file)) (Some (file_info ml_file)) tname; |
388 set_info tname (Some (file_info thy_file)) (Some (file_info ml_file)); |
368 set_path (); |
389 set_path (); |
369 |
390 |
370 (*Mark theories that have to be reloaded*) |
391 (*Mark theories that have to be reloaded*) |
371 mark_children tname |
392 mark_children tname |
372 ) |
393 ) |
414 | reload_changed [] = (); |
435 | reload_changed [] = (); |
415 |
436 |
416 (*Remove all theories that are no descendants of ProtoPure. |
437 (*Remove all theories that are no descendants of ProtoPure. |
417 If there are still children in the deleted theory's list |
438 If there are still children in the deleted theory's list |
418 schedule them for reloading *) |
439 schedule them for reloading *) |
419 fun collect_garbage not_garbage = |
440 fun collect_garbage no_garbage = |
420 let fun collect ((tname, ThyInfo {children, ...}) :: ts) = |
441 let fun collect ((tname, ThyInfo {children, ...}) :: ts) = |
421 if tname mem not_garbage then collect ts |
442 if tname mem no_garbage then collect ts |
422 else (writeln ("Theory \"" ^ tname ^ |
443 else (writeln ("Theory \"" ^ tname ^ |
423 "\" is no longer linked with ProtoPure - removing it."); |
444 "\" is no longer linked with ProtoPure - removing it."); |
424 remove_thy tname; |
445 remove_thy tname; |
425 seq mark_outdated children) |
446 seq mark_outdated children) |
426 | collect [] = () |
447 | collect [] = () |
427 |
|
428 in collect (Symtab.dest (!loaded_thys)) end; |
448 in collect (Symtab.dest (!loaded_thys)) end; |
429 in collect_garbage ("ProtoPure" :: (load_order ["ProtoPure"] [])); |
449 in collect_garbage ("ProtoPure" :: (load_order ["ProtoPure"] [])); |
430 reload_changed (load_order ["Pure", "CPure"] []) |
450 reload_changed (load_order ["Pure", "CPure"] []) |
431 end; |
451 end; |
432 |
452 |
433 (*Merge theories to build a base for a new theory. |
453 (*Merge theories to build a base for a new theory. |
434 Base members are only loaded if they are missing. *) |
454 Base members are only loaded if they are missing.*) |
435 fun mk_base bases child mk_draft = |
455 fun mk_base bases child mk_draft = |
436 let (*List all descendants of a theory list *) |
456 let (*Show the cycle that would be created by add_child *) |
437 fun list_descendants (t :: ts) = |
457 fun show_cycle base = |
438 let val tinfo = get_thyinfo t |
458 let fun find_it result curr = |
439 in if is_some tinfo then |
459 let val tinfo = get_thyinfo curr |
440 let val ThyInfo {children, ...} = the tinfo |
460 in if base = curr then |
441 in children union (list_descendants (ts union children)) |
461 error ("Cyclic dependency of theories: " |
442 end |
462 ^ child ^ "->" ^ base ^ result) |
443 else [] |
463 else if is_some tinfo then |
444 end |
464 let val ThyInfo {children, ...} = the tinfo |
445 | list_descendants [] = []; |
465 in seq (find_it ("->" ^ curr ^ result)) children |
446 |
466 end |
447 (*Show the cycle that would be created by add_child *) |
467 else () |
448 fun show_cycle base = |
468 end |
449 let fun find_it result curr = |
469 in find_it "" child end; |
450 let val tinfo = get_thyinfo curr |
470 |
451 in if base = curr then |
471 (*Check if a cycle would be created by add_child *) |
452 error ("Cyclic dependency of theories: " |
472 fun find_cycle base = |
453 ^ child ^ "->" ^ base ^ result) |
473 if base mem (get_descendants [child]) then show_cycle base |
454 else if is_some tinfo then |
474 else (); |
455 let val ThyInfo {children, ...} = the tinfo |
475 |
456 in seq (find_it ("->" ^ curr ^ result)) children |
476 (*Add child to child list of base *) |
457 end |
477 fun add_child base = |
458 else () |
478 let val tinfo = |
459 end |
479 case Symtab.lookup (!loaded_thys, base) of |
460 in find_it "" child end; |
480 Some (ThyInfo {path, children, thy_time, ml_time, |
461 |
481 theory, thms, thy_ss, simpset}) => |
462 (*Check if a cycle would be created by add_child *) |
482 ThyInfo {path = path, children = child ins children, |
463 fun find_cycle base = |
483 thy_time = thy_time, ml_time = ml_time, |
464 if base mem (list_descendants [child]) then show_cycle base |
484 theory = theory, thms = thms, |
465 else (); |
485 thy_ss = thy_ss, simpset = simpset} |
466 |
486 | None => ThyInfo {path = "", children = [child], |
467 (*Add child to child list of base *) |
487 thy_time = None, ml_time = None, |
468 fun add_child base = |
488 theory = None, thms = Symtab.null, |
469 let val tinfo = |
489 thy_ss = None, simpset = None}; |
470 case Symtab.lookup (!loaded_thys, base) of |
490 in loaded_thys := Symtab.update ((base, tinfo), !loaded_thys) end; |
471 Some (ThyInfo {path, children, thy_time, ml_time, |
491 |
472 theory, thms, thy_simps, ml_simps}) => |
492 (*Load a base theory if not already done |
473 ThyInfo {path = path, children = child ins children, |
493 and no cycle would be created *) |
474 thy_time = thy_time, ml_time = ml_time, |
494 fun load base = |
475 theory = theory, thms = thms, |
495 let val thy_loaded = already_loaded base |
476 thy_simps = thy_simps, ml_simps = ml_simps} |
496 (*test this before child is added *) |
477 | None => ThyInfo {path = "", children = [child], |
497 in |
478 thy_time = None, ml_time = None, |
498 if child = base then |
479 theory = None, thms = Symtab.null, |
499 error ("Cyclic dependency of theories: " ^ child |
480 thy_simps = [], ml_simps = []}; |
500 ^ "->" ^ child) |
481 in loaded_thys := Symtab.update ((base, tinfo), !loaded_thys) end; |
501 else |
482 |
502 (find_cycle base; |
483 (*Load a base theory if not already done |
503 add_child base; |
484 and no cycle would be created *) |
504 if thy_loaded then () |
485 fun load base = |
505 else (writeln ("Autoloading theory " ^ (quote base) |
486 let val thy_loaded = already_loaded base |
506 ^ " (used by " ^ (quote child) ^ ")"); |
487 (*test this before child is added *) |
507 use_thy base) |
488 in |
508 ) |
489 if child = base then |
509 end; |
490 error ("Cyclic dependency of theories: " ^ child |
510 |
491 ^ "->" ^ child) |
511 (*Get simpset for a theory*) |
492 else |
512 fun get_simpset tname = |
493 (find_cycle base; |
513 let val ThyInfo {simpset, ...} = the (get_thyinfo tname); |
494 add_child base; |
514 in simpset end; |
495 if thy_loaded then () |
515 |
496 else (writeln ("Autoloading theory " ^ (quote base) |
516 (*Load all needed files and make a list of all real theories *) |
497 ^ " (used by " ^ (quote child) ^ ")"); |
517 fun load_base (Thy b :: bs) = |
498 use_thy base) |
518 (load b; |
499 ) |
519 b :: (load_base bs)) |
500 end; |
520 | load_base (File b :: bs) = |
501 |
521 (load b; |
502 (*Load all needed files and make a list of all real theories *) |
522 load_base bs) (*don't add it to mergelist *) |
503 fun load_base (Thy b :: bs) = |
523 | load_base [] = []; |
504 (load b; |
524 |
505 b :: (load_base bs)) |
525 val dummy = unlink_thy child; |
506 | load_base (File b :: bs) = |
526 val mergelist = load_base bases; |
507 (load b; |
527 |
508 load_base bs) (*don't add it to mergelist *) |
528 val base_thy = (writeln ("Loading theory " ^ (quote child)); |
509 | load_base [] = []; |
529 merge_thy_list mk_draft (map get_theory mergelist)); |
510 |
530 in simpset := foldr merge_ss (mapfilter get_simpset mergelist, empty_ss); |
511 val mergelist = (unlink_thy child; |
531 base_thy |
512 load_base bases); |
532 end; |
513 in writeln ("Loading theory " ^ (quote child)); |
|
514 merge_thy_list mk_draft (map get_theory mergelist) end; |
|
515 |
533 |
516 (*Change theory object for an existent item of loaded_thys |
534 (*Change theory object for an existent item of loaded_thys |
517 or create a new item; also store axioms in Thm database*) |
535 or create a new item*) |
518 fun store_theory (thy, tname) = |
536 fun store_theory (thy, tname) = |
519 let val tinfo = case Symtab.lookup (!loaded_thys, tname) of |
537 let val tinfo = case Symtab.lookup (!loaded_thys, tname) of |
520 Some (ThyInfo {path, children, thy_time, ml_time, thms, |
538 Some (ThyInfo {path, children, thy_time, ml_time, thms, |
521 thy_simps, ml_simps, ...}) => |
539 thy_ss, simpset, ...}) => |
522 ThyInfo {path = path, children = children, |
540 ThyInfo {path = path, children = children, |
523 thy_time = thy_time, ml_time = ml_time, |
541 thy_time = thy_time, ml_time = ml_time, |
524 theory = Some thy, thms = thms, |
542 theory = Some thy, thms = thms, |
525 thy_simps = thy_simps, ml_simps = ml_simps} |
543 thy_ss = thy_ss, simpset = simpset} |
526 | None => ThyInfo {path = "", children = [], |
544 | None => ThyInfo {path = "", children = [], |
527 thy_time = None, ml_time = None, |
545 thy_time = None, ml_time = None, |
528 theory = Some thy, thms = Symtab.null, |
546 theory = Some thy, thms = Symtab.null, |
529 thy_simps = [], ml_simps = []}; |
547 thy_ss = None, simpset = None}; |
530 in loaded_thys := Symtab.update ((tname, tinfo), !loaded_thys) |
548 in loaded_thys := Symtab.update ((tname, tinfo), !loaded_thys) |
531 end; |
549 end; |
532 |
550 |
533 |
551 |
534 (** store and retrieve theorems **) |
552 (** store and retrieve theorems **) |
567 |
585 |
568 (*Store a theorem in the thy_info of its theory*) |
586 (*Store a theorem in the thy_info of its theory*) |
569 fun store_thm (name, thm) = |
587 fun store_thm (name, thm) = |
570 let |
588 let |
571 val (thy_name, ThyInfo {path, children, thy_time, ml_time, theory, thms, |
589 val (thy_name, ThyInfo {path, children, thy_time, ml_time, theory, thms, |
572 thy_simps, ml_simps}) = |
590 thy_ss, simpset}) = |
573 thyinfo_of_sign (#sign (rep_thm thm)); |
591 thyinfo_of_sign (#sign (rep_thm thm)); |
574 |
592 |
575 val thms' = Symtab.update_new ((name, thm), thms) |
593 val (thms', duplicate) = (Symtab.update_new ((name, thm), thms), false) |
576 handle Symtab.DUPLICATE s => |
594 handle Symtab.DUPLICATE s => |
577 (if same_thm (the (Symtab.lookup (thms, name)), thm) then |
595 (if eq_thm (the (Symtab.lookup (thms, name)), thm) then |
578 (writeln ("Warning: Theory database already contains copy of\ |
596 (writeln ("Warning: Theory database already contains copy of\ |
579 \ theorem " ^ quote name); |
597 \ theorem " ^ quote name); |
580 thms) |
598 (thms, true)) |
581 else error ("Duplicate theorem name " ^ quote s |
599 else error ("Duplicate theorem name " ^ quote s |
582 ^ " used in theory database")); |
600 ^ " used in theory database")); |
583 in |
601 in |
584 loaded_thys := Symtab.update |
602 loaded_thys := Symtab.update |
585 ((thy_name, ThyInfo {path = path, children = children, |
603 ((thy_name, ThyInfo {path = path, children = children, |
586 thy_time = thy_time, ml_time = ml_time, |
604 thy_time = thy_time, ml_time = ml_time, |
587 theory = theory, thms = thms', |
605 theory = theory, thms = thms', |
588 thy_simps = thy_simps, ml_simps = ml_simps}), |
606 thy_ss = thy_ss, simpset = simpset}), |
589 !loaded_thys); |
607 !loaded_thys); |
590 store_thm_db (name, thm) |
608 if duplicate then thm else store_thm_db (name, thm) |
591 end; |
609 end; |
592 |
610 |
593 (*Store result of proof in loaded_thys and as ML value*) |
611 (*Store result of proof in loaded_thys and as ML value*) |
594 |
612 |
595 val qed_thm = ref flexpair_def(*dummy*); |
613 val qed_thm = ref flexpair_def(*dummy*); |
611 |
629 |
612 |
630 |
613 (* Retrieve theorems *) |
631 (* Retrieve theorems *) |
614 |
632 |
615 (*Get all theorems belonging to a given theory*) |
633 (*Get all theorems belonging to a given theory*) |
616 fun thmtab_ofthy thy = |
634 fun thmtab_of_thy thy = |
617 let val (_, ThyInfo {thms, ...}) = thyinfo_of_sign (sign_of thy); |
635 let val (_, ThyInfo {thms, ...}) = thyinfo_of_sign (sign_of thy); |
618 in thms end; |
636 in thms end; |
619 |
637 |
620 fun thmtab_ofname name = |
638 fun thmtab_of_name name = |
621 let val ThyInfo {thms, ...} = the (get_thyinfo name); |
639 let val ThyInfo {thms, ...} = the (get_thyinfo name); |
622 in thms end; |
640 in thms end; |
623 |
641 |
624 (*Get a stored theorem specified by theory and name*) |
642 (*Get a stored theorem specified by theory and name*) |
625 fun get_thm thy name = |
643 fun get_thm thy name = |
626 let fun get [] [] searched = |
644 let fun get [] [] searched = |
627 raise THEORY ("get_thm: no theorem " ^ quote name, [thy]) |
645 raise THEORY ("get_thm: no theorem " ^ quote name, [thy]) |
628 | get [] ng searched = |
646 | get [] ng searched = |
629 get (ng \\ searched) [] searched |
647 get (ng \\ searched) [] searched |
630 | get (t::ts) ng searched = |
648 | get (t::ts) ng searched = |
631 (case Symtab.lookup (thmtab_ofname t, name) of |
649 (case Symtab.lookup (thmtab_of_name t, name) of |
632 Some thm => thm |
650 Some thm => thm |
633 | None => get ts (ng union (get_parents t)) (t::searched)); |
651 | None => get ts (ng union (get_parents t)) (t::searched)); |
634 |
652 |
635 val (tname, _) = thyinfo_of_sign (sign_of thy); |
653 val (tname, _) = thyinfo_of_sign (sign_of thy); |
636 in get [tname] [] [] end; |
654 in get [tname] [] [] end; |
637 |
655 |
638 (*Get stored theorems of a theory*) |
656 (*Get stored theorems of a theory*) |
639 val thms_of = Symtab.dest o thmtab_ofthy; |
657 val thms_of = Symtab.dest o thmtab_of_thy; |
640 |
658 |
|
659 (*Get simpset of a theory*) |
|
660 fun simpset_of tname = |
|
661 case get_thyinfo tname of |
|
662 Some (ThyInfo {simpset, ...}) => |
|
663 if is_some simpset then the simpset |
|
664 else error ("Simpset of theory " ^ tname ^ " has not been stored yet") |
|
665 | None => error ("Theory " ^ tname ^ " not stored by loader"); |
641 |
666 |
642 (* print theory *) |
667 (* print theory *) |
643 |
668 |
644 fun print_thms thy = |
669 fun print_thms thy = |
645 let |
670 let |