53 fun cycle_msg names = loader_msg ("cyclic dependency of " ^ show_path names) []; |
53 fun cycle_msg names = loader_msg ("cyclic dependency of " ^ show_path names) []; |
54 |
54 |
55 |
55 |
56 (* derived graph operations *) |
56 (* derived graph operations *) |
57 |
57 |
58 fun add_deps name parents G = Graph.add_deps_acyclic (name, parents) G |
58 fun add_deps name parents G = String_Graph.add_deps_acyclic (name, parents) G |
59 handle Graph.CYCLES namess => error (cat_lines (map cycle_msg namess)); |
59 handle String_Graph.CYCLES namess => error (cat_lines (map cycle_msg namess)); |
60 |
60 |
61 fun new_entry name parents entry = |
61 fun new_entry name parents entry = |
62 Graph.new_node (name, entry) #> add_deps name parents; |
62 String_Graph.new_node (name, entry) #> add_deps name parents; |
63 |
63 |
64 |
64 |
65 (* thy database *) |
65 (* thy database *) |
66 |
66 |
67 type deps = |
67 type deps = |
72 |
72 |
73 fun master_dir (d: deps option) = the_default Path.current (Option.map (Path.dir o #1 o #master) d); |
73 fun master_dir (d: deps option) = the_default Path.current (Option.map (Path.dir o #1 o #master) d); |
74 fun base_name s = Path.implode (Path.base (Path.explode s)); |
74 fun base_name s = Path.implode (Path.base (Path.explode s)); |
75 |
75 |
76 local |
76 local |
77 val database = Unsynchronized.ref (Graph.empty: (deps option * theory option) Graph.T); |
77 val database = |
|
78 Unsynchronized.ref (String_Graph.empty: (deps option * theory option) String_Graph.T); |
78 in |
79 in |
79 fun get_thys () = ! database; |
80 fun get_thys () = ! database; |
80 fun change_thys f = NAMED_CRITICAL "Thy_Info" (fn () => Unsynchronized.change database f); |
81 fun change_thys f = NAMED_CRITICAL "Thy_Info" (fn () => Unsynchronized.change database f); |
81 end; |
82 end; |
82 |
83 |
83 |
84 |
84 (* access thy graph *) |
85 (* access thy graph *) |
85 |
86 |
86 fun thy_graph f x = f (get_thys ()) x; |
87 fun thy_graph f x = f (get_thys ()) x; |
87 |
88 |
88 fun get_names () = Graph.topological_order (get_thys ()); |
89 fun get_names () = String_Graph.topological_order (get_thys ()); |
89 |
90 |
90 |
91 |
91 (* access thy *) |
92 (* access thy *) |
92 |
93 |
93 fun lookup_thy name = |
94 fun lookup_thy name = |
94 SOME (thy_graph Graph.get_node name) handle Graph.UNDEF _ => NONE; |
95 SOME (thy_graph String_Graph.get_node name) handle String_Graph.UNDEF _ => NONE; |
95 |
96 |
96 val known_thy = is_some o lookup_thy; |
97 val known_thy = is_some o lookup_thy; |
97 |
98 |
98 fun get_thy name = |
99 fun get_thy name = |
99 (case lookup_thy name of |
100 (case lookup_thy name of |
137 |
138 |
138 fun remove_thy name = NAMED_CRITICAL "Thy_Info" (fn () => |
139 fun remove_thy name = NAMED_CRITICAL "Thy_Info" (fn () => |
139 if is_finished name then error (loader_msg "attempt to change finished theory" [name]) |
140 if is_finished name then error (loader_msg "attempt to change finished theory" [name]) |
140 else |
141 else |
141 let |
142 let |
142 val succs = thy_graph Graph.all_succs [name]; |
143 val succs = thy_graph String_Graph.all_succs [name]; |
143 val _ = Output.urgent_message (loader_msg "removing" succs); |
144 val _ = Output.urgent_message (loader_msg "removing" succs); |
144 val _ = List.app (perform Remove) succs; |
145 val _ = List.app (perform Remove) succs; |
145 val _ = change_thys (fold Graph.del_node succs); |
146 val _ = change_thys (fold String_Graph.del_node succs); |
146 in () end); |
147 in () end); |
147 |
148 |
148 fun kill_thy name = NAMED_CRITICAL "Thy_Info" (fn () => |
149 fun kill_thy name = NAMED_CRITICAL "Thy_Info" (fn () => |
149 if known_thy name then remove_thy name |
150 if known_thy name then remove_thy name |
150 else ()); |
151 else ()); |
177 |
178 |
178 fun finish_thy ((thy, present, commit): result) = |
179 fun finish_thy ((thy, present, commit): result) = |
179 (Thm.join_theory_proofs thy; Future.join present; commit (); thy); |
180 (Thm.join_theory_proofs thy; Future.join present; commit (); thy); |
180 |
181 |
181 val schedule_seq = |
182 val schedule_seq = |
182 Graph.schedule (fn deps => fn (_, task) => |
183 String_Graph.schedule (fn deps => fn (_, task) => |
183 (case task of |
184 (case task of |
184 Task (parents, body) => finish_thy (body (task_parents deps parents)) |
185 Task (parents, body) => finish_thy (body (task_parents deps parents)) |
185 | Finished thy => thy)) #> ignore; |
186 | Finished thy => thy)) #> ignore; |
186 |
187 |
187 val schedule_futures = uninterruptible (fn _ => |
188 val schedule_futures = uninterruptible (fn _ => |
188 Graph.schedule (fn deps => fn (name, task) => |
189 String_Graph.schedule (fn deps => fn (name, task) => |
189 (case task of |
190 (case task of |
190 Task (parents, body) => |
191 Task (parents, body) => |
191 (singleton o Future.forks) |
192 (singleton o Future.forks) |
192 {name = "theory:" ^ name, group = NONE, |
193 {name = "theory:" ^ name, group = NONE, |
193 deps = map (Future.task_of o #2) deps, pri = 0, interrupts = true} |
194 deps = map (Future.task_of o #2) deps, pri = 0, interrupts = true} |
263 and require_thy initiators dir (str, require_pos) tasks = |
264 and require_thy initiators dir (str, require_pos) tasks = |
264 let |
265 let |
265 val path = Path.expand (Path.explode str); |
266 val path = Path.expand (Path.explode str); |
266 val name = Path.implode (Path.base path); |
267 val name = Path.implode (Path.base path); |
267 in |
268 in |
268 (case try (Graph.get_node tasks) name of |
269 (case try (String_Graph.get_node tasks) name of |
269 SOME task => (task_finished task, tasks) |
270 SOME task => (task_finished task, tasks) |
270 | NONE => |
271 | NONE => |
271 let |
272 let |
272 val dir' = Path.append dir (Path.dir path); |
273 val dir' = Path.append dir (Path.dir path); |
273 val _ = member (op =) initiators name andalso error (cycle_msg initiators); |
274 val _ = member (op =) initiators name andalso error (cycle_msg initiators); |