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