| author | wenzelm | 
| Sat, 10 Oct 2020 20:56:09 +0200 | |
| changeset 72422 | 9d59738102b8 | 
| parent 72103 | 7b318273a4aa | 
| child 72574 | d892f6d66402 | 
| permissions | -rw-r--r-- | 
| 50686 | 1 | (* Title: Pure/Tools/build.ML | 
| 48418 | 2 | Author: Makarius | 
| 3 | ||
| 4 | Build Isabelle sessions. | |
| 5 | *) | |
| 6 | ||
| 72103 | 7 | structure Build: sig end = | 
| 48418 | 8 | struct | 
| 9 | ||
| 51662 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 10 | (* command timings *) | 
| 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 11 | |
| 56615 | 12 | type timings = ((string * Time.time) Inttab.table) Symtab.table; (*file -> offset -> name, time*) | 
| 51662 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 13 | |
| 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 14 | val empty_timings: timings = Symtab.empty; | 
| 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 15 | |
| 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 16 | fun update_timings props = | 
| 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 17 | (case Markup.parse_command_timing_properties props of | 
| 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 18 |     SOME ({file, offset, name}, time) =>
 | 
| 51666 
b97aeb018900
add command timings (like document command status);
 wenzelm parents: 
51662diff
changeset | 19 | Symtab.map_default (file, Inttab.empty) | 
| 62826 | 20 | (Inttab.map_default (offset, (name, time)) (fn (_, t) => (name, t + time))) | 
| 51662 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 21 | | NONE => I); | 
| 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 22 | |
| 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 23 | fun approximative_id name pos = | 
| 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 24 | (case (Position.file_of pos, Position.offset_of pos) of | 
| 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 25 | (SOME file, SOME offset) => | 
| 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 26 |       if name = "" then NONE else SOME {file = file, offset = offset, name = name}
 | 
| 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 27 | | _ => NONE); | 
| 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 28 | |
| 65058 
3e9f382fb67e
absent timing information means zero, according to 0070053570c4, f235646b1b73;
 wenzelm parents: 
