Skip to content
Snippets Groups Projects
Commit f3f31512 authored by erwan's avatar erwan
Browse files

Update: some progress to get time-travel working with rdbgui4sasa

parent 66b73846
No related branches found
No related tags found
No related merge requests found
(* Time-stamp: <modified the 31/05/2021 (at 11:56) by Erwan Jahier> *) (* Time-stamp: <modified the 03/06/2021 (at 12:02) by Erwan Jahier> *)
#thread #thread
#require "lablgtk3" #require "lablgtk3"
...@@ -117,14 +117,23 @@ let display_event b = ...@@ -117,14 +117,23 @@ let display_event b =
(**********************************************************************************) (**********************************************************************************)
(* *) (* *)
let goto_hook_call () = let goto_hook_call e =
if custom_mode then ( if custom_mode then
e := next_cond !e (fun e -> e.name = "mv_hook" && e.kind = Call) next_cond e (fun e -> e.name = "mv_hook" && e.kind = Call)
) else
e
let goto_hook_exit e =
if custom_mode then
next_cond e (fun e -> e.name = "mv_hook" && e.kind = Exit)
else
e
let goto_hook_exit () = let goto_top e =
if custom_mode then if custom_mode then
e := next_cond !e (fun e -> e.name = "mv_hook" && e.kind = Exit) next_cond e (fun e -> e.kind = Ltop)
else
e
let init_rdbg_hook () = let init_rdbg_hook () =
let guidaemon sl = let guidaemon sl =
...@@ -175,7 +184,7 @@ let init_rdbg_hook () = ...@@ -175,7 +184,7 @@ let init_rdbg_hook () =
let set_tooltip b = b#misc#set_tooltip_text let set_tooltip b = b#misc#set_tooltip_text
let custom_daemon p gtext vbox step_button round_button legitimate_button = let custom_daemon p gtext vbox step_button back_step_button round_button legitimate_button =
(* création du rdbg_mv_hook et de tout ce qu'il faut autour *) (* création du rdbg_mv_hook et de tout ce qu'il faut autour *)
init_rdbg_hook (); init_rdbg_hook ();
...@@ -200,8 +209,8 @@ let custom_daemon p gtext vbox step_button round_button legitimate_button = ...@@ -200,8 +209,8 @@ let custom_daemon p gtext vbox step_button round_button legitimate_button =
(* Necessary for salut (to perform a fake step that let sasa provide (* Necessary for salut (to perform a fake step that let sasa provide
the first set of enables) *) the first set of enables) *)
if args.salut_mode then goto_hook_exit (); if args.salut_mode then e := goto_hook_exit !e;
goto_hook_call (); e := goto_hook_call !e;
blue_add gtext#buffer (str_of_sasa_event false !e); blue_add gtext#buffer (str_of_sasa_event false !e);
d(); d();
let nodes_enabled = rdbg_nodes_enabled !e in let nodes_enabled = rdbg_nodes_enabled !e in
...@@ -222,7 +231,6 @@ let custom_daemon p gtext vbox step_button round_button legitimate_button = ...@@ -222,7 +231,6 @@ let custom_daemon p gtext vbox step_button round_button legitimate_button =
blue gtext#buffer txt; blue gtext#buffer txt;
Hashtbl.replace daemongui_activate node activate Hashtbl.replace daemongui_activate node activate
); );
in in
(* 1 case par noeud : activer/pas activer *) (* 1 case par noeud : activer/pas activer *)
...@@ -291,8 +299,8 @@ let custom_daemon p gtext vbox step_button round_button legitimate_button = ...@@ -291,8 +299,8 @@ let custom_daemon p gtext vbox step_button round_button legitimate_button =
ignore(pushbox#event#connect#button_press ignore(pushbox#event#connect#button_press
~callback: (fun _ -> ~callback: (fun _ ->
update_rdbg_hook name true; update_rdbg_hook name true;
goto_hook_exit (); e := goto_hook_exit !e;
goto_hook_call (); e := goto_hook_call !e;
display_event gtext; display_event gtext;
store !e.nb; store !e.nb;
refresh (); refresh ();
...@@ -348,6 +356,7 @@ let custom_daemon p gtext vbox step_button round_button legitimate_button = ...@@ -348,6 +356,7 @@ let custom_daemon p gtext vbox step_button round_button legitimate_button =
match !daemon_kind with match !daemon_kind with
| Manual -> | Manual ->
show step_button; show checkbox_grid; show step_button; show checkbox_grid;
hide back_step_button;
hide legitimate_button; hide legitimate_button;
(match !oracle_button_ref with Some b -> hide b | None -> ()); (match !oracle_button_ref with Some b -> hide b | None -> ());
hide round_button; hide pushbox_grid; hide counter_grid; hide round_button; hide pushbox_grid; hide counter_grid;
...@@ -362,14 +371,17 @@ let custom_daemon p gtext vbox step_button round_button legitimate_button = ...@@ -362,14 +371,17 @@ let custom_daemon p gtext vbox step_button round_button legitimate_button =
| ManualCentral -> | ManualCentral ->
hide legitimate_button; hide legitimate_button;
(match !oracle_button_ref with Some b -> hide b | None -> ()); (match !oracle_button_ref with Some b -> hide b | None -> ());
hide step_button; hide round_button; hide checkbox_grid; hide counter_grid; (* hide back_step_button; *)
hide step_button;
hide round_button; hide checkbox_grid; hide counter_grid;
show pushbox_grid; show pushbox_grid;
let pushbox = Hashtbl.find pushbox_map node in let pushbox = Hashtbl.find pushbox_map node in
if enabled then show pushbox else hide pushbox; if enabled then show pushbox else hide pushbox;
pushbox#set_sensitive enabled pushbox#set_sensitive enabled
| Distributed | Synchronous | Central | LocCentral -> | Distributed | Synchronous | Central | LocCentral ->
(match !oracle_button_ref with Some b -> show b | None -> ()); (match !oracle_button_ref with Some b -> show b | None -> ());
show step_button; show round_button; show counter_grid; show legitimate_button; show back_step_button; show step_button; show round_button;
show counter_grid; show legitimate_button;
hide checkbox_grid; hide pushbox_grid; hide checkbox_grid; hide pushbox_grid;
in in
let update_all_checkboxes () = let update_all_checkboxes () =
...@@ -425,63 +437,57 @@ let custom_daemon p gtext vbox step_button round_button legitimate_button = ...@@ -425,63 +437,57 @@ let custom_daemon p gtext vbox step_button round_button legitimate_button =
in in
aux 0 [] nl aux 0 [] nl
in in
let step () = let set_daemongui_tbl e =
let nodes_enabled = rdbg_nodes_enabled !e in (* In automatic modes:
- looks who is enabled,
- chooses whom to activate, and
- sets the the tbl shared with the hook function
Should therefore be used at events where the enabled process info is available
*)
let nodes_enabled = rdbg_nodes_enabled e in
let nodes = List.filter (fun (_,b) -> b) nodes_enabled in let nodes = List.filter (fun (_,b) -> b) nodes_enabled in
let nodes = get_higher_prioriry nodes in let nodes = get_higher_prioriry nodes in
(* p ("==> gtkgui: CALL =" ^ (string_of_event !e)); *) (* p ("==> gtkgui: CALL =" ^ (string_of_event e)); *)
(match !daemon_kind with (match !daemon_kind with
| Distributed -> ( | Distributed -> (
let nodes = List.map (fun x -> [x]) nodes in let nodes = List.map (fun x -> [x]) nodes in
let to_activate = Daemon.distributed nodes in let to_activate = Daemon.distributed nodes in
Hashtbl.clear daemongui_activate; Hashtbl.clear daemongui_activate;
List.iter (fun n -> Hashtbl.replace daemongui_activate n true) to_activate; List.iter (fun n -> Hashtbl.replace daemongui_activate n true) to_activate
goto_hook_exit (); )
goto_hook_call (); | Synchronous -> (
) Hashtbl.clear daemongui_activate;
| Synchronous -> ( List.iter (fun n -> Hashtbl.replace daemongui_activate n true) nodes
Hashtbl.clear daemongui_activate; )
List.iter (fun n -> Hashtbl.replace daemongui_activate n true) nodes; | Central -> (
goto_hook_exit (); let nodes = List.map (fun x -> [x]) nodes in
goto_hook_call (); let to_activate = Daemon.central nodes in
) Hashtbl.clear daemongui_activate;
| Central -> ( List.iter (fun n ->
let nodes = List.map (fun x -> [x]) nodes in Printf.printf "Activating %s\n" n;
let to_activate = Daemon.central nodes in Hashtbl.replace daemongui_activate n true) to_activate
Hashtbl.clear daemongui_activate; )
List.iter (fun n -> | LocCentral -> (
Printf.printf "Activating %s\n" n; let get_neigbors x =
Hashtbl.replace daemongui_activate n true) to_activate; let succ = snd (List.split (topology.succ x)) in
goto_hook_exit (); let pred = topology.pred x in
goto_hook_call (); let res = List.fold_left
) (fun acc x -> if List.mem x acc then acc else x::acc) succ pred
| LocCentral -> ( in
let get_neigbors x = (* p (Printf.sprintf "voisins(%s)=%s\n" x (String.concat "," res)); *)
let succ = snd (List.split (topology.succ x)) in res
let pred = topology.pred x in in
let res = List.fold_left (fun acc x -> if List.mem x acc then acc else x::acc) succ pred in let nodes = List.map (fun x -> [x, get_neigbors x]) nodes in
(* p (Printf.sprintf "voisins(%s)=%s\n" x (String.concat "," res)); *) let to_activate = Daemon.locally_central nodes in
res Hashtbl.clear daemongui_activate;
in List.iter (fun n -> Hashtbl.replace daemongui_activate n true) to_activate
let nodes = List.map (fun x -> [x, get_neigbors x]) nodes in )
let to_activate = Daemon.locally_central nodes in | ManualCentral -> () (* SNO; the step is done in pushbox callbacks *)
Hashtbl.clear daemongui_activate; | Manual -> ()
List.iter (fun n -> Hashtbl.replace daemongui_activate n true) to_activate;
goto_hook_exit ();
goto_hook_call ();
) )
| ManualCentral -> () (* SNO; the step is done in pushbox callbacks *)
| Manual ->
goto_hook_exit ();
goto_hook_call ();
store !e.nb;
);
if not args.salut_mode && is_silent !e then
(* go to Ltop so that the round number can be updated *)
e := next_cond !e (fun e -> e.kind = Ltop);
d ()
in in
step set_daemongui_tbl
let prefix = let prefix =
try try
...@@ -550,7 +556,6 @@ let main () = ...@@ -550,7 +556,6 @@ let main () =
let back_step_button = button ~use_mnemonic:true ~stock:`GO_BACK ~packing:bbox#add () in let back_step_button = button ~use_mnemonic:true ~stock:`GO_BACK ~packing:bbox#add () in
set_tooltip back_step_button "Move BACKWARD to the previous STEP"; set_tooltip back_step_button "Move BACKWARD to the previous STEP";
change_label back_step_button "Ste_p"; change_label back_step_button "Ste_p";
ignore (back_step_button#connect#clicked ~callback:(button_cb true true bd));
let step_button = button ~use_mnemonic:true ~packing:bbox#add ~stock:`GO_FORWARD () in let step_button = button ~use_mnemonic:true ~packing:bbox#add ~stock:`GO_FORWARD () in
let back_round_button = let back_round_button =
...@@ -564,19 +569,55 @@ let main () = ...@@ -564,19 +569,55 @@ let main () =
"Move FORWARD until a legitimate configuration is reached (silence by default)"; "Move FORWARD until a legitimate configuration is reached (silence by default)";
let image = GMisc.image ~file:(libui_prefix^"/chut_small.svg") () in let image = GMisc.image ~file:(libui_prefix^"/chut_small.svg") () in
legitimate_button#set_image image#coerce; legitimate_button#set_image image#coerce;
let ze_step = let set_daemongui_tbl =
if custom_mode then if custom_mode then
custom_daemon p text_out w step_button round_button legitimate_button custom_daemon p text_out w step_button back_step_button round_button legitimate_button
else else
s (* cf sasa-rdbg-cmds.ml *) (fun _ -> ())
in in
let step () = let a_gui_step e =
ze_step(); (* set the daemongui_tbl and step to the next event where the user
d() is asked to choose whom to activate *)
if custom_mode then (
set_daemongui_tbl e;
let e = goto_hook_exit e in
let e = goto_hook_call e in
if not args.salut_mode && is_silent e then
(* go to Ltop so that the round number can be updated *)
next_cond e (fun e -> e.kind = Ltop)
else
e
)
else
let e = sasa_step e in
store e.nb;
print_event e;
e
in
let back_step_gui () =
let lnext e =
if args.salut_mode then
let e = goto_top e in
set_daemongui_tbl e;
e
else
let e = goto_hook_call e in
set_daemongui_tbl e;
e
in
let ne = rev_cond_gen !e (fun ne -> ne.step = !e.step-1) lnext in
if ne.kind <> !e.kind || ne.name <> !e.name then
e:=next_cond ne (fun ne -> ne.kind = !e.kind || ne.name = !e.name)
else
e:=ne
in in
ignore (back_step_button#connect#clicked
~callback:(button_cb true false back_step_gui));
let step () = if not (is_silent !e) then (e := a_gui_step !e; d()) in
let rec legitimate_gui () = let rec legitimate_gui () =
ze_step(); if is_silent !e then () else e := a_gui_step !e;
if is_legitimate !e || is_silent !e then () else (legitimate_gui ()); if is_legitimate !e || is_silent !e then () else (legitimate_gui ());
in in
(* change_label legitimate_button "Silen_t"; *) (* change_label legitimate_button "Silen_t"; *)
...@@ -588,7 +629,7 @@ let main () = ...@@ -588,7 +629,7 @@ let main () =
if custom_mode then legitimate_button#misc#hide(); if custom_mode then legitimate_button#misc#hide();
(* indeed, in the defaut mode (manual central), it should be hided *) (* indeed, in the defaut mode (manual central), it should be hided *)
let rec next_round_gui rn = let rec next_round_gui rn =
ze_step(); if is_silent !e then () else e:=a_gui_step !e;
if rn < !roundnb || is_silent !e then () else (next_round_gui rn); if rn < !roundnb || is_silent !e then () else (next_round_gui rn);
in in
...@@ -602,8 +643,10 @@ let main () = ...@@ -602,8 +643,10 @@ let main () =
button_cb true true (fun () -> button_cb true true (fun () ->
if custom_mode then ( if custom_mode then (
next_round_gui !roundnb; next_round_gui !roundnb;
if custom_mode && !e.name <> "mv_hook" && !e.kind <> Call then if custom_mode && !e.name <> "mv_hook" && !e.kind <> Call
goto_hook_call () && not (is_silent !e)
then
e:= goto_hook_call !e
) )
else else
nr () nr ()
...@@ -612,7 +655,7 @@ let main () = ...@@ -612,7 +655,7 @@ let main () =
set_tooltip back_round_button "Move BACKWARD to the previous ROUND"; set_tooltip back_round_button "Move BACKWARD to the previous ROUND";
change_label back_round_button "Roun_d"; change_label back_round_button "Roun_d";
ignore (back_round_button#connect#clicked ignore (back_round_button#connect#clicked
~callback:(button_cb true true (fun () -> pr();pr(); goto_hook_call ()))); ~callback:(button_cb true true (fun () -> pr();pr(); e:=goto_hook_call !e)));
let graph () = let graph () =
...@@ -636,7 +679,7 @@ let main () = ...@@ -636,7 +679,7 @@ let main () =
let oracle_button = let oracle_button =
make_button `OK "_Oracle" "Move FORWARD until an oracle is violated" make_button `OK "_Oracle" "Move FORWARD until an oracle is violated"
(button_cb_string (button_cb_string
(fun () -> let str = viol_string () in goto_hook_call (); d(); store !e.nb; str)) (fun () -> let str = viol_string () in e:=goto_hook_call !e; d(); store !e.nb; str))
in in
oracle_button#misc#hide(); (* indeed, in the defaut mode (manual central), it should be hided *) oracle_button#misc#hide(); (* indeed, in the defaut mode (manual central), it should be hided *)
oracle_button_ref := Some oracle_button oracle_button_ref := Some oracle_button
...@@ -653,8 +696,8 @@ let main () = ...@@ -653,8 +696,8 @@ let main () =
(* in this mode, the hook plays first to provide fake values to sasa (* in this mode, the hook plays first to provide fake values to sasa
but the hook does not need input at this first step but the hook does not need input at this first step
*) *)
goto_hook_exit (); e:=goto_hook_exit !e;
goto_hook_call (); e:=goto_hook_call !e;
d())) d()))
in in
let _ = make_button `REFRESH "_New Seed" "Restart from the beginning using a New Seed" let _ = make_button `REFRESH "_New Seed" "Restart from the beginning using a New Seed"
...@@ -670,8 +713,8 @@ let main () = ...@@ -670,8 +713,8 @@ let main () =
(* in this mode, the hook plays first to provide fake values to sasa (* in this mode, the hook plays first to provide fake values to sasa
but the hook does not need input at this first step but the hook does not need input at this first step
*) *)
goto_hook_exit (); e:=goto_hook_exit !e;
goto_hook_call (); e:=goto_hook_call !e;
d())) d()))
in in
let _ = make_button `MEDIA_PLAY "_Sim2chro" "Launch sim2chro on the generated data (so far)" let _ = make_button `MEDIA_PLAY "_Sim2chro" "Launch sim2chro on the generated data (so far)"
......
...@@ -8,13 +8,24 @@ open RdbgMain ...@@ -8,13 +8,24 @@ open RdbgMain
open Sasacore.Topology;; open Sasacore.Topology;;
#use "dot4sasa.ml";; #use "dot4sasa.ml";;
let is_silent e =
match List.assoc_opt "silent" e.data with
| Some B b -> b
| _ -> failwith "The silent value is not available in this event"
let is_legitimate e =
match List.assoc_opt "legitimate" e.data with
| Some B b -> b
| _ -> failwith ("legitimate not available at this event: "^(string_of_event e))
(**********************************************************************) (**********************************************************************)
(** Computing rounds *) (** Computing rounds *)
let roundnb = ref (-666) let roundnb = ref (-666)
let mask = ref [] (* nodes we look the activation of *) (* XXX use an array! *) let mask = ref [] (* nodes we look the activation of *) (* XXX use an array! *)
let roundtbl = Hashtbl.create 10;; let roundtbl = Hashtbl.create 10;; (* maps event nb to round + round nb *)
(* let _ = Hashtbl.add roundtbl 1 (1,true);; *) (* let _ = Hashtbl.add roundtbl 1 (1,true);; *)
let verbose = ref false let verbose = ref false
...@@ -47,12 +58,14 @@ let enabled pl = (* returns the enabled processes *) ...@@ -47,12 +58,14 @@ let enabled pl = (* returns the enabled processes *)
(* called at each event via the time-travel hook *) (* called at each event via the time-travel hook *)
let (round : RdbgEvent.t -> bool) = fun e -> let (round : RdbgEvent.t -> bool) = fun e ->
match Hashtbl.find_opt roundtbl e.nb with match Hashtbl.find_opt roundtbl e.nb with
| Some (croundnb, round) -> | Some (croundnb, round, cmask) ->
(* Printf.printf "round tabulated at e.nb %d: croundnb=%d round = %b\n%!" *) (* Printf.printf "round tabulated at e.nb %d: croundnb=%d round = %b\n%!" *)
(* e.nb croundnb round; *) (* e.nb croundnb round; *)
roundnb := croundnb; roundnb := croundnb;
mask := cmask;
round round
| None -> | None ->
if !mask = [] && is_silent e then false else
let round = let round =
( (* we check if a round occurs when activated processes are available *) ( (* we check if a round occurs when activated processes are available *)
if args.salut_mode then if args.salut_mode then
...@@ -91,7 +104,7 @@ let (round : RdbgEvent.t -> bool) = fun e -> ...@@ -91,7 +104,7 @@ let (round : RdbgEvent.t -> bool) = fun e ->
res res
in in
if round then incr roundnb; if round then incr roundnb;
Hashtbl.add roundtbl e.nb (!roundnb, round); Hashtbl.add roundtbl e.nb (!roundnb, round, !mask);
(* Printf.printf "round computed at e.nb %d: croundnb=%d round = %b\n%!" (* Printf.printf "round computed at e.nb %d: croundnb=%d round = %b\n%!"
e.nb !roundnb round; *) e.nb !roundnb round; *)
round round
...@@ -99,7 +112,7 @@ let (round : RdbgEvent.t -> bool) = fun e -> ...@@ -99,7 +112,7 @@ let (round : RdbgEvent.t -> bool) = fun e ->
let update_round_nb e = let update_round_nb e =
match Hashtbl.find_opt roundtbl e.nb with match Hashtbl.find_opt roundtbl e.nb with
| None -> () | None -> ()
| Some (n,_) -> roundnb := n | Some (n,_, m) -> roundnb := n; mask := m
(* go to next round *) (* go to next round *)
let next_round e = let next_round e =
...@@ -108,8 +121,8 @@ let next_round e = ...@@ -108,8 +121,8 @@ let next_round e =
(**********************************************************************) (**********************************************************************)
(* redefine (more meaningful) step and back-step for sasa *) (* redefine (more meaningful) step and back-step for sasa *)
let sasa_step e = next_cond e (fun ne -> ne.kind = e.kind) let sasa_step e = next_cond e (fun ne -> ne.kind = e.kind && ne.name = e.name)
let sasa_bstep e = rev_cond e (fun ne -> ne.kind = e.kind) let sasa_bstep e = rev_cond e (fun ne -> ne.kind = e.kind && ne.name = e.name)
let s () = e:=sasa_step !e ; emacs_udate !e; store !e.nb;pe() let s () = e:=sasa_step !e ; emacs_udate !e; store !e.nb;pe()
let b () = e:=sasa_bstep !e ; emacs_udate !e; store !e.nb;pe() let b () = e:=sasa_bstep !e ; emacs_udate !e; store !e.nb;pe()
...@@ -168,6 +181,33 @@ let r () = ...@@ -168,6 +181,33 @@ let r () =
(* if the first event is not a round, add it as a check_point *) (* if the first event is not a round, add it as a check_point *)
if !ckpt_list = [] then ckpt_list := [!e];; if !ckpt_list = [] then ckpt_list := [!e];;
(**********************************************************************)
(* Move forward until silence *)
let goto_silence e = next_cond e is_silent
let silence () = e:=goto_silence !e; !dot_view ();;
let _ = add_doc_entry
"silence" "unit -> unit" "Move forward until is_silent returns true"
"sasa" "sasa-rdbg-cmds.ml";
add_doc_entry
"is_silent" "RdbgEvent.t -> bool"
"does the event correspond to a silent configuration? (i.e., no enable node)"
"sasa" "sasa-rdbg-cmds.ml";;
let goto_legitimate e = next_cond e is_legitimate
let legitimate () = e:=goto_legitimate !e; !dot_view ();;
let _ =
add_doc_entry
"legitimate" "unit -> unit"
" Move forward until a legitimate configuration is reached (uses 'silence' by default)"
"sasa" "sasa-rdbg-cmds.ml";
add_doc_entry
"is_legitimate" "RdbgEvent.t -> bool"
"does the event correspond to a legitimate configuration?"
"sasa" "sasa-rdbg-cmds.ml";;
(**********************************************************************) (**********************************************************************)
(* print_event tuning *) (* print_event tuning *)
...@@ -279,42 +319,6 @@ let _ = add_doc_entry ...@@ -279,42 +319,6 @@ let _ = add_doc_entry
"sasa" "sasa-rdbg-cmds.ml" "sasa" "sasa-rdbg-cmds.ml"
(**********************************************************************)
(* Move forward until silence *)
let is_silent e =
match List.assoc_opt "silent" e.data with
| Some B b -> b
| _ -> failwith "The silent value is not available in this event"
let goto_silence e = next_cond e is_silent
let silence () = e:=goto_silence !e; !dot_view ();;
let _ = add_doc_entry
"silence" "unit -> unit" "Move forward until is_silent returns true"
"sasa" "sasa-rdbg-cmds.ml";
add_doc_entry
"is_silent" "RdbgEvent.t -> bool"
"does the event correspond to a silent configuration? (i.e., no enable node)"
"sasa" "sasa-rdbg-cmds.ml";;
let is_legitimate e =
match List.assoc_opt "legitimate" e.data with
| Some B b -> b
| _ -> failwith ("legitimate not available at this event: "^(string_of_event e))
let goto_legitimate e = next_cond e is_legitimate
let legitimate () = e:=goto_legitimate !e; !dot_view ();;
let _ =
add_doc_entry
"legitimate" "unit -> unit"
" Move forward until a legitimate configuration is reached (uses 'silence' by default)"
"sasa" "sasa-rdbg-cmds.ml";
add_doc_entry
"is_legitimate" "RdbgEvent.t -> bool"
"does the event correspond to a legitimate configuration?"
"sasa" "sasa-rdbg-cmds.ml";;
(**********************************************************************) (**********************************************************************)
(* Perform the checkpointing at rounds! *) (* Perform the checkpointing at rounds! *)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment