| author | wenzelm | 
| Tue, 25 Sep 2012 18:24:49 +0200 | |
| changeset 49564 | 03381c41235b | 
| parent 49011 | 9c68e43502ce | 
| child 50845 | 477ca927676f | 
| permissions | -rw-r--r-- | 
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 1 | (* Title: Pure/Thy/thy_info.ML | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 2 | Author: Markus Wenzel, TU Muenchen | 
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 3 | |
| 37978 
548f3f165d05
simplified Thy_Header.read -- include Source.of_string_limited here;
 wenzelm parents: 
37977diff
changeset | 4 | Global theory info database, with auto-loading according to theory and | 
| 15801 | 5 | file dependencies. | 
| 3976 | 6 | *) | 
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 7 | |
| 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 8 | signature THY_INFO = | 
| 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 9 | sig | 
| 37981 
9a15982f41fe
theory loader: removed obsolete touch/outdate operations (require_thy no longer changes the database implicitly);
 wenzelm parents: 
37980diff
changeset | 10 | datatype action = Update | Remove | 
| 7099 | 11 | val add_hook: (action -> string -> unit) -> unit | 
| 26614 | 12 | val get_names: unit -> string list | 
| 7288 | 13 | val lookup_theory: string -> theory option | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 14 | val get_theory: string -> theory | 
| 24563 | 15 | val is_finished: string -> bool | 
| 26983 | 16 | val master_directory: string -> Path.T | 
| 24080 
8c67d869531b
added register_thy (replaces pretend_use_thy_only and really flag);
 wenzelm parents: 
24071diff
changeset | 17 | val loaded_files: string -> Path.T list | 
| 29421 
db532e37cda2
use_thys: perform consolidate_thy on loaded theories, which removes failed nodes in post-hoc fashion;
 wenzelm parents: 
29118diff
changeset | 18 | val remove_thy: string -> unit | 
| 
db532e37cda2
use_thys: perform consolidate_thy on loaded theories, which removes failed nodes in post-hoc fashion;
 wenzelm parents: 
29118diff
changeset | 19 | val kill_thy: string -> unit | 
| 48927 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48898diff
changeset | 20 | val use_thys_wrt: Path.T -> (string * Position.T) list -> unit | 
| 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48898diff
changeset | 21 | val use_thys: (string * Position.T) list -> unit | 
| 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48898diff
changeset | 22 | val use_thy: string * Position.T -> unit | 
| 46938 
cda018294515
some support for outer syntax keyword declarations within theory header;
 wenzelm parents: 
46774diff
changeset | 23 | val toplevel_begin_theory: Path.T -> Thy_Header.header -> theory | 
| 37954 
a2e73df0b1e0
simplified/clarified register_thy: more precise treatment of new dependencies, remove descendants;
 wenzelm parents: 
37953diff
changeset | 24 | val register_thy: theory -> unit | 
| 24080 
8c67d869531b
added register_thy (replaces pretend_use_thy_only and really flag);
 wenzelm parents: 
24071diff
changeset | 25 | val finish: unit -> unit | 
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 26 | end; | 
| 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 27 | |
| 37216 
3165bc303f66
modernized some structure names, keeping a few legacy aliases;
 wenzelm parents: 
36953diff
changeset | 28 | structure Thy_Info: THY_INFO = | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 29 | struct | 
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 30 | |
| 7099 | 31 | (** theory loader actions and hooks **) | 
| 32 | ||
| 37981 
9a15982f41fe
theory loader: removed obsolete touch/outdate operations (require_thy no longer changes the database implicitly);
 wenzelm parents: 
37980diff
changeset | 33 | datatype action = Update | Remove; | 
| 7099 | 34 | |
| 35 | local | |
| 43640 | 36 | val hooks = Synchronized.var "Thy_Info.hooks" ([]: (action -> string -> unit) list); | 
| 7099 | 37 | in | 
| 43640 | 38 | fun add_hook f = Synchronized.change hooks (cons f); | 
| 39 | fun perform action name = | |
| 40 | List.app (fn f => (try (fn () => f action name) (); ())) (Synchronized.value hooks); | |
| 7099 | 41 | end; | 
| 42 | ||
| 43 | ||
| 44 | ||
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 45 | (** thy database **) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 46 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 47 | (* messages *) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 48 | |
| 23871 | 49 | fun loader_msg txt [] = "Theory loader: " ^ txt | 
| 50 | | loader_msg txt names = "Theory loader: " ^ txt ^ " " ^ commas_quote names; | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 51 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 52 | val show_path = space_implode " via " o map quote; | 
| 9332 | 53 | fun cycle_msg names = loader_msg ("cyclic dependency of " ^ show_path names) [];
 | 
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 54 | |
| 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 55 | |
| 6666 | 56 | (* derived graph operations *) | 
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 57 | |
| 9327 | 58 | fun add_deps name parents G = Graph.add_deps_acyclic (name, parents) G | 
| 9332 | 59 | handle Graph.CYCLES namess => error (cat_lines (map cycle_msg namess)); | 
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 60 | |
| 37984 
f26352bd82cf
clarified register_thy: clean slate via kill_thy, more precise CRITICAL section;
 wenzelm parents: 
