author | wenzelm |
Wed, 02 Jan 2019 20:20:01 +0100 | |
changeset 69572 | 09a6a7c04b45 |
parent 68221 | dbef88c2b6c5 |
child 69573 | c7a69b6cd405 |
permissions | -rw-r--r-- |
65477 | 1 |
/* Title: Pure/ML/ml_process.scala |
62544 | 2 |
Author: Makarius |
3 |
||
62586 | 4 |
The raw ML process. |
62544 | 5 |
*/ |
6 |
||
7 |
package isabelle |
|
8 |
||
9 |
||
62573 | 10 |
import java.io.{File => JFile} |
11 |
||
12 |
||
62544 | 13 |
object ML_Process |
14 |
{ |
|
15 |
def apply(options: Options, |
|
62634
aa3b47b32100
less physical "logic" argument, with option -l like "isabelle console" etc.;
wenzelm
parents:
62633
diff
changeset
|
16 |
logic: String = "", |
62544 | 17 |
args: List[String] = Nil, |
62637
0189fe0f6452
support for Poly/ML heap hierarchy, which saves a lot of disk space;
wenzelm
parents:
62634
diff
changeset
|
18 |
dirs: List[Path] = Nil, |
62556
c115e69f457f
more abstract Session.start, without prover command-line;
wenzelm
parents:
62548
diff
changeset
|
19 |
modes: List[String] = Nil, |
62643 | 20 |
raw_ml_system: Boolean = false, |
62573 | 21 |
cwd: JFile = null, |
62610
4c89504c76fb
more uniform signature for various process invocations;
wenzelm
parents:
62606
diff
changeset
|
22 |
env: Map[String, String] = Isabelle_System.settings(), |
62557 | 23 |
redirect: Boolean = false, |
62603 | 24 |
cleanup: () => Unit = () => (), |
68204 | 25 |
sessions_structure: Option[Sessions.Structure] = None, |
65431
4a3e6cda3b94
provide session base for "isabelle build" and "isabelle console" ML process;
wenzelm
parents:
65420
diff
changeset
|
26 |
session_base: Option[Sessions.Base] = None, |
68209 | 27 |
store: Option[Sessions.Store] = None): Bash.Process = |
62544 | 28 |
{ |
62637
0189fe0f6452
support for Poly/ML heap hierarchy, which saves a lot of disk space;
wenzelm
parents:
62634
diff
changeset
|
29 |
val logic_name = Isabelle_System.default_logic(logic) |
68211 | 30 |
val _store = store.getOrElse(Sessions.store(options)) |
68209 | 31 |
|
62637
0189fe0f6452
support for Poly/ML heap hierarchy, which saves a lot of disk space;
wenzelm
parents:
62634
diff
changeset
|
32 |
val heaps: List[String] = |
62643 | 33 |
if (raw_ml_system) Nil |
62637
0189fe0f6452
support for Poly/ML heap hierarchy, which saves a lot of disk space;
wenzelm
parents:
62634
diff
changeset
|
34 |
else { |
65419 | 35 |
val selection = Sessions.Selection(sessions = List(logic_name)) |
67025
961285f581e6
clarifified selection: always wrt. build_graph structure;
wenzelm
parents:
66961
diff
changeset
|
36 |
val selected_sessions = |
68204 | 37 |
sessions_structure.getOrElse(Sessions.load_structure(options, dirs = dirs)) |
38 |
.selection(selection) |
|
66848 | 39 |
selected_sessions.build_requirements(List(logic_name)). |
68221 | 40 |
map(a => File.platform_path(_store.the_heap(a))) |
62544 | 41 |
} |
42 |
||
62637
0189fe0f6452
support for Poly/ML heap hierarchy, which saves a lot of disk space;
wenzelm
parents:
62634
diff
changeset
|
43 |
val eval_init = |
62634
aa3b47b32100
less physical "logic" argument, with option -l like "isabelle console" etc.;
wenzelm
parents:
62633
diff
changeset
|
44 |
if (heaps.isEmpty) { |
62544 | 45 |
List( |
62912 | 46 |
""" |
47 |
fun chapter (_: string) = (); |
|
48 |
fun section (_: string) = (); |
|
49 |
fun subsection (_: string) = (); |
|
50 |
fun subsubsection (_: string) = (); |
|
51 |
fun paragraph (_: string) = (); |
|
52 |
fun subparagraph (_: string) = (); |
|
53 |
val ML_file = PolyML.use; |
|
54 |
""", |
|
64557
37074e22e8be
more tight thread attributes, based in internal word arithmetic instead of symbolic datatypes: measurable performance improvement;
wenzelm
parents:
64304
diff
changeset
|
55 |
if (Isabelle_System.getenv("ML_SYSTEM") == "polyml-5.6") |
37074e22e8be
more tight thread attributes, based in internal word arithmetic instead of symbolic datatypes: measurable performance improvement;
wenzelm
parents:
64304
diff
changeset
|
56 |
""" |
37074e22e8be
more tight thread attributes, based in internal word arithmetic instead of symbolic datatypes: measurable performance improvement;
wenzelm
parents:
64304
diff
changeset
|
57 |
structure FixedInt = IntInf; |
37074e22e8be
more tight thread attributes, based in internal word arithmetic instead of symbolic datatypes: measurable performance improvement;
wenzelm
parents:
64304
diff
changeset
|
58 |
structure RunCall = |
37074e22e8be
more tight thread attributes, based in internal word arithmetic instead of symbolic datatypes: measurable performance improvement;
wenzelm
parents:
64304
diff
changeset
|
59 |
struct |
37074e22e8be
more tight thread attributes, based in internal word arithmetic instead of symbolic datatypes: measurable performance improvement;
wenzelm
parents:
64304
diff
changeset
|
60 |
open RunCall |
37074e22e8be
more tight thread attributes, based in internal word arithmetic instead of symbolic datatypes: measurable performance improvement;
wenzelm
parents:
64304
diff
changeset
|
61 |
val loadWord: word * word -> word = |
37074e22e8be
more tight thread attributes, based in internal word arithmetic instead of symbolic datatypes: measurable performance improvement;
wenzelm
parents:
64304
diff
changeset
|
62 |
run_call2 RuntimeCalls.POLY_SYS_load_word; |
37074e22e8be
more tight thread attributes, based in internal word arithmetic instead of symbolic datatypes: measurable performance improvement;
wenzelm
parents:
64304
diff
changeset
|
63 |
val storeWord: word * word * word -> unit = |
37074e22e8be
more tight thread attributes, based in internal word arithmetic instead of symbolic datatypes: measurable performance improvement;
wenzelm
parents:
64304
diff
changeset
|
64 |
run_call3 RuntimeCalls.POLY_SYS_assign_word; |
37074e22e8be
more tight thread attributes, based in internal word arithmetic instead of symbolic datatypes: measurable performance improvement;
wenzelm
parents:
64304
diff
changeset
|
65 |
end; |
37074e22e8be
more tight thread attributes, based in internal word arithmetic instead of symbolic datatypes: measurable performance improvement;
wenzelm
parents:
64304
diff
changeset
|
66 |
""" |
62855
82859dac5f59
clarified bootstrap -- avoid conditional compilation in ROOT.ML;
wenzelm
parents:
62835
diff
changeset
|
67 |
else "", |
62544 | 68 |
if (Platform.is_windows) |
69 |
"fun exit 0 = OS.Process.exit OS.Process.success" + |
|
70 |
" | exit 1 = OS.Process.exit OS.Process.failure" + |
|
71 |
" | exit rc = OS.Process.exit (RunCall.unsafeCast (Word8.fromInt rc))" |
|
62560 | 72 |
else |
73 |
"fun exit rc = Posix.Process.exit (Word8.fromInt rc)", |
|
62629
1815513a57f1
clarified prompt: "ML" usually means Isabelle/ML;
wenzelm
parents:
62614
diff
changeset
|
74 |
"PolyML.Compiler.prompt1 := \"Poly/ML> \"", |
1815513a57f1
clarified prompt: "ML" usually means Isabelle/ML;
wenzelm
parents:
62614
diff
changeset
|
75 |
"PolyML.Compiler.prompt2 := \"Poly/ML# \"") |
62544 | 76 |
} |
62637
0189fe0f6452
support for Poly/ML heap hierarchy, which saves a lot of disk space;
wenzelm
parents:
62634
diff
changeset
|
77 |
else |
0189fe0f6452
support for Poly/ML heap hierarchy, which saves a lot of disk space;
wenzelm
parents:
62634
diff
changeset
|
78 |
List( |
0189fe0f6452
support for Poly/ML heap hierarchy, which saves a lot of disk space;
wenzelm
parents:
62634
diff
changeset
|
79 |
"(PolyML.SaveState.loadHierarchy " + |
66782 | 80 |
ML_Syntax.print_list(ML_Syntax.print_string_bytes)(heaps) + |
62637
0189fe0f6452
support for Poly/ML heap hierarchy, which saves a lot of disk space;
wenzelm
parents:
62634
diff
changeset
|
81 |
"; PolyML.print_depth 0) handle exn => (TextIO.output (TextIO.stdErr, General.exnMessage exn ^ " + |
66782 | 82 |
ML_Syntax.print_string_bytes(": " + logic_name + "\n") + |
62637
0189fe0f6452
support for Poly/ML heap hierarchy, which saves a lot of disk space;
wenzelm
parents:
62634
diff
changeset
|
83 |
"); OS.Process.exit OS.Process.failure)") |
62544 | 84 |
|
85 |
val eval_modes = |
|
86 |
if (modes.isEmpty) Nil |
|
66782 | 87 |
else List("Print_Mode.add_modes " + ML_Syntax.print_list(ML_Syntax.print_string_bytes)(modes)) |
62544 | 88 |
|
89 |
// options |
|
90 |
val isabelle_process_options = Isabelle_System.tmp_file("options") |
|
69572
09a6a7c04b45
more robust system channel via options that are private to the user;
wenzelm
parents:
68221
diff
changeset
|
91 |
Isabelle_System.bash("chmod 600 " + File.bash_path(File.path(isabelle_process_options))) |
62544 | 92 |
File.write(isabelle_process_options, YXML.string_of_body(options.encode)) |
62573 | 93 |
val env_options = Map("ISABELLE_PROCESS_OPTIONS" -> File.standard_path(isabelle_process_options)) |
62634
aa3b47b32100
less physical "logic" argument, with option -l like "isabelle console" etc.;
wenzelm
parents:
62633
diff
changeset
|
94 |
val eval_options = if (heaps.isEmpty) Nil else List("Options.load_default ()") |
62544 | 95 |
|
65431
4a3e6cda3b94
provide session base for "isabelle build" and "isabelle console" ML process;
wenzelm
parents:
65420
diff
changeset
|
96 |
// session base |
4a3e6cda3b94
provide session base for "isabelle build" and "isabelle console" ML process;
wenzelm
parents:
65420
diff
changeset
|
97 |
val eval_session_base = |
4a3e6cda3b94
provide session base for "isabelle build" and "isabelle console" ML process;
wenzelm
parents:
65420
diff
changeset
|
98 |
session_base match { |
4a3e6cda3b94
provide session base for "isabelle build" and "isabelle console" ML process;
wenzelm
parents:
65420
diff
changeset
|
99 |
case None => Nil |
4a3e6cda3b94
provide session base for "isabelle build" and "isabelle console" ML process;
wenzelm
parents:
65420
diff
changeset
|
100 |
case Some(base) => |
65441 | 101 |
def print_table(table: List[(String, String)]): String = |
65431
4a3e6cda3b94
provide session base for "isabelle build" and "isabelle console" ML process;
wenzelm
parents:
65420
diff
changeset
|
102 |
ML_Syntax.print_list( |
4a3e6cda3b94
provide session base for "isabelle build" and "isabelle console" ML process;
wenzelm
parents:
65420
diff
changeset
|
103 |
ML_Syntax.print_pair( |
66782 | 104 |
ML_Syntax.print_string_bytes, ML_Syntax.print_string_bytes))(table) |
66712 | 105 |
def print_list(list: List[String]): String = |
66782 | 106 |
ML_Syntax.print_list(ML_Syntax.print_string_bytes)(list) |
67493
c4e9e0c50487
treat sessions as entities with defining position;
wenzelm
parents:
67471
diff
changeset
|
107 |
def print_sessions(list: List[(String, Position.T)]): String = |
c4e9e0c50487
treat sessions as entities with defining position;
wenzelm
parents:
67471
diff
changeset
|
108 |
ML_Syntax.print_list( |
c4e9e0c50487
treat sessions as entities with defining position;
wenzelm
parents:
67471
diff
changeset
|
109 |
ML_Syntax.print_pair(ML_Syntax.print_string_bytes, ML_Syntax.print_properties))(list) |
c4e9e0c50487
treat sessions as entities with defining position;
wenzelm
parents:
67471
diff
changeset
|
110 |
|
65532 | 111 |
List("Resources.init_session_base" + |
67493
c4e9e0c50487
treat sessions as entities with defining position;
wenzelm
parents:
67471
diff
changeset
|
112 |
" {sessions = " + print_sessions(base.known.sessions.toList) + |
67520 | 113 |
", docs = " + print_list(base.doc_names) + |
67219 | 114 |
", global_theories = " + print_table(base.global_theories.toList) + |
66717
67dbf5cdc056
more informative loaded_theories: dependencies and syntax;
wenzelm
parents:
66712
diff
changeset
|
115 |
", loaded_theories = " + print_list(base.loaded_theories.keys) + |
65441 | 116 |
", known_theories = " + print_table(base.dest_known_theories) + "}") |
65431
4a3e6cda3b94
provide session base for "isabelle build" and "isabelle console" ML process;
wenzelm
parents:
65420
diff
changeset
|
117 |
} |
4a3e6cda3b94
provide session base for "isabelle build" and "isabelle console" ML process;
wenzelm
parents:
65420
diff
changeset
|
118 |
|
4a3e6cda3b94
provide session base for "isabelle build" and "isabelle console" ML process;
wenzelm
parents:
65420
diff
changeset
|
119 |
// process |
62544 | 120 |
val eval_process = |
62634
aa3b47b32100
less physical "logic" argument, with option -l like "isabelle console" etc.;
wenzelm
parents:
62633
diff
changeset
|
121 |
if (heaps.isEmpty) |
62712 | 122 |
List("PolyML.print_depth " + ML_Syntax.print_int(options.int("ML_print_depth"))) |
69572
09a6a7c04b45
more robust system channel via options that are private to the user;
wenzelm
parents:
68221
diff
changeset
|
123 |
else List("Isabelle_Process.init ()") |
62544 | 124 |
|
62601
a937889f0086
create ISABELLE_TMP in Scala (despite odd/obsolete chmod in d84b4d39bce1);
wenzelm
parents:
62600
diff
changeset
|
125 |
// ISABELLE_TMP |
a937889f0086
create ISABELLE_TMP in Scala (despite odd/obsolete chmod in d84b4d39bce1);
wenzelm
parents:
62600
diff
changeset
|
126 |
val isabelle_tmp = Isabelle_System.tmp_dir("process") |
a937889f0086
create ISABELLE_TMP in Scala (despite odd/obsolete chmod in d84b4d39bce1);
wenzelm
parents:
62600
diff
changeset
|
127 |
val env_tmp = Map("ISABELLE_TMP" -> File.standard_path(isabelle_tmp)) |
a937889f0086
create ISABELLE_TMP in Scala (despite odd/obsolete chmod in d84b4d39bce1);
wenzelm
parents:
62600
diff
changeset
|
128 |
|
64274 | 129 |
val ml_runtime_options = |
130 |
{ |
|
131 |
val ml_options = Word.explode(Isabelle_System.getenv("ML_OPTIONS")) |
|
132 |
if (ml_options.exists(_.containsSlice("gcthreads"))) ml_options |
|
133 |
else ml_options ::: List("--gcthreads", options.int("threads").toString) |
|
134 |
} |
|
135 |
||
62545
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
wenzelm
parents:
62544
diff
changeset
|
136 |
// bash |
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
wenzelm
parents:
62544
diff
changeset
|
137 |
val bash_args = |
64274 | 138 |
ml_runtime_options ::: |
65431
4a3e6cda3b94
provide session base for "isabelle build" and "isabelle console" ML process;
wenzelm
parents:
65420
diff
changeset
|
139 |
(eval_init ::: eval_modes ::: eval_options ::: eval_session_base ::: eval_process). |
62545
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
wenzelm
parents:
62544
diff
changeset
|
140 |
map(eval => List("--eval", eval)).flatten ::: args |
62546 | 141 |
|
63986
c7a4b03727ae
options for process policy, notably for multiprocessor machines;
wenzelm
parents:
62912
diff
changeset
|
142 |
Bash.process( |
c7a4b03727ae
options for process policy, notably for multiprocessor machines;
wenzelm
parents:
62912
diff
changeset
|
143 |
"exec " + options.string("ML_process_policy") + """ "$ML_HOME/poly" -q """ + |
64304 | 144 |
Bash.strings(bash_args), |
62614 | 145 |
cwd = cwd, |
67586
8b19a8a7f029
more robust: avoid global change of LD_LIBRARY_PATH (e.g. relevant for subprocesses);
wenzelm
parents:
67520
diff
changeset
|
146 |
env = env ++ env_options ++ env_tmp, |
62614 | 147 |
redirect = redirect, |
62602 | 148 |
cleanup = () => |
149 |
{ |
|
150 |
isabelle_process_options.delete |
|
151 |
Isabelle_System.rm_tree(isabelle_tmp) |
|
62603 | 152 |
cleanup() |
62602 | 153 |
}) |
62544 | 154 |
} |
62586 | 155 |
|
156 |
||
62835
1a9ce1b13b20
prefer internal tool -- assuming that ISABELLE_TMP_PREFIX is created properly by Isabelle_System.isabelle_tmp_prefix;
wenzelm
parents:
62712
diff
changeset
|
157 |
/* Isabelle tool wrapper */ |
62586 | 158 |
|
62835
1a9ce1b13b20
prefer internal tool -- assuming that ISABELLE_TMP_PREFIX is created properly by Isabelle_System.isabelle_tmp_prefix;
wenzelm
parents:
62712
diff
changeset
|
159 |
val isabelle_tool = Isabelle_Tool("process", "raw ML process (batch mode)", args => |
62586 | 160 |
{ |
62835
1a9ce1b13b20
prefer internal tool -- assuming that ISABELLE_TMP_PREFIX is created properly by Isabelle_System.isabelle_tmp_prefix;
wenzelm
parents:
62712
diff
changeset
|
161 |
var dirs: List[Path] = Nil |
1a9ce1b13b20
prefer internal tool -- assuming that ISABELLE_TMP_PREFIX is created properly by Isabelle_System.isabelle_tmp_prefix;
wenzelm
parents:
62712
diff
changeset
|
162 |
var eval_args: List[String] = Nil |
1a9ce1b13b20
prefer internal tool -- assuming that ISABELLE_TMP_PREFIX is created properly by Isabelle_System.isabelle_tmp_prefix;
wenzelm
parents:
62712
diff
changeset
|
163 |
var logic = Isabelle_System.getenv("ISABELLE_LOGIC") |
1a9ce1b13b20
prefer internal tool -- assuming that ISABELLE_TMP_PREFIX is created properly by Isabelle_System.isabelle_tmp_prefix;
wenzelm
parents:
62712
diff
changeset
|
164 |
var modes: List[String] = Nil |
1a9ce1b13b20
prefer internal tool -- assuming that ISABELLE_TMP_PREFIX is created properly by Isabelle_System.isabelle_tmp_prefix;
wenzelm
parents:
62712
diff
changeset
|
165 |
var options = Options.init() |
62586 | 166 |
|
62835
1a9ce1b13b20
prefer internal tool -- assuming that ISABELLE_TMP_PREFIX is created properly by Isabelle_System.isabelle_tmp_prefix;
wenzelm
parents:
62712
diff
changeset
|
167 |
val getopts = Getopts(""" |
62634
aa3b47b32100
less physical "logic" argument, with option -l like "isabelle console" etc.;
wenzelm
parents:
62633
diff
changeset
|
168 |
Usage: isabelle process [OPTIONS] |
62586 | 169 |
|
170 |
Options are: |
|
62677 | 171 |
-T THEORY load theory |
62639 | 172 |
-d DIR include session directory |
62586 | 173 |
-e ML_EXPR evaluate ML expression on startup |
174 |
-f ML_FILE evaluate ML file on startup |
|
62634
aa3b47b32100
less physical "logic" argument, with option -l like "isabelle console" etc.;
wenzelm
parents:
62633
diff
changeset
|
175 |
-l NAME logic session name (default ISABELLE_LOGIC=""" + quote(logic) + """) |
62586 | 176 |
-m MODE add print mode for output |
177 |
-o OPTION override Isabelle system OPTION (via NAME=VAL or NAME) |
|
178 |
||
62634
aa3b47b32100
less physical "logic" argument, with option -l like "isabelle console" etc.;
wenzelm
parents:
62633
diff
changeset
|
179 |
Run the raw Isabelle ML process in batch mode. |
62586 | 180 |
""", |
62835
1a9ce1b13b20
prefer internal tool -- assuming that ISABELLE_TMP_PREFIX is created properly by Isabelle_System.isabelle_tmp_prefix;
wenzelm
parents:
62712
diff
changeset
|
181 |
"T:" -> (arg => |
66782 | 182 |
eval_args = eval_args ::: List("--eval", "use_thy " + ML_Syntax.print_string_bytes(arg))), |
62835
1a9ce1b13b20
prefer internal tool -- assuming that ISABELLE_TMP_PREFIX is created properly by Isabelle_System.isabelle_tmp_prefix;
wenzelm
parents:
62712
diff
changeset
|
183 |
"d:" -> (arg => dirs = dirs ::: List(Path.explode(arg))), |
1a9ce1b13b20
prefer internal tool -- assuming that ISABELLE_TMP_PREFIX is created properly by Isabelle_System.isabelle_tmp_prefix;
wenzelm
parents:
62712
diff
changeset
|
184 |
"e:" -> (arg => eval_args = eval_args ::: List("--eval", arg)), |
1a9ce1b13b20
prefer internal tool -- assuming that ISABELLE_TMP_PREFIX is created properly by Isabelle_System.isabelle_tmp_prefix;
wenzelm
parents:
62712
diff
changeset
|
185 |
"f:" -> (arg => eval_args = eval_args ::: List("--use", arg)), |
1a9ce1b13b20
prefer internal tool -- assuming that ISABELLE_TMP_PREFIX is created properly by Isabelle_System.isabelle_tmp_prefix;
wenzelm
parents:
62712
diff
changeset
|
186 |
"l:" -> (arg => logic = arg), |
1a9ce1b13b20
prefer internal tool -- assuming that ISABELLE_TMP_PREFIX is created properly by Isabelle_System.isabelle_tmp_prefix;
wenzelm
parents:
62712
diff
changeset
|
187 |
"m:" -> (arg => modes = arg :: modes), |
1a9ce1b13b20
prefer internal tool -- assuming that ISABELLE_TMP_PREFIX is created properly by Isabelle_System.isabelle_tmp_prefix;
wenzelm
parents:
62712
diff
changeset
|
188 |
"o:" -> (arg => options = options + arg)) |
62586 | 189 |
|
62835
1a9ce1b13b20
prefer internal tool -- assuming that ISABELLE_TMP_PREFIX is created properly by Isabelle_System.isabelle_tmp_prefix;
wenzelm
parents:
62712
diff
changeset
|
190 |
val more_args = getopts(args) |
1a9ce1b13b20
prefer internal tool -- assuming that ISABELLE_TMP_PREFIX is created properly by Isabelle_System.isabelle_tmp_prefix;
wenzelm
parents:
62712
diff
changeset
|
191 |
if (args.isEmpty || !more_args.isEmpty) getopts.usage() |
62586 | 192 |
|
62888 | 193 |
val rc = ML_Process(options, logic = logic, args = eval_args, dirs = dirs, modes = modes). |
62835
1a9ce1b13b20
prefer internal tool -- assuming that ISABELLE_TMP_PREFIX is created properly by Isabelle_System.isabelle_tmp_prefix;
wenzelm
parents:
62712
diff
changeset
|
194 |
result().print_stdout.rc |
62888 | 195 |
sys.exit(rc) |
62835
1a9ce1b13b20
prefer internal tool -- assuming that ISABELLE_TMP_PREFIX is created properly by Isabelle_System.isabelle_tmp_prefix;
wenzelm
parents:
62712
diff
changeset
|
196 |
}) |
62544 | 197 |
} |