From f3f315124d5c0832a120b151426020d4f21a4a78 Mon Sep 17 00:00:00 2001 From: Erwan Jahier <erwan.jahier@univ-grenoble-alpes.fr> Date: Thu, 3 Jun 2021 14:08:19 +0200 Subject: [PATCH] Update: some progress to get time-travel working with rdbgui4sasa --- tools/rdbg4sasa/gtkgui.ml | 215 ++++++++++++++++++------------ tools/rdbg4sasa/sasa-rdbg-cmds.ml | 90 +++++++------ 2 files changed, 176 insertions(+), 129 deletions(-) diff --git a/tools/rdbg4sasa/gtkgui.ml b/tools/rdbg4sasa/gtkgui.ml index 966af367..90fe497d 100644 --- a/tools/rdbg4sasa/gtkgui.ml +++ b/tools/rdbg4sasa/gtkgui.ml @@ -1,4 +1,4 @@ -(* 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 #require "lablgtk3" @@ -117,14 +117,23 @@ let display_event b = (**********************************************************************************) (* *) -let goto_hook_call () = - if custom_mode then ( - e := next_cond !e (fun e -> e.name = "mv_hook" && e.kind = Call) - ) +let goto_hook_call e = + if custom_mode then + 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 - 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 guidaemon sl = @@ -175,7 +184,7 @@ let init_rdbg_hook () = 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 *) init_rdbg_hook (); @@ -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 the first set of enables) *) - if args.salut_mode then goto_hook_exit (); - goto_hook_call (); + if args.salut_mode then e := goto_hook_exit !e; + e := goto_hook_call !e; blue_add gtext#buffer (str_of_sasa_event false !e); d(); let nodes_enabled = rdbg_nodes_enabled !e in @@ -222,7 +231,6 @@ let custom_daemon p gtext vbox step_button round_button legitimate_button = blue gtext#buffer txt; Hashtbl.replace daemongui_activate node activate ); - in (* 1 case par noeud : activer/pas activer *) @@ -291,8 +299,8 @@ let custom_daemon p gtext vbox step_button round_button legitimate_button = ignore(pushbox#event#connect#button_press ~callback: (fun _ -> update_rdbg_hook name true; - goto_hook_exit (); - goto_hook_call (); + e := goto_hook_exit !e; + e := goto_hook_call !e; display_event gtext; store !e.nb; refresh (); @@ -348,6 +356,7 @@ let custom_daemon p gtext vbox step_button round_button legitimate_button = match !daemon_kind with | Manual -> show step_button; show checkbox_grid; + hide back_step_button; hide legitimate_button; (match !oracle_button_ref with Some b -> hide b | None -> ()); 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 = | ManualCentral -> hide legitimate_button; (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; let pushbox = Hashtbl.find pushbox_map node in if enabled then show pushbox else hide pushbox; pushbox#set_sensitive enabled | Distributed | Synchronous | Central | LocCentral -> (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; in let update_all_checkboxes () = @@ -425,63 +437,57 @@ let custom_daemon p gtext vbox step_button round_button legitimate_button = in aux 0 [] nl in - let step () = - let nodes_enabled = rdbg_nodes_enabled !e in + let set_daemongui_tbl e = + (* 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 = get_higher_prioriry nodes in - (* p ("==> gtkgui: CALL =" ^ (string_of_event !e)); *) + (* p ("==> gtkgui: CALL =" ^ (string_of_event e)); *) (match !daemon_kind with - | Distributed -> ( - let nodes = List.map (fun x -> [x]) nodes in - let to_activate = Daemon.distributed nodes in - Hashtbl.clear daemongui_activate; - List.iter (fun n -> Hashtbl.replace daemongui_activate n true) to_activate; - goto_hook_exit (); - goto_hook_call (); - ) - | Synchronous -> ( - Hashtbl.clear daemongui_activate; - List.iter (fun n -> Hashtbl.replace daemongui_activate n true) nodes; - goto_hook_exit (); - goto_hook_call (); - ) - | Central -> ( - let nodes = List.map (fun x -> [x]) nodes in - let to_activate = Daemon.central nodes in - Hashtbl.clear daemongui_activate; - List.iter (fun n -> - Printf.printf "Activating %s\n" n; - Hashtbl.replace daemongui_activate n true) to_activate; - goto_hook_exit (); - goto_hook_call (); - ) - | LocCentral -> ( - let get_neigbors x = - let succ = snd (List.split (topology.succ x)) in - let pred = topology.pred x in - let res = List.fold_left (fun acc x -> if List.mem x acc then acc else x::acc) succ pred in - (* p (Printf.sprintf "voisins(%s)=%s\n" x (String.concat "," res)); *) - res - in - let nodes = List.map (fun x -> [x, get_neigbors x]) nodes in - let to_activate = Daemon.locally_central nodes in - Hashtbl.clear daemongui_activate; - List.iter (fun n -> Hashtbl.replace daemongui_activate n true) to_activate; - goto_hook_exit (); - goto_hook_call (); + | Distributed -> ( + let nodes = List.map (fun x -> [x]) nodes in + let to_activate = Daemon.distributed nodes in + Hashtbl.clear daemongui_activate; + List.iter (fun n -> Hashtbl.replace daemongui_activate n true) to_activate + ) + | Synchronous -> ( + Hashtbl.clear daemongui_activate; + List.iter (fun n -> Hashtbl.replace daemongui_activate n true) nodes + ) + | Central -> ( + let nodes = List.map (fun x -> [x]) nodes in + let to_activate = Daemon.central nodes in + Hashtbl.clear daemongui_activate; + List.iter (fun n -> + Printf.printf "Activating %s\n" n; + Hashtbl.replace daemongui_activate n true) to_activate + ) + | LocCentral -> ( + let get_neigbors x = + let succ = snd (List.split (topology.succ x)) in + let pred = topology.pred x in + let res = List.fold_left + (fun acc x -> if List.mem x acc then acc else x::acc) succ pred + in + (* p (Printf.sprintf "voisins(%s)=%s\n" x (String.concat "," res)); *) + res + in + let nodes = List.map (fun x -> [x, get_neigbors x]) nodes in + let to_activate = Daemon.locally_central nodes in + Hashtbl.clear daemongui_activate; + List.iter (fun n -> Hashtbl.replace daemongui_activate n true) to_activate + ) + | ManualCentral -> () (* SNO; the step is done in pushbox callbacks *) + | Manual -> () ) - | 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 - step + set_daemongui_tbl let prefix = try @@ -550,7 +556,6 @@ let main () = 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"; 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 back_round_button = @@ -564,19 +569,55 @@ let main () = "Move FORWARD until a legitimate configuration is reached (silence by default)"; let image = GMisc.image ~file:(libui_prefix^"/chut_small.svg") () in legitimate_button#set_image image#coerce; - - let ze_step = + + let set_daemongui_tbl = 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 - s (* cf sasa-rdbg-cmds.ml *) - in - let step () = - ze_step(); - d() + (fun _ -> ()) + in + let a_gui_step e = + (* set the daemongui_tbl and step to the next event where the user + 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 + 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 () = - ze_step(); + if is_silent !e then () else e := a_gui_step !e; if is_legitimate !e || is_silent !e then () else (legitimate_gui ()); in (* change_label legitimate_button "Silen_t"; *) @@ -588,7 +629,7 @@ let main () = if custom_mode then legitimate_button#misc#hide(); (* indeed, in the defaut mode (manual central), it should be hided *) 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); in @@ -602,8 +643,10 @@ let main () = button_cb true true (fun () -> if custom_mode then ( next_round_gui !roundnb; - if custom_mode && !e.name <> "mv_hook" && !e.kind <> Call then - goto_hook_call () + if custom_mode && !e.name <> "mv_hook" && !e.kind <> Call + && not (is_silent !e) + then + e:= goto_hook_call !e ) else nr () @@ -612,7 +655,7 @@ let main () = set_tooltip back_round_button "Move BACKWARD to the previous ROUND"; change_label back_round_button "Roun_d"; 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 () = @@ -636,7 +679,7 @@ let main () = let oracle_button = make_button `OK "_Oracle" "Move FORWARD until an oracle is violated" (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 oracle_button#misc#hide(); (* indeed, in the defaut mode (manual central), it should be hided *) oracle_button_ref := Some oracle_button @@ -653,8 +696,8 @@ let main () = (* in this mode, the hook plays first to provide fake values to sasa but the hook does not need input at this first step *) - goto_hook_exit (); - goto_hook_call (); + e:=goto_hook_exit !e; + e:=goto_hook_call !e; d())) in let _ = make_button `REFRESH "_New Seed" "Restart from the beginning using a New Seed" @@ -670,8 +713,8 @@ let main () = (* in this mode, the hook plays first to provide fake values to sasa but the hook does not need input at this first step *) - goto_hook_exit (); - goto_hook_call (); + e:=goto_hook_exit !e; + e:=goto_hook_call !e; d())) in let _ = make_button `MEDIA_PLAY "_Sim2chro" "Launch sim2chro on the generated data (so far)" diff --git a/tools/rdbg4sasa/sasa-rdbg-cmds.ml b/tools/rdbg4sasa/sasa-rdbg-cmds.ml index d7859a2b..627fb956 100644 --- a/tools/rdbg4sasa/sasa-rdbg-cmds.ml +++ b/tools/rdbg4sasa/sasa-rdbg-cmds.ml @@ -8,13 +8,24 @@ open RdbgMain open Sasacore.Topology;; #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 *) - let roundnb = ref (-666) 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 verbose = ref false @@ -47,12 +58,14 @@ let enabled pl = (* returns the enabled processes *) (* called at each event via the time-travel hook *) let (round : RdbgEvent.t -> bool) = fun e -> 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%!" *) (* e.nb croundnb round; *) roundnb := croundnb; + mask := cmask; round | None -> + if !mask = [] && is_silent e then false else let round = ( (* we check if a round occurs when activated processes are available *) if args.salut_mode then @@ -91,7 +104,7 @@ let (round : RdbgEvent.t -> bool) = fun e -> res in 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%!" e.nb !roundnb round; *) round @@ -99,7 +112,7 @@ let (round : RdbgEvent.t -> bool) = fun e -> let update_round_nb e = match Hashtbl.find_opt roundtbl e.nb with | None -> () - | Some (n,_) -> roundnb := n + | Some (n,_, m) -> roundnb := n; mask := m (* go to next round *) let next_round e = @@ -108,8 +121,8 @@ let next_round e = (**********************************************************************) (* redefine (more meaningful) step and back-step for sasa *) -let sasa_step e = next_cond e (fun ne -> ne.kind = e.kind) -let sasa_bstep e = rev_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 && ne.name = e.name) 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() @@ -168,6 +181,33 @@ let r () = (* if the first event is not a round, add it as a check_point *) 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 *) @@ -279,42 +319,6 @@ let _ = add_doc_entry "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! *) -- GitLab