37981diff
changeset | 61 | fun new_entry name parents entry = | 
| 37977 
3ceccd415145
simplified/clarified theory loader: more explicit task management, kill old versions at start, commit results only in the very end, non-optional master dependency, do not store text in deps;
 wenzelm parents: 
37955diff
changeset | 62 | Graph.new_node (name, entry) #> add_deps name parents; | 
| 
3ceccd415145
simplified/clarified theory loader: more explicit task management, kill old versions at start, commit results only in the very end, non-optional master dependency, do not store text in deps;
 wenzelm parents: 
37955diff
changeset | 63 | |
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 64 | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 65 | (* thy database *) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 66 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 67 | type deps = | 
| 41955 
703ea96b13c6
files are identified via SHA1 digests -- discontinued ISABELLE_FILE_IDENT;
 wenzelm parents: 
41678diff
changeset | 68 |  {master: (Path.T * SHA1.digest),  (*master dependencies for thy file*)
 | 
| 48927 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48898diff
changeset | 69 | imports: (string * Position.T) list}; (*source specification of imports (partially qualified)*) | 
| 23886 
f40fba467384
simplified ThyLoad interfaces: only one additional directory;
 wenzelm parents: 
23871diff
changeset | 70 | |
| 38148 
d2f3c8d4a89f
uniform naming of imports (source specification) vs. parents (thy node names) vs. parent_thys (theory values);
 wenzelm parents: 
38147diff
changeset | 71 | fun make_deps master imports : deps = {master = master, imports = imports};
 | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 72 | |
| 37980 
b8c3d4dc1e3e
avoid repeated File.read for theory text (as before);
 wenzelm parents: 
