| author | wenzelm | 
| Sat, 20 May 2023 16:12:37 +0200 | |
| changeset 78084 | f0aca0506531 | 
| parent 77548 | 28b94fe1c00f | 
| child 78435 | a623cb346b4a | 
| permissions | -rw-r--r-- | 
| 68308 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 1 | /* Title: Pure/Tools/dump.scala | 
| 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 2 | Author: Makarius | 
| 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 3 | |
| 68348 | 4 | Dump cumulative PIDE session database. | 
| 68308 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 5 | */ | 
| 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 6 | |
| 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 7 | package isabelle | 
| 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 8 | |
| 71534 | 9 | import java.io.{BufferedWriter, FileOutputStream, OutputStreamWriter}
 | 
| 10 | ||
| 68308 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 11 | |
| 75393 | 12 | object Dump {
 | 
| 68316 | 13 | /* aspects */ | 
| 14 | ||
| 15 | sealed case class Aspect_Args( | |
| 68355 | 16 | options: Options, | 
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 17 | deps: Sessions.Deps, | 
| 68355 | 18 | progress: Progress, | 
| 69896 | 19 | output_dir: Path, | 
| 68929 | 20 | snapshot: Document.Snapshot, | 
| 75393 | 21 | status: Document_Status.Node_Status | 
| 22 |   ) {
 | |
| 23 |     def write_path(file_name: Path): Path = {
 | |
| 68929 | 24 | val path = output_dir + Path.basic(snapshot.node_name.theory) + file_name | 
| 72375 | 25 | Isabelle_System.make_directory(path.dir) | 
| 71534 | 26 | path | 
| 68319 | 27 | } | 
| 28 | ||
| 71534 | 29 | def write(file_name: Path, bytes: Bytes): Unit = | 
| 30 | Bytes.write(write_path(file_name), bytes) | |
| 31 | ||
| 68365 | 32 | def write(file_name: Path, text: String): Unit = | 
| 33 | write(file_name, Bytes(text)) | |
| 68332 | 34 | |
| 68365 | 35 | def write(file_name: Path, body: XML.Body): Unit = | 
| 71534 | 36 | using(File.writer(write_path(file_name).file))( | 
| 37 | writer => YXML.traversal(s => writer.write(Symbol.encode(s)), body)) | |
| 68319 | 38 | } | 
| 68316 | 39 | |
| 75393 | 40 | sealed case class Aspect( | 
| 41 | name: String, | |
| 42 | description: String, | |
| 43 | operation: Aspect_Args => Unit, | |
| 44 | options: List[String] = Nil | |
| 45 |   ) {
 | |
| 68345 | 46 | override def toString: String = name | 
| 47 | } | |
| 68316 | 48 | |
| 69521 | 49 | val known_aspects: List[Aspect] = | 
| 68316 | 50 | List( | 
| 68365 | 51 |       Aspect("markup", "PIDE markup (YXML format)",
 | 
| 72724 | 52 | args => args.write(Path.explode(Export.MARKUP), args.snapshot.xml_markup())), | 
| 68319 | 53 |       Aspect("messages", "output messages (YXML format)",
 | 
| 72724 | 54 | args => args.write(Path.explode(Export.MESSAGES), args.snapshot.messages.map(_._1))), | 
| 68347 | 55 |       Aspect("latex", "generated LaTeX source",
 | 
| 72724 | 56 | args => | 
| 57 |           for {
 | |
| 58 | entry <- args.snapshot.exports | |
| 59 | if entry.name_has_prefix(Export.DOCUMENT_PREFIX) | |
| 76852 | 60 | } args.write(Path.explode(entry.name), entry.bytes)), | 
| 68347 | 61 |       Aspect("theory", "foundational theory content",
 | 
| 72724 | 62 | args => | 
| 63 |           for {
 | |
| 64 | entry <- args.snapshot.exports | |
| 65 | if entry.name_has_prefix(Export.THEORY_PREFIX) | |
| 76852 | 66 | } args.write(Path.explode(entry.name), entry.bytes), | 
| 72724 | 67 |         options = List("export_theory"))
 | 
| 68345 | 68 | ).sortBy(_.name) | 
| 68316 | 69 | |
| 70 | def show_aspects: String = | |
| 68345 | 71 | cat_lines(known_aspects.map(aspect => aspect.name + " - " + aspect.description)) | 
| 68316 | 72 | |
| 73 | def the_aspect(name: String): Aspect = | |
| 74 | known_aspects.find(aspect => aspect.name == name) getOrElse | |
| 75 |       error("Unknown aspect " + quote(name))
 | |
| 76 | ||
| 77 | ||
| 70856 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 78 | /* context and session */ | 
| 69538 
faf547d2834c
clarified signature, notably cascade of dump_options, deps, resources, session;
 wenzelm parents: 
69537diff
changeset | 79 | |
| 69896 | 80 | sealed case class Args( | 
| 69897 | 81 | session: Headless.Session, | 
| 82 | snapshot: Document.Snapshot, | |
| 75393 | 83 | status: Document_Status.Node_Status | 
| 84 |   ) {
 | |
| 69896 | 85 | def print_node: String = snapshot.node_name.toString | 
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 86 | } | 
| 69896 | 87 | |
| 75393 | 88 |   object Context {
 | 
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 89 | def apply( | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 90 | options: Options, | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 91 | aspects: List[Aspect] = Nil, | 
| 71726 
a5fda30edae2
clarified signature: more uniform treatment of stopped/interrupted state;
 wenzelm parents: 
71678diff
changeset | 92 | progress: Progress = new Progress, | 
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 93 | dirs: List[Path] = Nil, | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 94 | select_dirs: List[Path] = Nil, | 
| 71161 
ffccc1f346ae
avoid vacuous session Pure -- dump does not read_pure_theory;
 wenzelm parents: 
71159diff
changeset | 95 | selection: Sessions.Selection = Sessions.Selection.empty, | 
| 71573 
c67076c07fb8
avoid accidental update of base session sources (following documentation in "system" manual);
 wenzelm parents: 
71534diff
changeset | 96 | pure_base: Boolean = false, | 
| 75393 | 97 | skip_base: Boolean = false | 
| 98 |     ): Context = {
 | |
| 99 |       val session_options: Options = {
 | |
| 70856 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 100 | val options1 = | 
| 77548 | 101 | Host.process_policy(options, Host.numa_node0()) + | 
| 70856 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 102 | "parallel_proofs=0" + | 
| 71678 | 103 | "completion_limit=0" + | 
| 76426 | 104 | "editor_tracing_messages=0" | 
| 73359 | 105 |         aspects.foldLeft(options1) { case (opts, aspect) => aspect.options.foldLeft(opts)(_ + _) }
 | 
| 70856 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 106 | } | 
| 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 107 | |
| 70869 | 108 | val sessions_structure: Sessions.Structure = | 
| 70856 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 109 | Sessions.load_structure(session_options, dirs = dirs, select_dirs = select_dirs). | 
| 70869 | 110 | selection(selection) | 
| 111 | ||
| 112 |       {
 | |
| 113 | val selection_size = sessions_structure.build_graph.size | |
| 114 |         if (selection_size > 1) progress.echo("Loading " + selection_size + " sessions ...")
 | |
| 115 | } | |
| 116 | ||
| 117 | val deps: Sessions.Deps = | |
| 118 | Sessions.deps(sessions_structure, progress = progress).check_errors | |
| 70856 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 119 | |
| 71573 
c67076c07fb8
avoid accidental update of base session sources (following documentation in "system" manual);
 wenzelm parents: 
71534diff
changeset | 120 | new Context(options, progress, dirs, select_dirs, pure_base, skip_base, session_options, deps) | 
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 121 | } | 
| 69896 | 122 | } | 
| 123 | ||
| 70856 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 124 | class Context private( | 
| 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 125 | val options: Options, | 
| 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 126 | val progress: Progress, | 
| 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 127 | val dirs: List[Path], | 
| 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 128 | val select_dirs: List[Path], | 
| 71161 
ffccc1f346ae
avoid vacuous session Pure -- dump does not read_pure_theory;
 wenzelm parents: 
71159diff
changeset | 129 | val pure_base: Boolean, | 
| 71573 
c67076c07fb8
avoid accidental update of base session sources (following documentation in "system" manual);
 wenzelm parents: 
71534diff
changeset | 130 | val skip_base: Boolean, | 
| 70856 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 131 | val session_options: Options, | 
| 75393 | 132 | val deps: Sessions.Deps | 
| 133 |   ) {
 | |
| 70859 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 134 | context => | 
| 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 135 | |
| 70856 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 136 | def session_dirs: List[Path] = dirs ::: select_dirs | 
| 68926 | 137 | |
| 75393 | 138 |     def build_logic(logic: String): Unit = {
 | 
| 70857 | 139 | Build.build_logic(options, logic, build_heap = true, progress = progress, | 
| 140 | dirs = session_dirs, strict = true) | |
| 141 | } | |
| 142 | ||
| 70864 | 143 | def sessions( | 
| 70859 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 144 | logic: String = default_logic, | 
| 75393 | 145 | log: Logger = No_Logger | 
| 146 |     ): List[Session] = {
 | |
| 70869 | 147 | /* partitions */ | 
| 148 | ||
| 149 | def session_info(session_name: String): Sessions.Info = | |
| 150 | deps.sessions_structure(session_name) | |
| 151 | ||
| 70870 
877fe56af178
proper build_graph to make session selection work as in "isabelle build";
 wenzelm parents: 
70869diff
changeset | 152 | val session_graph = deps.sessions_structure.build_graph | 
| 70869 | 153 | val all_sessions = session_graph.topological_order | 
| 70859 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 154 | |
| 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 155 | val afp_sessions = | 
| 70869 | 156 | (for (name <- all_sessions if session_info(name).is_afp) yield name).toSet | 
| 70859 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 157 | |
| 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 158 | val afp_bulky_sessions = | 
| 70869 | 159 | (for (name <- all_sessions if session_info(name).is_afp_bulky) yield name).toList | 
| 70859 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 160 | |
| 70862 | 161 | val base_sessions = | 
| 72065 
11dc8929832d
clarified order --- proper sorting of requirements;
 wenzelm parents: 
71894diff
changeset | 162 | session_graph.all_preds_rev(List(logic).filter(session_graph.defined)) | 
| 70859 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 163 | |
| 70869 | 164 | val proof_sessions = | 
| 165 | session_graph.all_succs( | |
| 166 | for (name <- all_sessions if session_info(name).record_proofs) yield name) | |
| 167 | ||
| 168 | ||
| 169 | /* resulting sessions */ | |
| 170 | ||
| 171 | def make_session( | |
| 172 | selected_sessions: List[String], | |
| 71158 | 173 | session_logic: String = logic, | 
| 71159 | 174 | strict: Boolean = false, | 
| 75393 | 175 | record_proofs: Boolean = false | 
| 176 |       ): List[Session] = {
 | |
| 71159 | 177 | if (selected_sessions.isEmpty && !strict) Nil | 
| 71158 | 178 | else List(new Session(context, session_logic, log, selected_sessions, record_proofs)) | 
| 70869 | 179 | } | 
| 180 | ||
| 71161 
ffccc1f346ae
avoid vacuous session Pure -- dump does not read_pure_theory;
 wenzelm parents: 
71159diff
changeset | 181 | val PURE = isabelle.Thy_Header.PURE | 
| 
ffccc1f346ae
avoid vacuous session Pure -- dump does not read_pure_theory;
 wenzelm parents: 
71159diff
changeset | 182 | |
| 70859 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 183 | val base = | 
| 71573 
c67076c07fb8
avoid accidental update of base session sources (following documentation in "system" manual);
 wenzelm parents: 
71534diff
changeset | 184 | if ((logic == PURE && !pure_base) || skip_base) Nil | 
| 71161 
ffccc1f346ae
avoid vacuous session Pure -- dump does not read_pure_theory;
 wenzelm parents: 
71159diff
changeset | 185 | else make_session(base_sessions, session_logic = PURE, strict = logic == PURE) | 
| 70859 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 186 | |
| 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 187 | val main = | 
| 70869 | 188 | make_session( | 
| 70859 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 189 | session_graph.topological_order.filterNot(name => | 
| 70869 | 190 | afp_sessions.contains(name) || | 
| 191 | base_sessions.contains(name) || | |
| 192 | proof_sessions.contains(name))) | |
| 193 | ||
| 71161 
ffccc1f346ae
avoid vacuous session Pure -- dump does not read_pure_theory;
 wenzelm parents: 
71159diff
changeset | 194 | val proofs = make_session(proof_sessions, session_logic = PURE, record_proofs = true) | 
| 70859 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 195 | |
| 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 196 | val afp = | 
| 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 197 | if (afp_sessions.isEmpty) Nil | 
| 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 198 |         else {
 | 
| 75393 | 199 |           val (part1, part2) = {
 | 
| 70859 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 200 | val graph = session_graph.restrict(afp_sessions -- afp_bulky_sessions) | 
| 70862 | 201 | val force_partition1 = AFP.force_partition1.filter(graph.defined) | 
| 70859 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 202 | val force_part1 = graph.all_preds(graph.all_succs(force_partition1)).toSet | 
| 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 203 | graph.keys.partition(a => force_part1(a) || graph.is_isolated(a)) | 
| 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 204 | } | 
| 70869 | 205 | List(part1, part2, afp_bulky_sessions).flatMap(make_session(_)) | 
| 70859 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 206 | } | 
| 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 207 | |
| 70874 
2010397f7c9a
load HOL-Proofs first: it introduces some extra "thm" items that are required later on;
 wenzelm parents: 
70871diff
changeset | 208 | proofs ::: base ::: main ::: afp | 
| 70857 | 209 | } | 
| 70875 
a62c34770df9
proper guard for process_theory: ensure uniform precedence of results;
 wenzelm parents: 
70874diff
changeset | 210 | |
| 
a62c34770df9
proper guard for process_theory: ensure uniform precedence of results;
 wenzelm parents: 
70874diff
changeset | 211 | |
| 
a62c34770df9
proper guard for process_theory: ensure uniform precedence of results;
 wenzelm parents: 
70874diff
changeset | 212 | /* processed theories */ | 
| 
a62c34770df9
proper guard for process_theory: ensure uniform precedence of results;
 wenzelm parents: 
70874diff
changeset | 213 | |
| 
a62c34770df9
proper guard for process_theory: ensure uniform precedence of results;
 wenzelm parents: 
70874diff
changeset | 214 | private val processed_theories = Synchronized(Set.empty[String]) | 
| 
a62c34770df9
proper guard for process_theory: ensure uniform precedence of results;
 wenzelm parents: 
70874diff
changeset | 215 | |
| 
a62c34770df9
proper guard for process_theory: ensure uniform precedence of results;
 wenzelm parents: 
70874diff
changeset | 216 | def process_theory(theory: String): Boolean = | 
| 
a62c34770df9
proper guard for process_theory: ensure uniform precedence of results;
 wenzelm parents: 
70874diff
changeset | 217 | processed_theories.change_result(processed => (!processed(theory), processed + theory)) | 
| 70876 | 218 | |
| 219 | ||
| 220 | /* errors */ | |
| 221 | ||
| 222 | private val errors = Synchronized(List.empty[String]) | |
| 223 | ||
| 75393 | 224 |     def add_errors(more_errs: List[String]): Unit = {
 | 
| 70876 | 225 | errors.change(errs => errs ::: more_errs) | 
| 226 | } | |
| 227 | ||
| 75393 | 228 |     def check_errors: Unit = {
 | 
| 70876 | 229 | val errs = errors.value | 
| 230 |       if (errs.nonEmpty) error(errs.mkString("\n\n"))
 | |
| 231 | } | |
| 70856 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 232 | } | 
| 68926 | 233 | |
| 70859 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 234 | class Session private[Dump]( | 
| 70867 | 235 | val context: Context, | 
| 236 | val logic: String, | |
| 237 | log: Logger, | |
| 70869 | 238 | selected_sessions: List[String], | 
| 75393 | 239 | record_proofs: Boolean | 
| 240 |   ) {
 | |
| 70856 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 241 | /* resources */ | 
| 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 242 | |
| 70869 | 243 | val options: Options = | 
| 244 | if (record_proofs) context.session_options + "record_proofs=2" | |
| 245 | else context.session_options | |
| 70866 | 246 | |
| 70867 | 247 | private def deps = context.deps | 
| 248 | private def progress = context.progress | |
| 70856 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 249 | |
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 250 | val resources: Headless.Resources = | 
| 70865 | 251 | Headless.Resources.make(options, logic, progress = progress, log = log, | 
| 70856 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 252 | session_dirs = context.session_dirs, | 
| 70867 | 253 | include_sessions = deps.sessions_structure.imports_topological_order) | 
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 254 | |
| 75393 | 255 |     val used_theories: List[Document.Node.Name] = {
 | 
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 256 |       for {
 | 
| 70867 | 257 | session_name <- | 
| 70871 
2beac4adc565
more complete coverage of sessions: process_theory operation needs to handle duplicate theories;
 wenzelm parents: 
70870diff
changeset | 258 | deps.sessions_structure.build_graph.restrict(selected_sessions.toSet).topological_order | 
| 70867 | 259 | (name, theory_options) <- deps(session_name).used_theories | 
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 260 | if !resources.session_base.loaded_theory(name.theory) | 
| 70867 | 261 |         if {
 | 
| 262 | def warn(msg: String): Unit = | |
| 263 |             progress.echo_warning("Skipping theory " + name + "  (" + msg + ")")
 | |
| 264 | ||
| 265 | val conditions = | |
| 266 |             space_explode(',', theory_options.string("condition")).
 | |
| 267 | filter(cond => Isabelle_System.getenv(cond) == "") | |
| 268 |           if (conditions.nonEmpty) {
 | |
| 269 |             warn("undefined " + conditions.mkString(", "))
 | |
| 270 | false | |
| 271 | } | |
| 272 |           else if (options.bool("skip_proofs") && !theory_options.bool("skip_proofs")) {
 | |
| 273 |             warn("option skip_proofs")
 | |
| 274 | false | |
| 275 | } | |
| 276 | else true | |
| 277 | } | |
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 278 | } yield name | 
| 68926 | 279 | } | 
| 280 | ||
| 281 | ||
| 70856 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 282 | /* process */ | 
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 283 | |
| 75393 | 284 |     def process(process_theory: Args => Unit, unicode_symbols: Boolean = false): Unit = {
 | 
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 285 | val session = resources.start_session(progress = progress) | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 286 | |
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 287 | |
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 288 | // asynchronous consumer | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 289 | |
| 75393 | 290 |       object Consumer {
 | 
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 291 | sealed case class Bad_Theory( | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 292 | name: Document.Node.Name, | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 293 | status: Document_Status.Node_Status, | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 294 | errors: List[String]) | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 295 | |
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 296 | private val consumer_bad_theories = Synchronized(List.empty[Bad_Theory]) | 
| 68318 | 297 | |
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 298 | private val consumer = | 
| 75394 | 299 | Consumer_Thread.fork(name = "dump")(consume = | 
| 300 |             { (args: (Document.Snapshot, Document_Status.Node_Status)) =>
 | |
| 301 | val (snapshot, status) = args | |
| 302 | val name = snapshot.node_name | |
| 303 |               if (status.ok) {
 | |
| 304 |                 try {
 | |
| 305 |                   if (context.process_theory(name.theory)) {
 | |
| 306 | process_theory(Args(session, snapshot, status)) | |
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 307 | } | 
| 70871 
2beac4adc565
more complete coverage of sessions: process_theory operation needs to handle duplicate theories;
 wenzelm parents: 
70870diff
changeset | 308 | } | 
| 75394 | 309 |                 catch {
 | 
| 310 | case exn: Throwable if !Exn.is_interrupt(exn) => | |
| 311 | val msg = Exn.message(exn) | |
| 312 |                     progress.echo("FAILED to process theory " + name)
 | |
| 313 | progress.echo_error_message(msg) | |
| 314 | consumer_bad_theories.change(Bad_Theory(name, status, List(msg)) :: _) | |
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 315 | } | 
| 75394 | 316 | } | 
| 317 |               else {
 | |
| 318 | val msgs = | |
| 319 | for ((elem, pos) <- snapshot.messages if Protocol.is_error(elem)) | |
| 320 |                   yield {
 | |
| 321 | "Error" + Position.here(pos) + ":\n" + | |
| 322 | XML.content(Pretty.formatted(List(elem))) | |
| 323 | } | |
| 324 |                 progress.echo("FAILED to process theory " + name)
 | |
| 77509 
3bc49507bae5
clarified treatment of "verbose" messages, e.g. Progress.theory();
 wenzelm parents: 
77477diff
changeset | 325 | msgs.foreach(progress.echo_error_message(_)) | 
| 75394 | 326 | consumer_bad_theories.change(Bad_Theory(name, status, msgs) :: _) | 
| 327 | } | |
| 328 | true | |
| 329 | }) | |
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 330 | |
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 331 | def apply(snapshot: Document.Snapshot, status: Document_Status.Node_Status): Unit = | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 332 | consumer.send((snapshot, status)) | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 333 | |
| 75393 | 334 |         def shutdown(): List[Bad_Theory] = {
 | 
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 335 | consumer.shutdown() | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 336 | consumer_bad_theories.value.reverse | 
| 70634 
0f8742b5a9e8
more scalable isabelle dump (and derivatives): mark individual theories to share common data in ML;
 wenzelm parents: 
70626diff
changeset | 337 | } | 
| 
0f8742b5a9e8
more scalable isabelle dump (and derivatives): mark individual theories to share common data in ML;
 wenzelm parents: 
70626diff
changeset | 338 | } | 
| 
0f8742b5a9e8
more scalable isabelle dump (and derivatives): mark individual theories to share common data in ML;
 wenzelm parents: 
70626diff
changeset | 339 | |
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 340 | |
| 70653 
f7c5b30fc432
load theories in stages, to reduce ML heap requirements;
 wenzelm parents: 
70645diff
changeset | 341 | // synchronous body | 
| 68320 
1d33697199c1
shutdown ML process before output: Theories_Result is timeless/stateless;
 wenzelm parents: 
68319diff
changeset | 342 | |
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 343 |       try {
 | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 344 | val use_theories_result = | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 345 | session.use_theories(used_theories.map(_.theory), | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 346 | unicode_symbols = unicode_symbols, | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 347 | progress = progress, | 
| 71601 | 348 | commit = Some(Consumer.apply)) | 
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 349 | |
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 350 | val bad_theories = Consumer.shutdown() | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 351 | val bad_msgs = | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 352 | bad_theories.map(bad => | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 353 | Output.clean_yxml( | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 354 | "FAILED theory " + bad.name + | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 355 | (if (bad.status.consolidated) "" else ": " + bad.status.percentage + "% finished") + | 
| 77368 | 356 |                 if_proper(bad.errors, bad.errors.mkString("\n", "\n", ""))))
 | 
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 357 | |
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 358 | val pending_msgs = | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 359 |           use_theories_result.nodes_pending match {
 | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 360 | case Nil => Nil | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 361 |             case pending => List("Pending theories: " + commas(pending.map(p => p._1.toString)))
 | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 362 | } | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 363 | |
| 70876 | 364 | context.add_errors(bad_msgs ::: pending_msgs) | 
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 365 | } | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 366 |       finally { session.stop() }
 | 
| 69032 
90bb4cabe1e8
clarified errors: no result from forced session.stop, check pending theories;
 wenzelm parents: 
69026diff
changeset | 367 | } | 
| 68308 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 368 | } | 
| 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 369 | |
| 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 370 | |
| 69523 | 371 | /* dump */ | 
| 372 | ||
| 373 |   val default_output_dir: Path = Path.explode("dump")
 | |
| 70858 | 374 | val default_logic: String = Thy_Header.PURE | 
| 69523 | 375 | |
| 70640 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 376 | def dump( | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 377 | options: Options, | 
| 
5f4b8a505090
more explicit type Dump.Session, with context information;
 wenzelm parents: 
70634diff
changeset | 378 | logic: String, | 
| 69523 | 379 | aspects: List[Aspect] = Nil, | 
| 71726 
a5fda30edae2
clarified signature: more uniform treatment of stopped/interrupted state;
 wenzelm parents: 
71678diff
changeset | 380 | progress: Progress = new Progress, | 
| 69523 | 381 | log: Logger = No_Logger, | 
| 382 | dirs: List[Path] = Nil, | |
| 383 | select_dirs: List[Path] = Nil, | |
| 384 | output_dir: Path = default_output_dir, | |
| 75393 | 385 | selection: Sessions.Selection = Sessions.Selection.empty | 
| 386 |   ): Unit = {
 | |
| 70856 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 387 | val context = | 
| 
545229df2f82
clarified signature: static Dump.Context vs. dynamic Dump.Session;
 wenzelm parents: 
70796diff
changeset | 388 | Context(options, aspects = aspects, progress = progress, dirs = dirs, | 
| 70796 
2739631ac368
discontinued pointless dump_checkpoint and share_common_data -- superseded by base logic image in Isabelle/MMT;
 wenzelm parents: 
70779diff
changeset | 389 | select_dirs = select_dirs, selection = selection) | 
| 69523 | 390 | |
| 70864 | 391 | context.build_logic(logic) | 
| 392 | ||
| 70865 | 393 |     for (session <- context.sessions(logic = logic, log = log)) {
 | 
| 75394 | 394 |       session.process({ (args: Args) =>
 | 
| 395 |         progress.echo("Processing theory " + args.print_node + " ...")
 | |
| 396 | val aspect_args = | |
| 397 | Aspect_Args(session.options, context.deps, progress, output_dir, | |
| 398 | args.snapshot, args.status) | |
| 399 | aspects.foreach(_.operation(aspect_args)) | |
| 400 | }) | |
| 70865 | 401 | } | 
| 70876 | 402 | |
| 403 | context.check_errors | |
| 69523 | 404 | } | 
| 405 | ||
| 406 | ||
| 68308 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 407 | /* Isabelle tool wrapper */ | 
| 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 408 | |
| 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 409 | val isabelle_tool = | 
| 75393 | 410 |     Isabelle_Tool("dump", "dump cumulative PIDE session database", Scala_Project.here,
 | 
| 75394 | 411 |       { args =>
 | 
| 412 | var aspects: List[Aspect] = known_aspects | |
| 413 | var base_sessions: List[String] = Nil | |
| 414 | var select_dirs: List[Path] = Nil | |
| 415 | var output_dir = default_output_dir | |
| 416 | var requirements = false | |
| 417 | var exclude_session_groups: List[String] = Nil | |
| 418 | var all_sessions = false | |
| 419 | var logic = default_logic | |
| 420 | var dirs: List[Path] = Nil | |
| 421 | var session_groups: List[String] = Nil | |
| 422 | var options = Options.init() | |
| 423 | var verbose = false | |
| 424 | var exclude_sessions: List[String] = Nil | |
| 68308 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 425 | |
| 75394 | 426 |         val getopts = Getopts("""
 | 
| 68308 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 427 | Usage: isabelle dump [OPTIONS] [SESSIONS ...] | 
| 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 428 | |
| 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 429 | Options are: | 
| 68345 | 430 |     -A NAMES     dump named aspects (default: """ + known_aspects.mkString("\"", ",", "\"") + """)
 | 
| 68308 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 431 | -B NAME include session NAME and all descendants | 
| 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 432 | -D DIR include session directory and select its sessions | 
| 68316 | 433 | -O DIR output directory for dumped files (default: """ + default_output_dir + """) | 
| 71807 | 434 | -R refer to requirements of selected sessions | 
| 68308 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 435 | -X NAME exclude sessions from group NAME and all descendants | 
| 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 436 | -a select all sessions | 
| 70859 
6e6254bbce1f
split into standard partitions, for improved scalability;
 wenzelm parents: 
70858diff
changeset | 437 | -b NAME base logic image (default """ + isabelle.quote(default_logic) + """) | 
| 68308 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 438 | -d DIR include session directory | 
| 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 439 | -g NAME select session group NAME | 
| 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 440 | -o OPTION override Isabelle system OPTION (via NAME=VAL or NAME) | 
| 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 441 | -v verbose | 
| 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 442 | -x NAME exclude session NAME and all descendants | 
| 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 443 | |
| 68348 | 444 | Dump cumulative PIDE session database, with the following aspects: | 
| 68316 | 445 | |
| 73736 | 446 | """ + Library.indent_lines(4, show_aspects) + "\n", | 
| 75394 | 447 |         "A:" -> (arg => aspects = Library.distinct(space_explode(',', arg)).map(the_aspect)),
 | 
| 448 | "B:" -> (arg => base_sessions = base_sessions ::: List(arg)), | |
| 449 | "D:" -> (arg => select_dirs = select_dirs ::: List(Path.explode(arg))), | |
| 450 | "O:" -> (arg => output_dir = Path.explode(arg)), | |
| 451 | "R" -> (_ => requirements = true), | |
| 452 | "X:" -> (arg => exclude_session_groups = exclude_session_groups ::: List(arg)), | |
| 453 | "a" -> (_ => all_sessions = true), | |
| 454 | "b:" -> (arg => logic = arg), | |
| 455 | "d:" -> (arg => dirs = dirs ::: List(Path.explode(arg))), | |
| 456 | "g:" -> (arg => session_groups = session_groups ::: List(arg)), | |
| 457 | "o:" -> (arg => options = options + arg), | |
| 458 | "v" -> (_ => verbose = true), | |
| 459 | "x:" -> (arg => exclude_sessions = exclude_sessions ::: List(arg))) | |
| 68308 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 460 | |
| 75394 | 461 | val sessions = getopts(args) | 
| 68308 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 462 | |
| 75394 | 463 | val progress = new Console_Progress(verbose = verbose) | 
| 68308 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 464 | |
| 75394 | 465 | val start_date = Date.now() | 
| 71661 
6db526adccac
clarified messages: indicate termination explicitly;
 wenzelm parents: 
71573diff
changeset | 466 | |
| 77510 
f5d6cd98b16a
clarified signature: manage "verbose" flag via "progress";
 wenzelm parents: 
77509diff
changeset | 467 |         progress.echo("Started at " + Build_Log.print_date(start_date), verbose = true)
 | 
| 71661 
6db526adccac
clarified messages: indicate termination explicitly;
 wenzelm parents: 
71573diff
changeset | 468 | |
| 75394 | 469 |         progress.interrupt_handler {
 | 
| 470 | dump(options, logic, | |
| 471 | aspects = aspects, | |
| 472 | progress = progress, | |
| 473 | dirs = dirs, | |
| 474 | select_dirs = select_dirs, | |
| 475 | output_dir = output_dir, | |
| 476 | selection = Sessions.Selection( | |
| 477 | requirements = requirements, | |
| 478 | all_sessions = all_sessions, | |
| 479 | base_sessions = base_sessions, | |
| 480 | exclude_session_groups = exclude_session_groups, | |
| 481 | exclude_sessions = exclude_sessions, | |
| 482 | session_groups = session_groups, | |
| 483 | sessions = sessions)) | |
| 484 | } | |
| 71661 
6db526adccac
clarified messages: indicate termination explicitly;
 wenzelm parents: 
71573diff
changeset | 485 | |
| 75394 | 486 | val end_date = Date.now() | 
| 487 | val timing = end_date.time - start_date.time | |
| 71661 
6db526adccac
clarified messages: indicate termination explicitly;
 wenzelm parents: 
71573diff
changeset | 488 | |
| 77510 
f5d6cd98b16a
clarified signature: manage "verbose" flag via "progress";
 wenzelm parents: 
77509diff
changeset | 489 |         progress.echo("\nFinished at " + Build_Log.print_date(end_date), verbose = true)
 | 
| 75394 | 490 | progress.echo(timing.message_hms + " elapsed time") | 
| 491 | }) | |
| 68308 
119fc05f6b00
support to dump build database produced by PIDE session;
 wenzelm parents: diff
changeset | 492 | } |