121 val dirs: List[Path], |
121 val dirs: List[Path], |
122 val select_dirs: List[Path], |
122 val select_dirs: List[Path], |
123 val session_options: Options, |
123 val session_options: Options, |
124 val deps: Sessions.Deps) |
124 val deps: Sessions.Deps) |
125 { |
125 { |
|
126 context => |
|
127 |
126 def session_dirs: List[Path] = dirs ::: select_dirs |
128 def session_dirs: List[Path] = dirs ::: select_dirs |
127 |
129 |
128 def build_logic(logic: String) |
130 def build_logic(logic: String) |
129 { |
131 { |
130 Build.build_logic(options, logic, build_heap = true, progress = progress, |
132 Build.build_logic(options, logic, build_heap = true, progress = progress, |
132 } |
134 } |
133 |
135 |
134 def session(logic: String, log: Logger = No_Logger): Session = |
136 def session(logic: String, log: Logger = No_Logger): Session = |
135 { |
137 { |
136 build_logic(logic) |
138 build_logic(logic) |
137 new Session(this, logic, log) |
139 new Session(context, logic, log, deps.sessions_structure.imports_topological_order) |
138 } |
140 } |
139 } |
141 |
140 |
142 def partition_sessions( |
141 class Session private[Dump](context: Context, logic: String, log: Logger) |
143 logic: String = default_logic, |
|
144 log: Logger = No_Logger, |
|
145 split_partitions: Boolean = false): List[Session] = |
|
146 { |
|
147 val session_graph = deps.sessions_structure.imports_graph |
|
148 |
|
149 val afp_sessions = |
|
150 if (split_partitions) { |
|
151 (for ((name, (info, _)) <- session_graph.iterator if info.is_afp) yield name).toSet |
|
152 } |
|
153 else Set.empty[String] |
|
154 |
|
155 val afp_bulky_sessions = |
|
156 (for (name <- afp_sessions.iterator if deps.sessions_structure(name).is_afp_bulky) |
|
157 yield name).toList |
|
158 |
|
159 val base_sessions = session_graph.all_preds(List(logic)).reverse |
|
160 |
|
161 val base = |
|
162 if (logic == isabelle.Thy_Header.PURE) Nil |
|
163 else List(new Session(context, isabelle.Thy_Header.PURE, log, base_sessions)) |
|
164 |
|
165 val main = |
|
166 new Session(context, logic, log, |
|
167 session_graph.topological_order.filterNot(name => |
|
168 afp_sessions.contains(name) || base_sessions.contains(name))) |
|
169 |
|
170 val afp = |
|
171 if (afp_sessions.isEmpty) Nil |
|
172 else { |
|
173 val (part1, part2) = |
|
174 { |
|
175 val graph = session_graph.restrict(afp_sessions -- afp_bulky_sessions) |
|
176 val force_partition1 = AFP.force_partition1.filter(graph.defined(_)) |
|
177 val force_part1 = graph.all_preds(graph.all_succs(force_partition1)).toSet |
|
178 graph.keys.partition(a => force_part1(a) || graph.is_isolated(a)) |
|
179 } |
|
180 for (part <- List(part1, part2, afp_bulky_sessions) if part.nonEmpty) |
|
181 yield new Session(context, logic, log, part) |
|
182 } |
|
183 |
|
184 build_logic(logic) |
|
185 base ::: List(main) ::: afp |
|
186 } |
|
187 } |
|
188 |
|
189 class Session private[Dump]( |
|
190 context: Context, val logic: String, log: Logger, val selected_sessions: List[String]) |
142 { |
191 { |
143 /* resources */ |
192 /* resources */ |
144 |
193 |
145 private val progress = context.progress |
194 private val progress = context.progress |
|
195 |
|
196 private val selected_session = selected_sessions.toSet |
|
197 |
|
198 private def selected_theory(name: Document.Node.Name): Boolean = |
|
199 selected_session(context.deps.sessions_structure.theory_qualifier(name.theory)) |
146 |
200 |
147 val resources: Headless.Resources = |
201 val resources: Headless.Resources = |
148 Headless.Resources.make(context.session_options, logic, progress = progress, log = log, |
202 Headless.Resources.make(context.session_options, logic, progress = progress, log = log, |
149 session_dirs = context.session_dirs, |
203 session_dirs = context.session_dirs, |
150 include_sessions = context.deps.sessions_structure.imports_topological_order) |
204 include_sessions = context.deps.sessions_structure.imports_topological_order) |
151 |
205 |
152 val used_theories: List[Document.Node.Name] = |
206 val used_theories: List[Document.Node.Name] = |
153 { |
207 { |
154 for { |
208 for { |
155 (name, _) <- |
209 (name, _) <- |
156 context.deps.used_theories_condition(context.session_options, progress = progress) |
210 context.deps.used_theories_condition(context.session_options, |
|
211 restrict = selected_session, |
|
212 progress = progress) |
157 if !resources.session_base.loaded_theory(name.theory) |
213 if !resources.session_base.loaded_theory(name.theory) |
158 } yield name |
214 } yield name |
159 } |
215 } |
160 |
216 |
161 |
217 |
181 Consumer_Thread.fork(name = "dump")( |
237 Consumer_Thread.fork(name = "dump")( |
182 consume = (args: (Document.Snapshot, Document_Status.Node_Status)) => |
238 consume = (args: (Document.Snapshot, Document_Status.Node_Status)) => |
183 { |
239 { |
184 val (snapshot, status) = args |
240 val (snapshot, status) = args |
185 val name = snapshot.node_name |
241 val name = snapshot.node_name |
186 if (status.ok) { |
242 if (status.ok && selected_theory(name)) { |
187 try { process_theory(Args(session, snapshot, status)) } |
243 try { process_theory(Args(session, snapshot, status)) } |
188 catch { |
244 catch { |
189 case exn: Throwable if !Exn.is_interrupt(exn) => |
245 case exn: Throwable if !Exn.is_interrupt(exn) => |
190 val msg = Exn.message(exn) |
246 val msg = Exn.message(exn) |
191 progress.echo("FAILED to process theory " + name) |
247 progress.echo("FAILED to process theory " + name) |
192 progress.echo_error_message(msg) |
248 progress.echo_error_message(msg) |
193 consumer_bad_theories.change(Bad_Theory(name, status, List(msg)) :: _) |
249 consumer_bad_theories.change(Bad_Theory(name, status, List(msg)) :: _) |
194 } |
250 } |
195 } |
251 } |
196 else { |
252 else { |
197 val msgs = |
253 val msgs = |
198 for ((tree, pos) <- snapshot.messages if Protocol.is_error(tree)) |
254 for ((tree, pos) <- snapshot.messages if Protocol.is_error(tree)) |
261 progress: Progress = No_Progress, |
317 progress: Progress = No_Progress, |
262 log: Logger = No_Logger, |
318 log: Logger = No_Logger, |
263 dirs: List[Path] = Nil, |
319 dirs: List[Path] = Nil, |
264 select_dirs: List[Path] = Nil, |
320 select_dirs: List[Path] = Nil, |
265 output_dir: Path = default_output_dir, |
321 output_dir: Path = default_output_dir, |
|
322 split_partitions: Boolean = false, |
266 selection: Sessions.Selection = Sessions.Selection.empty) |
323 selection: Sessions.Selection = Sessions.Selection.empty) |
267 { |
324 { |
268 val context = |
325 val context = |
269 Context(options, aspects = aspects, progress = progress, dirs = dirs, |
326 Context(options, aspects = aspects, progress = progress, dirs = dirs, |
270 select_dirs = select_dirs, selection = selection) |
327 select_dirs = select_dirs, selection = selection) |
271 |
328 |
272 context.session(logic, log = log).process((args: Args) => |
329 context.partition_sessions(logic = logic, log = log, split_partitions = split_partitions). |
273 { |
330 foreach(_.process((args: Args) => |
274 progress.echo("Processing theory " + args.print_node + " ...") |
331 { |
275 val aspect_args = |
332 progress.echo("Processing theory " + args.print_node + " ...") |
276 Aspect_Args(context.session_options, context.deps, progress, output_dir, |
333 val aspect_args = |
277 args.snapshot, args.status) |
334 Aspect_Args(context.session_options, context.deps, progress, output_dir, |
278 aspects.foreach(_.operation(aspect_args)) |
335 args.snapshot, args.status) |
279 }) |
336 aspects.foreach(_.operation(aspect_args)) |
|
337 })) |
280 } |
338 } |
281 |
339 |
282 |
340 |
283 /* Isabelle tool wrapper */ |
341 /* Isabelle tool wrapper */ |
284 |
342 |
287 { |
345 { |
288 var aspects: List[Aspect] = known_aspects |
346 var aspects: List[Aspect] = known_aspects |
289 var base_sessions: List[String] = Nil |
347 var base_sessions: List[String] = Nil |
290 var select_dirs: List[Path] = Nil |
348 var select_dirs: List[Path] = Nil |
291 var output_dir = default_output_dir |
349 var output_dir = default_output_dir |
|
350 var split_partitions = false |
292 var requirements = false |
351 var requirements = false |
293 var exclude_session_groups: List[String] = Nil |
352 var exclude_session_groups: List[String] = Nil |
294 var all_sessions = false |
353 var all_sessions = false |
|
354 var logic = default_logic |
295 var dirs: List[Path] = Nil |
355 var dirs: List[Path] = Nil |
296 var session_groups: List[String] = Nil |
356 var session_groups: List[String] = Nil |
297 var logic = default_logic |
|
298 var options = Options.init() |
357 var options = Options.init() |
299 var verbose = false |
358 var verbose = false |
300 var exclude_sessions: List[String] = Nil |
359 var exclude_sessions: List[String] = Nil |
301 |
360 |
302 val getopts = Getopts(""" |
361 val getopts = Getopts(""" |
305 Options are: |
364 Options are: |
306 -A NAMES dump named aspects (default: """ + known_aspects.mkString("\"", ",", "\"") + """) |
365 -A NAMES dump named aspects (default: """ + known_aspects.mkString("\"", ",", "\"") + """) |
307 -B NAME include session NAME and all descendants |
366 -B NAME include session NAME and all descendants |
308 -D DIR include session directory and select its sessions |
367 -D DIR include session directory and select its sessions |
309 -O DIR output directory for dumped files (default: """ + default_output_dir + """) |
368 -O DIR output directory for dumped files (default: """ + default_output_dir + """) |
|
369 -P split into standard partitions (AFP, non-AFP, ...) |
310 -R operate on requirements of selected sessions |
370 -R operate on requirements of selected sessions |
311 -X NAME exclude sessions from group NAME and all descendants |
371 -X NAME exclude sessions from group NAME and all descendants |
312 -a select all sessions |
372 -a select all sessions |
|
373 -b NAME base logic image (default """ + isabelle.quote(default_logic) + """) |
313 -d DIR include session directory |
374 -d DIR include session directory |
314 -g NAME select session group NAME |
375 -g NAME select session group NAME |
315 -l NAME logic session name (default """ + quote(logic) + """) |
|
316 -o OPTION override Isabelle system OPTION (via NAME=VAL or NAME) |
376 -o OPTION override Isabelle system OPTION (via NAME=VAL or NAME) |
317 -v verbose |
377 -v verbose |
318 -x NAME exclude session NAME and all descendants |
378 -x NAME exclude session NAME and all descendants |
319 |
379 |
320 Dump cumulative PIDE session database, with the following aspects: |
380 Dump cumulative PIDE session database, with the following aspects: |
322 """ + Library.prefix_lines(" ", show_aspects) + "\n", |
382 """ + Library.prefix_lines(" ", show_aspects) + "\n", |
323 "A:" -> (arg => aspects = Library.distinct(space_explode(',', arg)).map(the_aspect(_))), |
383 "A:" -> (arg => aspects = Library.distinct(space_explode(',', arg)).map(the_aspect(_))), |
324 "B:" -> (arg => base_sessions = base_sessions ::: List(arg)), |
384 "B:" -> (arg => base_sessions = base_sessions ::: List(arg)), |
325 "D:" -> (arg => select_dirs = select_dirs ::: List(Path.explode(arg))), |
385 "D:" -> (arg => select_dirs = select_dirs ::: List(Path.explode(arg))), |
326 "O:" -> (arg => output_dir = Path.explode(arg)), |
386 "O:" -> (arg => output_dir = Path.explode(arg)), |
|
387 "P" -> (_ => split_partitions = true), |
327 "R" -> (_ => requirements = true), |
388 "R" -> (_ => requirements = true), |
328 "X:" -> (arg => exclude_session_groups = exclude_session_groups ::: List(arg)), |
389 "X:" -> (arg => exclude_session_groups = exclude_session_groups ::: List(arg)), |
329 "a" -> (_ => all_sessions = true), |
390 "a" -> (_ => all_sessions = true), |
|
391 "b:" -> (arg => logic = arg), |
330 "d:" -> (arg => dirs = dirs ::: List(Path.explode(arg))), |
392 "d:" -> (arg => dirs = dirs ::: List(Path.explode(arg))), |
331 "g:" -> (arg => session_groups = session_groups ::: List(arg)), |
393 "g:" -> (arg => session_groups = session_groups ::: List(arg)), |
332 "l:" -> (arg => logic = arg), |
|
333 "o:" -> (arg => options = options + arg), |
394 "o:" -> (arg => options = options + arg), |
334 "v" -> (_ => verbose = true), |
395 "v" -> (_ => verbose = true), |
335 "x:" -> (arg => exclude_sessions = exclude_sessions ::: List(arg))) |
396 "x:" -> (arg => exclude_sessions = exclude_sessions ::: List(arg))) |
336 |
397 |
337 val sessions = getopts(args) |
398 val sessions = getopts(args) |
343 aspects = aspects, |
404 aspects = aspects, |
344 progress = progress, |
405 progress = progress, |
345 dirs = dirs, |
406 dirs = dirs, |
346 select_dirs = select_dirs, |
407 select_dirs = select_dirs, |
347 output_dir = output_dir, |
408 output_dir = output_dir, |
|
409 split_partitions = split_partitions, |
348 selection = Sessions.Selection( |
410 selection = Sessions.Selection( |
349 requirements = requirements, |
411 requirements = requirements, |
350 all_sessions = all_sessions, |
412 all_sessions = all_sessions, |
351 base_sessions = base_sessions, |
413 base_sessions = base_sessions, |
352 exclude_session_groups = exclude_session_groups, |
414 exclude_session_groups = exclude_session_groups, |