37979diff
changeset | 73 | fun master_dir (d: deps option) = the_default Path.current (Option.map (Path.dir o #1 o #master) d); | 
| 44225 
a8f921e6484f
more robust Thy_Header.base_name, with minimal assumptions about path syntax;
 wenzelm parents: 
44222diff
changeset | 74 | fun base_name s = Path.implode (Path.base (Path.explode s)); | 
| 23967 | 75 | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 76 | local | 
| 37905 | 77 | val database = Unsynchronized.ref (Graph.empty: (deps option * theory option) Graph.T); | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 78 | in | 
| 6362 | 79 | fun get_thys () = ! database; | 
| 38145 
675827e61eb9
more precise CRITICAL sections, using NAMED_CRITICAL uniformly;
 wenzelm parents: 
38143diff
changeset | 80 | fun change_thys f = NAMED_CRITICAL "Thy_Info" (fn () => Unsynchronized.change database f); | 
| 3604 
6bf9f09f3d61
Moved functions for theory information storage / retrieval
 berghofe parents: diff
changeset | 81 | end; | 
| 5209 | 82 | |
| 83 | ||
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 84 | (* access thy graph *) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 85 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 86 | fun thy_graph f x = f (get_thys ()) x; | 
| 9417 | 87 | |
| 23967 | 88 | fun get_names () = Graph.topological_order (get_thys ()); | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 89 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 90 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 91 | (* access thy *) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 92 | |
| 7935 | 93 | fun lookup_thy name = | 
| 15531 | 94 | SOME (thy_graph Graph.get_node name) handle Graph.UNDEF _ => NONE; | 
| 7935 | 95 | |
| 16047 | 96 | val known_thy = is_some o lookup_thy; | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 97 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 98 | fun get_thy name = | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 99 | (case lookup_thy name of | 
| 15531 | 100 | SOME thy => thy | 
| 101 | | NONE => error (loader_msg "nothing known about theory" [name])); | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 102 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 103 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 104 | (* access deps *) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 105 | |
| 15570 | 106 | val lookup_deps = Option.map #1 o lookup_thy; | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 107 | val get_deps = #1 o get_thy; | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 108 | |
| 26983 | 109 | val is_finished = is_none o get_deps; | 
| 37980 
b8c3d4dc1e3e
avoid repeated File.read for theory text (as before);
 wenzelm parents: 
37979diff
changeset | 110 | val master_directory = master_dir o get_deps; | 
| 7191 | 111 | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 112 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 113 | (* access theory *) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 114 | |
| 7687 | 115 | fun lookup_theory name = | 
| 116 | (case lookup_thy name of | |
| 38142 | 117 | SOME (_, SOME theory) => SOME theory | 
| 15531 | 118 | | _ => NONE); | 
| 7288 | 119 | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 120 | fun get_theory name = | 
| 7288 | 121 | (case lookup_theory name of | 
| 23871 | 122 | SOME theory => theory | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 123 | | _ => error (loader_msg "undefined theory entry for" [name])); | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 124 | |
| 44337 
d453faed4815
clarified get_imports -- should not rely on accidental order within graph;
 wenzelm parents: 
44302diff
changeset | 125 | val get_imports = Thy_Load.imports_of o get_theory; | 
| 
d453faed4815
clarified get_imports -- should not rely on accidental order within graph;
 wenzelm parents: 
44302diff
changeset | 126 | |
| 38145 
675827e61eb9
more precise CRITICAL sections, using NAMED_CRITICAL uniformly;
 wenzelm parents: 
38143diff
changeset | 127 | fun loaded_files name = NAMED_CRITICAL "Thy_Info" (fn () => | 
| 37949 
48a874444164
moved management of auxiliary theory source files to Thy_Load -- as theory data instead of accidental loader state;
 wenzelm parents: 
37942diff
changeset | 128 | (case get_deps name of | 
| 
48a874444164
moved management of auxiliary theory source files to Thy_Load -- as theory data instead of accidental loader state;
 wenzelm parents: 
37942diff
changeset | 129 | NONE => [] | 
| 38145 
675827e61eb9
more precise CRITICAL sections, using NAMED_CRITICAL uniformly;
 wenzelm parents: 
38143diff
changeset | 130 |   | SOME {master = (thy_path, _), ...} => thy_path :: Thy_Load.loaded_files (get_theory name)));
 | 
| 37949 
48a874444164
moved management of auxiliary theory source files to Thy_Load -- as theory data instead of accidental loader state;
 wenzelm parents: 
37942diff
changeset | 131 | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 132 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 133 | |
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 134 | (** thy operations **) | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 135 | |
| 43640 | 136 | (* main loader actions *) | 
| 29421 
db532e37cda2
use_thys: perform consolidate_thy on loaded theories, which removes failed nodes in post-hoc fashion;
 wenzelm parents: 
29118diff
changeset | 137 | |
| 38145 
675827e61eb9
more precise CRITICAL sections, using NAMED_CRITICAL uniformly;
 wenzelm parents: 
38143diff
changeset | 138 | fun remove_thy name = NAMED_CRITICAL "Thy_Info" (fn () => | 
| 37979 | 139 | if is_finished name then error (loader_msg "attempt to change finished theory" [name]) | 
| 29421 
db532e37cda2
use_thys: perform consolidate_thy on loaded theories, which removes failed nodes in post-hoc fashion;
 wenzelm parents: 
29118diff
changeset | 140 | else | 
| 29434 | 141 | let | 
| 142 | val succs = thy_graph Graph.all_succs [name]; | |
| 40132 
7ee65dbffa31
renamed Output.priority to Output.urgent_message to emphasize its special role more clearly;
 wenzelm parents: 
39557diff
changeset | 143 | val _ = Output.urgent_message (loader_msg "removing" succs); | 
| 38142 | 144 | val _ = List.app (perform Remove) succs; | 
| 46665 
919dfcdf6d8a
discontinued slightly odd Graph.del_nodes (inefficient due to full Table.map);
 wenzelm parents: 
46122diff
changeset | 145 | val _ = change_thys (fold Graph.del_node succs); | 
| 38142 | 146 | in () end); | 
| 29421 
db532e37cda2
use_thys: perform consolidate_thy on loaded theories, which removes failed nodes in post-hoc fashion;
 wenzelm parents: 
29118diff
changeset | 147 | |
| 38145 
675827e61eb9
more precise CRITICAL sections, using NAMED_CRITICAL uniformly;
 wenzelm parents: 
38143diff
changeset | 148 | fun kill_thy name = NAMED_CRITICAL "Thy_Info" (fn () => | 
| 37977 
3ceccd415145
simplified/clarified theory loader: more explicit task management, kill old versions at start, commit results only in the very end, non-optional master dependency, do not store text in deps;
 wenzelm parents: 
37955diff
changeset | 149 | if known_thy name then remove_thy name | 
| 38142 | 150 | else ()); | 
| 7099 | 151 | |
| 43640 | 152 | fun update_thy deps theory = NAMED_CRITICAL "Thy_Info" (fn () => | 
| 153 | let | |
| 154 | val name = Context.theory_name theory; | |
| 155 | val parents = map Context.theory_name (Theory.parents_of theory); | |
| 156 | val _ = kill_thy name; | |
| 157 | val _ = map get_theory parents; | |
| 158 | val _ = change_thys (new_entry name parents (SOME deps, SOME theory)); | |
| 159 | val _ = perform Update name; | |
| 160 | in () end); | |
| 161 | ||
| 7099 | 162 | |
| 24209 | 163 | (* scheduling loader tasks *) | 
| 164 | ||
| 43641 
081e009549dc
uniform finish_thy -- always Global_Theory.join_proofs, even with sequential scheduling;
 wenzelm parents: 
43640diff
changeset | 165 | type result = theory * unit future * (unit -> unit); | 
| 
081e009549dc
uniform finish_thy -- always Global_Theory.join_proofs, even with sequential scheduling;
 wenzelm parents: 
43640diff
changeset | 166 | |
| 37977 
3ceccd415145
simplified/clarified theory loader: more explicit task management, kill old versions at start, commit results only in the very end, non-optional master dependency, do not store text in deps;
 wenzelm parents: 
37955diff
changeset | 167 | datatype task = | 
| 43641 
081e009549dc
uniform finish_thy -- always Global_Theory.join_proofs, even with sequential scheduling;
 wenzelm parents: 
43640diff
changeset | 168 | Task of string list * (theory list -> result) | | 
| 37977 
3ceccd415145
simplified/clarified theory loader: more explicit task management, kill old versions at start, commit results only in the very end, non-optional master dependency, do not store text in deps;
 wenzelm parents: 
37955diff
changeset | 169 | Finished of theory; | 
| 
3ceccd415145
simplified/clarified theory loader: more explicit task management, kill old versions at start, commit results only in the very end, non-optional master dependency, do not store text in deps;
 wenzelm parents: 
37955diff
changeset | 170 | |
| 
3ceccd415145
simplified/clarified theory loader: more explicit task management, kill old versions at start, commit results only in the very end, non-optional master dependency, do not store text in deps;
 wenzelm parents: 
37955diff
changeset | 171 | fun task_finished (Task _) = false | 
| 
3ceccd415145
simplified/clarified theory loader: more explicit task management, kill old versions at start, commit results only in the very end, non-optional master dependency, do not store text in deps;
 wenzelm parents: 
37955diff
changeset | 172 | | task_finished (Finished _) = true; | 
| 24209 | 173 | |
| 44162 | 174 | fun task_parents deps (parents: string list) = map (the o AList.lookup (op =) deps) parents; | 
| 175 | ||
| 29118 | 176 | local | 
| 177 | ||
| 43641 
081e009549dc
uniform finish_thy -- always Global_Theory.join_proofs, even with sequential scheduling;
 wenzelm parents: 
43640diff
changeset | 178 | fun finish_thy ((thy, present, commit): result) = | 
| 49011 
9c68e43502ce
some support for registering forked proofs within Proof.state, using its bottom context;
 wenzelm parents: 
49010diff
changeset | 179 | (Thm.join_theory_proofs thy; Future.join present; commit (); thy); | 
| 43641 
081e009549dc
uniform finish_thy -- always Global_Theory.join_proofs, even with sequential scheduling;
 wenzelm parents: 
43640diff
changeset | 180 | |
| 44162 | 181 | val schedule_seq = | 
| 182 | Graph.schedule (fn deps => fn (_, task) => | |
| 183 | (case task of | |
| 184 | Task (parents, body) => finish_thy (body (task_parents deps parents)) | |
| 185 | | Finished thy => thy)) #> ignore; | |
| 29000 
5e03bc760355
improved future_schedule: more robust handling of failed parents (explicit join), final join of all futures, including Exn.release_all;
 wenzelm parents: 
28980diff
changeset | 186 | |
| 44162 | 187 | val schedule_futures = uninterruptible (fn _ => | 
| 188 | Graph.schedule (fn deps => fn (name, task) => | |
| 189 | (case task of | |
| 190 | Task (parents, body) => | |
| 44302 | 191 | (singleton o Future.forks) | 
| 192 |           {name = "theory:" ^ name, group = NONE,
 | |
| 193 | deps = map (Future.task_of o #2) deps, pri = 0, interrupts = true} | |
| 44162 | 194 | (fn () => | 
| 195 | (case filter (not o can Future.join o #2) deps of | |
| 196 | [] => body (map (#1 o Future.join) (task_parents deps parents)) | |
| 197 | | bad => | |
| 198 |                 error (loader_msg ("failed to load " ^ quote name ^
 | |
| 199 | " (unresolved " ^ commas_quote (map #1 bad) ^ ")") []))) | |
| 200 | | Finished thy => Future.value (thy, Future.value (), I))) | |
| 201 | #> maps (fn result => (finish_thy (Future.join result); []) handle exn => [Exn.Exn exn]) | |
| 44247 | 202 | #> rev #> Par_Exn.release_all) #> ignore; | 
| 29429 
a6c641f08af7
schedule_futures: tuned final consolidation, explicit after_load phase;
 wenzelm parents: 
29421diff
changeset | 203 | |
| 24209 | 204 | in | 
| 205 | ||
| 32794 | 206 | fun schedule_tasks tasks = | 
| 29118 | 207 | if not (Multithreading.enabled ()) then schedule_seq tasks | 
| 208 | else if Multithreading.self_critical () then | |
| 24209 | 209 | (warning (loader_msg "no multithreading within critical section" []); | 
| 210 | schedule_seq tasks) | |
| 29118 | 211 | else schedule_futures tasks; | 
| 24209 | 212 | |
| 213 | end; | |
| 214 | ||
| 215 | ||
| 23967 | 216 | (* require_thy -- checking database entries wrt. the file-system *) | 
| 15065 | 217 | |
| 7211 | 218 | local | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 219 | |
| 37977 
3ceccd415145
simplified/clarified theory loader: more explicit task management, kill old versions at start, commit results only in the very end, non-optional master dependency, do not store text in deps;
 wenzelm parents: 
37955diff
changeset | 220 | fun required_by _ [] = "" | 
| 
3ceccd415145
simplified/clarified theory loader: more explicit task management, kill old versions at start, commit results only in the very end, non-optional master dependency, do not store text in deps;
 wenzelm parents: 
37955diff
changeset | 221 | | required_by s initiators = s ^ "(required by " ^ show_path (rev initiators) ^ ")"; | 
| 
3ceccd415145
simplified/clarified theory loader: more explicit task management, kill old versions at start, commit results only in the very end, non-optional master dependency, do not store text in deps;
 wenzelm parents: 
37955diff
changeset | 222 | |
| 48927 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48898diff
changeset | 223 | fun load_thy initiators update_time deps text (name, pos) uses keywords parents = | 
| 37977 
3ceccd415145
simplified/clarified theory loader: more explicit task management, kill old versions at start, commit results only in the very end, non-optional master dependency, do not store text in deps;
 wenzelm parents: 
37955diff
changeset | 224 | let | 
| 
3ceccd415145
simplified/clarified theory loader: more explicit task management, kill old versions at start, commit results only in the very end, non-optional master dependency, do not store text in deps;
 wenzelm parents: 
37955diff
changeset | 225 | val _ = kill_thy name; | 
| 40132 
7ee65dbffa31
renamed Output.priority to Output.urgent_message to emphasize its special role more clearly;
 wenzelm parents: 
39557diff
changeset | 226 |     val _ = Output.urgent_message ("Loading theory " ^ quote name ^ required_by " " initiators);
 | 
| 37977 
3ceccd415145
simplified/clarified theory loader: more explicit task management, kill old versions at start, commit results only in the very end, non-optional master dependency, do not store text in deps;
 wenzelm parents: 
37955diff
changeset | 227 | |
| 41548 
bd0bebf93fa6
Thy_Load.begin_theory: maintain source specification of imports;
 wenzelm parents: 
41536diff
changeset | 228 |     val {master = (thy_path, _), imports} = deps;
 | 
| 38134 
3de75ca6f166
load_thy: refer to physical master directory (not accumulated source import directory) and enable loading files relatively to that;
 wenzelm parents: 
37985diff
changeset | 229 | val dir = Path.dir thy_path; | 
| 48927 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48898diff
changeset | 230 | val header = Thy_Header.make (name, pos) imports keywords uses; | 
| 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48898diff
changeset | 231 | |
| 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48898diff
changeset | 232 | val _ = Position.reports (map #2 imports ~~ map Theory.get_markup parents); | 
| 37977 
3ceccd415145
simplified/clarified theory loader: more explicit task management, kill old versions at start, commit results only in the very end, non-optional master dependency, do not store text in deps;
 wenzelm parents: 
37955diff
changeset | 233 | |
| 48638 | 234 | val (theory, present) = | 
| 48927 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48898diff
changeset | 235 | Thy_Load.load_thy update_time dir header (Path.position thy_path) text | 
| 48638 | 236 | (if name = Context.PureN then [ML_Context.the_global_context ()] else parents); | 
| 43640 | 237 | fun commit () = update_thy deps theory; | 
| 42129 
c17508a61f49
present theory content as future, depending on intermediate proof state futures -- potential to reduce memory requirements and improve parallelization;
 wenzelm parents: 
42003diff
changeset | 238 | in (theory, present, commit) end; | 
| 37977 
3ceccd415145
simplified/clarified theory loader: more explicit task management, kill old versions at start, commit results only in the very end, non-optional master dependency, do not store text in deps;
 wenzelm parents: 
37955diff
changeset | 239 | |
| 48898 
9fc880720663
simplified Thy_Load.check_thy (again) -- no need to pass keywords nor find files in body text;
 wenzelm parents: 
48888diff
changeset | 240 | fun check_deps dir name = | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 241 | (case lookup_deps name of | 
| 48928 | 242 | SOME NONE => (true, NONE, Position.none, get_imports name, [], []) | 
| 23893 
8babfcaaf129
deps: maintain source specification of parents (prevents repeated ThyLoad.deps_thy);
 wenzelm parents: 
23886diff
changeset | 243 | | NONE => | 
| 48928 | 244 |       let val {master, text, theory_pos, imports, keywords, uses} = Thy_Load.check_thy dir name
 | 
| 245 | in (false, SOME (make_deps master imports, text), theory_pos, imports, uses, keywords) end | |
| 42129 
c17508a61f49
present theory content as future, depending on intermediate proof state futures -- potential to reduce memory requirements and improve parallelization;
 wenzelm parents: 
42003diff
changeset | 246 |   | SOME (SOME {master, ...}) =>
 | 
| 42003 
6e45dc518ebb
replaced File.check by specific File.check_file, File.check_dir;
 wenzelm parents: 
41955diff
changeset | 247 | let | 
| 48928 | 248 |         val {master = master', text = text', theory_pos = theory_pos', imports = imports',
 | 
| 249 | uses = uses', keywords = keywords'} = Thy_Load.check_thy dir name; | |
| 42003 
6e45dc518ebb
replaced File.check by specific File.check_file, File.check_dir;
 wenzelm parents: 
41955diff
changeset | 250 | val deps' = SOME (make_deps master' imports', text'); | 
| 
6e45dc518ebb
replaced File.check by specific File.check_file, File.check_dir;
 wenzelm parents: 
41955diff
changeset | 251 | val current = | 
| 
6e45dc518ebb
replaced File.check by specific File.check_file, File.check_dir;
 wenzelm parents: 
41955diff
changeset | 252 | #2 master = #2 master' andalso | 
| 
6e45dc518ebb
replaced File.check by specific File.check_file, File.check_dir;
 wenzelm parents: 
41955diff
changeset | 253 | (case lookup_theory name of | 
| 
6e45dc518ebb
replaced File.check by specific File.check_file, File.check_dir;
 wenzelm parents: 
41955diff
changeset | 254 | NONE => false | 
| 48886 
9604c6563226
discontinued separate list of required files -- maintain only provided files as they occur at runtime;
 wenzelm parents: 
48876diff
changeset | 255 | | SOME theory => Thy_Load.load_current theory); | 
| 48928 | 256 | in (current, deps', theory_pos', imports', uses', keywords') end); | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 257 | |
| 23967 | 258 | in | 
| 259 | ||
| 48898 
9fc880720663
simplified Thy_Load.check_thy (again) -- no need to pass keywords nor find files in body text;
 wenzelm parents: 
48888diff
changeset | 260 | fun require_thys initiators dir strs tasks = | 
| 
9fc880720663
simplified Thy_Load.check_thy (again) -- no need to pass keywords nor find files in body text;
 wenzelm parents: 
48888diff
changeset | 261 | fold_map (require_thy initiators dir) strs tasks |>> forall I | 
| 48928 | 262 | and require_thy initiators dir (str, require_pos) tasks = | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 263 | let | 
| 21858 
05f57309170c
avoid conflict with Alice keywords: renamed pack -> implode, unpack -> explode, any -> many, avoided assert;
 wenzelm parents: 
20664diff
changeset | 264 | val path = Path.expand (Path.explode str); | 
| 
05f57309170c
avoid conflict with Alice keywords: renamed pack -> implode, unpack -> explode, any -> many, avoided assert;
 wenzelm parents: 
20664diff
changeset | 265 | val name = Path.implode (Path.base path); | 
| 7066 | 266 | in | 
| 32794 | 267 | (case try (Graph.get_node tasks) name of | 
| 48898 
9fc880720663
simplified Thy_Load.check_thy (again) -- no need to pass keywords nor find files in body text;
 wenzelm parents: 
48888diff
changeset | 268 | SOME task => (task_finished task, tasks) | 
| 23967 | 269 | | NONE => | 
| 270 | let | |
| 43651 
511df47bcadc
some support for theory files within Isabelle/Scala session;
 wenzelm parents: 
43641diff
changeset | 271 | val dir' = Path.append dir (Path.dir path); | 
| 
511df47bcadc
some support for theory files within Isabelle/Scala session;
 wenzelm parents: 
43641diff
changeset | 272 | val _ = member (op =) initiators name andalso error (cycle_msg initiators); | 
| 
511df47bcadc
some support for theory files within Isabelle/Scala session;
 wenzelm parents: 
43641diff
changeset | 273 | |
| 48928 | 274 | val (current, deps, theory_pos, imports, uses, keywords) = check_deps dir' name | 
| 23967 | 275 | handle ERROR msg => cat_error msg | 
| 276 | (loader_msg "the error(s) above occurred while examining theory" [name] ^ | |
| 48992 | 277 | Position.here require_pos ^ required_by "\n" initiators); | 
| 37981 
9a15982f41fe
theory loader: removed obsolete touch/outdate operations (require_thy no longer changes the database implicitly);
 wenzelm parents: 
37980diff
changeset | 278 | |
| 48927 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48898diff
changeset | 279 | val parents = map (base_name o #1) imports; | 
| 48898 
9fc880720663
simplified Thy_Load.check_thy (again) -- no need to pass keywords nor find files in body text;
 wenzelm parents: 
48888diff
changeset | 280 | val (parents_current, tasks') = | 
| 42003 
6e45dc518ebb
replaced File.check by specific File.check_file, File.check_dir;
 wenzelm parents: 
41955diff
changeset | 281 | require_thys (name :: initiators) | 
| 48898 
9fc880720663
simplified Thy_Load.check_thy (again) -- no need to pass keywords nor find files in body text;
 wenzelm parents: 
48888diff
changeset | 282 | (Path.append dir (master_dir (Option.map #1 deps))) imports tasks; | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 283 | |
| 23967 | 284 | val all_current = current andalso parents_current; | 
| 37977 
3ceccd415145
simplified/clarified theory loader: more explicit task management, kill old versions at start, commit results only in the very end, non-optional master dependency, do not store text in deps;
 wenzelm parents: 
37955diff
changeset | 285 | val task = | 
| 
3ceccd415145
simplified/clarified theory loader: more explicit task management, kill old versions at start, commit results only in the very end, non-optional master dependency, do not store text in deps;
 wenzelm parents: 
37955diff
changeset | 286 | if all_current then Finished (get_theory name) | 
| 
3ceccd415145
simplified/clarified theory loader: more explicit task management, kill old versions at start, commit results only in the very end, non-optional master dependency, do not store text in deps;
 wenzelm parents: 
37955diff
changeset | 287 | else | 
| 37980 
b8c3d4dc1e3e
avoid repeated File.read for theory text (as before);
 wenzelm parents: 
37979diff
changeset | 288 | (case deps of | 
| 
b8c3d4dc1e3e
avoid repeated File.read for theory text (as before);
 wenzelm parents: 
37979diff
changeset | 289 | NONE => raise Fail "Malformed deps" | 
| 42003 
6e45dc518ebb
replaced File.check by specific File.check_file, File.check_dir;
 wenzelm parents: 
41955diff
changeset | 290 | | SOME (dep, text) => | 
| 48876 
157dd47032e0
more standard Thy_Load.check_thy for Pure.thy, relying on its header;
 wenzelm parents: 
48874diff
changeset | 291 | let | 
| 
157dd47032e0
more standard Thy_Load.check_thy for Pure.thy, relying on its header;
 wenzelm parents: 
48874diff
changeset | 292 | val update_time = serial (); | 
| 48928 | 293 | val load = | 
| 294 | load_thy initiators update_time dep text (name, theory_pos) uses keywords; | |
| 48876 
157dd47032e0
more standard Thy_Load.check_thy for Pure.thy, relying on its header;
 wenzelm parents: 
48874diff
changeset | 295 | in Task (parents, load) end); | 
| 48874 
ff9cd47be39b
refined Thy_Load.check_thy: find more uses in body text, based on keywords;
 wenzelm parents: 
48710diff
changeset | 296 | |
| 
ff9cd47be39b
refined Thy_Load.check_thy: find more uses in body text, based on keywords;
 wenzelm parents: 
48710diff
changeset | 297 | val tasks'' = new_entry name parents task tasks'; | 
| 48898 
9fc880720663
simplified Thy_Load.check_thy (again) -- no need to pass keywords nor find files in body text;
 wenzelm parents: 
48888diff
changeset | 298 | in (all_current, tasks'') end) | 
| 7066 | 299 | end; | 
| 6484 
3f098b0ec683
use_thy etc.: may specify path prefix, which is temporarily used as load path;
 wenzelm parents: 
6389diff
changeset | 300 | |
| 23967 | 301 | end; | 
| 302 | ||
| 303 | ||
| 37979 | 304 | (* use_thy *) | 
| 23967 | 305 | |
| 38146 | 306 | fun use_thys_wrt dir arg = | 
| 48898 
9fc880720663
simplified Thy_Load.check_thy (again) -- no need to pass keywords nor find files in body text;
 wenzelm parents: 
48888diff
changeset | 307 | schedule_tasks (snd (require_thys [] dir arg Graph.empty)); | 
| 23967 | 308 | |
| 38146 | 309 | val use_thys = use_thys_wrt Path.current; | 
| 37949 
48a874444164
moved management of auxiliary theory source files to Thy_Load -- as theory data instead of accidental loader state;
 wenzelm parents: 
37942diff
changeset | 310 | val use_thy = use_thys o single; | 
| 7211 | 311 | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 312 | |
| 37979 | 313 | (* toplevel begin theory -- without maintaining database *) | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 314 | |
| 48888 | 315 | fun toplevel_begin_theory master_dir (header: Thy_Header.header) = | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 316 | let | 
| 48927 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48898diff
changeset | 317 |     val {name = (name, _), imports, ...} = header;
 | 
| 37977 
3ceccd415145
simplified/clarified theory loader: more explicit task management, kill old versions at start, commit results only in the very end, non-optional master dependency, do not store text in deps;
 wenzelm parents: 
37955diff
changeset | 318 | val _ = kill_thy name; | 
| 48888 | 319 | val _ = use_thys_wrt master_dir imports; | 
| 46958 
0ec8f04e753a
define keywords early when processing the theory header, before running the body commands;
 wenzelm parents: 
46938diff
changeset | 320 | val _ = Thy_Header.define_keywords header; | 
| 48927 
ef462b5558eb
theory def/ref position reports, which enable hyperlinks etc.;
 wenzelm parents: 
48898diff
changeset | 321 | val parents = map (get_theory o base_name o fst) imports; | 
| 48888 | 322 | in Thy_Load.begin_theory master_dir header parents end; | 
| 7244 | 323 | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 324 | |
| 37977 
3ceccd415145
simplified/clarified theory loader: more explicit task management, kill old versions at start, commit results only in the very end, non-optional master dependency, do not store text in deps;
 wenzelm parents: 
37955diff
changeset | 325 | (* register theory *) | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 326 | |
| 37954 
a2e73df0b1e0
simplified/clarified register_thy: more precise treatment of new dependencies, remove descendants;
 wenzelm parents: 
37953diff
changeset | 327 | fun register_thy theory = | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 328 | let | 
| 16454 | 329 | val name = Context.theory_name theory; | 
| 48898 
9fc880720663
simplified Thy_Load.check_thy (again) -- no need to pass keywords nor find files in body text;
 wenzelm parents: 
48888diff
changeset | 330 |     val {master, ...} = Thy_Load.check_thy (Thy_Load.master_directory theory) name;
 | 
| 41548 
bd0bebf93fa6
Thy_Load.begin_theory: maintain source specification of imports;
 wenzelm parents: 
41536diff
changeset | 331 | val imports = Thy_Load.imports_of theory; | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 332 | in | 
| 38145 
675827e61eb9
more precise CRITICAL sections, using NAMED_CRITICAL uniformly;
 wenzelm parents: 
38143diff
changeset | 333 | NAMED_CRITICAL "Thy_Info" (fn () => | 
| 38142 | 334 | (kill_thy name; | 
| 40132 
7ee65dbffa31
renamed Output.priority to Output.urgent_message to emphasize its special role more clearly;
 wenzelm parents: 
39557diff
changeset | 335 |       Output.urgent_message ("Registering theory " ^ quote name);
 | 
| 43640 | 336 | update_thy (make_deps master imports) theory)) | 
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 337 | end; | 
| 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 338 | |
| 24080 
8c67d869531b
added register_thy (replaces pretend_use_thy_only and really flag);
 wenzelm parents: 
24071diff
changeset | 339 | |
| 
8c67d869531b
added register_thy (replaces pretend_use_thy_only and really flag);
 wenzelm parents: 
24071diff
changeset | 340 | (* finish all theories *) | 
| 
8c67d869531b
added register_thy (replaces pretend_use_thy_only and really flag);
 wenzelm parents: 
24071diff
changeset | 341 | |
| 39021 | 342 | fun finish () = change_thys (Graph.map (fn _ => fn (_, entry) => (NONE, entry))); | 
| 24080 
8c67d869531b
added register_thy (replaces pretend_use_thy_only and really flag);
 wenzelm parents: 
24071diff
changeset | 343 | |
| 6211 
43d0efafa025
Theory loader database: theory and file dependencies, theory values
 wenzelm parents: 
5211diff
changeset | 344 | end; |