281 |
281 |
282 (* load_file *) |
282 (* load_file *) |
283 |
283 |
284 local |
284 local |
285 |
285 |
286 fun provide path name info (deps as SOME {update_time, master, text, parents, files}) = |
286 fun provide path name info (SOME {update_time, master, text, parents, files}) = |
287 (if AList.defined (op =) files path then () |
287 (if AList.defined (op =) files path then () |
288 else warning (loader_msg "undeclared dependency of theory" [name] ^ |
288 else warning (loader_msg "undeclared dependency of theory" [name] ^ |
289 " on file: " ^ quote (Path.implode path)); |
289 " on file: " ^ quote (Path.implode path)); |
290 SOME (make_deps update_time master text parents |
290 SOME (make_deps update_time master text parents |
291 (AList.update (op =) (path, SOME info) files))) |
291 (AList.update (op =) (path, SOME info) files))) |
336 | required_by s initiators = s ^ "(required by " ^ show_path (rev initiators) ^ ")"; |
336 | required_by s initiators = s ^ "(required by " ^ show_path (rev initiators) ^ ")"; |
337 |
337 |
338 fun load_thy time upd_time initiators name = |
338 fun load_thy time upd_time initiators name = |
339 let |
339 let |
340 val _ = priority ("Loading theory " ^ quote name ^ required_by " " initiators); |
340 val _ = priority ("Loading theory " ^ quote name ^ required_by " " initiators); |
341 val (pos, text, files) = |
341 val (pos, text, _) = |
342 (case get_deps name of |
342 (case get_deps name of |
343 SOME {master = SOME (master_path, _), text as _ :: _, files, ...} => |
343 SOME {master = SOME (master_path, _), text as _ :: _, files, ...} => |
344 (Path.position master_path, text, files) |
344 (Path.position master_path, text, files) |
345 | _ => error (loader_msg "corrupted dependency information" [name])); |
345 | _ => error (loader_msg "corrupted dependency information" [name])); |
346 val _ = touch_thy name; |
346 val _ = touch_thy name; |
408 in after_load () handle exn => (kill_thy name; reraise exn) end |
408 in after_load () handle exn => (kill_thy name; reraise exn) end |
409 | _ => ())); |
409 | _ => ())); |
410 |
410 |
411 in |
411 in |
412 |
412 |
413 fun schedule_tasks tasks n = |
413 fun schedule_tasks tasks = |
414 if not (Multithreading.enabled ()) then schedule_seq tasks |
414 if not (Multithreading.enabled ()) then schedule_seq tasks |
415 else if Multithreading.self_critical () then |
415 else if Multithreading.self_critical () then |
416 (warning (loader_msg "no multithreading within critical section" []); |
416 (warning (loader_msg "no multithreading within critical section" []); |
417 schedule_seq tasks) |
417 schedule_seq tasks) |
418 else schedule_futures tasks; |
418 else schedule_futures tasks; |
436 (case lookup_deps name of |
436 (case lookup_deps name of |
437 SOME NONE => (true, NONE, get_parents name) |
437 SOME NONE => (true, NONE, get_parents name) |
438 | NONE => |
438 | NONE => |
439 let val {master, text, imports = parents, uses = files} = ThyLoad.deps_thy dir name |
439 let val {master, text, imports = parents, uses = files} = ThyLoad.deps_thy dir name |
440 in (false, init_deps (SOME master) text parents files, parents) end |
440 in (false, init_deps (SOME master) text parents files, parents) end |
441 | SOME (deps as SOME {update_time, master, text, parents, files}) => |
441 | SOME (SOME {update_time, master, text, parents, files}) => |
442 let |
442 let |
443 val (thy_path, thy_id) = ThyLoad.check_thy dir name; |
443 val (thy_path, thy_id) = ThyLoad.check_thy dir name; |
444 val master' = SOME (thy_path, thy_id); |
444 val master' = SOME (thy_path, thy_id); |
445 in |
445 in |
446 if Option.map #2 master <> SOME thy_id then |
446 if Option.map #2 master <> SOME thy_id then |
469 val path = Path.expand (Path.explode str); |
469 val path = Path.expand (Path.explode str); |
470 val name = Path.implode (Path.base path); |
470 val name = Path.implode (Path.base path); |
471 val dir' = Path.append dir (Path.dir path); |
471 val dir' = Path.append dir (Path.dir path); |
472 val _ = member (op =) initiators name andalso error (cycle_msg initiators); |
472 val _ = member (op =) initiators name andalso error (cycle_msg initiators); |
473 in |
473 in |
474 (case try (Graph.get_node (fst tasks)) name of |
474 (case try (Graph.get_node tasks) name of |
475 SOME task => (task_finished task, tasks) |
475 SOME task => (task_finished task, tasks) |
476 | NONE => |
476 | NONE => |
477 let |
477 let |
478 val (current, deps, parents) = check_deps dir' name |
478 val (current, deps, parents) = check_deps dir' name |
479 handle ERROR msg => cat_error msg |
479 handle ERROR msg => cat_error msg |
480 (loader_msg "the error(s) above occurred while examining theory" [name] ^ |
480 (loader_msg "the error(s) above occurred while examining theory" [name] ^ |
481 required_by "\n" initiators); |
481 required_by "\n" initiators); |
482 val parent_names = map base_name parents; |
482 val parent_names = map base_name parents; |
483 |
483 |
484 val (parents_current, (tasks_graph', tasks_len')) = |
484 val (parents_current, tasks_graph') = |
485 require_thys time (name :: initiators) |
485 require_thys time (name :: initiators) |
486 (Path.append dir (master_dir' deps)) parents tasks; |
486 (Path.append dir (master_dir' deps)) parents tasks; |
487 |
487 |
488 val all_current = current andalso parents_current; |
488 val all_current = current andalso parents_current; |
489 val _ = if not all_current andalso known_thy name then outdate_thy name else (); |
489 val _ = if not all_current andalso known_thy name then outdate_thy name else (); |
494 |
494 |
495 val upd_time = serial (); |
495 val upd_time = serial (); |
496 val tasks_graph'' = tasks_graph' |> new_deps name parent_names |
496 val tasks_graph'' = tasks_graph' |> new_deps name parent_names |
497 (if all_current then Finished |
497 (if all_current then Finished |
498 else Task (fn () => load_thy time upd_time initiators name)); |
498 else Task (fn () => load_thy time upd_time initiators name)); |
499 val tasks_len'' = if all_current then tasks_len' else tasks_len' + 1; |
499 in (all_current, tasks_graph'') end) |
500 in (all_current, (tasks_graph'', tasks_len'')) end) |
|
501 end; |
500 end; |
502 |
501 |
503 end; |
502 end; |
504 |
503 |
505 |
504 |
506 (* use_thy etc. *) |
505 (* use_thy etc. *) |
507 |
506 |
508 local |
507 local |
509 |
508 |
510 fun gen_use_thy' req dir arg = |
509 fun gen_use_thy' req dir arg = |
511 let val (_, (tasks, n)) = req [] dir arg (Graph.empty, 0) |
510 schedule_tasks (snd (req [] dir arg Graph.empty)); |
512 in schedule_tasks tasks n end; |
|
513 |
511 |
514 fun gen_use_thy req str = |
512 fun gen_use_thy req str = |
515 let val name = base_name str in |
513 let val name = base_name str in |
516 check_unfinished warning name; |
514 check_unfinished warning name; |
517 gen_use_thy' req Path.current str |
515 gen_use_thy' req Path.current str |