Theory Munta_Certificate_Compile_Poly
section ‹Build and Test Exported Program With Poly/ML›
text_raw ‹\label{build-poly}›
theory Munta_Certificate_Compile_Poly
imports Simple_Network_Language_Certificate_Code Munta_Certificate_Testing
begin
paragraph ‹Mock Compilation›
text ‹
Instead of using Poly/ML's ‹polyc›, we emulate compilation within Isabelle's Poly/ML environment.
Below we also show how ‹polyc› could be used alternatively.
We prepare a few pieces of code that will be passed to Poly/ML for mocking compilation.
This will be used for evaluating the code:›
ML ‹
val flags = {environment = ML_Env.SML, redirect = false, verbose = false, catch_all = true,
debug = NONE, writeln = writeln, warning = warning}
fun eval cmd = ML_Context.eval flags Position.none (ML_Lex.read_text (cmd, Position.none))
›
ML ‹
val mock_print = ▩‹
val out_stream_ref = ref (NONE : BinIO.outstream option);
fun print s =
BinIO.output (Option.valOf (!out_stream_ref), Byte.stringToBytes s)
›
›
ML ‹
val mock_cmd = ▩‹
structure CommandLine =
struct
val mock_args = ref [""]
fun arguments () = !mock_args
fun set_mock_args s =
mock_args := String.tokens (fn c => c = #" ") s;
end
›
›
ML ‹
fun run_cmd dir args =
let
val out_path = dir + Path.basic "out" |> Path.expand |> Path.implode
in ▩‹
CommandLine.set_mock_args "› ^ args ^ ▩‹";
val out_stream = BinIO.openOut "› ^ out_path ^ ▩‹";
val _ = out_stream_ref := SOME out_stream;
main ();
BinIO.flushOut out_stream;
BinIO.closeOut out_stream
› end
›
ML ‹
val files = [
"Unsynchronized.sml",
"Writeln.sml",
"basics.ML",
"library.ML",
"parallel_task_queue.sml"
]
val mlunta_files = [
"prelude.sml",
"serializable.sml",
"certificate.sml"
]
val final_files = [
"Util.sml",
"Muntac.sml"
]
›
ML ‹
fun mock_compile dir file_name =
let
val _ = eval mock_cmd
val _ = eval mock_print
fun mk_path file_name = Path.append dir (Path.explode file_name)
fun mk_mlunta_path file_name =
dir + Path.explode mlunta_certificate_path + Path.basic file_name |> Path.expand
val _ = app (fn x => mk_path x |> ML_Context.eval_file flags) files
val _ = ML_Context.eval_file flags (dir + Path.basic file_name)
val _ = app (fn x => mk_mlunta_path x |> ML_Context.eval_file flags) mlunta_files
val _ = app (fn x => mk_path x |> ML_Context.eval_file flags) final_files
in () end
›
ML ‹
fun mock_exec_check_cert dir title muntac_path name =
let
fun check () =
Generated_Files.execute dir title ▩‹./check_benchmark.sh cat out›
fun mk_path name ext = dir + Path.basic name |> Path.ext ext |> Path.expand |> Path.implode
val args = implode_space [
muntac_path,
"-certificate", mk_path name "cert",
"-renaming", mk_path name "renaming",
"-model", mk_path name "muntax"
]
val cmd = run_cmd dir args
val _ = eval cmd
in
check ()
end
›
paragraph ‹Compilation and Testing›
text ‹Here is how to compile Munta Certifier with Poly/ML and then run some benchmarks:›
compile_generated_files "code/Certificate.ML" (in Simple_Network_Language_Certificate_Code)
external_files
‹Writeln.sml›
‹Util.sml›
‹Muntac.sml›
‹Mlton_Main.sml›
‹Unsynchronized.sml›
‹sequential.sml›
‹parallel_task_queue.sml›
‹build_muntac.sml›
‹check_benchmark.sh›
(in "ML")
and
‹HDDI_02.muntax›
‹HDDI_02_broadcast.muntax›
‹HDDI_08_broadcast.muntax›
‹PM_all_1.muntax›
‹PM_all_2.muntax›
‹PM_all_3.muntax›
‹PM_all_4.muntax›
‹PM_all_5.muntax›
‹PM_all_6.muntax›
‹PM_all_urgent.muntax›
‹bridge.muntax›
‹csma_05.muntax›
‹csma_06.muntax›
‹fischer.muntax›
‹fischer_05.muntax›
‹hddi_08.muntax›
‹light_switch.muntax› (in "benchmarks")
export_files ‹muntac_poly› (exe)
where ‹fn dir =>
let
val mock = true
val exec = Generated_Files.execute dir
val _ = exec ‹Copy MLunta› ("cp -r '" ^ Path.implode mlunta_dir ^ "' .")
val _ = exec ‹Compile MLunta› "cd mlunta && mlton=$ISABELLE_MLTON make build_checker && cd .."
val mlunta_path = "mlunta/build/mluntac-mlton"
val _ =
exec ‹Copy Isabelle library files›
("cp '" ^ library_path ^ "' library.ML && cp '" ^ basics_path ^ "' basics.ML")
val _ =
exec ‹Preparation›
"mv code/Certificate.ML Certificate.ML"
val _ =
exec ‹Replace int type›
"sed -i -e 's/IntInf/Int/g' Certificate.ML"
val _ =
exec ‹set›
"set -x"
val _ =
if mock then
(mock_compile dir "Certificate.ML";
exec ‹Compilation› "touch muntac_poly")
else
exec ‹Compilation›
("MLUNTA_CERT=" ^ mlunta_certificate_path ^ " " ^
▩‹$ML_HOME› ^
"/polyc -o muntac_poly build_muntac.sml")
val muntac_path = if mock then "" else "./muntac_poly"
val muntac_path_n6 = muntac_path ^ " -n 6"
val muntac_path_dc = muntac_path ^ " -dc"
val _ = writeln "Generating certificates."
val _ = exec ‹Gen HDDI_02› (mk_cert mlunta_path "HDDI_02")
val _ = exec ‹Gen HDDI_02_broadcast› (mk_cert mlunta_path "HDDI_02_broadcast")
val _ = exec ‹Gen HDDI_08_broadcast› (mk_cert mlunta_path "HDDI_08_broadcast")
val _ = exec ‹Gen hddi_08› (mk_cert mlunta_path "hddi_08")
val _ = exec ‹Gen PM_all_1› (mk_cert mlunta_path "PM_all_1")
val _ = exec ‹Gen PM_all_2› (mk_cert mlunta_path "PM_all_2")
val _ = exec ‹Gen PM_all_3› (mk_cert mlunta_path "PM_all_3")
val _ = exec ‹Gen PM_all_4› (mk_cert mlunta_path "PM_all_4")
val _ = exec ‹Gen PM_all_5› (mk_cert mlunta_path "PM_all_5")
val _ = exec ‹Gen csma_05› (mk_cert mlunta_path "csma_05")
val _ = exec ‹Gen csma_06› (mk_cert mlunta_path "csma_06")
val _ = exec ‹Gen fischer_05› (mk_cert mlunta_path "fischer_05")
val _ = writeln "Finished generating certificates. Now checking.";
fun exec_check_cert title muntac_path name =
if mock then
mock_exec_check_cert dir title muntac_path name
else
exec title (check_cert muntac_path name)
val _ = exec_check_cert ‹Test HDDI_02› muntac_path "HDDI_02"
val _ = exec_check_cert ‹Test HDDI_02_broadcast› muntac_path "HDDI_02_broadcast"
val _ = exec_check_cert ‹Test HDDI_08_broadcast› muntac_path "HDDI_08_broadcast"
val _ = exec_check_cert ‹Test PM_all_1› muntac_path "PM_all_1"
val _ = exec_check_cert ‹Test PM_all_2› muntac_path "PM_all_2"
val _ = exec_check_cert ‹Test PM_all_3› muntac_path "PM_all_3"
val _ = exec_check_cert ‹Test csma_05› muntac_path_n6 "csma_05"
val _ = exec_check_cert ‹Test fischer_05› muntac_path_n6 "fischer_05"
val _ = exec_check_cert ‹Test hddi_08› muntac_path "hddi_08"
val _ = exec_check_cert ‹Test PM_all_4› muntac_path "PM_all_4"
val _ = exec_check_cert ‹Test deadlock HDDI_02› muntac_path_dc "HDDI_02"
in () end›
end