64599diff
changeset | 29 | fun get_timings timings tr = | 
| 51662 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 30 | (case approximative_id (Toplevel.name_of tr) (Toplevel.pos_of tr) of | 
| 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 31 |     SOME {file, offset, name} =>
 | 
| 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 32 | (case Symtab.lookup timings file of | 
| 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 33 | SOME offsets => | 
| 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 34 | (case Inttab.lookup offsets offset of | 
| 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 35 | SOME (name', time) => if name = name' then SOME time else NONE | 
| 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 36 | | NONE => NONE) | 
| 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 37 | | NONE => NONE) | 
| 65058 
3e9f382fb67e
absent timing information means zero, according to 0070053570c4, f235646b1b73;
 wenzelm parents: 
64599diff
changeset | 38 | | NONE => NONE) | 
| 
3e9f382fb67e
absent timing information means zero, according to 0070053570c4, f235646b1b73;
 wenzelm parents: 
64599diff
changeset | 39 | |> the_default Time.zeroTime; | 
| 51662 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 40 | |
| 
3391a493f39a
just one timing protocol function, with 3 implementations: TTY/PG, PIDE/document, build;
 wenzelm parents: 
51661diff
changeset | 41 | |
| 52052 
892061142ba6
discontinued obsolete isabelle usedir, mkdir, make;
 wenzelm parents: 
52041diff
changeset | 42 | (* session timing *) | 
| 
892061142ba6
discontinued obsolete isabelle usedir, mkdir, make;
 wenzelm parents: 
52041diff
changeset | 43 | |
| 72019 | 44 | fun session_timing f x = | 
| 52052 
892061142ba6
discontinued obsolete isabelle usedir, mkdir, make;
 wenzelm parents: 
52041diff
changeset | 45 | let | 
| 
892061142ba6
discontinued obsolete isabelle usedir, mkdir, make;
 wenzelm parents: 
52041diff
changeset | 46 | val start = Timing.start (); | 
| 
892061142ba6
discontinued obsolete isabelle usedir, mkdir, make;
 wenzelm parents: 
52041diff
changeset | 47 | val y = f x; | 
| 
892061142ba6
discontinued obsolete isabelle usedir, mkdir, make;
 wenzelm parents: 
52041diff
changeset | 48 | val timing = Timing.result start; | 
| 
892061142ba6
discontinued obsolete isabelle usedir, mkdir, make;
 wenzelm parents: 
52041diff
changeset | 49 | |
| 62925 | 50 | val threads = string_of_int (Multithreading.max_threads ()); | 
| 72019 | 51 |     val props = [("threads", threads)] @ Markup.timing_properties timing;
 | 
| 52 | val _ = Output.protocol_message (Markup.session_timing :: props) []; | |
| 52052 
892061142ba6
discontinued obsolete isabelle usedir, mkdir, make;
 wenzelm parents: 
52041diff
changeset | 53 | in y end; | 
| 
892061142ba6
discontinued obsolete isabelle usedir, mkdir, make;
 wenzelm parents: 
52041diff
changeset | 54 | |
| 
892061142ba6
discontinued obsolete isabelle usedir, mkdir, make;
 wenzelm parents: 
52041diff
changeset | 55 | |
| 65307 | 56 | (* build theories *) | 
| 50683 | 57 | |
| 67297 
86a099f896fc
formal check of @{cite} bibtex entries -- only in batch-mode session builds;
 wenzelm parents: 
67219diff
changeset | 58 | fun build_theories symbols bibtex_entries last_timing qualifier master_dir (options, thys) = | 
| 59366 
e94df7f6b608
clarified build_theories: proper protocol handler;
 wenzelm parents: 
59364diff
changeset | 59 | let | 
| 68179 
da70c9e91135
clarified signature: more explicit type "context" with full options;
 wenzelm parents: 
68148diff
changeset | 60 | val context = | 
| 
da70c9e91135
clarified signature: more explicit type "context" with full options;
 wenzelm parents: 
68148diff
changeset | 61 |       {options = options, symbols = symbols, bibtex_entries = bibtex_entries,
 | 
| 
da70c9e91135
clarified signature: more explicit type "context" with full options;
 wenzelm parents: 
68148diff
changeset | 62 | last_timing = last_timing}; | 
| 59366 
e94df7f6b608
clarified build_theories: proper protocol handler;
 wenzelm parents: 
59364diff
changeset | 63 | val condition = space_explode "," (Options.string options "condition"); | 
| 
e94df7f6b608
clarified build_theories: proper protocol handler;
 wenzelm parents: 
59364diff
changeset | 64 | val conds = filter_out (can getenv_strict) condition; | 
| 
e94df7f6b608
clarified build_theories: proper protocol handler;
 wenzelm parents: 
59364diff
changeset | 65 | in | 
| 
e94df7f6b608
clarified build_theories: proper protocol handler;
 wenzelm parents: 
59364diff
changeset | 66 | if null conds then | 
| 69755 | 67 | (Options.set_default options; | 
| 62714 | 68 | Isabelle_Process.init_options (); | 
| 64599 
80ef54198f44
dummy fork to produce ML_statistics even in sequential mode (e.g. for heap size);
 wenzelm parents: 
64308diff
changeset | 69 | Future.fork I; | 
| 68179 
da70c9e91135
clarified signature: more explicit type "context" with full options;
 wenzelm parents: 
68148diff
changeset | 70 | (Thy_Info.use_theories context qualifier master_dir | 
| 64308 | 71 | |> | 
| 72 | (case Options.string options "profiling" of | |
| 73 | "" => I | |
| 74 | | "time" => profile_time | |
| 75 | | "allocations" => profile_allocations | |
| 76 |           | bad => error ("Bad profiling option: " ^ quote bad))
 | |
| 59366 
e94df7f6b608
clarified build_theories: proper protocol handler;
 wenzelm parents: 
59364diff
changeset | 77 | |> Unsynchronized.setmp print_mode | 
| 62714 | 78 | (space_explode "," (Options.string options "print_mode") @ print_mode_value ())) thys) | 
| 59366 
e94df7f6b608
clarified build_theories: proper protocol handler;
 wenzelm parents: 
59364diff
changeset | 79 | else | 
| 
e94df7f6b608
clarified build_theories: proper protocol handler;
 wenzelm parents: 
59364diff
changeset | 80 |       Output.physical_stderr ("Skipping theories " ^ commas_quote (map #1 thys) ^
 | 
| 
e94df7f6b608
clarified build_theories: proper protocol handler;
 wenzelm parents: 
59364diff
changeset | 81 | " (undefined " ^ commas conds ^ ")\n") | 
| 
e94df7f6b608
clarified build_theories: proper protocol handler;
 wenzelm parents: 
59364diff
changeset | 82 | end; | 
| 
e94df7f6b608
clarified build_theories: proper protocol handler;
 wenzelm parents: 
59364diff
changeset | 83 | |
| 65307 | 84 | |
| 85 | (* build session *) | |
| 86 | ||
| 87 | val _ = | |
| 88 | Isabelle_Process.protocol_command "build_session" | |
| 65313 | 89 | (fn [args_yxml] => | 
| 70991 
f9f7c34b7dd4
more scalable protocol_message: use XML.body directly (Output.output hook is not required);
 wenzelm parents: 
70907diff
changeset | 90 | let | 
| 72103 | 91 | val (symbol_codes, (command_timings, (verbose, (browser_info, | 
| 92 | (document_files, (graph_file, (parent_name, (chapter, (session_name, (master_dir, | |
| 93 | (theories, (session_positions, (session_directories, (doc_names, (global_theories, | |
| 94 | (loaded_theories, bibtex_entries)))))))))))))))) = | |
| 95 | YXML.parse_body args_yxml |> | |
| 96 | let | |
| 97 | open XML.Decode; | |
| 98 | val position = Position.of_properties o properties; | |
| 99 | val path = Path.explode o string; | |
| 100 | in | |
| 101 | pair (list (pair string int)) (pair (list properties) (pair bool (pair path | |
| 102 | (pair (list (pair path path)) (pair path (pair string (pair string (pair string | |
| 103 | (pair path | |
| 104 | (pair (((list (pair Options.decode (list (pair string position)))))) | |
| 105 | (pair (list (pair string properties)) | |
| 106 | (pair (list (pair string string)) (pair (list string) | |
| 107 | (pair (list (pair string string)) (pair (list string) (list string)))))))))))))))) | |
| 108 | end; | |
| 109 | ||
| 110 | val symbols = HTML.make_symbols symbol_codes; | |
| 111 | ||
| 112 | fun build () = | |
| 113 | let | |
| 114 | val _ = | |
| 115 | Resources.init_session | |
| 116 |                   {session_positions = session_positions,
 | |
| 117 | session_directories = session_directories, | |
| 118 | docs = doc_names, | |
| 119 | global_theories = global_theories, | |
| 120 | loaded_theories = loaded_theories}; | |
| 121 | ||
| 122 | val _ = | |
| 123 | Session.init | |
| 124 | symbols | |
| 125 | (Options.default_bool "browser_info") | |
| 126 | browser_info | |
| 127 | (Options.default_string "document") | |
| 128 | (Options.default_string "document_output") | |
| 129 | (Present.document_variants (Options.default ())) | |
| 130 | document_files | |
| 131 | graph_file | |
| 132 | parent_name | |
| 133 | (chapter, session_name) | |
| 134 | verbose; | |
| 135 | ||
| 136 | val last_timing = get_timings (fold update_timings command_timings empty_timings); | |
| 137 | ||
| 138 | val res1 = | |
| 139 | theories |> | |
| 140 | (List.app | |
| 141 | (build_theories symbols bibtex_entries last_timing session_name master_dir) | |
| 142 | |> session_timing | |
| 143 | |> Exn.capture); | |
| 144 | val res2 = Exn.capture Session.finish (); | |
| 145 | ||
| 146 | val _ = Resources.finish_session_base (); | |
| 147 | val _ = Par_Exn.release_all [res1, res2]; | |
| 148 | val _ = | |
| 149 | if session_name = Context.PureN | |
| 150 | then Theory.install_pure (Thy_Info.get_theory Context.PureN) else (); | |
| 151 | in () end; | |
| 152 | ||
| 71880 
0ca353521753
asynchronous build_session: notably for Scala.fulfill protocol commands during run;
 wenzelm parents: 
71879diff
changeset | 153 | fun exec e = | 
| 
0ca353521753
asynchronous build_session: notably for Scala.fulfill protocol commands during run;
 wenzelm parents: 
71879diff
changeset | 154 | if can Theory.get_pure () then | 
| 
0ca353521753
asynchronous build_session: notably for Scala.fulfill protocol commands during run;
 wenzelm parents: 
71879diff
changeset | 155 | Isabelle_Thread.fork | 
| 71884 | 156 |                 {name = "build_session", stack_limit = Isabelle_Thread.stack_limit (),
 | 
| 157 | interrupts = false} e | |
| 71880 
0ca353521753
asynchronous build_session: notably for Scala.fulfill protocol commands during run;
 wenzelm parents: 
71879diff
changeset | 158 | |> ignore | 
| 
0ca353521753
asynchronous build_session: notably for Scala.fulfill protocol commands during run;
 wenzelm parents: 
71879diff
changeset | 159 | else e (); | 
| 71667 
4d2de35214c5
proper treatment of protocol exceptions and prover termination: avoid session.stop while saving image;
 wenzelm parents: 
71656diff
changeset | 160 | in | 
| 71880 
0ca353521753
asynchronous build_session: notably for Scala.fulfill protocol commands during run;
 wenzelm parents: 
71879diff
changeset | 161 | exec (fn () => | 
| 72103 | 162 | (Future.interruptible_task (fn () => (build (); (0, []))) () handle exn => | 
| 71880 
0ca353521753
asynchronous build_session: notably for Scala.fulfill protocol commands during run;
 wenzelm parents: 
71879diff
changeset | 163 | ((1, Runtime.exn_message_list exn) handle _ (*sic!*) => (2, ["CRASHED"]))) | 
| 71879 | 164 | |> let open XML.Encode in pair int (list string) end | 
| 71880 
0ca353521753
asynchronous build_session: notably for Scala.fulfill protocol commands during run;
 wenzelm parents: 
71879diff
changeset | 165 | |> Output.protocol_message Markup.build_session_finished) | 
| 71667 
4d2de35214c5
proper treatment of protocol exceptions and prover termination: avoid session.stop while saving image;
 wenzelm parents: 
71656diff
changeset | 166 | end | 
| 70991 
f9f7c34b7dd4
more scalable protocol_message: use XML.body directly (Output.output hook is not required);
 wenzelm parents: 
70907diff
changeset | 167 | | _ => raise Match); | 
| 59366 
e94df7f6b608
clarified build_theories: proper protocol handler;
 wenzelm parents: 
59364diff
changeset | 168 | |
| 48418 | 169 | end; |