diff --git a/.merlin b/.merlin deleted file mode 100644 index 85d3a654aab398a822e7c90a0fc7cfca3ae8a9cd..0000000000000000000000000000000000000000 --- a/.merlin +++ /dev/null @@ -1,10 +0,0 @@ -PKG lutils rdbg lustre-v6 lutin - -S src/ -S lib/sasacore/ -S lib/sasa/ -S lib/algo/ - -B _build/default/lib/algo/.algo.objs/* -B _build/default/lib/sasa/.sasa.objs/* -B _build/default/lib/sasacore/.sasacore.objs/* diff --git a/guides/users/Makefile b/guides/users/Makefile index 3148f5eaff68fe67319f3f9090d1baa21c8c92d6..2ff6311b683a54cc16f3b56707d0789b734ed219 100644 --- a/guides/users/Makefile +++ b/guides/users/Makefile @@ -10,17 +10,17 @@ algo: cp -rf ../../_build/default/_doc/_html . %.html:%.org - emacs25 --batch --eval="(add-to-list 'load-path \".\") (add-to-list 'load-path \"./el\")" --eval="(require 'htmlize)" --load=emacs-org.el \ + emacs --batch --load=emacs-org.el \ --visit=$*.org --funcall org-html-export-to-html %.md:%.org - emacs25 --batch --eval="(add-to-list 'load-path \".\") (add-to-list 'load-path \"./el\")" --eval="(require 'htmlize)" --load=emacs-org.el --visit=$*.org --funcall org-md-export-to-markdown + emacs --batch --eval="(add-to-list 'load-path \".\")" --load=emacs-org.el --visit=$*.org --funcall org-md-export-to-markdown %.html3:%.org emacs --batch --eval="(add-to-list 'load-path \".\") (add-to-list 'load-path \"./el\")" --eval="(require 'htmlize)" --load=emacs-org.el \ --visit=$*.org --funcall org-html-export-to-html -EMACS=emacs25 \ +EMACS=emacs \ --load=htmlize.el \ --load=el/ob-ocaml.el \ --load=emacs-org.el diff --git a/guides/users/emacs-org.el b/guides/users/emacs-org.el index ea864dbfc6ca9dcb60c2157bad761942c6af28fe..86cfcae31af990b53af4b2d8c0a2a2f39dd45cf5 100644 --- a/guides/users/emacs-org.el +++ b/guides/users/emacs-org.el @@ -1,6 +1,7 @@ (setq load-path (cons (expand-file-name "./el") load-path)) +(setq load-path (cons (expand-file-name "./") load-path)) (setq auto-mode-alist (cons '("\\.lut$" . lutin-mode) auto-mode-alist)) @@ -49,7 +50,7 @@ (lutin . t) (dot . t) (rif . t) - (sh . t) + (shell . t) ) ) diff --git a/lib/algo/algo.ml b/lib/algo/algo.ml index 91d0bed03bf7664114694c28beea997162baa880..de8f960747589e2447d429589b252089ddddbdc3 100644 --- a/lib/algo/algo.ml +++ b/lib/algo/algo.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 13/10/2020 (at 15:55) by Erwan Jahier> *) +(* Time-stamp: <modified the 09/04/2021 (at 10:04) by Erwan Jahier> *) open Sasacore (* Process programmer API *) @@ -144,11 +144,15 @@ let max_degree = Register.max_degree let is_cyclic = Register.is_cyclic let is_connected = Register.is_connected let is_directed = Register.is_directed -let is_tree = Register.is_tree -let height = Register.height let links_number = Register.links_number let diameter = Register.diameter +let is_tree = Register.is_tree +let is_in_tree = Register.is_in_tree +let is_out_tree = Register.is_out_tree +let height = Register.height +let sub_tree_size = Register.sub_tree_size +let parent = Register.parent (* let pid n = n.pid diff --git a/lib/algo/algo.mli b/lib/algo/algo.mli index b2195f0cb6587155c27488b580a6b9bbcc84c3c7..4c48f6d23f7435f0c29b476d6887bdb8d3e2d353 100644 --- a/lib/algo/algo.mli +++ b/lib/algo/algo.mli @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 04/11/2020 (at 08:15) by Erwan Jahier> *) +(* Time-stamp: <modified the 09/04/2021 (at 10:39) by Erwan Jahier> *) (** {1 The Algorithm programming Interface} A SASA process is an instance of an algorithm defined via this @@ -22,15 +22,16 @@ type 's enable_fun = 's -> 's neighbor list -> action list type 's step_fun = 's -> 's neighbor list -> action -> 's (** [enable_fun] and [step_fun] have the same arguments in input: - - The first argument holds the current state of the process. As it is - polymorphic (['s]), algorithms designers can put anything they need - into this state (an integer, a structure, etc.). The only constraint - is that all algorithms should use the same type. + - The first argument holds the current state of the process. As it + is polymorphic (['s]), algorithms designers can put anything they + need into this state (an integer, a structure, etc.). The only + constraint is that all algorithms should use the same type. - - The second argument holds the process neighbors. Note that SASA - processes, that live in graph nodes, can only access to their - immediate neighbors. From each neighbor, a process can access to - various information (cf [state], [reply], and [weight] functions below). + - The second argument holds the process neighbors (its successors + in the graph). Note that SASA processes, that live in graph nodes, + can only access to their immediate neighbors. From each neighbor, + a process can access to various information (cf [state], [reply], + and [weight] functions below). [enable_fun] returns the list of enable actions. @@ -82,7 +83,7 @@ val state : 's neighbor -> 's (** Returns the neighbor channel number, that let this neighbor access to the content of the current process, if its neighbor can access - it. The channel number is the rank,starting at 0, in the + it. The channel number is the rank, starting at 0, in the neighbors' list. Returns -1 if the neighbor can not access to the process, which may happen in directed graphs. @@ -111,11 +112,26 @@ val max_degree : unit -> int val is_directed : unit -> bool val is_cyclic : unit -> bool val is_connected : unit -> bool -val is_tree : unit -> bool -val height : unit -> (string (* the node id *) -> int) option val links_number : unit -> int val diameter : unit -> int +(** {3 Trees} *) +val is_tree : unit -> bool +val is_in_tree : unit -> bool +val is_out_tree : unit -> bool + +(** The 3 functions below work for in_tree or out_tree only. *) + +(* maps each node to the size of the corresponding sub-tree *) +val sub_tree_size : string (* the node id *) -> int + +(** maps each node to its height in the tree *) +val height : string (* the node id *) -> int + +(** maps each node to the channel number of its parent, and to None + for the tree root. *) +val parent : string (* the node id *) -> int option + (** It is possible to set some global parameters in the dot file using graph attributes. This function allows one the get their values. *) diff --git a/lib/sasa/sasaRun.ml b/lib/sasa/sasaRun.ml index 99f0e1bb0f742a2f476e58c3cf679260bc727615..5b2301cf6e2c5fdbd25f47ea5aded2845795b5b0 100644 --- a/lib/sasa/sasaRun.ml +++ b/lib/sasa/sasaRun.ml @@ -15,16 +15,16 @@ let (get_action_value : (string * Data.v) list -> string -> string -> bool) = open Sasacore open Process -let (from_sasa_env : 'v Main.layout -> 'v Env.t -> RdbgPlugin.sl) = - fun p_nl_l e -> +let (from_sasa_env : 'v SimuState.t -> RdbgPlugin.sl) = + fun st -> List.fold_left - (fun acc (p,_) -> - let state = Env.get e p.pid in + (fun acc p -> + let state = Env.get st.config p.pid in let sl = SasaState.to_rdbg_subst p.pid state in acc@sl ) [] - p_nl_l + st.network let (get_sl_out: bool -> 'v Process.t list -> bool list list -> RdbgPlugin.sl) = fun enab pl ll -> @@ -37,188 +37,177 @@ let (get_sl_out: bool -> 'v Process.t list -> bool list list -> RdbgPlugin.sl) = pl ll ) -let (compute_potentiel: ('v Process.t * 'v Register.neighbor list) list -> - 'v Env.t -> RdbgPlugin.sl) = - fun p_nl_l ne -> +module StringMap = Map.Make(String) +let (compute_potentiel: 'v SimuState.t -> RdbgPlugin.sl) = + fun st -> match Register.get_potential () with | None -> [] | Some user_pf -> - let pidl = List.map (fun (p,_) -> p.Process.pid) p_nl_l in - let get_info pid = - let nl = snd (List.find (fun (p,_) -> p.Process.pid = pid) p_nl_l) in - Env.get ne pid, - List.map (fun n -> n, n.Register.pid) nl - in - let p = (user_pf pidl get_info) in + let pidl = List.map (fun p -> p.Process.pid) st.network in + let p = user_pf pidl (SimuState.neigbors_of_pid st) in [("potential", Data.F p)] -let (compute_legitimate: bool -> ('v Process.t * 'v Register.neighbor list) list -> - 'v Env.t -> bool) = - fun silent p_nl_l ne -> +let (compute_legitimate: bool -> 'v SimuState.t -> bool) = + fun silent st -> silent || match Register.get_legitimate () with | None -> silent | Some f -> - let pidl = List.map (fun (p,_) -> p.Process.pid) p_nl_l in - let get_info pid = - let nl = snd (List.find (fun (p,_) -> p.Process.pid = pid) p_nl_l) in - Env.get ne pid, - List.map (fun n -> n, n.Register.pid) nl - in - f pidl get_info + let pidl = List.map (fun p -> p.Process.pid) st.network in + f pidl (SimuState.neigbors_of_pid st) -(* The nl local state needs to be updated w.r.t. e *) -let update_p_nl_l e p_nl_l = List.map - (fun (p,nl) -> p, List.map (Sasacore.Main.update_neighbor_env e) nl) - p_nl_l - -let (make_do: string array -> SasArg.t -> - ('v Process.t * 'v Register.neighbor list) list -> 'v Env.t -> RdbgPlugin.t) = - fun argv args p_nl_l e -> - let pl = fst (List.split p_nl_l) in - let prog_id = Printf.sprintf "%s (with sasa Version %s)" - (String.concat " " (Array.to_list argv)) SasaVersion.str - in - let vntl_i = - List.map (fun (vn,vt) -> vn, Data.type_of_string vt) - (Sasacore.Main.get_inputs_rif_decl args pl) - in - let vntl_o = - List.map (fun (vn,vt) -> vn, Data.type_of_string vt) - (Sasacore.Main.get_outputs_rif_decl args pl) - in - let vntl_o = - if Register.get_potential () = None then vntl_o else - ("potential", Data.Real)::vntl_o in - let vntl_o = ("silent", Data.Bool)::("legitimate", Data.Bool)::vntl_o in - let pre_enable_processes_opt = ref None in - let sasa_env = ref e in - let reset () = - pre_enable_processes_opt := None; - sasa_env := e - in - (* Do the same job as SasaMain.simustep *) - let (step: RdbgPlugin.sl -> RdbgPlugin.sl) = - fun sl_in -> - let e = !sasa_env in - let p_nl_l = update_p_nl_l e p_nl_l in - match !pre_enable_processes_opt with - | None -> ( (* the first step *) - (* 1: Get enable processes *) - let pnall, enab_ll = Sasacore.Main.get_enable_processes p_nl_l e in - let sasa_nenv = from_sasa_env p_nl_l e in - let pot_sl = compute_potentiel p_nl_l e in - let silent = List.for_all (fun b -> not b) (List.flatten enab_ll) in - let legit = compute_legitimate silent p_nl_l e in - pre_enable_processes_opt := Some(pnall, enab_ll); - ("silent", Data.B silent)::("legitimate", Data.B legit)::pot_sl - @ sasa_nenv @ (get_sl_out true pl enab_ll) - ) - | Some (pre_pnall, pre_enab_ll) -> - (* 2: read the actions from the outside process, i.e., from sl_in *) - let _, pnal = Daemon.f args.dummy_input - (args.verbose > 0) args.daemon p_nl_l e pre_pnall pre_enab_ll - (get_action_value sl_in) - in - (* 3: Do the steps *) - let ne = Sasacore.Step.f pnal e in - let new_p_nl_l = update_p_nl_l ne p_nl_l in - let sasa_nenv = from_sasa_env p_nl_l ne in - (* 1': Get enable processes *) - let pnall, enab_ll = Sasacore.Main.get_enable_processes p_nl_l ne in - let pot_sl = compute_potentiel new_p_nl_l ne in +open SimuState +let (make_do: string array -> 'v SimuState.t -> RdbgPlugin.t) = + fun argv st -> + let pl = st.network in + let prog_id = Printf.sprintf "%s (with sasa Version %s)" + (String.concat " " (Array.to_list argv)) SasaVersion.str + in + let vntl_i = + List.map (fun (vn,vt) -> vn, Data.type_of_string vt) + (Sasacore.SimuState.get_inputs_rif_decl st.sasarg pl) + in + let vntl_o = + List.map (fun (vn,vt) -> vn, Data.type_of_string vt) + (Sasacore.SimuState.get_outputs_rif_decl st.sasarg pl) + in + let vntl_o = + if Register.get_potential () = None then vntl_o else + ("potential", Data.Real)::vntl_o in + let vntl_o = ("silent", Data.Bool)::("legitimate", Data.Bool)::vntl_o in + let pre_enable_processes_opt = ref None in + let sasa_config = ref st.config in + let reset () = + pre_enable_processes_opt := None; + sasa_config := st.config + in + (* Do the same job as SasaSimuState.simustep *) + let (step_custom: RdbgPlugin.sl -> RdbgPlugin.sl) = + fun sl_in -> + let st = Sasacore.SimuState.update_config !sasa_config st in + match !pre_enable_processes_opt with + | None -> ( (* the first step *) + (* 1: Get enable processes *) + let pnall, enab_ll = Sasacore.SimuState.get_enable_processes st in + let sasa_nenv = from_sasa_env st in + let pot_sl = compute_potentiel st in let silent = List.for_all (fun b -> not b) (List.flatten enab_ll) in - let legit = compute_legitimate silent p_nl_l e in + let legit = compute_legitimate silent st in pre_enable_processes_opt := Some(pnall, enab_ll); - sasa_env := ne; - ("silent", Data.B silent)::("legitimate", Data.B legit)::pot_sl @ - sasa_nenv @ (get_sl_out true pl enab_ll) - in - let (step_internal_daemon: RdbgPlugin.sl -> RdbgPlugin.sl) = - fun sl_in -> - (* in this mode, sasa does not play first *) - let e = !sasa_env in - let p_nl_l = update_p_nl_l e p_nl_l in - (* 1: Get enable processes *) - let pnall, enab_ll = Sasacore.Main.get_enable_processes p_nl_l e in - let pot_sl = compute_potentiel p_nl_l e in - let silent = List.for_all (fun b -> not b) (List.flatten enab_ll) in - let legit = compute_legitimate silent p_nl_l e in - if silent then ( - ("silent", Data.B silent)::("legitimate", Data.B legit)::pot_sl@ - (from_sasa_env p_nl_l e) @ (get_sl_out true pl enab_ll) + ("silent", Data.B silent)::("legitimate", Data.B legit)::pot_sl + @ sasa_nenv @ (get_sl_out true pl enab_ll) ) - else - (* 2: read the actions from the outside process, i.e., from sl_in *) - let activate_val, pnal = Daemon.f args.dummy_input - (args.verbose > 0) args.daemon p_nl_l e pnall enab_ll - (get_action_value sl_in) - in - (* 3: Do the steps *) - let ne = Sasacore.Step.f pnal e in - sasa_env := ne; - ("silent", Data.B silent)::("legitimate", Data.B legit)::pot_sl @ - (from_sasa_env p_nl_l e) @ (get_sl_out true pl enab_ll) @ - (get_sl_out false pl activate_val) - in - let step = if args.daemon = Daemon.Custom then step else step_internal_daemon in - let ss_table = Hashtbl.create 10 in - let step_dbg sl_in ctx cont = - let sl_out = step sl_in in - { ctx with - (* RdbgEvent.nb = 0; *) - (* RdbgEvent.step = 0; (* we are actually in the middle of the first step! *) *) - RdbgEvent.depth = ctx.RdbgEvent.depth + 1; - RdbgEvent.kind = RdbgEvent.Exit; - RdbgEvent.lang = "sasa"; - RdbgEvent.sinfo = None; - RdbgEvent.name = "sasa"; - RdbgEvent.inputs = vntl_i; - RdbgEvent.outputs = vntl_o; - RdbgEvent.locals = []; - RdbgEvent.data = sl_in@sl_out; - RdbgEvent.next = ( - fun () -> - let ctx = { ctx with RdbgEvent.nb = 1 + ctx.RdbgEvent.nb } in - cont sl_out ctx ); - } - in - let (mems_in : Data.subst list) = [] in - let (mems_out : Data.subst list) = [] in - { - id = prog_id; - inputs = vntl_i; - outputs= vntl_o; - reset=(fun () -> reset()); - kill=(fun _ -> flush stdout; flush stderr); - init_inputs=mems_in; - init_outputs=mems_out; - step=step; - step_dbg = step_dbg; - save_state = (fun i -> - let prgs = Random.get_state () in - (* Printf.eprintf "Save state %i from sasa\n%!" i; *) - Hashtbl.replace ss_table i - (prgs, !sasa_env, !pre_enable_processes_opt) - ); - restore_state = (fun i -> - match Hashtbl.find_opt ss_table i with - | Some (prgs, e, pepo) -> - Random.set_state prgs; - (* Printf.eprintf "Restore state %i from sasa\n%!" i; *) - sasa_env := e; pre_enable_processes_opt := pepo - | None -> - Printf.eprintf "Cannot restore state %i from sasa\n" i; - flush stderr - ); + | Some (pre_pnall, pre_enab_ll) -> + (* let was_silent = List.for_all (fun b -> not b) (List.flatten pre_enab_ll) in *) + (* if was_silent then failwith "Silent"; *) + (* 2: read the actions from the outside process, i.e., from sl_in *) + let _, pnal = Daemon.f st.sasarg.dummy_input + (st.sasarg.verbose > 0) st.sasarg.daemon st.network + (SimuState.neigbors_of_pid st) st.config pre_pnall pre_enab_ll + (get_action_value sl_in) + in + (* 3: Do the steps *) + let ne = Sasacore.Step.f pnal st.config in + let nst = update_config ne st in + let sasa_nenv = from_sasa_env nst in + (* 1': Get enable processes *) + let pnall, enab_ll = Sasacore.SimuState.get_enable_processes nst in + let pot_sl = compute_potentiel nst in + let silent = List.for_all (fun b -> not b) (List.flatten enab_ll) in + let legit = compute_legitimate silent nst in + pre_enable_processes_opt := Some(pnall, enab_ll); + sasa_config := ne; + ("silent", Data.B silent)::("legitimate", Data.B legit)::pot_sl @ + sasa_nenv @ (get_sl_out true pl enab_ll) + in + let (step_internal_daemon: RdbgPlugin.sl -> RdbgPlugin.sl) = + fun sl_in -> + (* in this mode, sasa does not play first *) + let st = update_config !sasa_config st in + (* 1: Get enable processes *) + let pnall, enab_ll = Sasacore.SimuState.get_enable_processes st in + let pot_sl = compute_potentiel st in + let silent = List.for_all (fun b -> not b) (List.flatten enab_ll) in + let legit = compute_legitimate silent st in + if silent then ( + let enab = get_sl_out true pl enab_ll in + let trigger = (* set all trig var to false *) + List.map (fun (n,v) -> String.sub n 5 ((String.length n) -5),v) enab + in + ("silent", Data.B silent)::("legitimate", Data.B legit)::pot_sl@ + (from_sasa_env st) @ enab @ trigger + ) + else + (* 2: read the actions from the outside process, i.e., from sl_in *) + let activate_val, pnal = Daemon.f st.sasarg.dummy_input + (st.sasarg.verbose > 0) st.sasarg.daemon st.network (SimuState.neigbors_of_pid st) + st.config pnall enab_ll + (get_action_value sl_in) + in + (* 3: Do the steps *) + let ne = Sasacore.Step.f pnal st.config in + sasa_config := ne; + ("silent", Data.B silent)::("legitimate", Data.B legit)::pot_sl @ + (from_sasa_env st) @ (get_sl_out true pl enab_ll) @ + (get_sl_out false pl activate_val) + in + let step = if st.sasarg.daemon = Daemon.Custom then step_custom else step_internal_daemon in + let ss_table = Hashtbl.create 10 in + let step_dbg sl_in ctx cont = + let sl_out = step sl_in in + { ctx with + (* RdbgEvent.nb = 0; *) + (* RdbgEvent.step = 0; (* we are actually in the middle of the first step! *) *) + RdbgEvent.depth = ctx.RdbgEvent.depth + 1; + RdbgEvent.kind = RdbgEvent.Exit; + RdbgEvent.lang = "sasa"; + RdbgEvent.sinfo = None; + RdbgEvent.name = "sasa"; + RdbgEvent.inputs = vntl_i; + RdbgEvent.outputs = vntl_o; + RdbgEvent.locals = []; + RdbgEvent.data = sl_in@sl_out; + RdbgEvent.next = ( + fun () -> + let ctx = { ctx with RdbgEvent.nb = 1 + ctx.RdbgEvent.nb } in + cont sl_out ctx ); } + in + let (mems_in : Data.subst list) = [] in + let (mems_out : Data.subst list) = [] in + { + id = prog_id; + inputs = vntl_i; + outputs= vntl_o; + reset=(fun () -> reset()); + kill=(fun _ -> flush stdout; flush stderr); + init_inputs=mems_in; + init_outputs=mems_out; + step=step; + step_dbg = step_dbg; + save_state = (fun i -> + let prgs = Random.get_state () in + (* Printf.eprintf "Save state %i from sasa\n%!" i; *) + Hashtbl.replace ss_table i + (prgs, !sasa_config, !pre_enable_processes_opt) + ); + restore_state = (fun i -> + match Hashtbl.find_opt ss_table i with + | Some (prgs, e, pepo) -> + Random.set_state prgs; + (* Printf.eprintf "Restore state %i from sasa\n%!" i; *) + sasa_config := e; pre_enable_processes_opt := pepo + | None -> + Printf.eprintf "Cannot restore state %i from sasa\n" i; + flush stderr + ); + } let (make: string array -> RdbgPlugin.t) = fun argv -> try - let args, p_nl_l, e = Sasacore.Main.make false argv in - make_do argv args p_nl_l e + make_do argv (Sasacore.SimuState.make false argv) with | Dynlink.Error e -> Printf.printf "Error (SasaRun.make): %s\n" (Dynlink.error_message e); diff --git a/lib/sasacore/daemon.ml b/lib/sasacore/daemon.ml index 9756932dab6e154e110f6af61defeb4b9af7fb35..e4f2a3ec8d79aa7cc684d0e74f0cbd6407ea4d9d 100644 --- a/lib/sasacore/daemon.ml +++ b/lib/sasacore/daemon.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 08/12/2020 (at 16:09) by Erwan Jahier> *) +(* Time-stamp: <modified the 03/05/2021 (at 16:16) by Erwan Jahier> *) type t = | Synchronous (* select all actions *) @@ -120,35 +120,35 @@ let (get_activate_val: 'v pna list -> 'v Process.t list -> bool list list)= let al = List.map (fun (p,_,a) -> p,a) al in List.map (List.map (fun a -> List.mem a al)) actions -let (f: bool -> bool -> t -> ('v Process.t * 'v Register.neighbor list) list -> - 'v Env.t -> 'v pna list list -> bool list list -> - (string -> string -> bool) -> bool list list * 'v pna list) = - fun dummy_input verbose_mode daemon p_nl_l e all enab get_action_value -> +let (f: bool -> bool -> t -> 'v Process.t list -> + (string -> 'v * ('v Register.neighbor * string) list) -> 'v Env.t -> + 'v pna list list -> bool list list -> (string -> string -> bool) -> + bool list list * 'v pna list) = + fun dummy_input verbose_mode daemon pl neigbors_of_pid e all enab get_action_value -> let nall = remove_empty_list all in if nall = [] then assert false (* failwith "Silent" *); - let pl = fst(List.split p_nl_l) in - if daemon <> Custom && dummy_input then - ignore (RifRead.bool verbose_mode ((List.hd pl).pid) ""); - match daemon with - | Synchronous -> - let al = synchrone nall in - get_activate_val al pl, al - | Central -> - let al = central nall in - get_activate_val al pl, al - | LocallyCentral -> - let al = locally_central nall in - get_activate_val al pl, al - | Distributed -> - let al = distributed nall in - get_activate_val al pl, al - | Greedy -> - let al = Evil.greedy verbose_mode e p_nl_l nall in - get_activate_val al pl, al - | GreedyCentral -> - let al = Evil.greedy_central verbose_mode e p_nl_l nall in - get_activate_val al pl, al - | Bad i -> - let al = Evil.bad i e nall in - get_activate_val al pl, al - | Custom -> custom all pl enab get_action_value + if daemon <> Custom && dummy_input then + ignore (RifRead.bool verbose_mode ((List.hd pl).pid) ""); + match daemon with + | Synchronous -> + let al = synchrone nall in + get_activate_val al pl, al + | Central -> + let al = central nall in + get_activate_val al pl, al + | LocallyCentral -> + let al = locally_central nall in + get_activate_val al pl, al + | Distributed -> + let al = distributed nall in + get_activate_val al pl, al + | Greedy -> + let al = Evil.greedy verbose_mode e pl neigbors_of_pid nall in + get_activate_val al pl, al + | GreedyCentral -> + let al = Evil.greedy_central verbose_mode e pl neigbors_of_pid nall in + get_activate_val al pl, al + | Bad i -> + let al = Evil.bad i e nall in + get_activate_val al pl, al + | Custom -> custom all pl enab get_action_value diff --git a/lib/sasacore/daemon.mli b/lib/sasacore/daemon.mli index 182fca664d33c0db7c15186728d7af3cf3136831..1c5d94fbb5b2028049fe576154f6418c87709c24 100644 --- a/lib/sasacore/daemon.mli +++ b/lib/sasacore/daemon.mli @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 30/09/2020 (at 13:53) by Erwan Jahier> *) +(* Time-stamp: <modified the 03/05/2021 (at 16:16) by Erwan Jahier> *) type t = | Synchronous (* select all actions *) @@ -44,7 +44,8 @@ nb: it is possible that we read on stdin that an action should be inhibit the activation. *) -val f : bool -> bool -> t -> ('v Process.t * 'v Register.neighbor list) list -> - 'v Env.t -> 'v pna list list -> bool list list -> - (string -> string -> bool) -> bool list list * 'v pna list +val f : bool -> bool -> t -> 'v Process.t list -> + (string -> 'v * ('v Register.neighbor * string) list) -> + 'v Env.t -> 'v pna list list -> bool list list -> + (string -> string -> bool) -> bool list list * 'v pna list diff --git a/lib/sasacore/diameter.ml b/lib/sasacore/diameter.ml index 8bada291889891d25666068c9204a54294ee6e50..5026a3da27befca9e32f779965c599402ec27bbe 100644 --- a/lib/sasacore/diameter.ml +++ b/lib/sasacore/diameter.ml @@ -58,5 +58,6 @@ let (max_mat: int array array -> int) = (* takes a graph t in argument and returns the diameter *) let (get: Topology.t -> int ) = fun t -> - (max_mat(floydwarshall (graph_to_adjency t))) - \ No newline at end of file + let d = (max_mat(floydwarshall (graph_to_adjency t))) in + Printf.eprintf " ====> The Graph Diameter is %d \n%!" d; + d diff --git a/lib/sasacore/env.mli b/lib/sasacore/env.mli index c22d152dfd974b0be63355edb270f245e23dfd73..2b3505d3c16af7ed8cbe74d0f1c07d97d3320d95 100644 --- a/lib/sasacore/env.mli +++ b/lib/sasacore/env.mli @@ -1,4 +1,10 @@ -(* Storing process variables values *) +(* Time-stamp: <modified the 15/04/2021 (at 11:46) by Erwan Jahier> *) + +(** Storing process variables values. + +nb: in order to be closer to the SS community wordings, this module + could (should?) be named Configuration (or maybe just Conf). +*) type 'v t val init: unit -> 'v t diff --git a/lib/sasacore/evil.ml b/lib/sasacore/evil.ml index 732e349c1fbbc41fa11643b2780520a4ad4527cb..e8ed51c1a0501657ce0f5e30214827f959fa0db6 100644 --- a/lib/sasacore/evil.ml +++ b/lib/sasacore/evil.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 07/12/2020 (at 10:20) by Erwan Jahier> *) +(* Time-stamp: <modified the 03/05/2021 (at 16:17) by Erwan Jahier> *) type 'v pna = 'v Process.t * 'v Register.neighbor list * Register.action @@ -118,20 +118,20 @@ let time3 verb lbl f x y z = if verb then Printf.eprintf " [%s] Execution time: %fs\n" lbl (Sys.time() -. t); fxy -let (greedy: bool -> 'v Env.t -> ('v Process.t * 'v Register.neighbor list) list -> - 'v pna list list -> 'v pna list) = - fun verb e p_nl_l all -> +let (greedy: bool -> 'v Env.t -> 'v Process.t list -> + (string -> 'v * ('v Register.neighbor * string) list) -> 'v pna list list -> + 'v pna list) = + fun verb e pl neigbors_of_pid all -> assert (all<>[]); match Register.get_potential () with | None -> failwith "No potential function has been provided" | Some user_pf -> let pf pnal = (* pnal contains a list of activated processes *) - let pidl = List.map (fun (p,_) -> p.Process.pid) p_nl_l in + let pidl = List.map (fun p -> p.Process.pid) pl in let ne = Step.f pnal e in let get_info pid = - let nl = snd (List.find (fun (p,_) -> p.Process.pid = pid) p_nl_l) in - Env.get ne pid, - List.map (fun n -> n, n.Register.pid) nl + let _, nl = neigbors_of_pid pid in + Env.get ne pid, nl in user_pf pidl get_info in @@ -160,20 +160,20 @@ let (greedy: bool -> 'v Env.t -> ('v Process.t * 'v Register.neighbor list) list if verb then Printf.eprintf " [Evil.greedy] Number of trials: %i\n%!" !cpt; res -let (greedy_central: bool -> 'v Env.t -> ('v Process.t * 'v Register.neighbor list) list - -> 'v pna list list -> 'v pna list) = - fun verb e p_nl_l all -> +(* val greedy_central: bool -> 'v Env.t -> ('v Process.t * 'v Register.neighbor list) list -> *) +let (greedy_central: bool -> 'v Env.t -> 'v Process.t list -> + (string -> 'v * ('v Register.neighbor * string) list) -> 'v pna list list -> 'v pna list) = + fun verb e pl neigbors_of_pid all -> assert (all<>[]); match Register.get_potential () with | None -> failwith "No potential function has been provided" | Some user_pf -> let pf pna = - let pidl = List.map (fun (p,_) -> p.Process.pid) p_nl_l in + let pidl = List.map (fun p -> p.Process.pid) pl in let ne = Step.f [pna] e in let get_info pid = - let nl = snd (List.find (fun (p,_) -> p.Process.pid = pid) p_nl_l) in - Env.get ne pid, - List.map (fun n -> n, n.Register.pid) nl + let _, nl = neigbors_of_pid pid in + Env.get ne pid, nl in user_pf pidl get_info in diff --git a/lib/sasacore/evil.mli b/lib/sasacore/evil.mli index 10d6aa37b15e1e735df34b158bfa1125a8f93bdf..6cee4338fab758b80d1e42e35ab9f78692cfcf2e 100644 --- a/lib/sasacore/evil.mli +++ b/lib/sasacore/evil.mli @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 07/12/2020 (at 10:16) by Erwan Jahier> *) +(* Time-stamp: <modified the 03/05/2021 (at 16:17) by Erwan Jahier> *) (** This module gathers daemons that tries to reach the worst case with @@ -6,15 +6,17 @@ type 'v pna = 'v Process.t * 'v Register.neighbor list * Register.action -(** [greedy verb e p_nl_l all] take the worst case among the combinations of +(** [greedy verb e pl neigbors_of_pid all] take the worst case among the combinations of length 1, i.e., O(2^n) where n is the number of enabled processes (|all|) *) -val greedy: bool -> 'v Env.t -> ('v Process.t * 'v Register.neighbor list) list -> +val greedy: bool -> 'v Env.t -> 'v Process.t list -> + (string -> 'v * ('v Register.neighbor * string) list) -> 'v pna list list -> 'v pna list (** Ditto, but for central daemons (of a connected component) *) -val greedy_central: bool -> 'v Env.t -> ('v Process.t * 'v Register.neighbor list) list -> - 'v pna list list -> 'v pna list +val greedy_central: bool -> 'v Env.t -> 'v Process.t list -> + (string -> 'v * ('v Register.neighbor * string) list) -> 'v pna list list -> + 'v pna list (** Returns the worst case among the combinations of length 1 for convex potential functions, and just a bad one otherwise (O(n) diff --git a/lib/sasacore/main.mli b/lib/sasacore/main.mli deleted file mode 100644 index 96332eff677bf259666c654aa4a05287e00a701c..0000000000000000000000000000000000000000 --- a/lib/sasacore/main.mli +++ /dev/null @@ -1,21 +0,0 @@ -(* Time-stamp: <modified the 25/08/2020 (at 17:06) by Erwan Jahier> *) - - -(* XXX find a better name *) -type 'v layout = ('v Process.t * 'v Register.neighbor list) list -type 'v t = SasArg.t * 'v layout * 'v Env.t - -(* [make dynlink_flag argv] *) -val make : bool -> string array -> 'v t - -type 'v enable_processes = - ('v Process.t * 'v Register.neighbor list * Register.action) list list * bool list list - -val get_enable_processes: 'v layout -> 'v Env.t -> 'v enable_processes - - -val get_inputs_rif_decl : SasArg.t -> 'v Process.t list -> (string * string) list -val get_outputs_rif_decl: SasArg.t -> 'v Process.t list -> (string * string) list - - -val update_neighbor_env: 'v Env.t -> 'v Register.neighbor -> 'v Register.neighbor diff --git a/lib/sasacore/process.mli b/lib/sasacore/process.mli index 0fbc4d3ad61ba2981d146dbe3e7635fcba29db1f..e6d85f3ba139d6f5daf6b87650d9d4c2563fb7f4 100644 --- a/lib/sasacore/process.mli +++ b/lib/sasacore/process.mli @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 06/09/2019 (at 15:51) by Erwan Jahier> *) +(* Time-stamp: <modified the 15/04/2021 (at 11:55) by Erwan Jahier> *) (** There is such a Process.t per node in the dot file. *) type 'v t = { @@ -9,11 +9,13 @@ type 'v t = { step : 'v Register.step_fun; } -(** [make custom_mode_flag node init_state] builds a process out of a dot - node. To do that, it retreives the registered functions by Dynamic - linking of the cmxs file specified in the "algo" field of the dot +(** [make custom_mode_flag node init_state] builds a process out of a + node. To do that, it retrieves the registered functions by Dynamic + linking of the cmxs file specified in the "algo" field of the dot node. - nb: it provides variable initial values if not done in the dot - (via the init field) nor in the Algo (via Algo.reg_init_vars) *) + The custom_mode_flag is set in the sasa command line. + + nb: the provided initial values comes from the dot file if the + init field; otherwise it comes from in the Algo.init_state function *) val make: bool -> Topology.node -> 'v -> 'v t diff --git a/lib/sasacore/register.ml b/lib/sasacore/register.ml index 2c646c476484fee0808e3b41fcc1dce14e84313a..af989bd69090ce9c8e5d61782fed2e87a8ee2445 100644 --- a/lib/sasacore/register.ml +++ b/lib/sasacore/register.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 13/10/2020 (at 15:37) by Erwan Jahier> *) +(* Time-stamp: <modified the 21/04/2021 (at 15:58) by Erwan Jahier> *) type 's neighbor = { state: 's ; @@ -30,29 +30,24 @@ type 's internal_tables = { mutable legitimate: Obj.t; mutable fault: Obj.t; mutable actions:action list; - mutable card : int ; - mutable min_deg : int; - mutable mean_deg : float; - mutable max_deg : int; + mutable topology : Topology.t option; + mutable card : int option; + mutable min_deg : int option; + mutable mean_deg : float option; + mutable max_deg : int option; mutable is_cyclic : bool option; mutable is_connected : bool option; mutable is_tree : bool option; + mutable is_in_tree : bool option; + mutable is_out_tree : bool option; mutable is_directed : bool option; - mutable height : (string -> int); - mutable links_number : int; - mutable diameter : int; + mutable height : (string -> int) option; + mutable sub_tree_size: (string -> int) option; + mutable parent : (string -> int option) option; + mutable links_number : int option; + mutable diameter : int option; } -type properties_functions = { - mutable card : unit -> int; - mutable min_max : unit -> int*int; - mutable mean_deg : unit -> float; - mutable is_connected_cyclic : unit -> bool*bool; - mutable is_directed : unit -> bool; - mutable links_number : unit -> int; - mutable diameter : unit -> int -} - type node_id = string (* cf topology.mli *) let (tbls:'s internal_tables) = { @@ -67,27 +62,22 @@ let (tbls:'s internal_tables) = { legitimate = (Obj.repr None); fault = (Obj.repr None); actions = []; - card = (-1); - min_deg = (-1); - mean_deg = (-1.); - max_deg = (-1); + topology = None; + card = None; + min_deg = None; + mean_deg = None; + max_deg = None; is_cyclic = None; is_connected = None; is_tree = None; + is_in_tree = None; + is_out_tree = None; is_directed = None; - height = (fun _ -> -1); - links_number = (-1); - diameter = (-1) -} - -let (prop_funs:properties_functions) = { - card = (fun () -> -1); - min_max = (fun () -> (-1,-1)); - mean_deg = (fun () -> -1.); - is_connected_cyclic = (fun () -> (false,false)); - is_directed = (fun () -> false); - links_number = (fun () -> -1); - diameter = (fun () -> -1) + height = None; + parent = None; + sub_tree_size =None; + links_number = None; + diameter = None } let verbose_level = ref 0 @@ -96,14 +86,13 @@ exception Unregistred of string * string let print_table lbl tbl = let keys = Hashtbl.fold (fun k _ acc -> Printf.sprintf "%s,%s" k acc) tbl "" in if !verbose_level > 0 then Printf.eprintf "Defined keys for %s: %s\n%!" lbl keys - let (reg_init_state : algo_id -> (int -> string -> 's) -> unit) = fun algo_id x -> - if !verbose_level > 0 then Printf.eprintf "Registering %s init_vars\n%!" algo_id; - Hashtbl.replace tbls.init_state algo_id (Obj.repr x) + if !verbose_level > 0 then + Printf.eprintf "Registering %s init_vars\n%!" algo_id; + Hashtbl.replace tbls.init_state algo_id (Obj.repr x) - let (get_init_state : algo_id -> int -> string -> 's) = fun algo_id -> try Obj.obj (Hashtbl.find tbls.init_state algo_id) @@ -111,7 +100,6 @@ let (get_init_state : algo_id -> int -> string -> 's) = print_table "init_state" tbls.init_state; raise (Unregistred ("init_state", algo_id)) - let (reg_enable : algo_id -> 's enable_fun -> unit) = fun algo_id x -> if !verbose_level > 0 then Printf.eprintf "Registering %s enable\n%!" algo_id; Hashtbl.replace tbls.enable algo_id (Obj.repr x) @@ -177,7 +165,6 @@ let (get_value_of_string : unit -> (string -> 's) option) = fun () -> try Some (Obj.obj (Hashtbl.find tbls.value_of_string "_global")) with Not_found -> None - let (reg_copy_value : ('s -> 's) -> unit) = fun f -> if !verbose_level > 0 then Printf.eprintf "Registering copy_value\n%!"; @@ -190,132 +177,144 @@ let (get_copy_value : unit -> ('s -> 's)) = fun () -> raise (Unregistred ("copy_value", "_global")) -let set_min_max : (unit -> unit) = - fun () -> - let (x,y) = prop_funs.min_max () in - tbls.min_deg <- x; - tbls.max_deg <- y - -let set_connec_cycl : (unit -> unit) = - fun () -> - let (x,y) = prop_funs.is_connected_cyclic () in - tbls.is_connected <- Some x; - tbls.is_cyclic <- Some y - +let set_topology g = tbls.topology <- Some g +let get_topology () = match tbls.topology with + | None -> assert false (* SNO if set_topology is called in Main *) + | Some g -> g + let (card : unit -> int) = fun () -> match tbls.card with - | -1 -> - let c = prop_funs.card () in - tbls.card <- c; - c - | c -> c + | None -> + let x = List.length (get_topology()).nodes in + tbls.card <- Some x; + x + | Some b -> b let (is_directed : unit -> bool) = fun () -> match tbls.is_directed with | None -> - let c = prop_funs.is_directed () in - tbls.is_directed <- Some c; - c - | Some c -> c - -let (min_degree : unit -> int) = - fun () -> match tbls.min_deg with - | -1 -> (set_min_max (); tbls.min_deg) - | m -> m - + let x = (get_topology()).directed in + tbls.is_directed <- Some x; + x + | Some b -> b + let (mean_degree : unit -> float) = fun () -> match tbls.mean_deg with - | -1. -> - let m = prop_funs.mean_deg () in - tbls.mean_deg <- m; - m - | m -> m + | None -> + let x = Topology.get_mean_degree (get_topology()) in + tbls.mean_deg <- Some x; + x + | Some b -> b -let (max_degree : unit -> int) = - fun () -> match tbls.max_deg with - | -1 -> (set_min_max (); tbls.max_deg) - | m -> m +let (min_degree : unit -> int) = fun () -> + match tbls.min_deg with + | None -> + let mind,maxd = Topology.get_degree (get_topology()) in + tbls.max_deg <- Some maxd; + tbls.min_deg <- Some mind; + mind + | Some b -> b + +let (max_degree : unit -> int) = fun () -> + match tbls.max_deg with + | None -> + let mind,maxd = Topology.get_degree (get_topology()) in + tbls.max_deg <- Some maxd; + tbls.min_deg <- Some mind; + maxd + | Some b -> b let (is_cyclic : unit -> bool) = fun () -> match tbls.is_cyclic with | None -> - set_connec_cycl (); - (match tbls.is_cyclic with - | Some b -> b - | _ -> assert false) + let cyclic = Topology.is_cyclic (get_topology()) in + tbls.is_cyclic <- Some cyclic; + cyclic | Some b -> b let (is_connected : unit -> bool) = fun () -> match tbls.is_connected with - | None -> ( - set_connec_cycl (); - match tbls.is_connected with - | Some b -> b - | _ -> assert false) + | None -> + let connect = Topology.is_connected (get_topology()) in + tbls.is_connected <- Some connect; + connect | Some b -> b - + let (is_tree : unit -> bool) = fun () -> match tbls.is_tree with | None -> - let b = (not (is_cyclic ()) && (is_connected ())) in + let b = Topology.is_tree (get_topology()) in tbls.is_tree <- Some b; b | Some b -> b -(* Caution : this option is not the same as the option in the type tbls.height. - * If height () = None, then the graph doesn't have a height (because it isn't a tree)*) -let height : (unit -> (string -> int) option) = - fun () -> - if is_tree () then - Some tbls.height - else None +let (is_in_tree : unit -> bool) = fun () -> + match tbls.is_in_tree with + | None -> + let b = Topology.is_in_tree (get_topology()) in + tbls.is_in_tree <- Some b; + b + | Some b -> b + +let (is_out_tree : unit -> bool) = fun () -> + match tbls.is_out_tree with + | None -> + let b = Topology.is_out_tree (get_topology()) in + tbls.is_out_tree <- Some b; + b + | Some b -> b + +let not_a_tree () = failwith "The graph is not a tree" + +let height : (string -> int) = + fun pid -> + if is_tree () then ( + match tbls.height with + | Some h -> h pid + | None -> + let h = Topology.get_height (get_topology ()) in + tbls.height <- Some h; h pid + ) + else not_a_tree () + +let sub_tree_size : (string -> int) = + fun pid -> + if is_tree () then ( + match tbls.sub_tree_size with + | Some s -> s pid + | None -> + let s = Topology.get_sub_tree_size (get_topology ()) in + tbls.sub_tree_size <- Some s; s pid + ) + else not_a_tree () + +let parent : (string -> int option) = + fun pid -> + match tbls.parent with + | Some p -> p pid + | None -> + let p = Topology.get_parent (get_topology ()) in + tbls.parent <- Some p; p pid let (links_number : unit -> int) = fun () -> - match tbls.links_number with - | -1 -> - let n = prop_funs.links_number () in - tbls.links_number <- n; - n - | n -> n + match tbls.links_number with + | Some x -> x + | None -> + let x = Topology.get_nb_link (get_topology ()) in + tbls.links_number <- Some x; + x let (diameter : unit -> int) = fun () -> match tbls.diameter with - | -1 -> - let d = (prop_funs.diameter ()) in - tbls.diameter <- d; - d - | d -> d - - - -let set_card : ((unit -> int) -> unit) = - fun f -> prop_funs.card <- f - -let set_is_directed : ((unit -> bool) -> unit) = - fun f -> prop_funs.is_directed <- f - -let set_degrees : ((unit -> int*int) -> unit) = - fun f -> prop_funs.min_max <- f - -let set_mean_deg : ((unit -> float) -> unit) = - fun f -> prop_funs.mean_deg <- f - -let set_is_connected_cyclic : ((unit -> bool*bool) -> unit) = - fun f -> prop_funs.is_connected_cyclic <- f - -let set_height : ((node_id -> int) -> unit) = - fun f -> tbls.height <- f - -let set_links_number : ((unit -> int) -> unit) = - fun f -> prop_funs.links_number <- f - -let set_diameter : ((unit -> int) -> unit) = - fun f -> prop_funs.diameter <- f - - + | Some x -> x + | None -> + let x = Diameter.get (get_topology ()) in + tbls.diameter <- Some x; + x + let (to_string : 's -> string) = fun v -> (get_value_to_string ()) v diff --git a/lib/sasacore/register.mli b/lib/sasacore/register.mli index e405b94d6cbb8e3020a9760482a03e6ca7446e7f..b33fed0e2bc7eeba40fd309e2d8080b897f4c6e7 100644 --- a/lib/sasacore/register.mli +++ b/lib/sasacore/register.mli @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 13/10/2020 (at 15:36) by Erwan Jahier> *) +(* Time-stamp: <modified the 08/04/2021 (at 21:55) by Erwan Jahier> *) (** This module duplicates and extends the Algo module with get_* functions. @@ -43,15 +43,16 @@ val mean_degree : unit -> float val max_degree : unit -> int val is_cyclic : unit -> bool val is_connected : unit -> bool -val is_tree : unit -> bool -val is_directed : unit -> bool - -(** If height () = None, then the graph doesn't have a height (because it isn't a tree) - Otherwise, height () = Some h.*) -val height : unit -> (string -> int) option val links_number : unit -> int val diameter : unit -> int +val is_tree : unit -> bool +val is_in_tree : unit -> bool +val is_out_tree : unit -> bool +val sub_tree_size : string -> int +val parent : string -> int option +val is_directed : unit -> bool +val height : string -> int val verbose_level: int ref val get_graph_attribute : string -> string @@ -74,15 +75,8 @@ val get_copy_value : unit -> ('s -> 's) val to_string : 's -> string (** Those are called by sasa once the graph has been parsed *) -val set_card : (unit -> int) -> unit -val set_degrees : (unit -> int*int) -> unit -val set_mean_deg : (unit -> float) -> unit -val set_is_connected_cyclic : (unit -> bool*bool) -> unit -val set_is_directed : (unit -> bool) -> unit +val set_topology : Topology.t -> unit type node_id = string (* cf topology.mli *) -val set_height : (node_id -> int) -> unit -val set_links_number : (unit -> int) -> unit -val set_diameter : (unit -> int) -> unit val set_graph_attribute : string -> string -> unit val graph_attribute_list: unit -> (string * string) list diff --git a/lib/sasacore/sasArg.ml b/lib/sasacore/sasArg.ml index 44260098c9b38bfd8baa4edd228d1d9ff53a7cd2..d2c451170747353ac5698b31e43213e2366518b9 100644 --- a/lib/sasacore/sasArg.ml +++ b/lib/sasacore/sasArg.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 02/12/2020 (at 11:14) by Erwan Jahier> *) +(* Time-stamp: <modified the 02/04/2021 (at 15:45) by Erwan Jahier> *) type t = { @@ -126,25 +126,26 @@ let reset_the_seed_to_last args = Printf.eprintf " [sasa] W: cannot recover the seed in %s\n" f; flush stderr; false - -let rec seed_get args = match args.seed with + +let rec seed_get args = + match args.seed with | Some i -> i | None -> - (* No seed is set: - - in -replay mode, we first try to read the seed in the seed file - - otherwise, we create a random seed and save if into args, and - into a file for -replay *) - if args.replay_seed && reset_the_seed_to_last args then (seed_get args) else - let seed = Random.self_init (); Random.int 1073741823 in - let seed_file = seed_file_name args in - let oc = open_out seed_file in - Printf.fprintf oc "%d\n%s\n" seed - (Mypervasives.entete "#" SasaVersion.str SasaVersion.sha); - flush oc; - close_out oc; - seed_set args (Some seed); - seed - + (* No seed is set: + - in -replay mode, we first try to read the seed in the seed file + - otherwise, we create a random seed and save if into args, and + into a file for -replay *) + if args.replay_seed && reset_the_seed_to_last args then (seed_get args) else ( + let seed = Random.self_init (); Random.int 1073741823 in + let seed_file = seed_file_name args in + let oc = open_out seed_file in + Printf.fprintf oc "%d\n%s\n" seed + (Mypervasives.entete "#" SasaVersion.str SasaVersion.sha); + flush oc; + close_out oc; + seed_set args (Some seed); + seed + ) (*******************************************************************************) (*** User Options Tab **) @@ -280,16 +281,16 @@ let unexpected s = ( let parse argv = ( let save_current = !current in try ( - let args = make_args () in + let args = make_args () in mkoptab argv args; - Arg.parse_argv ~current:current argv args._args (add_other args) (usage_msg argv.(0)); + Arg.parse_argv ~current:current argv args._args (add_other args) (usage_msg argv.(0)); (List.iter (fun f -> - if (String.sub f 0 1 = "-") then - unexpected f - else if not (Sys.file_exists f) then - file_notfound f - else () + if (String.sub f 0 1 = "-") then + unexpected f + else if not (Sys.file_exists f) then + file_notfound f + else () ) args._others); current := save_current; diff --git a/lib/sasacore/sasaState.ml b/lib/sasacore/sasaState.ml index bdb8ef1723a2f141484e3d75baed762033da1381..689ef9a9c091e65b318898600e1e903d1d69dead 100644 --- a/lib/sasacore/sasaState.ml +++ b/lib/sasacore/sasaState.ml @@ -1,16 +1,9 @@ - - - - -(* All the remaining fnctions are based on to_string *) - -(* Try to guess the type of values using get_value_to_string *) +(* Time-stamp: <modified the 15/04/2021 (at 11:28) by Erwan Jahier> *) type pid = string +(* Try to guess the type of values held in a string *) type data_or_name = Data of Data.v * Data.t | Name of string - - let (string_to_data : string -> data_or_name) = fun str -> match int_of_string_opt str with @@ -26,6 +19,7 @@ let (string_to_data : string -> data_or_name) = ) ) +(* All the functions below are based on Algo.state_to_string *) let (to_list : 'v -> data_or_name list) = fun v -> let str = Register.to_string v in @@ -57,7 +51,6 @@ let (to_rif_data : 'v -> string) = in String.concat " " lstr - let (to_data: pid -> 'v -> (string * Data.v * Data.t) list) = fun pid v -> let lopt = to_list v in @@ -78,19 +71,13 @@ let (to_rif_decl : pid -> 'v -> (string * Data.t) list) = fun pid v -> let dl = to_data pid v in List.map (fun (n,_v,t) -> n,t) dl - let (to_var_names : pid -> 'v -> string list) = fun pid v -> let dl = to_data pid v in List.map (fun (n,_v,_t) -> n) dl - let (to_rdbg_subst : pid -> 'v -> (string * Data.v) list) = fun pid v -> let dl = to_data pid v in List.map (fun (n,v,_) -> n,v) dl - - - - diff --git a/lib/sasacore/sasaState.mli b/lib/sasacore/sasaState.mli index 3e6408dd1fe7077619b455d2efef2543cc858e1d..836977e2c8954dd9404cc7fe547295c62939198d 100644 --- a/lib/sasacore/sasaState.mli +++ b/lib/sasacore/sasaState.mli @@ -1,32 +1,31 @@ +(* Time-stamp: <modified the 15/04/2021 (at 11:37) by Erwan Jahier> *) -(* 'v is the type of Algo local state, and is defined by users. In - order to avoid the need for the user to define (and register a set - of functions over such a state type, we try to guess them using - only one of them: Algo.to_string (obtained via - Algo.get_value_to_string). +(** 'v is the type of Algo local state, and is defined by users. - The reasons for doing that are: + Instead of requiring functions that convert 'v into Data.t, I + choose to implement them on top of Algo.state_to_string (although + it is probably less robust). - - it is only required for interacting with synchronous tools in RIF - - it is boring to do - - it is not so easy, as all func definitions should be consistent + The reasons for doing that are: + - Data.v are only required for interacting with synchronous tools + in RIF + - it is boring to do + - it is not so easy, as all function definitions should be + consistent - Moreover, it also provides a mean to hide some information. Indeed, - if the user only want to show part of the local state, he can. - -*) - - -(* All the remaining fonctions are based on Algo.to_string *) + Moreover, requiring a state_to_string also provides an easy mean to + hide information in the RIF. Indeed, if the user only wants to + show part of the local state, he just need to hide it via the + state_to_string function. *) type pid = string -val to_var_names : pid -> 'v -> string list -(** used to produce RIF *) +(** Returns a list variable names used in the RIF outputs. Those names are + made of the pid and the type 'v using the state_to_string function *) val to_rif_decl : pid -> 'v -> (string * Data.t) list val to_rif_data : 'v -> string +val to_var_names : pid -> 'v -> string list (** used to interact with rdbg *) val to_rdbg_subst : pid -> 'v -> (string * Data.v) list - diff --git a/lib/sasacore/main.ml b/lib/sasacore/simuState.ml similarity index 72% rename from lib/sasacore/main.ml rename to lib/sasacore/simuState.ml index 2cc0e07a4155c31a358287618ca699aa4d3c9da9..bd1d98752e80d459ab4911085060a8868059369a 100644 --- a/lib/sasacore/main.ml +++ b/lib/sasacore/simuState.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 02/12/2020 (at 15:11) by Erwan Jahier> *) +(* Time-stamp: <modified the 04/05/2021 (at 08:36) by Erwan Jahier> *) open Register @@ -10,17 +10,6 @@ let (update_env_with_init : 'v Env.t -> 'v Process.t list -> 'v Env.t) = in List.fold_left aux e pl -(** Returns the channel number that let [p_neighbor] access to the - content of [p], if [p] is a neighbor of [p_neighbor]. Returns -1 if - [p] is not a neigbhbor of [p_neigbor], which can happen in directed - graphs. *) -let (reply: Topology.t -> string -> string -> int) = - fun g p p_neighbor -> - let rec f i = function - | [] -> (-1) (* may happen in directed graphs *) - | (_w,x)::t -> if x=p then i else f (i+1) t - in - f 0 (g.succ p_neighbor) let (get_neighors: Topology.t -> Topology.node_id -> 'v -> 'v Register.neighbor list) = fun g source_id init -> @@ -32,71 +21,104 @@ let (get_neighors: Topology.t -> Topology.node_id -> 'v -> 'v Register.neighbor state = init; pid = node.id; spid = source_id; - reply = (fun () -> reply g source_id neighbor_id); + reply = (fun () -> Topology.reply g source_id neighbor_id); weight = (fun () -> w) } ) idl -let (dump_process: 'v Process.t * 'v Register.neighbor list -> unit) = - fun (p,nl) -> +let (dump_process: string -> 'v Process.t * 'v Register.neighbor list -> unit) = + fun msg (p,nl) -> let pvars = String.concat "," (SasaState.to_var_names p.pid p.init) in let neighbors = List.map StringOf.algo_neighbor nl in - Printf.eprintf "process %s\n\tvars:%s\n\tneighors: \n\t\t%s\n%!" p.pid pvars + Printf.eprintf "%s: process %s\n\tvars:%s\n\tneighors: \n\t\t%s\n%!" msg p.pid pvars (String.concat "\n\t\t" neighbors) open Process +open SasArg + +module StringMap = Map.Make(String) +type 'v t = { + sasarg: SasArg.t; + (* network: ('v Process.t * 'v Register.neighbor list) list; *) + network: 'v Process.t list; + neighbors: ('v Register.neighbor list) Map.Make(String).t; + config: 'v Env.t +} -let (update_neighbor_env: 'v Env.t -> 'v Register.neighbor -> 'v Register.neighbor) = - fun e n -> - { n with state = Env.get_copy e n.Register.pid } +let (neigbors_of_pid : 'v t -> pid -> 's * ('s neighbor * pid) list) = + fun st pid -> + let nl = + match StringMap.find_opt pid st.neighbors with + | Some x -> x + | None -> + failwith ( + Printf.sprintf "no %s found in %s" pid + (String.concat "," (List.map (fun p -> p.Process.pid) st.network))) + in + Env.get st.config pid, List.map (fun n -> n, n.Register.pid) nl + +let (update_neighbor_env: 'v Env.t -> 'v Register.neighbor list -> 'v Register.neighbor list) = + fun e nl -> + List.map (fun n -> { n with state = Env.get_copy e n.Register.pid }) nl -type 'v layout = ('v Process.t * 'v Register.neighbor list) list +let update_neighbors config neighbors = StringMap.map + (fun nl -> update_neighbor_env config nl) + neighbors + +let (update_config: 'v Env.t -> 'v t -> 'v t) = + fun e st -> + let verb = !Register.verbose_level > 0 in + if verb then Printf.eprintf " ===> update_neighbor_env\n%!"; + { st with neighbors = update_neighbors e st.neighbors ; config = e } type 'v enable_processes = ('v Process.t * 'v Register.neighbor list * Register.action) list list * bool list list -let (get_enable_processes: 'v layout -> 'v Env.t -> 'v enable_processes) = - fun pl_n e -> +let (get_enable_processes: 'v t -> 'v enable_processes) = + fun st -> + let pl_n = List.map (fun p -> p, StringMap.find p.pid st.neighbors) st.network in + let e = st.config in assert (pl_n <> []); let all = List.fold_left - (fun acc (p,nl) -> - let nl = List.map (update_neighbor_env e) nl in - let lenv = Env.get_copy e p.pid in - let al = p.enable nl lenv in - let al = - List.map (fun a -> - if not (List.mem a p.actions) then - (Printf.printf - "[sasa] Error: The action label \"%s\" is not declared (i.e., not in [%s])\n%!" - a (String.concat "; " (List.map (fun s -> "\""^s^"\"") p.actions)); - exit 2); - - p,nl,a) - al - in - al::acc) - [] pl_n + (fun acc (p,nl) -> + (* let nl0 = nl in *) + (* let nl = update_neighbor_env e nl in (* already done? *) *) + (* if List.exists2 (fun n1 n2 -> (n1.state <> n2.state)) nl nl0 then ( *) + (* dump_process "avant" (p,nl0); *) + (* dump_process "apres" (p,nl); *) + (* assert false *) + (* ); *) + let lenv = Env.get_copy e p.pid in + let al = p.enable nl lenv in + let al = + List.map (fun a -> + if not (List.mem a p.actions) then + (Printf.printf + "[sasa] Error: The action label \"%s\" is not declared (i.e., not in [%s])\n%!" + a (String.concat "; " (List.map (fun s -> "\""^s^"\"") p.actions)); + exit 2); + + p,nl,a) + al + in + al::acc) + [] pl_n in assert (List.length pl_n = List.length all); let all = List.rev all in let enab_ll = List.map2 (fun (p,_) al -> - let al = List.map (fun (_,_,a) -> a) al in - List.map (fun a_static -> List.mem a_static al) p.actions) + let al = List.map (fun (_,_,a) -> a) al in + List.map (fun a_static -> List.mem a_static al) p.actions) pl_n all in all, enab_ll - -open SasArg -type 'v t = SasArg.t * 'v layout * 'v Env.t - - let (get_inputs_rif_decl: SasArg.t -> 'v Process.t list -> (string * string) list) = fun args pl -> if args.daemon <> Custom then @@ -125,7 +147,7 @@ let (get_outputs_rif_decl: SasArg.t -> 'v Process.t list -> (string * string) li (fun acc a -> ((Printf.sprintf "%s_%s" p.pid (StringOf.action a)),"bool")::acc) acc - p.actions + (List.rev p.actions) ) vars pl @@ -138,7 +160,7 @@ let (get_outputs_rif_decl: SasArg.t -> 'v Process.t list -> (string * string) li (fun acc a -> ((Printf.sprintf "Enab_%s_%s" p.pid (StringOf.action a)),"bool")::acc) acc - p.actions + (List.rev p.actions) ) vars pl @@ -176,6 +198,7 @@ let (make : bool -> string array -> 'v t) = flush stdout; exit 2 in + let seed = seed_get args in try let dynlink = if args.output_algos then false else dynlink in let dot_file = args.topo in @@ -207,14 +230,7 @@ let (make : bool -> string array -> 'v t) = let nidl = List.map (fun n -> n.Topology.id) nl in let nstr = String.concat "," nidl in - Register.set_card (fun () -> List.length nl); - Register.set_degrees (fun () -> Topology.get_degree g); - Register.set_mean_deg (fun () -> Topology.get_mean_degree g); - Register.set_is_connected_cyclic (fun () -> Topology.is_connected_and_cyclic g); - Register.set_height (Topology.get_height g); - Register.set_links_number (fun () -> Topology.get_nb_link g); - Register.set_diameter (fun () -> Diameter.get g); - Register.set_is_directed (fun () -> g.directed); + Register.set_topology g; List.iter (fun (n,v) -> Register.set_graph_attribute n v) g.attributes; Register.verbose_level := args.verbose; @@ -250,8 +266,10 @@ let (make : bool -> string array -> 'v t) = let pl = List.map2 (Process.make (args.daemon=Custom)) nl initl in let e = Env.init () in let e = update_env_with_init e pl in + let algo_neighors = List.map (update_neighbor_env e) algo_neighors in let pl_n = List.combine pl algo_neighors in - if !Register.verbose_level > 1 then List.iter dump_process pl_n; + + if !Register.verbose_level > 1 then List.iter (dump_process "") pl_n; if args.gen_lutin then ( let fn = (Filename.remove_extension args.topo) ^ ".lut" in if Sys.file_exists fn then ( @@ -273,7 +291,6 @@ let (make : bool -> string array -> 'v t) = close_out oc; Printf.eprintf " [sasa] %s has been generated.\n%!" fn; exit 0); - let seed = seed_get args in if args.no_data_file then () else ( let oc = if args.rif then stderr else stdout in if !Register.verbose_level > 0 then Printf.eprintf "==> open rif file...\n%!"; @@ -305,8 +322,17 @@ let (make : bool -> string array -> 'v t) = pl; Printf.eprintf "Ignoring the first vectors of sasa inputs\n%!"; ); - if !Register.verbose_level > 0 then Printf.eprintf "==> Main.make done !\n%!"; - args, pl_n, e + if !Register.verbose_level > 0 then Printf.eprintf "==> SimuState.make done !\n%!"; + let neighbors = + List.fold_left (fun acc (p,nl) -> StringMap.add p.pid nl acc) + StringMap.empty pl_n + in + { + sasarg = args; + network = pl; + neighbors = neighbors; + config = e + } with | Dynlink.Error e -> Printf.eprintf " [sasa] Error when dynlinking (Sasacore.make): %s\n%!" diff --git a/lib/sasacore/simuState.mli b/lib/sasacore/simuState.mli new file mode 100644 index 0000000000000000000000000000000000000000..6c02a144ddfeed5473a0e9f156e9bd05087b2047 --- /dev/null +++ b/lib/sasacore/simuState.mli @@ -0,0 +1,35 @@ +(* Time-stamp: <modified the 04/05/2021 (at 08:27) by Erwan Jahier> *) + +(** The module is used by + - the main sasa simulation loop (in ../../src/sasaMain.ml) + - the RdbgPlugin.t maker (in ../sasa/sasaRun.ml) + +*) + + + +(* type 'v t = SasArg.t * 'v layout * 'v Env.t *) +type 'v t = { + sasarg: SasArg.t; + network: 'v Process.t list; + neighbors: ('v Register.neighbor list) Map.Make(String).t; (* pid's neigbors *) + config: 'v Env.t +} + +(* [make dynlink_flag argv] *) +val make : bool -> string array -> 'v t + +type 'v enable_processes = + ('v Process.t * 'v Register.neighbor list * Register.action) list list * bool list list + +val get_enable_processes: 'v t -> 'v enable_processes + +(** update the config and network processes *) +val update_config: 'v Env.t -> 'v t -> 'v t + +(** Get pid's state and neigbors *) +val neigbors_of_pid : 'v t -> string -> 'v * ('v Register.neighbor * string) list + +(* For SasaRun *) +val get_inputs_rif_decl : SasArg.t -> 'v Process.t list -> (string * string) list +val get_outputs_rif_decl: SasArg.t -> 'v Process.t list -> (string * string) list diff --git a/lib/sasacore/topology.ml b/lib/sasacore/topology.ml index d40bcbf25dd639dd30ffa014c6a5c3fc2eef1243..4ad1c28c30e1a2de4e5249fda5f09fc449f965ff 100644 --- a/lib/sasacore/topology.ml +++ b/lib/sasacore/topology.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 09/11/2020 (at 21:58) by Erwan Jahier> *) +(* Time-stamp: <modified the 09/04/2021 (at 10:58) by Erwan Jahier> *) open Graph open Graph.Dot_ast @@ -14,6 +14,7 @@ type node = { type t = { nodes: node list; succ: node_id -> (int * node_id) list; + pred: node_id -> node_id list; of_id: node_id -> node; directed:bool; attributes: (string * string) list; @@ -22,12 +23,15 @@ type t = { type node_info_t = (string, node) Hashtbl.t let node_info:node_info_t = Hashtbl.create 100 -type node_succ_t = (string, (int * node_id) list) Hashtbl.t +type node_succ_t = (string, int * node_id) Hashtbl.t let node_succ:node_succ_t = Hashtbl.create 100 +type node_pred_t = (string, node_id) Hashtbl.t +let node_pred:node_pred_t = Hashtbl.create 100 let clean_tbl () = Hashtbl.clear node_info; - Hashtbl.clear node_succ + Hashtbl.clear node_succ; + Hashtbl.clear node_pred let (of_id:Dot_ast.id -> string) = function Ident str | Html str | Number str | String str -> str @@ -89,7 +93,7 @@ let (do_stmt: bool -> node list * attrs -> Dot_ast.stmt -> node list * attrs) = let id = of_node_id node_id in let inits = get_init dot_attrs in let node = { id=id ; file = get_file node_id dot_attrs ; init = inits } in - Hashtbl.replace node_info id node; + Hashtbl.add node_info id node; node::n, attrs | Edge_stmt (dot_node, nodes, dot_attrs) -> let node = of_node dot_node in @@ -110,12 +114,12 @@ let (do_stmt: bool -> node list * attrs -> Dot_ast.stmt -> node list * attrs) = if n1 = n2 then failwith (Printf.sprintf "Bad topology: %s can not ne a neighbor of itself!" n1); - let pn1 = try Hashtbl.find node_succ n1 with Not_found -> [] in - let pn2 = try Hashtbl.find node_succ n2 with Not_found -> [] in + let pn1 = Hashtbl.find_all node_succ n1 in + let pn2 = Hashtbl.find_all node_succ n2 in if not (List.mem (weight,n2) pn1) then - Hashtbl.replace node_succ n1 ((weight,n2)::pn1); + Hashtbl.add node_succ n1 (weight,n2); if not directed && not (List.mem (weight,n1) pn2) then - Hashtbl.replace node_succ n2 ((weight,n1)::pn2); + Hashtbl.add node_succ n2 (weight,n1); n2 in ignore (List.fold_left add_edge node nodes); @@ -133,10 +137,20 @@ let (read: string -> t) = fun f -> clean_tbl (); let dot_file = Graph.Dot.parse_dot_ast f in assert (not dot_file.strict); - let nodes, attrs = List.fold_left (do_stmt dot_file.digraph) ([], []) dot_file.stmts in + let nodes, attrs = + List.fold_left (do_stmt dot_file.digraph) ([], []) dot_file.stmts + in + Hashtbl.iter + (fun pid (_, pid_succ) -> + Hashtbl.add node_pred pid_succ pid + ) + node_succ; + let succ str = Hashtbl.find_all node_succ str in + let pred str = Hashtbl.find_all node_pred str in { nodes = List.rev nodes; - succ = (fun str -> try Hashtbl.find node_succ str with Not_found -> []); + succ = succ; + pred = pred; of_id = (fun str -> try Hashtbl.find node_info str with Not_found -> failwith (str^ " unknown node id") ); @@ -153,7 +167,8 @@ let (to_adjacency: t -> bool array array) = List.iteri (fun i n -> Hashtbl.add rank_node_tbl n.id i) t.nodes; List.iteri (fun i n -> - List.iter (fun (_,target) -> m.(i).(rank_node target) <- true) (t.succ n.id) + List.iter (fun (_,target) -> + m.(i).(rank_node target) <- true) (t.succ n.id) ) t.nodes; m @@ -163,21 +178,29 @@ let (get_degree: t -> int*int) = match t.nodes with | [] -> 0,0 | n::tl -> - let node_deg n = List.length (t.succ (n.id)) in + let node_deg n = + if t.directed then + List.length (t.succ (n.id)) + List.length (t.pred (n.id)) + else + List.length (t.succ (n.id)) + in let d0 = node_deg n in let dmin, dmax = List.fold_left - (fun (d_min,d_max) n -> - (min (node_deg n) d_min, max (node_deg n) d_max) - ) - (d0, d0) - tl + (fun (d_min,d_max) n -> + (min (node_deg n) d_min, max (node_deg n) d_max) + ) + (d0, d0) + tl in - if t.directed then 2*dmin, 2*dmax else dmin, dmax + dmin, dmax let (get_nb_link: t -> int) = fun t -> let res = List.fold_left - (fun acc n -> ((List.length (t.succ n.id))) + acc) 0 t.nodes + (fun acc n -> + (* let succ = String.concat "," (List.map snd (t.succ n.id)) in *) + (* Printf.printf "%s->%s\n%!" n.id succ; *) + ((List.length (t.succ n.id))) + acc) 0 t.nodes in if t.directed then res else res/2 @@ -185,6 +208,42 @@ let (get_mean_degree : t -> float) = fun t -> 2.0 *. (float_of_int (get_nb_link t)) /. (float_of_int (List.length t.nodes)) +type color = W | G | B +exception Cycle +let directed_is_cyclic : t -> bool = + fun g -> + assert (g.directed); + let t = Hashtbl.create (List.length g.nodes) in + let nodes = List.map (fun n -> n.id) g.nodes in + let color pid = match Hashtbl.find_opt t pid with + Some c -> c | None -> assert false + in + List.iter (fun n -> Hashtbl.add t n W) nodes; + let rec visit pid = + match color pid with + | G -> raise Cycle + | B -> () + | W -> + Hashtbl.replace t pid G; + List.iter visit (g.pred pid); + Hashtbl.replace t pid B + in + try List.iter visit nodes; false + with Cycle -> true + +let is_connected : t -> bool = + fun g -> + let visited = Hashtbl.create 0 in + let rec f acc pid = + if Hashtbl.mem visited pid then acc else + (Hashtbl.add visited pid pid; + List.fold_left f (pid::acc) + (List.rev_append (List.map snd (g.succ pid)) (g.pred pid)) + ) + in + let accessible = f [] (List.hd g.nodes).id in + List.length accessible = List.length g.nodes + let bfs : (t -> string -> bool * string list) = fun t n -> let q = Queue.create () in @@ -206,26 +265,123 @@ let bfs : (t -> string -> bool * string list) = parents ) ) !parent (t.succ node) - done; (!cyclic, !discovered) -let is_connected_and_cyclic : t -> bool*bool = - fun t -> match t.nodes with - | [] -> (false,false) +let non_directed_is_cyclic : t -> bool = + fun t -> + assert(not t.directed); + match t.nodes with + | [] -> false | hd::_ -> - let (cyclic,bfs_nodes) = (bfs t hd.id) in - ((List.compare_lengths t.nodes bfs_nodes) = 0, cyclic) - -let rec height : string list -> t -> string -> int = - fun parents t n -> - (List.fold_left (fun h (_,succ) -> - if List.mem succ parents then - h - else - max h (height (n::parents) t succ)) (-1) (t.succ n)) + 1 - -let get_height : t -> string -> int = - fun t -> - height ([]) t + let (cyclic, _bfs_nodes) = (bfs t hd.id) in + cyclic + +let is_cyclic : t -> bool = + fun g -> + if g.directed then directed_is_cyclic g else non_directed_is_cyclic g + +let is_tree : t -> bool = + fun g -> + (not (is_cyclic g)) && (is_connected g) + + +(** Returns the channel number that let [p_neighbor] access to the + content of [p], if [p] is a neighbor of [p_neighbor]. Returns -1 if + [p] is not a neigbhbor of [p_neigbor], which can happen in directed + graphs. *) +let (reply: t -> string -> string -> int) = + fun g p p_neighbor -> + let rec f i = function + | [] -> (-1) (* may happen in directed graphs *) + | (_w,x)::t -> if x=p then i else f (i+1) t + in + f 0 (g.succ p_neighbor) + +let (reply_pred: t -> string -> string -> int) = + fun g p p_neighbor -> + let rec f i = function + | [] -> (-1) (* may happen in directed graphs *) + | x::t -> if x=p then i else f (i+1) t + in + f 0 (g.pred p_neighbor) + +let is_in_tree g = + (is_tree g) && + (List.for_all (fun n -> List.length (g.pred n.id) <= 1) g.nodes) + +let is_out_tree g = + (is_tree g) && + (List.for_all (fun n -> List.length (g.succ n.id) <= 1) g.nodes) + +let not_a_io_tree () = failwith "The graph is not an in-tree nor an out-tree" + +let get_parent = fun g pid -> + let in_tree = is_in_tree g in + let out_tree = is_out_tree g in + if not in_tree && not out_tree then + not_a_io_tree () + else + let succ,reply = + if out_tree then + (fun pid -> List.map snd (g.succ pid)), reply_pred + else + (fun pid -> g.pred pid), reply + in + match succ pid with + | [] -> None + | [par] -> Some (reply g pid par) + | l -> + Printf.printf "%s->%s\n%!" pid (String.concat "," l); + assert false + +let get_sub_tree_size g pid = + let in_tree = is_in_tree g in + let out_tree = is_out_tree g in + if not in_tree && not out_tree then + not_a_io_tree () + else + let succ = + if in_tree then + (fun pid -> List.map snd (g.succ pid)) + else + (fun pid -> g.pred pid) + in + let visited = Hashtbl.create 0 in + let rec f acc pid = + if Hashtbl.mem visited pid then acc else + (Hashtbl.add visited pid pid; + List.fold_left + (fun acc pid -> f acc pid) + (acc+1) + (succ pid) + ) + in + f 0 pid + +let rec height : (string -> string list) -> string list -> string -> int = + fun succ parents n -> + (List.fold_left + (fun h pid -> + if List.mem pid parents then h else + max h (height succ (n::parents) pid) + ) + (-1) + (succ n) + ) + 1 + +let get_height : t -> string -> int = + fun g -> + let in_tree = is_in_tree g in + let out_tree = is_out_tree g in + if not in_tree && not out_tree then + not_a_io_tree () + else + let succ = + if out_tree then + (fun pid -> List.map snd (g.succ pid)) + else + (fun pid -> g.pred pid) + in + height succ [] diff --git a/lib/sasacore/topology.mli b/lib/sasacore/topology.mli index a27f0e6dde7311ded6171929042e486bf8465fb5..e37cbf4ca48210c8d85f17a7eb60a6d123f08db6 100644 --- a/lib/sasacore/topology.mli +++ b/lib/sasacore/topology.mli @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 31/08/2020 (at 16:45) by Erwan Jahier> *) +(* Time-stamp: <modified the 21/04/2021 (at 15:56) by Erwan Jahier> *) (** {1 Topology: internal representation of Graphs } *) @@ -13,6 +13,7 @@ type node = { type t = { nodes: node list; (** *) succ: node_id -> (int * node_id) list; (** get neighbors, with weight *) + pred: node_id -> node_id list; of_id: node_id -> node; (** *) directed:bool; (** true if the graph is directed *) attributes: (string * string) list (** (name, value) list of graph attributes *) @@ -22,11 +23,22 @@ type t = { val read: string -> t (** {1 Various eponymous util functions } *) - + val to_adjacency: t -> bool array array val get_nb_link: t -> int val get_mean_degree : t -> float -val is_connected_and_cyclic : t -> bool * bool -val height : string list -> t -> string -> int +val is_connected : t -> bool +val is_cyclic : t -> bool +val is_tree : t -> bool +val is_in_tree : t -> bool +val is_out_tree : t -> bool val get_height : t -> string -> int -val get_degree: t -> int * int +val get_parent : t -> string -> int option +val get_sub_tree_size : t -> string -> int +val get_degree: t -> int * int + +(** [reply g p p_neighbor] returns the channel number that let + [p_neighbor] access to the content of [p], if [p] is a neighbor of + [p_neighbor]. Returns -1 if [p] is not a neighbor of [p_neigbor], + which can happen in directed graphs. *) +val reply: t -> string -> string -> int diff --git a/src/sasaMain.ml b/src/sasaMain.ml index 0782229ee82d64c16c55a591377ee7d79342847e..65f1918af948dae27a0db544066587d170da575f 100644 --- a/src/sasaMain.ml +++ b/src/sasaMain.ml @@ -39,7 +39,7 @@ exception Legitimate of int let moves = ref 0 let rounds = ref 0 let round_mask = ref [] - + let (update_round : bool list list -> bool list list -> unit) = fun acti_ll enab_ll -> if !round_mask = [] then round_mask := enab_ll; @@ -51,175 +51,143 @@ let (update_round : bool list list -> bool list list -> unit) = ); () - let bool_ll_to_string bll = String.concat " " (List.map (fun b -> if b then "t" else "f") (List.flatten bll)) -let legitimate p_nl_l e = +open Sasacore.SimuState + +let legitimate st = match Register.get_legitimate () with | None -> false | Some ulf -> - let pidl = List.map (fun (p,_) -> p.Process.pid) p_nl_l in - let rec from_pid p_nl_l pid = (* XXX use StringMap instead *) - match p_nl_l with - | [] -> assert false (* sno *) - | (p,nl)::tail -> - if p.Process.pid = pid then - let nl = List.map (Sasacore.Main.update_neighbor_env e) nl in - let nl = List.map (fun n -> n,n.Register.pid) nl in - Env.get e pid, - nl - else - from_pid tail pid - in - ulf pidl (from_pid p_nl_l) + let pidl = List.map (fun p -> p.Process.pid) st.network in + ulf pidl (SimuState.neigbors_of_pid st) -let inject_fault ff p_nl e = - let update_nodes e (p,nl) = +module StringMap = Map.Make(String) + +let inject_fault ff st = + let update_nodes e p = + let nl = StringMap.find p.Process.pid st.neighbors in let pid = p.Process.pid in let v = Env.get e pid in let v = ff (List.length nl) pid v in Env.set e pid v in - List.fold_left update_nodes e p_nl + let e = List.fold_left update_nodes st.config st.network in + update_config e st let plur i = if i>1 then "s" else "" -let (compute_potentiel: ('v Process.t * 'v Register.neighbor list) list -> - 'v Env.t -> string) = - fun p_nl_l ne -> +let (compute_potentiel: 'v SimuState.t -> string) = + fun st -> match Register.get_potential () with | None -> "" | Some user_pf -> - let pidl = List.map (fun (p,_) -> p.Process.pid) p_nl_l in - let get_info pid = - let nl = match List.find_opt (fun (p,_) -> p.Process.pid = pid) p_nl_l with - None -> - failwith ( - Printf.sprintf "no %s found in %s" pid - (String.concat "," (List.map (fun (p,_) -> p.Process.pid) p_nl_l))) - | Some (_,x) -> x - in - Env.get ne pid, - List.map (fun n -> n, n.Register.pid) nl - in - let p = (user_pf pidl get_info) in + let pidl = List.map (fun p -> p.Process.pid) st.network in + let p = user_pf pidl (SimuState.neigbors_of_pid st) in string_of_float p - -let (simustep: int -> int -> SasArg.t -> string -> - ('v Process.t * 'v Register.neighbor list) list -> 'v Env.t -> 'v Env.t * string) = - fun n i args activate_val p_nl_l e -> + +let (simustep: int -> int -> string -> 'v SimuState.t -> 'v SimuState.t * string) = + fun n i activate_val st -> (* 1: Get enable processes *) - if !Register.verbose_level > 0 then - Printf.eprintf "==> SasaMain.simustep :1: Get enable processes\n%!"; - let all, enab_ll = Sasacore.Main.get_enable_processes p_nl_l e in - let pot = compute_potentiel p_nl_l e in - let pl = fst(List.split p_nl_l) in - let e, all, enab_ll = + let verb = !Register.verbose_level > 0 in + if verb then Printf.eprintf "==> SasaSimuState.simustep :1: Get enable processes\n%!"; + let all, enab_ll = Sasacore.SimuState.get_enable_processes st in + let pot = compute_potentiel st in + let pl = st.network in + let st, all, enab_ll = if (* not (args.rif) && *) List.for_all (fun b -> not b) (List.flatten enab_ll) then ( match Register.get_fault () with | None -> - print_step n i pot args e pl activate_val enab_ll; + print_step n i pot st.sasarg st.config pl activate_val enab_ll; incr rounds; raise (Silent (n-i)) | Some ff -> - print_step n i pot args e pl activate_val enab_ll; - let str = if args.rif then "#" else "" in + print_step n i pot st.sasarg st.config pl activate_val enab_ll; + let str = if st.sasarg.rif then "#" else "" in Printf.eprintf "\n%sThis algo is silent after %i move%s, %i step%s, %i round%s.\n" str !moves (plur !moves) (n-i) (plur (n-i)) !rounds (plur !rounds); Printf.eprintf "%s==> Inject a fault\n%!" str; - let e = inject_fault ff p_nl_l e in - let all, enab_ll = Sasacore.Main.get_enable_processes p_nl_l e in - e, all, enab_ll + let st = inject_fault ff st in + let all, enab_ll = Sasacore.SimuState.get_enable_processes st in + st, all, enab_ll ) - else if legitimate p_nl_l e then ( + else if legitimate st then ( match Register.get_fault () with | None -> - print_step n i pot args e pl activate_val enab_ll; + print_step n i pot st.sasarg st.config pl activate_val enab_ll; raise (Legitimate (n-i)) | Some ff -> - print_step n i pot args e pl activate_val enab_ll; - let str = if args.rif then "#" else "#" in + print_step n i pot st.sasarg st.config pl activate_val enab_ll; + let str = if st.sasarg.rif then "#" else "#" in Printf.eprintf "\n%sThis algo reached a legitimate configuration after %i move%s, %i step%s, %i round%s.\n" str !moves (plur !moves) (n-i) (plur (n-i)) !rounds (plur !rounds); Printf.eprintf "%s==> Inject a fault\n%!" str; - let e = inject_fault ff p_nl_l e in - let all, enab_ll = Sasacore.Main.get_enable_processes p_nl_l e in - e, all, enab_ll + let st = inject_fault ff st in + let all, enab_ll = Sasacore.SimuState.get_enable_processes st in + st, all, enab_ll ) else - e, all, enab_ll + st, all, enab_ll in - if args.daemon = Daemon.Custom then - print_step n i pot args e pl activate_val enab_ll; + if st.sasarg.daemon = Daemon.Custom then + print_step n i pot st.sasarg st.config pl activate_val enab_ll; (* 2: read the actions *) - if !Register.verbose_level > 0 then - Printf.eprintf "==> SasaMain.simustep : 2: read the actions\n%!"; - let get_action_value = RifRead.bool (args.verbose > 1) in - let next_activate_val, pnal = Daemon.f args.dummy_input - (args.verbose >= 1) args.daemon p_nl_l e all enab_ll get_action_value + if verb then Printf.eprintf "==> SasaSimuState.simustep : 2: read the actions\n%!"; + let get_action_value = RifRead.bool (st.sasarg.verbose > 1) in + let next_activate_val, pnal = Daemon.f st.sasarg.dummy_input + (st.sasarg.verbose >= 1) st.sasarg.daemon st.network (SimuState.neigbors_of_pid st) + st.config all enab_ll get_action_value in List.iter (List.iter (fun b -> if b then incr moves)) next_activate_val; update_round next_activate_val enab_ll; let next_activate_val = bool_ll_to_string next_activate_val in (* 3: Do the steps *) - if !Register.verbose_level > 0 then - Printf.eprintf "==> SasaMain.simustep : 3: Do the steps\n%!"; - if args.daemon <> Daemon.Custom then - print_step n i pot args e pl next_activate_val enab_ll; - let ne = Sasacore.Step.f pnal e in - ne, next_activate_val + if verb then Printf.eprintf "==> SasaSimuState.simustep : 3: Do the steps\n%!"; + if st.sasarg.daemon <> Daemon.Custom then + print_step n i pot st.sasarg st.config pl next_activate_val enab_ll; + let ne = Sasacore.Step.f pnal st.config in + let st = update_config ne st in + st, next_activate_val -let rec (simuloop: int -> int -> SasArg.t -> string -> - ('v Process.t * 'v Register.neighbor list) list -> 'v Env.t -> unit) = - fun n i args activate_val p_nl_l e -> - if !Register.verbose_level > 0 then Printf.eprintf "==> SasaMain.simuloop %d/%d \n%!" i n; - let ne, next_activate_val = simustep n i args activate_val p_nl_l e in - let p_nl_l = List.map - (fun (p,nl) -> p, List.map (Sasacore.Main.update_neighbor_env ne) nl) - p_nl_l - in - if i > 0 then simuloop n (i-1) args next_activate_val p_nl_l ne else ( - print_string "#q\n"; flush stdout +let rec (simuloop: int -> int -> string -> 'v SimuState.t -> unit) = + fun n i activate_val st -> + if !Register.verbose_level > 0 then Printf.eprintf "==> SasaSimuState.simuloop %d/%d \n%!" i n; + let st, next_activate_val = simustep n i activate_val st in + if i > 0 then simuloop n (i-1) next_activate_val st else ( + print_string "#q\n"; flush_all () ) - let () = - let args, p_nl_l, e = Sasacore.Main.make true Sys.argv in + let st = Sasacore.SimuState.make true Sys.argv in try - let n = args.length in - simuloop n n args "" p_nl_l e + let n = st.sasarg.length in + simuloop n n "" st with | Silent i -> - let str = if args.rif then "#" else "" in + let str = if st.sasarg.rif then "#" else "" in Printf.printf "\n%sThis algo is silent after %i move%s, %i step%s, %i round%s.\n%!" str !moves (plur !moves) i (plur i) !rounds (plur !rounds); - flush stderr; - flush stdout; print_string "\nq\n#quit\n%!"; - flush stderr; - flush stdout + flush_all() | Legitimate i -> - let str = if args.rif then "#" else "" in + let str = if st.sasarg.rif then "#" else "" in Printf.printf "\n%s%sThis algo reached a legitimate configuration after %i move%s, %i step%s, %i round%s.\n%!" - (if args.rif then "#" else "#") + (if st.sasarg.rif then "#" else "#") str !moves (plur !moves) i (plur i) !rounds (plur !rounds); - flush stderr; - flush stdout; print_string "\n#quit\n"; - flush stderr; - flush stdout + flush_all() | e -> - Printf.printf "%s%s\n%!" - (if args.rif then "#" else "") - (Printexc.to_string e); - flush stderr; - print_string "\nq\n#quit\n%!" + Printf.printf "%s%s\n%!" (if st.sasarg.rif then "#" else "") (Printexc.to_string e); + print_string "\nq\n#quit\n%!"; + flush_all(); + exit 2 + diff --git a/test/Makefile b/test/Makefile index 28f1c7e961d81cb10f89dd850f67d3379209fd9f..ce08dd844a7bcf092bb917b88e7c6edf34de2a98 100644 --- a/test/Makefile +++ b/test/Makefile @@ -15,7 +15,9 @@ test: cd st-KK06-algo1/ && make cd st-KK06-algo2/ && make cd bfs-st-HC92/ && make - cd rsp-tree/ && make + cd rsp-tree/ && make + cd toy-example-a5sf/ && make + echo "Every test went fine!" clean: @@ -36,5 +38,6 @@ clean: cd st-KK06-algo2/ && make clean cd bfs-st-HC92/ && make clean cd rsp-tree/ && make clean + cd toy-example-a5sf/ && make clean -include Makefile.untracked diff --git a/test/Makefile.dot b/test/Makefile.dot index 7cbb79ed548becc01be978bc38c2025f4ddd6cef..0e01d5ab0fc1bb0383826909c0002b03bbc6be54 100644 --- a/test/Makefile.dot +++ b/test/Makefile.dot @@ -1,5 +1,4 @@ -# Time-stamp: <modified the 29/03/2021 (at 14:48) by Erwan Jahier> - +# Time-stamp: <modified the 05/05/2021 (at 13:20) by Erwan Jahier> # Rules to generate various dot files. # The DECO_PATTERN variable should be defined @@ -33,10 +32,22 @@ ring%.dot: gg ring -n $* -o $@ gg-deco $(DECO_PATTERN) $@ -o $@ -dtree%.dot: +tree%.dot: gg tree -n $* -o $@ gg-deco $(DECO_PATTERN) $@ -o $@ +intree%.dot: + gg tree --in-tree -n $* -o $@ + gg-deco $(DECO_PATTERN) $@ -o $@ + +outtree%.dot: + gg tree --out-tree -n $* -o $@ + gg-deco $(DECO_PATTERN) $@ -o $@ + +inouttree%.dot: + gg tree --in-out-tree -n $* -o $@ + gg-deco $(DECO_PATTERN) $@ -o $@ + cleandot: rm -f ring5* ring30* er30* er100* grid* ba100* udg* qudg* diff --git a/test/Makefile.inc b/test/Makefile.inc index 0f5e45a983658e283e8853384470c3628d618764..e1d325510db3fbd2b4873985bf4ed0cb9136e383 100644 --- a/test/Makefile.inc +++ b/test/Makefile.inc @@ -1,4 +1,4 @@ -# Time-stamp: <modified the 08/12/2020 (at 13:37) by Erwan Jahier> +# Time-stamp: <modified the 27/04/2021 (at 09:37) by Erwan Jahier> # # Define some default rules that ought to work most of the time # @@ -20,7 +20,7 @@ OCAMLOPT=ocamlfind ocamlopt -bin-annot genclean: rm -f *.cmxs sasa *.cm* *.o *.pdf *.rif *.gp *.log *.dro *.seed *.c *.h sasa-*.dot *.cmt *.annot - rm -f rdbg-session*.ml luretteSession* *.lut a.out *.cov read_dot.ml + rm -f rdbg-session*.ml luretteSession* a.out *.cov read_dot.ml rm -f *.exec grid*.ml read_dot.ml rdbg-history rdbg-cmds.ml clean: genclean diff --git a/test/async-unison/Makefile b/test/async-unison/Makefile index 3109e40dd943937a610f28d3605fa71aba804ad0..8193d5ed819bfb7e2d92d18f124e3f612d57ba56 100644 --- a/test/async-unison/Makefile +++ b/test/async-unison/Makefile @@ -1,8 +1,14 @@ -# Time-stamp: <modified the 04/11/2020 (at 11:08) by Erwan Jahier> +# Time-stamp: <modified the 04/05/2021 (at 11:10) by Erwan Jahier> test: ring.cmxs ring.lut rdbg_test - $(sasa) -l 500 ring.dot + $(sasa) -l 500 ring.dot -seed 42 > ring.rif && \ + diff -I "# on" -I " version " -B -u -i -w ring.rif.exp ring.rif > test.res + [ ! -s test.res ] && make clean + +utest: ring.rif + cp ring.rif ring.rif.exp ; true + DECO_PATTERN="0-:p.ml" -include ../Makefile.dot diff --git a/test/async-unison/ring.rif.exp b/test/async-unison/ring.rif.exp new file mode 100644 index 0000000000000000000000000000000000000000..4b231df948f396f30ba85ecf272456328bbe220e --- /dev/null +++ b/test/async-unison/ring.rif.exp @@ -0,0 +1,1512 @@ +# Automatically generated by /home/jahier/.opam/4.10.0/bin/sasa version "4.3.27-1-g4eb78d9" ("4eb78d9") +# on crevetete the 4/5/2021 at 10:36:07 +#sasa -l 500 ring.dot -seed 42 + +#seed 42 +#inputs +#outputs "p1_c":int "p2_c":int "p3_c":int "p4_c":int "p5_c":int "p6_c":int "p7_c":int "Enab_p1_Ip":bool "Enab_p1_Rp":bool "Enab_p2_Ip":bool "Enab_p2_Rp":bool "Enab_p3_Ip":bool "Enab_p3_Rp":bool "Enab_p4_Ip":bool "Enab_p4_Rp":bool "Enab_p5_Ip":bool "Enab_p5_Rp":bool "Enab_p6_Ip":bool "Enab_p6_Rp":bool "Enab_p7_Ip":bool "Enab_p7_Rp":bool "p1_Ip":bool "p1_Rp":bool "p2_Ip":bool "p2_Rp":bool "p3_Ip":bool "p3_Rp":bool "p4_Ip":bool "p4_Rp":bool "p5_Ip":bool "p5_Rp":bool "p6_Ip":bool "p6_Rp":bool "p7_Ip":bool "p7_Rp":bool + + +#step 0 +#outs 14 5 23 3 7 5 34 f t f t f t f t f f f t f t f t f t f t f t f f f f f f + +#step 1 +#outs 0 0 0 0 7 5 34 f f t f t f t f f f f t f t f f f f f f f f f f f f f t + +#step 2 +#outs 0 0 0 0 7 5 0 t f t f t f t f f f f f t f f f t f f f f f f f f f f f + +#step 3 +#outs 0 1 0 0 7 5 0 t f f f t f t f f f f f t f f f f f t f t f f f f f f f + +#step 4 +#outs 0 1 1 1 7 5 0 t f f f t f t f f f f f t f t f f f t f f f f f f f f f + +#step 5 +#outs 1 1 2 1 7 5 0 f f t f f f t f f f f f t f f f t f f f t f f f f f f f + +#step 6 +#outs 1 2 2 2 7 5 0 f f f f t f t f f f f f t f f f f f f f t f f f f f f f + +#step 7 +#outs 1 2 2 3 7 5 0 f f f f t f f f f f f f t f f f f f f f f f f f f f t f + +#step 8 +#outs 1 2 2 3 7 5 1 t f f f t f f f f f f f t f t f f f f f f f f f f f t f + +#step 9 +#outs 2 2 2 3 7 5 2 t f t f t f f f f f f f t f f f f f t f f f f f f f f f + +#step 10 +#outs 2 2 3 3 7 5 2 t f t f f f t f f f f f t f t f t f f f t f f f f f t f + +#step 11 +#outs 3 3 3 4 7 5 3 t f t f t f f f f f f f t f f f t f t f f f f f f f t f + +#step 12 +#outs 3 4 4 4 7 5 4 t f f f t f t f f f f f f f f f f f f f t f f f f f f f + +#step 13 +#outs 3 4 4 5 7 5 4 t f f f t f f f f f f f f f t f f f f f f f f f f f f f + +#step 14 +#outs 4 4 4 5 7 5 4 t f t f t f f f f f f f t f f f f f t f f f f f f f f f + +#step 15 +#outs 4 4 5 5 7 5 4 t f t f f f t f f f f f t f f f t f f f f f f f f f f f + +#step 16 +#outs 4 5 5 5 7 5 4 t f f f t f t f f f f f t f t f f f f f f f f f f f t f + +#step 17 +#outs 5 5 5 5 7 5 5 t f t f t f t f f f t f t f t f f f f f f f f f f f t f + +#step 18 +#outs 6 5 5 5 7 5 6 f f t f t f t f f f t f f f f f t f t f t f f f t f f f + +#step 19 +#outs 6 6 6 6 7 6 6 t f t f t f t f f f t f t f f f t f t f t f f f t f f f + +#step 20 +#outs 6 7 7 7 7 7 6 t f f f t f t f t f f f t f t f f f f f t f t f f f f f + +#step 21 +#outs 7 7 7 8 8 7 6 f f t f t f f f f f f f t f f f t f t f f f f f f f t f + +#step 22 +#outs 7 8 8 8 8 7 7 t f f f t f t f f f t f t f t f f f t f f f f f t f f f + +#step 23 +#outs 8 8 9 8 8 8 7 f f t f f f t f t f f f t f f f f f f f t f f f f f t f + +#step 24 +#outs 8 8 9 9 8 8 8 t f t f f f f f t f t f t f t f t f f f f f t f f f t f + +#step 25 +#outs 9 9 9 9 9 8 9 t f t f t f t f f f t f f f t f t f t f t f f f t f f f + +#step 26 +#outs 10 10 10 10 9 9 9 f f t f t f f f t f t f t f f f t f t f f f t f f f t f + +#step 27 +#outs 10 11 11 10 10 9 10 t f f f f f t f f f t f f f t f f f f f f f f f f f f f + +#step 28 +#outs 11 11 11 10 10 9 10 f f t f f f t f f f t f f f f f t f f f f f f f f f f f + +#step 29 +#outs 11 12 11 10 10 9 10 f f f f f f t f f f t f f f f f f f f f t f f f t f f f + +#step 30 +#outs 11 12 11 11 10 10 10 f f f f t f f f t f t f t f f f f f t f f f f f f f t f + +#step 31 +#outs 11 12 12 11 10 10 11 t f f f f f f f t f t f f f t f f f f f f f f f f f f f + +#step 32 +#outs 12 12 12 11 10 10 11 f f t f f f f f t f t f f f f f t f f f f f f f f f f f + +#step 33 +#outs 12 13 12 11 10 10 11 f f f f f f f f t f t f f f f f f f f f f f f f t f f f + +#step 34 +#outs 12 13 12 11 10 11 11 f f f f f f f f t f f f t f f f f f f f f f t f f f t f + +#step 35 +#outs 12 13 12 11 11 11 12 t f f f f f t f t f t f f f t f f f f f f f t f f f f f + +#step 36 +#outs 13 13 12 11 12 11 12 f f f f f f t f f f t f f f f f f f f f f f f f t f f f + +#step 37 +#outs 13 13 12 11 12 12 12 f f f f f f t f f f t f t f f f f f f f f f f f t f t f + +#step 38 +#outs 13 13 12 11 12 13 13 t f f f f f t f f f f f t f f f f f f f t f f f f f t f + +#step 39 +#outs 13 13 12 12 12 13 14 t f f f t f t f t f f f f f t f f f t f f f f f f f f f + +#step 40 +#outs 14 13 13 12 12 13 14 f f t f f f t f t f f f f f f f t f f f t f f f f f f f + +#step 41 +#outs 14 14 13 13 12 13 14 t f f f t f f f t f f f f f t f f f f f f f t f f f f f + +#step 42 +#outs 15 14 13 13 13 13 14 f f f f t f t f t f t f f f f f f f f f f f t f t f f f + +#step 43 +#outs 15 14 13 13 14 14 14 f f f f t f t f f f t f t f f f f f t f t f f f f f t f + +#step 44 +#outs 15 14 14 14 14 14 15 f f t f t f t f t f t f f f f f t f t f f f f f t f f f + +#step 45 +#outs 15 15 15 14 14 15 15 t f t f f f t f t f f f t f f f f f f f f f f f f f t f + +#step 46 +#outs 15 15 15 14 14 15 16 t f t f f f t f t f f f f f f f f f f f t f t f f f f f + +#step 47 +#outs 15 15 15 15 15 15 16 t f t f t f t f t f t f f f t f f f t f t f t f f f f f + +#step 48 +#outs 16 15 16 16 16 15 16 f f t f f f t f f f t f f f f f t f f f f f f f f f f f + +#step 49 +#outs 16 16 16 16 16 15 16 t f t f t f t f f f t f f f f f t f f f t f f f t f f f + +#step 50 +#outs 16 17 16 17 16 16 16 t f f f t f f f t f t f t f t f f f f f f f f f f f t f + +#step 51 +#outs 17 17 16 17 16 16 17 t f f f t f f f t f t f f f t f f f f f f f f f t f f f + +#step 52 +#outs 18 17 16 17 16 17 17 f f f f t f f f t f f f t f f f f f t f f f t f f f f f + +#step 53 +#outs 18 17 17 17 17 17 17 f f t f t f t f t f t f t f f f f f t f t f t f t f t f + +#step 54 +#outs 18 17 18 18 18 18 18 f f t f f f t f t f t f t f f f t f f f t f t f f f f f + +#step 55 +#outs 18 18 18 19 19 18 18 t f t f t f f f f f t f t f f f t f f f f f f f f f t f + +#step 56 +#outs 18 19 18 19 19 18 19 t f f f t f f f f f t f f f f f f f t f f f f f t f f f + +#step 57 +#outs 18 19 19 19 19 19 19 t f f f t f t f t f t f f f f f f f t f f f t f f f f f + +#step 58 +#outs 18 19 20 19 20 19 19 t f f f f f t f f f t f f f t f f f f f f f f f t f f f + +#step 59 +#outs 19 19 20 19 20 20 19 t f t f f f t f f f f f t f t f t f f f t f f f f f t f + +#step 60 +#outs 20 20 20 20 20 20 20 t f t f t f t f t f t f t f t f f f t f f f f f f f f f + +#step 61 +#outs 21 20 21 20 20 20 20 f f t f f f t f t f t f t f f f f f f f t f f f f f t f + +#step 62 +#outs 21 20 21 21 20 20 21 f f t f f f f f t f t f f f f f f f f f f f t f t f f f + +#step 63 +#outs 21 20 21 21 21 21 21 f f t f f f t f t f t f t f f f f f f f t f f f f f t f + +#step 64 +#outs 21 20 21 22 21 21 22 f f t f f f f f t f t f f f f f f f f f f f t f f f f f + +#step 65 +#outs 21 20 21 22 22 21 22 f f t f f f f f f f t f f f f f t f f f f f f f t f f f + +#step 66 +#outs 21 21 21 22 22 22 22 t f t f t f f f t f t f f f f f t f f f f f t f t f f f + +#step 67 +#outs 21 22 21 22 23 23 22 t f f f t f f f f f f f f f t f f f t f f f f f f f f f + +#step 68 +#outs 22 22 22 22 23 23 22 t f t f t f t f f f f f t f t f t f t f f f f f f f t f + +#step 69 +#outs 23 23 23 22 23 23 23 t f t f f f t f f f t f t f f f f f f f t f f f f f f f + +#step 70 +#outs 23 23 23 23 23 23 23 t f t f t f t f t f t f t f f f f f t f f f t f t f t f + +#step 71 +#outs 23 23 24 23 24 24 24 t f t f f f t f f f t f f f f f t f f f f f f f f f f f + +#step 72 +#outs 23 24 24 23 24 24 24 t f f f f f t f f f t f f f t f f f f f t f f f t f f f + +#step 73 +#outs 24 24 24 24 24 25 24 t f t f t f t f t f f f t f t f t f t f f f t f f f f f + +#step 74 +#outs 25 25 25 24 25 25 24 f f t f f f t f f f f f t f f f t f f f f f f f f f f f + +#step 75 +#outs 25 26 25 24 25 25 24 f f f f f f t f f f f f t f f f f f f f t f f f f f t f + +#step 76 +#outs 25 26 25 25 25 25 25 t f f f t f t f t f t f t f t f f f f f t f f f t f f f + +#step 77 +#outs 26 26 25 26 25 26 25 f f f f t f f f t f f f t f f f f f t f f f t f f f t f + +#step 78 +#outs 26 26 26 26 26 26 26 t f t f t f t f t f t f t f t f f f t f t f t f f f f f + +#step 79 +#outs 27 26 27 27 27 26 26 f f t f f f t f f f t f t f f f t f f f f f f f t f f f + +#step 80 +#outs 27 27 27 27 27 27 26 f f t f t f t f t f f f t f f f t f t f t f t f f f t f + +#step 81 +#outs 27 28 28 28 28 27 27 t f f f t f t f f f t f t f t f f f t f f f f f t f f f + +#step 82 +#outs 28 28 29 28 28 28 27 f f t f f f t f t f f f t f f f t f f f t f f f f f t f + +#step 83 +#outs 28 29 29 29 28 28 28 t f f f t f f f t f t f t f f f f f f f f f f f t f f f + +#step 84 +#outs 28 29 29 29 28 29 28 t f f f t f f f t f f f t f f f f f t f f f t f f f t f + +#step 85 +#outs 28 29 30 29 29 29 29 t f f f f f t f t f t f f f f f f f f f t f t f t f f f + +#step 86 +#outs 28 29 30 30 30 30 29 t f f f f f t f t f f f f f t f f f f f f f t f f f f f + +#step 87 +#outs 29 29 30 30 31 30 29 t f t f f f t f f f f f t f t f t f f f t f f f f f f f + +#step 88 +#outs 30 30 30 31 31 30 29 f f t f t f f f f f f f t f f f t f t f f f f f f f t f + +#step 89 +#outs 30 31 31 31 31 30 30 t f f f t f t f f f t f t f f f f f t f t f f f t f t f + +#step 90 +#outs 30 31 32 32 31 31 31 t f f f f f f f t f t f f f t f f f f f f f t f f f f f + +#step 91 +#outs 31 31 32 32 32 31 31 t f t f f f t f f f t f t f f f t f f f f f f f t f t f + +#step 92 +#outs 31 32 32 32 32 32 32 t f f f t f t f t f t f f f f f f f t f f f f f f f f f + +#step 93 +#outs 31 32 33 32 32 32 32 t f f f f f t f t f t f f f t f f f f f t f t f f f f f + +#step 94 +#outs 32 32 33 33 33 32 32 t f t f f f t f f f t f t f t f t f f f t f f f t f t f + +#step 95 +#outs 33 33 33 34 33 33 33 t f t f t f f f t f t f t f t f f f t f f f f f t f f f + +#step 96 +#outs 34 33 34 34 33 34 33 f f t f f f f f t f f f t f f f t f f f f f t f f f f f + +#step 97 +#outs 34 34 34 34 34 34 33 f f t f t f t f t f f f t f f f f f f f f f f f f f t f + +#step 98 +#outs 34 34 34 34 34 34 34 t f t f t f t f t f t f t f t f t f t f f f t f t f t f + +#step 99 +#outs 35 35 35 34 35 35 35 t f t f f f t f f f t f t f f f t f f f f f f f t f t f + +#step 100 +#outs 35 36 35 34 35 36 36 t f f f f f t f f f f f f f t f f f f f f f f f f f f f + +#step 101 +#outs 36 36 35 34 35 36 36 t f f f f f t f f f f f t f t f f f f f f f f f f f t f + +#step 102 +#outs 37 36 35 34 35 36 37 f f f f f f t f f f f f f f f f f f f f t f f f f f f f + +#step 103 +#outs 37 36 35 35 35 36 37 f f f f t f t f t f f f f f f f f f t f t f t f f f f f + +#step 104 +#outs 37 36 36 36 36 36 37 f f t f t f t f t f t f f f f f f f f f t f f f f f f f + +#step 105 +#outs 37 36 36 37 36 36 37 f f t f t f f f t f t f f f f f t f t f f f f f f f f f + +#step 106 +#outs 37 37 37 37 36 36 37 t f t f t f f f t f t f f f t f f f f f f f f f f f f f + +#step 107 +#outs 38 37 37 37 36 36 37 f f t f t f f f t f t f f f f f f f f f f f t f t f f f + +#step 108 +#outs 38 37 37 37 37 37 37 f f t f t f t f t f t f t f f f t f f f t f f f t f t f + +#step 109 +#outs 38 38 37 38 37 38 38 t f f f t f f f t f f f t f f f f f f f f f t f f f f f + +#step 110 +#outs 38 38 37 38 38 38 38 t f f f t f f f t f t f t f f f f f f f f f f f t f t f + +#step 111 +#outs 38 38 37 38 38 39 39 t f f f t f f f t f f f f f t f f f t f f f f f f f f f + +#step 112 +#outs 39 38 38 38 38 39 39 f f t f t f t f t f f f t f f f f f t f t f f f f f f f + +#step 113 +#outs 39 38 39 39 38 39 39 f f t f f f f f t f f f t f f f t f f f f f t f f f t f + +#step 114 +#outs 39 39 39 39 39 39 40 t f t f t f t f t f t f f f t f f f t f t f f f t f f f + +#step 115 +#outs 40 39 40 40 39 40 40 f f t f f f f f t f f f t f f f t f f f f f f f f f f f + +#step 116 +#outs 40 40 40 40 39 40 40 t f t f t f f f t f f f t f f f t f t f f f t f f f t f + +#step 117 +#outs 40 41 41 40 40 40 41 t f f f f f t f t f t f f f f f f f f f t f f f t f f f + +#step 118 +#outs 40 41 41 41 40 41 41 t f f f t f f f t f f f f f f f f f f f f f t f f f f f + +#step 119 +#outs 40 41 41 41 41 41 41 t f f f t f t f t f t f f f f f f f t f t f t f f f f f + +#step 120 +#outs 40 41 42 42 42 41 41 t f f f f f t f f f t f f f t f f f f f f f f f t f f f + +#step 121 +#outs 41 41 42 42 42 42 41 t f t f f f t f t f f f t f f f f f f f t f t f f f t f + +#step 122 +#outs 41 41 42 43 43 42 42 t f t f f f f f f f t f f f f f f f f f f f f f t f f f + +#step 123 +#outs 41 41 42 43 43 43 42 t f t f f f f f t f f f f f f f t f f f f f t f f f f f + +#step 124 +#outs 41 42 42 43 44 43 42 t f f f t f f f f f f f f f f f f f t f f f f f f f f f + +#step 125 +#outs 41 42 43 43 44 43 42 t f f f f f t f f f f f f f f f f f f f t f f f f f f f + +#step 126 +#outs 41 42 43 44 44 43 42 t f f f f f f f f f f f f f t f f f f f f f f f f f f f + +#step 127 +#outs 42 42 43 44 44 43 42 t f t f f f f f f f f f t f f f t f f f f f f f f f t f + +#step 128 +#outs 42 43 43 44 44 43 43 t f f f t f f f f f t f f f t f f f t f f f f f t f f f + +#step 129 +#outs 43 43 44 44 44 44 43 t f t f f f t f t f f f t f t f t f f f t f t f f f t f + +#step 130 +#outs 44 44 44 45 45 44 44 t f t f t f f f f f t f t f t f f f f f f f f f t f t f + +#step 131 +#outs 45 44 44 45 45 45 45 f f t f t f f f t f t f t f f f t f f f f f t f t f f f + +#step 132 +#outs 45 45 44 45 46 46 45 t f f f t f f f f f f f t f t f f f t f f f f f f f f f + +#step 133 +#outs 46 45 45 45 46 46 45 f f t f t f t f f f f f t f f f t f f f f f f f f f f f + +#step 134 +#outs 46 46 45 45 46 46 45 f f f f t f t f f f f f t f f f f f f f f f f f f f t f + +#step 135 +#outs 46 46 45 45 46 46 46 t f f f t f t f f f t f t f f f f f f f f f f f f f t f + +#step 136 +#outs 46 46 45 45 46 46 47 t f f f t f t f f f t f f f f f f f t f t f f f t f f f + +#step 137 +#outs 46 46 46 46 46 47 47 t f t f t f t f t f f f f f t f f f f f t f t f f f f f + +#step 138 +#outs 47 46 46 47 47 47 47 f f t f t f f f t f t f t f f f t f t f f f f f t f f f + +#step 139 +#outs 47 47 47 47 47 48 47 t f t f t f t f t f f f t f t f f f f f f f t f f f f f + +#step 140 +#outs 48 47 47 47 48 48 47 f f t f t f t f f f f f t f f f f f t f t f f f f f f f + +#step 141 +#outs 48 47 48 48 48 48 47 f f t f f f t f t f f f t f f f t f f f f f t f f f f f + +#step 142 +#outs 48 48 48 48 49 48 47 f f t f t f t f f f f f t f f f t f t f t f f f f f f f + +#step 143 +#outs 48 49 49 49 49 48 47 f f f f t f t f f f f f t f f f f f f f t f f f f f f f + +#step 144 +#outs 48 49 49 0 49 48 47 f f f f t f f f f f f f t f f f f f f f f f f f f f t f + +#step 145 +#outs 48 49 49 0 49 48 48 t f f f t f f f f f t f t f f f f f t f f f f f f f t f + +#step 146 +#outs 48 49 0 0 49 48 49 t f f f f f f f f f t f f f f f f f f f f f f f t f f f + +#step 147 +#outs 48 49 0 0 49 49 49 t f f f f f f f t f t f f f f f f f f f f f t f f f f f + +#step 148 +#outs 48 49 0 0 0 49 49 t f f f f f t f f f t f f f t f f f f f t f f f t f f f + +#step 149 +#outs 49 49 0 1 0 0 49 t f t f f f f f t f f f t f t f t f f f f f f f f f f f + +#step 150 +#outs 0 0 0 1 0 0 49 f f t f t f f f t f f f t f f f t f t f f f t f f f f f + +#step 151 +#outs 0 1 1 1 1 0 49 f f f f t f t f f f f f t f f f f f f f t f f f f f t f + +#step 152 +#outs 0 1 1 2 1 0 0 t f f f t f f f f f t f t f t f f f f f f f f f f f t f + +#step 153 +#outs 1 1 1 2 1 0 1 t f t f t f f f f f t f f f t f t f t f f f f f f f f f + +#step 154 +#outs 2 2 2 2 1 0 1 f f t f t f f f f f t f f f f f t f t f f f f f t f f f + +#step 155 +#outs 2 3 3 2 1 1 1 f f f f f f f f t f t f t f f f f f f f f f f f f f t f + +#step 156 +#outs 2 3 3 2 1 1 2 t f f f f f f f t f t f f f t f f f f f f f t f t f f f + +#step 157 +#outs 3 3 3 2 2 2 2 f f t f f f t f t f t f t f f f t f f f t f t f f f f f + +#step 158 +#outs 3 4 3 3 3 2 2 f f f f t f t f f f t f t f f f f f f f f f f f t f t f + +#step 159 +#outs 3 4 3 3 3 3 3 t f f f t f t f t f t f t f f f f f f f f f t f f f f f + +#step 160 +#outs 3 4 3 3 4 3 3 t f f f t f t f f f t f t f t f f f f f f f f f t f f f + +#step 161 +#outs 4 4 3 3 4 4 3 f f f f t f t f f f f f t f f f f f t f t f f f f f t f + +#step 162 +#outs 4 4 4 4 4 4 4 t f t f t f t f t f t f t f t f t f f f t f t f t f t f + +#step 163 +#outs 5 5 4 5 5 5 5 t f f f t f f f t f t f t f f f f f t f f f f f t f f f + +#step 164 +#outs 5 5 5 5 5 6 5 t f t f t f t f t f f f t f f f f f t f f f f f f f f f + +#step 165 +#outs 5 5 6 5 5 6 5 t f t f f f t f t f f f t f f f f f f f f f t f f f f f + +#step 166 +#outs 5 5 6 5 6 6 5 t f t f f f t f f f f f t f t f t f f f t f f f f f f f + +#step 167 +#outs 6 6 6 6 6 6 5 f f t f t f t f t f f f t f f f t f t f t f f f f f t f + +#step 168 +#outs 6 7 7 7 6 6 6 t f f f t f f f t f t f t f f f f f f f f f t f f f f f + +#step 169 +#outs 6 7 7 7 7 6 6 t f f f t f t f f f t f t f t f f f t f t f f f f f f f + +#step 170 +#outs 7 7 8 8 7 6 6 f f t f f f f f f f t f t f f f t f f f f f f f f f t f + +#step 171 +#outs 7 8 8 8 7 6 7 t f f f t f f f f f t f f f t f f f t f f f f f t f f f + +#step 172 +#outs 8 8 9 8 7 7 7 f f t f f f f f t f t f t f f f t f f f f f f f t f f f + +#step 173 +#outs 8 9 9 8 7 8 7 f f f f f f f f t f f f t f f f f f f f f f t f f f t f + +#step 174 +#outs 8 9 9 8 8 8 8 t f f f f f t f t f t f t f t f f f f f t f t f f f t f + +#step 175 +#outs 9 9 9 9 9 8 9 t f t f t f t f f f t f f f t f t f f f f f f f t f f f + +#step 176 +#outs 10 10 9 9 9 9 9 f f f f t f t f t f t f t f f f f f f f f f t f t f t f + +#step 177 +#outs 10 10 9 9 10 10 10 t f f f t f t f f f t f t f t f f f f f t f f f t f t f + +#step 178 +#outs 11 10 9 10 10 11 11 f f f f t f f f t f f f t f f f f f f f f f t f f f f f + +#step 179 +#outs 11 10 9 10 11 11 11 f f f f t f f f f f t f t f f f f f f f f f f f t f t f + +#step 180 +#outs 11 10 9 10 11 12 12 f f f f t f f f f f f f f f f f f f t f f f f f f f f f + +#step 181 +#outs 11 10 10 10 11 12 12 f f t f t f t f f f f f f f f f f f t f t f f f f f f f + +#step 182 +#outs 11 10 11 11 11 12 12 f f t f f f t f t f f f f f f f t f f f t f t f f f f f + +#step 183 +#outs 11 11 11 12 12 12 12 t f t f t f f f t f t f f f f f f f t f f f f f f f f f + +#step 184 +#outs 11 11 12 12 12 12 12 t f t f f f t f t f t f f f t f t f f f f f t f t f f f + +#step 185 +#outs 12 12 12 12 13 13 12 t f t f t f t f f f f f t f t f t f t f f f f f f f f f + +#step 186 +#outs 13 13 13 12 13 13 12 f f t f f f t f f f f f t f f f t f f f f f f f f f f f + +#step 187 +#outs 13 14 13 12 13 13 12 f f f f f f t f f f f f t f f f f f f f f f f f f f t f + +#step 188 +#outs 13 14 13 12 13 13 13 t f f f f f t f f f t f t f t f f f f f f f f f f f f f + +#step 189 +#outs 14 14 13 12 13 13 13 f f f f f f t f f f t f t f f f f f f f t f f f f f t f + +#step 190 +#outs 14 14 13 13 13 13 14 t f f f t f t f t f t f f f t f f f t f t f f f t f f f + +#step 191 +#outs 15 14 14 14 13 14 14 f f t f t f f f t f f f t f f f f f t f f f t f f f t f + +#step 192 +#outs 15 14 15 14 14 14 15 f f t f f f t f t f t f f f f f f f f f t f t f f f f f + +#step 193 +#outs 15 14 15 15 15 14 15 f f t f f f t f f f t f f f f f t f f f f f f f f f f f + +#step 194 +#outs 15 15 15 15 15 14 15 t f t f t f t f f f t f f f f f f f t f t f f f t f f f + +#step 195 +#outs 15 15 16 16 15 15 15 t f t f f f f f t f t f t f f f t f f f f f f f f f f f + +#step 196 +#outs 15 16 16 16 15 15 15 t f f f t f f f t f t f t f t f f f t f f f t f t f t f + +#step 197 +#outs 16 16 17 16 16 16 16 t f t f f f t f t f t f t f f f f f f f t f f f f f f f + +#step 198 +#outs 16 16 17 17 16 16 16 t f t f f f f f t f t f t f t f t f f f f f f f f f f f + +#step 199 +#outs 17 17 17 17 16 16 16 f f t f t f f f t f t f t f f f t f t f f f t f f f f f + +#step 200 +#outs 17 18 18 17 17 16 16 f f f f f f t f f f t f t f f f f f f f f f f f t f t f + +#step 201 +#outs 17 18 18 17 17 17 17 t f f f f f t f t f t f t f t f f f f f t f t f t f t f + +#step 202 +#outs 18 18 18 18 18 18 18 t f t f t f t f t f t f t f t f f f f f f f f f f f t f + +#step 203 +#outs 19 18 18 18 18 18 19 f f t f t f t f t f t f f f f f t f t f t f t f t f f f + +#step 204 +#outs 19 19 19 19 19 19 19 t f t f t f t f t f t f t f t f f f t f f f t f t f f f + +#step 205 +#outs 20 19 20 19 20 20 19 f f t f f f t f f f f f t f f f f f f f f f f f f f t f + +#step 206 +#outs 20 19 20 19 20 20 20 f f t f f f t f f f t f t f f f f f f f t f f f f f t f + +#step 207 +#outs 20 19 20 20 20 20 21 f f t f f f t f t f t f f f f f t f f f f f t f f f f f + +#step 208 +#outs 20 20 20 20 21 20 21 t f t f t f t f f f t f f f f f t f t f t f f f f f f f + +#step 209 +#outs 20 21 21 21 21 20 21 t f f f t f t f f f t f f f t f f f t f t f f f t f f f + +#step 210 +#outs 21 21 22 22 21 21 21 t f t f f f f f t f t f t f t f t f f f f f f f t f f f + +#step 211 +#outs 22 22 22 22 21 22 21 f f t f t f f f t f f f t f f f t f t f f f f f f f t f + +#step 212 +#outs 22 23 23 22 21 22 22 t f f f f f f f t f f f t f t f f f f f f f f f f f t f + +#step 213 +#outs 23 23 23 22 21 22 23 t f t f f f f f t f f f f f t f t f f f f f t f f f f f + +#step 214 +#outs 24 24 23 22 22 22 23 f f f f f f t f t f t f f f f f f f f f t f t f t f f f + +#step 215 +#outs 24 24 23 23 23 23 23 f f f f t f t f t f t f t f f f f f t f t f t f f f f f + +#step 216 +#outs 24 24 24 24 24 23 23 f f t f t f t f f f t f t f f f f f t f f f f f f f f f + +#step 217 +#outs 24 24 25 24 24 23 23 f f t f f f t f f f t f t f f f t f f f t f f f t f f f + +#step 218 +#outs 24 25 25 25 24 24 23 f f f f t f f f t f f f t f f f f f f f f f t f f f f f + +#step 219 +#outs 24 25 25 25 25 24 23 f f f f t f t f f f f f t f f f f f f f t f f f f f t f + +#step 220 +#outs 24 25 25 26 25 24 24 t f f f t f f f f f t f t f t f f f f f f f f f f f f f + +#step 221 +#outs 25 25 25 26 25 24 24 f f t f t f f f f f t f t f f f t f f f f f f f f f t f + +#step 222 +#outs 25 26 25 26 25 24 25 t f f f t f f f f f t f f f f f f f t f f f f f t f f f + +#step 223 +#outs 25 26 26 26 25 25 25 t f f f t f f f t f t f t f t f f f t f f f t f f f t f + +#step 224 +#outs 26 26 27 26 26 25 26 t f t f f f t f f f t f f f f f t f f f t f f f f f f f + +#step 225 +#outs 26 27 27 27 26 25 26 t f f f t f f f f f t f f f t f f f f f f f f f f f f f + +#step 226 +#outs 27 27 27 27 26 25 26 f f t f t f f f f f t f f f f f f f f f f f f f t f f f + +#step 227 +#outs 27 27 27 27 26 26 26 f f t f t f f f t f t f t f f f t f f f f f f f f f f f + +#step 228 +#outs 27 28 27 27 26 26 26 f f f f t f f f t f t f t f f f f f t f f f t f f f f f + +#step 229 +#outs 27 28 28 27 27 26 26 f f f f f f t f f f t f t f f f f f f f t f f f t f f f + +#step 230 +#outs 27 28 28 28 27 27 26 f f f f t f f f t f f f t f f f f f f f f f t f f f t f + +#step 231 +#outs 27 28 28 28 28 27 27 t f f f t f t f f f t f t f f f f f t f t f f f f f t f + +#step 232 +#outs 27 28 29 29 28 27 28 t f f f f f f f f f t f f f t f f f f f f f f f f f f f + +#step 233 +#outs 28 28 29 29 28 27 28 t f t f f f f f f f t f f f t f f f f f f f f f t f f f + +#step 234 +#outs 29 28 29 29 28 28 28 f f t f f f f f t f t f t f f f t f f f f f f f t f f f + +#step 235 +#outs 29 29 29 29 28 29 28 f f t f t f f f t f f f t f f f f f f f f f t f f f f f + +#step 236 +#outs 29 29 29 29 29 29 28 f f t f t f t f t f f f t f f f t f t f t f t f f f f f + +#step 237 +#outs 29 30 30 30 30 29 28 f f f f t f t f f f f f t f f f f f t f f f f f f f f f + +#step 238 +#outs 29 30 31 30 30 29 28 f f f f f f t f f f f f t f f f f f f f f f f f f f t f + +#step 239 +#outs 29 30 31 30 30 29 29 t f f f f f t f f f t f t f f f f f f f t f f f t f f f + +#step 240 +#outs 29 30 31 31 30 30 29 t f f f f f f f t f f f t f t f f f f f f f t f f f t f + +#step 241 +#outs 30 30 31 31 31 30 30 t f t f f f t f f f t f t f t f f f f f f f f f t f t f + +#step 242 +#outs 31 30 31 31 31 31 31 f f t f f f t f t f t f t f f f t f f f t f f f f f f f + +#step 243 +#outs 31 31 31 32 31 31 31 t f t f t f f f t f t f t f f f f f t f f f t f f f f f + +#step 244 +#outs 31 31 32 32 32 31 31 t f t f f f t f f f t f t f t f f f f f f f f f t f f f + +#step 245 +#outs 32 31 32 32 32 32 31 f f t f f f t f t f f f t f f f t f f f f f f f f f t f + +#step 246 +#outs 32 32 32 32 32 32 32 t f t f t f t f t f t f t f f f f f t f f f f f t f f f + +#step 247 +#outs 32 32 33 32 32 33 32 t f t f f f t f t f f f t f t f f f f f t f t f f f t f + +#step 248 +#outs 33 32 33 33 33 33 33 f f t f f f t f t f t f t f f f f f f f f f t f f f f f + +#step 249 +#outs 33 32 33 33 34 33 33 f f t f f f t f f f t f t f f f t f f f t f f f f f f f + +#step 250 +#outs 33 33 33 34 34 33 33 t f t f t f f f f f t f t f t f t f t f f f f f f f f f + +#step 251 +#outs 34 34 34 34 34 33 33 f f t f t f t f f f t f t f f f t f t f f f f f f f t f + +#step 252 +#outs 34 35 35 34 34 33 34 t f f f f f t f f f t f f f f f f f f f t f f f t f f f + +#step 253 +#outs 34 35 35 35 34 34 34 t f f f t f f f t f t f t f t f f f t f f f t f f f t f + +#step 254 +#outs 35 35 36 35 35 34 35 t f t f f f t f f f t f f f f f f f f f t f f f t f f f + +#step 255 +#outs 35 35 36 36 35 35 35 t f t f f f f f t f t f t f f f t f f f f f f f f f t f + +#step 256 +#outs 35 36 36 36 35 35 36 t f f f t f f f t f t f f f f f f f t f f f t f t f f f + +#step 257 +#outs 35 36 37 36 36 36 36 t f f f f f t f t f t f f f t f f f f f f f t f f f f f + +#step 258 +#outs 36 36 37 36 37 36 36 t f t f f f t f f f t f t f t f f f f f t f f f t f f f + +#step 259 +#outs 37 36 37 37 37 37 36 f f t f f f t f t f f f t f f f f f f f f f t f f f f f + +#step 260 +#outs 37 36 37 37 38 37 36 f f t f f f t f f f f f t f f f t f f f t f f f f f t f + +#step 261 +#outs 37 37 37 38 38 37 37 t f t f t f f f f f t f t f f f t f t f f f f f f f f f + +#step 262 +#outs 37 38 38 38 38 37 37 t f f f t f t f f f t f t f t f f f t f t f f f t f f f + +#step 263 +#outs 38 38 39 39 38 38 37 f f t f f f f f t f f f t f f f f f f f f f t f f f f f + +#step 264 +#outs 38 38 39 39 39 38 37 f f t f f f t f f f f f t f f f t f f f t f f f f f f f + +#step 265 +#outs 38 39 39 40 39 38 37 f f f f t f f f f f f f t f f f f f t f f f f f f f f f + +#step 266 +#outs 38 39 40 40 39 38 37 f f f f f f f f f f f f t f f f f f f f f f f f f f t f + +#step 267 +#outs 38 39 40 40 39 38 38 t f f f f f f f f f t f t f t f f f f f f f f f f f f f + +#step 268 +#outs 39 39 40 40 39 38 38 f f t f f f f f f f t f t f f f t f f f f f f f t f f f + +#step 269 +#outs 39 40 40 40 39 39 38 f f f f t f f f t f f f t f f f f f t f f f f f f f t f + +#step 270 +#outs 39 40 41 40 39 39 39 t f f f f f f f t f t f t f t f f f f f f f f f t f t f + +#step 271 +#outs 40 40 41 40 39 40 40 t f t f f f f f t f f f t f f f t f f f f f f f f f f f + +#step 272 +#outs 40 41 41 40 39 40 40 t f f f f f f f t f f f t f t f f f f f f f t f f f f f + +#step 273 +#outs 41 41 41 40 40 40 40 f f t f f f t f t f t f t f f f f f f f t f f f t f f f + +#step 274 +#outs 41 41 41 41 40 41 40 f f t f t f f f t f f f t f f f f f f f f f t f f f f f + +#step 275 +#outs 41 41 41 41 41 41 40 f f t f t f t f t f f f t f f f t f t f t f f f f f t f + +#step 276 +#outs 41 42 42 42 41 41 41 t f f f t f f f t f t f t f t f f f f f f f t f t f f f + +#step 277 +#outs 42 42 42 42 42 42 41 f f t f t f t f t f f f t f f f t f f f f f t f f f f f + +#step 278 +#outs 42 43 42 42 43 42 41 f f f f t f t f f f f f t f f f f f t f t f f f f f t f + +#step 279 +#outs 42 43 43 43 43 42 42 t f f f t f t f f f t f t f f f f f f f t f f f f f t f + +#step 280 +#outs 42 43 43 44 43 42 43 t f f f t f f f f f t f f f t f f f t f f f f f t f f f + +#step 281 +#outs 43 43 44 44 43 43 43 t f t f f f f f t f t f t f t f f f f f f f f f t f f f + +#step 282 +#outs 44 43 44 44 43 44 43 f f t f f f f f t f f f t f f f t f f f f f f f f f t f + +#step 283 +#outs 44 44 44 44 43 44 44 t f t f t f f f t f f f t f f f f f f f f f f f f f t f + +#step 284 +#outs 44 44 44 44 43 44 45 t f t f t f f f t f f f f f f f t f f f f f t f f f f f + +#step 285 +#outs 44 45 44 44 44 44 45 t f f f t f t f t f t f f f t f f f f f t f t f t f f f + +#step 286 +#outs 45 45 44 45 45 45 45 t f f f t f f f t f t f t f t f f f t f f f t f t f t f + +#step 287 +#outs 46 45 45 45 46 46 46 f f t f t f t f f f t f t f f f t f f f t f f f t f f f + +#step 288 +#outs 46 46 45 46 46 47 46 t f f f t f f f t f f f t f t f f f f f f f t f f f t f + +#step 289 +#outs 47 46 45 46 47 47 47 f f f f t f f f f f t f t f f f f f t f f f f f t f f f + +#step 290 +#outs 47 46 46 46 47 48 47 f f t f t f t f f f f f t f f f t f f f f f f f f f f f + +#step 291 +#outs 47 47 46 46 47 48 47 t f f f t f t f f f f f t f f f f f t f f f f f f f f f + +#step 292 +#outs 47 47 47 46 47 48 47 t f t f f f t f f f f f t f t f f f f f f f f f f f t f + +#step 293 +#outs 48 47 47 46 47 48 48 f f t f f f t f f f f f t f f f f f f f t f f f f f t f + +#step 294 +#outs 48 47 47 47 47 48 49 f f t f t f t f t f f f f f f f f f t f f f f f f f f f + +#step 295 +#outs 48 47 48 47 47 48 49 f f t f f f t f t f f f f f f f t f f f f f f f f f f f + +#step 296 +#outs 48 48 48 47 47 48 49 t f t f f f t f t f f f f f t f f f f f f f f f f f f f + +#step 297 +#outs 49 48 48 47 47 48 49 f f t f f f t f t f f f f f f f t f f f t f t f f f f f + +#step 298 +#outs 49 49 48 48 48 48 49 t f f f t f t f t f t f f f t f f f t f f f t f f f f f + +#step 299 +#outs 0 49 49 48 49 48 49 f f t f f f t f f f t f f f f f t f f f f f f f f f f f + +#step 300 +#outs 0 0 49 48 49 48 49 f f f f f f t f f f t f f f f f f f f f t f f f t f f f + +#step 301 +#outs 0 0 49 49 49 49 49 f f f f t f t f t f t f t f f f f f f f f f t f f f f f + +#step 302 +#outs 0 0 49 49 0 49 49 f f f f t f t f f f t f t f f f f f t f f f f f t f f f + +#step 303 +#outs 0 0 0 49 0 0 49 f f t f f f t f f f f f t f f f f f f f t f f f f f f f + +#step 304 +#outs 0 0 0 0 0 0 49 f f t f t f t f t f f f t f f f t f t f t f f f f f f f + +#step 305 +#outs 0 1 1 1 0 0 49 f f f f t f f f t f f f t f f f f f t f f f f f f f t f + +#step 306 +#outs 0 1 2 1 0 0 0 t f f f f f f f t f t f t f f f f f f f f f f f t f t f + +#step 307 +#outs 0 1 2 1 0 1 1 t f f f f f f f t f f f f f t f f f f f f f f f f f f f + +#step 308 +#outs 1 1 2 1 0 1 1 t f t f f f f f t f f f t f t f f f f f f f f f f f f f + +#step 309 +#outs 2 1 2 1 0 1 1 f f t f f f f f t f f f t f f f f f f f f f t f f f t f + +#step 310 +#outs 2 1 2 1 1 1 2 f f t f f f t f t f t f f f f f f f f f f f t f t f f f + +#step 311 +#outs 2 1 2 1 2 2 2 f f t f f f t f f f t f t f f f t f f f f f f f t f t f + +#step 312 +#outs 2 2 2 1 2 3 3 t f t f f f t f f f f f f f f f f f f f t f f f f f f f + +#step 313 +#outs 2 2 2 2 2 3 3 t f t f t f t f t f f f f f t f f f t f t f t f f f f f + +#step 314 +#outs 3 2 3 3 3 3 3 f f t f f f t f t f t f t f f f t f f f t f t f t f f f + +#step 315 +#outs 3 3 3 4 4 4 3 t f t f t f f f t f f f t f f f t f f f f f f f f f t f + +#step 316 +#outs 3 4 3 4 4 4 4 t f f f t f f f t f t f f f f f f f t f f f t f t f f f + +#step 317 +#outs 3 4 4 4 5 5 4 t f f f t f t f f f f f f f t f f f t f f f f f f f f f + +#step 318 +#outs 4 4 5 4 5 5 4 t f t f f f t f f f f f t f t f f f f f t f f f f f t f + +#step 319 +#outs 5 4 5 5 5 5 5 f f t f f f t f t f t f t f f f t f f f f f t f t f t f + +#step 320 +#outs 5 5 5 5 6 6 6 t f t f t f t f f f t f f f f f f f f f t f f f t f f f + +#step 321 +#outs 5 5 5 6 6 7 6 t f t f t f f f t f f f f f t f t f t f f f f f f f f f + +#step 322 +#outs 6 6 6 6 6 7 6 t f t f t f t f t f f f t f t f f f t f t f f f f f f f + +#step 323 +#outs 7 6 7 7 6 7 6 f f t f f f f f t f f f t f f f t f f f f f f f f f t f + +#step 324 +#outs 7 7 7 7 6 7 7 t f t f t f f f t f f f t f t f f f f f f f f f f f f f + +#step 325 +#outs 8 7 7 7 6 7 7 f f t f t f f f t f f f t f f f t f t f f f f f f f f f + +#step 326 +#outs 8 8 8 7 6 7 7 f f t f f f f f t f f f t f f f t f f f f f t f f f t f + +#step 327 +#outs 8 9 8 7 7 7 8 t f f f f f t f t f t f f f f f f f f f t f t f f f f f + +#step 328 +#outs 8 9 8 8 8 7 8 t f f f t f t f f f t f f f f f f f f f f f f f t f f f + +#step 329 +#outs 8 9 8 8 8 8 8 t f f f t f t f t f t f t f t f f f t f f f t f t f f f + +#step 330 +#outs 9 9 9 8 9 9 8 f f t f f f t f f f f f t f f f t f f f t f f f f f f f + +#step 331 +#outs 9 10 9 9 9 9 8 f f f f t f t f t f f f t f f f f f f f t f t f f f t f + +#step 332 +#outs 9 10 9 10 10 9 9 t f f f t f f f f f t f t f t f f f f f f f f f f f t f + +#step 333 +#outs 10 10 9 10 10 9 10 t f f f t f f f f f t f f f t f f f f f f f f f f f f f + +#step 334 +#outs 11 10 9 10 10 9 10 f f f f t f f f f f t f f f f f f f t f f f f f f f f f + +#step 335 +#outs 11 10 10 10 10 9 10 f f t f t f t f f f t f f f f f t f t f t f f f t f f f + +#step 336 +#outs 11 11 11 11 10 10 10 f f t f t f f f t f t f t f f f t f f f f f t f f f f f + +#step 337 +#outs 11 12 11 11 11 10 10 f f f f t f t f f f t f t f f f f f t f t f f f f f t f + +#step 338 +#outs 11 12 12 12 11 10 11 t f f f t f f f f f t f f f t f f f f f f f f f t f f f + +#step 339 +#outs 12 12 12 12 11 11 11 f f t f t f f f t f t f t f f f f f t f f f t f t f f f + +#step 340 +#outs 12 12 13 12 12 12 11 f f t f f f t f t f f f t f f f f f f f f f t f f f t f + +#step 341 +#outs 12 12 13 12 13 12 12 t f t f f f t f f f t f t f t f f f f f f f f f t f f f + +#step 342 +#outs 13 12 13 12 13 13 12 f f t f f f t f f f f f t f f f f f f f t f f f f f t f + +#step 343 +#outs 13 12 13 13 13 13 13 f f t f f f t f t f t f t f f f t f f f f f t f t f t f + +#step 344 +#outs 13 13 13 13 14 14 14 t f t f t f t f f f t f f f f f t f t f f f f f t f f f + +#step 345 +#outs 13 14 14 13 14 15 14 t f f f f f t f f f f f f f t f f f f f t f f f f f f f + +#step 346 +#outs 14 14 14 14 14 15 14 t f t f t f t f t f f f t f f f t f t f f f t f f f f f + +#step 347 +#outs 14 15 15 14 15 15 14 t f f f f f t f f f f f t f t f f f f f t f f f f f t f + +#step 348 +#outs 15 15 15 15 15 15 15 t f t f t f t f t f t f t f f f t f f f f f f f t f t f + +#step 349 +#outs 15 16 15 15 15 16 16 t f f f t f t f t f f f f f t f f f t f t f t f f f f f + +#step 350 +#outs 16 16 16 16 16 16 16 t f t f t f t f t f t f t f f f t f f f f f f f f f f f + +#step 351 +#outs 16 17 16 16 16 16 16 t f f f t f t f t f t f t f t f f f t f t f t f f f f f + +#step 352 +#outs 17 17 17 17 17 16 16 f f t f t f t f f f t f t f f f t f f f f f f f f f f f + +#step 353 +#outs 17 18 17 17 17 16 16 f f f f t f t f f f t f t f f f f f t f f f f f t f f f + +#step 354 +#outs 17 18 18 17 17 17 16 f f f f f f t f t f f f t f f f f f f f f f t f f f f f + +#step 355 +#outs 17 18 18 17 18 17 16 f f f f f f t f f f f f t f f f f f f f f f f f f f t f + +#step 356 +#outs 17 18 18 17 18 17 17 t f f f f f t f f f t f t f f f f f f f t f f f f f t f + +#step 357 +#outs 17 18 18 18 18 17 18 t f f f t f t f f f t f f f t f f f t f t f f f t f f f + +#step 358 +#outs 18 18 19 19 18 18 18 t f t f f f f f t f t f t f t f f f f f f f f f t f t f + +#step 359 +#outs 19 18 19 19 18 19 19 f f t f f f f f t f f f t f f f t f f f f f t f f f t f + +#step 360 +#outs 19 19 19 19 19 19 20 t f t f t f t f t f t f f f f f t f f f f f f f t f f f + +#step 361 +#outs 19 20 19 19 19 20 20 t f f f t f t f t f f f f f t f f f t f f f t f f f f f + +#step 362 +#outs 20 20 20 19 20 20 20 t f t f f f t f f f t f t f f f f f f f f f f f t f f f + +#step 363 +#outs 20 20 20 19 20 21 20 t f t f f f t f f f f f t f t f t f f f f f f f f f t f + +#step 364 +#outs 21 21 20 19 20 21 21 t f f f f f t f f f f f t f f f f f f f f f f f f f t f + +#step 365 +#outs 21 21 20 19 20 21 22 t f f f f f t f f f f f f f f f f f f f t f f f f f f f + +#step 366 +#outs 21 21 20 20 20 21 22 t f f f t f t f t f f f f f t f f f t f f f f f f f f f + +#step 367 +#outs 22 21 21 20 20 21 22 f f t f f f t f t f f f f f f f t f f f f f t f f f f f + +#step 368 +#outs 22 22 21 20 21 21 22 t f f f f f t f f f t f f f t f f f f f t f f f t f f f + +#step 369 +#outs 23 22 21 21 21 22 22 f f f f t f t f t f f f t f f f f f f f f f t f f f f f + +#step 370 +#outs 23 22 21 21 22 22 22 f f f f t f t f f f t f t f f f f f f f t f f f t f t f + +#step 371 +#outs 23 22 21 22 22 23 23 f f f f t f f f t f f f t f f f f f f f f f t f f f t f + +#step 372 +#outs 23 22 21 22 23 23 24 f f f f t f f f f f t f f f f f f f t f f f f f f f f f + +#step 373 +#outs 23 22 22 22 23 23 24 f f t f t f t f f f t f f f f f f f f f t f f f f f f f + +#step 374 +#outs 23 22 22 23 23 23 24 f f t f t f f f t f t f f f f f f f t f f f f f t f f f + +#step 375 +#outs 23 22 23 23 23 24 24 f f t f f f t f t f f f f f f f t f f f f f f f f f f f + +#step 376 +#outs 23 23 23 23 23 24 24 t f t f t f t f t f f f f f t f f f f f f f t f f f f f + +#step 377 +#outs 24 23 23 23 24 24 24 f f t f t f t f f f t f t f f f t f f f t f f f t f t f + +#step 378 +#outs 24 24 23 24 24 25 25 t f f f t f f f t f f f f f t f f f f f f f f f f f f f + +#step 379 +#outs 25 24 23 24 24 25 25 f f f f t f f f t f f f t f f f f f f f f f f f f f t f + +#step 380 +#outs 25 24 23 24 24 25 26 f f f f t f f f t f f f f f f f f f t f f f f f f f f f + +#step 381 +#outs 25 24 24 24 24 25 26 f f t f t f t f t f f f f f f f t f f f t f f f f f f f + +#step 382 +#outs 25 25 24 25 24 25 26 t f f f t f f f t f f f f f t f f f t f f f f f f f f f + +#step 383 +#outs 26 25 25 25 24 25 26 f f t f t f f f t f f f f f f f f f t f f f f f f f f f + +#step 384 +#outs 26 25 26 25 24 25 26 f f t f f f f f t f f f f f f f f f f f f f t f f f f f + +#step 385 +#outs 26 25 26 25 25 25 26 f f t f f f t f t f t f f f f f t f f f f f t f f f f f + +#step 386 +#outs 26 26 26 25 26 25 26 t f t f f f t f f f t f f f f f t f f f t f f f f f f f + +#step 387 +#outs 26 27 26 26 26 25 26 t f f f t f t f f f t f f f t f f f f f t f f f t f f f + +#step 388 +#outs 27 27 26 27 26 26 26 f f f f t f f f t f t f t f f f f f t f f f f f f f f f + +#step 389 +#outs 27 27 27 27 26 26 26 f f t f t f f f t f t f t f f f t f f f f f t f t f t f + +#step 390 +#outs 27 28 27 27 27 27 27 t f f f t f t f t f t f t f f f f f f f f f f f t f f f + +#step 391 +#outs 27 28 27 27 27 28 27 t f f f t f t f t f f f t f t f f f f f t f t f f f t f + +#step 392 +#outs 28 28 27 28 28 28 28 t f f f t f f f t f t f t f f f f f t f f f t f f f f f + +#step 393 +#outs 28 28 28 28 29 28 28 t f t f t f t f f f t f t f t f f f f f t f f f f f t f + +#step 394 +#outs 29 28 28 29 29 28 29 f f t f t f f f f f t f f f f f t f t f f f f f f f f f + +#step 395 +#outs 29 29 29 29 29 28 29 t f t f t f t f f f t f f f t f t f t f f f f f f f f f + +#step 396 +#outs 30 30 30 29 29 28 29 f f t f f f t f f f t f f f f f f f f f t f f f f f f f + +#step 397 +#outs 30 30 30 30 29 28 29 f f t f t f f f f f t f f f f f t f t f f f f f t f f f + +#step 398 +#outs 30 31 31 30 29 29 29 f f f f f f f f t f t f t f f f f f f f f f t f t f t f + +#step 399 +#outs 30 31 31 30 30 30 30 t f f f f f t f t f t f t f f f f f f f f f t f f f t f + +#step 400 +#outs 30 31 31 30 31 30 31 t f f f f f t f f f t f f f t f f f f f t f f f f f f f + +#step 401 +#outs 31 31 31 31 31 30 31 t f t f t f t f f f t f f f f f t f t f t f f f f f f f + +#step 402 +#outs 31 32 32 32 31 30 31 t f f f t f f f f f t f f f f f f f t f f f f f t f f f + +#step 403 +#outs 31 32 33 32 31 31 31 t f f f f f f f t f t f t f f f f f f f f f t f f f t f + +#step 404 +#outs 31 32 33 32 32 31 32 t f f f f f t f f f t f f f f f f f f f f f f f t f f f + +#step 405 +#outs 31 32 33 32 32 32 32 t f f f f f t f t f t f f f t f f f f f t f f f t f f f + +#step 406 +#outs 32 32 33 33 32 33 32 t f t f f f f f t f f f t f t f f f f f f f f f f f f f + +#step 407 +#outs 33 32 33 33 32 33 32 f f t f f f f f t f f f t f f f f f f f f f t f f f t f + +#step 408 +#outs 33 32 33 33 33 33 33 f f t f f f t f t f t f t f f f t f f f t f t f f f t f + +#step 409 +#outs 33 33 33 34 34 33 34 t f t f t f f f f f t f f f f f t f t f f f f f f f f f + +#step 410 +#outs 33 34 34 34 34 33 34 t f f f t f t f f f t f f f t f f f f f t f f f f f f f + +#step 411 +#outs 34 34 34 35 34 33 34 t f t f t f f f f f t f f f t f f f t f f f f f f f f f + +#step 412 +#outs 35 34 35 35 34 33 34 f f t f f f f f f f t f f f f f f f f f f f f f t f f f + +#step 413 +#outs 35 34 35 35 34 34 34 f f t f f f f f t f t f t f f f t f f f f f t f t f t f + +#step 414 +#outs 35 35 35 35 35 35 35 t f t f t f t f t f t f t f f f t f t f f f t f t f t f + +#step 415 +#outs 35 36 36 35 36 36 36 t f f f f f t f f f t f f f f f f f f f t f f f t f f f + +#step 416 +#outs 35 36 36 36 36 37 36 t f f f t f t f t f f f f f t f f f t f t f t f f f f f + +#step 417 +#outs 36 36 37 37 37 37 36 t f t f f f t f t f f f t f t f f f f f t f t f f f f f + +#step 418 +#outs 37 36 37 38 38 37 36 f f t f f f f f f f f f t f f f f f f f f f f f f f t f + +#step 419 +#outs 37 36 37 38 38 37 37 f f t f f f f f f f t f t f f f f f f f f f f f f f t f + +#step 420 +#outs 37 36 37 38 38 37 38 f f t f f f f f f f t f f f f f t f f f f f f f t f f f + +#step 421 +#outs 37 37 37 38 38 38 38 t f t f t f f f t f t f f f f f f f t f f f f f t f f f + +#step 422 +#outs 37 37 38 38 38 39 38 t f t f f f t f t f f f f f f f t f f f t f t f f f f f + +#step 423 +#outs 37 38 38 39 39 39 38 t f f f t f f f t f f f f f t f f f f f f f t f f f f f + +#step 424 +#outs 38 38 38 39 40 39 38 t f t f t f f f f f f f t f f f t f f f f f f f f f t f + +#step 425 +#outs 38 39 38 39 40 39 39 t f f f t f f f f f t f f f t f f f t f f f f f f f f f + +#step 426 +#outs 39 39 39 39 40 39 39 t f t f t f t f f f t f t f f f t f t f f f f f f f f f + +#step 427 +#outs 39 40 40 39 40 39 39 t f f f f f t f f f t f t f t f f f f f t f f f f f t f + +#step 428 +#outs 40 40 40 40 40 39 40 t f t f t f t f f f t f f f f f t f f f t f f f t f f f + +#step 429 +#outs 40 41 40 41 40 40 40 t f f f t f f f t f t f t f t f f f f f f f f f t f f f + +#step 430 +#outs 41 41 40 41 40 41 40 f f f f t f f f t f f f t f f f f f f f f f t f f f t f + +#step 431 +#outs 41 41 40 41 41 41 41 t f f f t f f f t f t f t f t f f f f f f f f f t f f f + +#step 432 +#outs 42 41 40 41 41 42 41 f f f f t f f f t f f f t f f f f f t f f f t f f f t f + +#step 433 +#outs 42 41 41 41 42 42 42 f f t f t f t f f f t f t f f f f f f f t f f f f f t f + +#step 434 +#outs 42 41 41 42 42 42 43 f f t f t f f f t f t f f f f f t f f f f f f f t f f f + +#step 435 +#outs 42 42 41 42 42 43 43 t f f f t f f f t f f f f f t f f f t f f f t f f f f f + +#step 436 +#outs 43 42 42 42 43 43 43 f f t f t f t f f f t f t f f f t f t f t f f f f f t f + +#step 437 +#outs 43 43 43 43 43 43 44 t f t f t f t f t f t f f f f f t f f f f f t f t f f f + +#step 438 +#outs 43 44 43 43 44 44 44 t f f f t f t f f f t f f f f f f f t f t f f f f f f f + +#step 439 +#outs 43 44 44 44 44 44 44 t f f f t f t f t f t f f f f f f f t f t f t f t f f f + +#step 440 +#outs 43 44 45 45 45 45 44 t f f f f f t f t f f f f f f f f f f f t f t f f f f f + +#step 441 +#outs 43 44 45 46 46 45 44 t f f f f f f f f f f f f f t f f f f f f f f f f f f f + +#step 442 +#outs 44 44 45 46 46 45 44 t f t f f f f f f f f f t f f f t f f f f f f f f f t f + +#step 443 +#outs 44 45 45 46 46 45 45 t f f f t f f f f f t f f f t f f f f f f f f f t f f f + +#step 444 +#outs 45 45 45 46 46 46 45 t f t f t f f f t f f f t f f f f f f f f f f f f f t f + +#step 445 +#outs 45 45 45 46 46 46 46 t f t f t f f f t f t f f f f f f f t f f f t f f f f f + +#step 446 +#outs 45 45 46 46 47 46 46 t f t f f f t f f f t f f f t f f f f f t f f f f f f f + +#step 447 +#outs 46 45 46 47 47 46 46 f f t f f f f f f f t f t f f f t f f f f f f f t f t f + +#step 448 +#outs 46 46 46 47 47 47 47 t f t f t f f f t f t f f f f f t f f f f f t f f f f f + +#step 449 +#outs 46 47 46 47 48 47 47 t f f f t f f f f f t f f f t f f f f f f f f f f f f f + +#step 450 +#outs 47 47 46 47 48 47 47 t f f f t f f f f f t f t f t f f f t f f f f f f f t f + +#step 451 +#outs 48 47 47 47 48 47 48 f f t f t f t f f f t f f f f f f f f f t f f f f f f f + +#step 452 +#outs 48 47 47 48 48 47 48 f f t f t f f f f f t f f f f f f f t f f f f f f f f f + +#step 453 +#outs 48 47 48 48 48 47 48 f f t f f f t f f f t f f f f f t f f f f f f f f f f f + +#step 454 +#outs 48 48 48 48 48 47 48 t f t f t f t f f f t f f f t f f f f f f f f f f f f f + +#step 455 +#outs 49 48 48 48 48 47 48 f f t f t f t f f f t f f f f f t f t f t f f f f f f f + +#step 456 +#outs 49 49 49 49 48 47 48 f f t f t f f f f f t f f f f f t f t f f f f f f f f f + +#step 457 +#outs 49 0 0 49 48 47 48 f f f f f f f f f f t f f f f f f f f f f f f f t f f f + +#step 458 +#outs 49 0 0 49 48 48 48 f f f f f f f f t f t f t f f f f f f f f f t f t f f f + +#step 459 +#outs 49 0 0 49 49 49 48 f f f f f f t f t f f f t f f f f f f f t f f f f f f f + +#step 460 +#outs 49 0 0 0 49 49 48 f f f f t f f f t f f f t f f f f f f f f f t f f f t f + +#step 461 +#outs 49 0 0 0 0 49 49 t f f f t f t f f f t f t f f f f f t f t f f f t f t f + +#step 462 +#outs 49 0 1 1 0 0 0 t f f f f f f f t f t f f f f f f f f f f f t f f f f f + +#step 463 +#outs 49 0 1 1 1 0 0 t f f f f f t f f f t f f f t f f f f f f f f f f f f f + +#step 464 +#outs 0 0 1 1 1 0 0 t f t f f f t f f f t f t f t f f f f f f f f f f f t f + +#step 465 +#outs 1 0 1 1 1 0 1 f f t f f f t f f f t f f f f f f f f f f f f f t f f f + +#step 466 +#outs 1 0 1 1 1 1 1 f f t f f f t f t f t f t f f f t f f f f f t f t f t f + +#step 467 +#outs 1 1 1 1 2 2 2 t f t f t f t f f f t f f f t f f f f f t f f f f f f f + +#step 468 +#outs 2 1 1 2 2 2 2 f f t f t f f f t f t f t f f f t f t f f f f f t f f f + +#step 469 +#outs 2 2 2 2 2 3 2 t f t f t f t f t f f f t f f f f f t f t f t f f f t f + +#step 470 +#outs 2 2 3 3 3 3 3 t f t f f f t f t f t f f f t f t f f f f f f f f f f f + +#step 471 +#outs 3 3 3 3 3 3 3 t f t f t f t f t f t f t f t f t f t f t f t f f f f f + +#step 472 +#outs 4 4 4 4 4 3 3 f f t f t f t f f f t f t f f f f f t f f f f f f f t f + +#step 473 +#outs 4 4 5 4 4 3 4 t f t f f f t f f f t f f f f f f f f f f f f f t f f f + +#step 474 +#outs 4 4 5 4 4 4 4 t f t f f f t f t f t f t f f f t f f f f f t f f f f f + +#step 475 +#outs 4 5 5 4 5 4 4 t f f f f f t f f f t f t f f f f f f f t f f f t f t f + +#step 476 +#outs 4 5 5 5 5 5 5 t f f f t f t f t f t f f f t f f f t f f f f f t f f f + +#step 477 +#outs 5 5 6 5 5 6 5 t f t f f f t f t f f f t f t f t f f f f f t f f f t f + +#step 478 +#outs 6 6 6 5 6 6 6 t f t f f f t f f f t f t f f f f f f f t f f f f f f f + +#step 479 +#outs 6 6 6 6 6 6 6 t f t f t f t f t f t f t f t f f f f f f f t f t f f f + +#step 480 +#outs 7 6 6 6 7 7 6 f f t f t f t f f f f f t f f f f f f f t f f f f f f f + +#step 481 +#outs 7 6 6 7 7 7 6 f f t f t f f f t f f f t f f f t f f f f f t f f f f f + +#step 482 +#outs 7 7 6 7 8 7 6 f f f f t f f f f f f f t f f f f f t f f f f f f f f f + +#step 483 +#outs 7 7 7 7 8 7 6 f f t f t f t f f f f f t f f f f f t f t f f f f f f f + +#step 484 +#outs 7 7 8 8 8 7 6 f f t f f f t f f f f f t f f f f f f f f f f f f f t f + +#step 485 +#outs 7 7 8 8 8 7 7 t f t f f f t f f f t f t f t f t f f f f f f f f f f f + +#step 486 +#outs 8 8 8 8 8 7 7 f f t f t f t f f f t f t f f f t f t f f f f f f f t f + +#step 487 +#outs 8 9 9 8 8 7 8 t f f f f f t f f f t f f f t f f f f f f f f f f f f f + +#step 488 +#outs 9 9 9 8 8 7 8 f f t f f f t f f f t f f f f f f f f f f f f f t f f f + +#step 489 +#outs 9 9 9 8 8 8 8 f f t f f f t f t f t f t f f f f f f f t f f f f f f f + +#step 490 +#outs 9 9 9 9 8 8 8 f f t f t f f f t f t f t f f f t f f f f f f f t f t f + +#step 491 +#outs 9 10 9 9 8 9 9 t f f f t f f f t f f f t f t f f f f f f f f f f f f f + +#step 492 +#outs 10 10 9 9 8 9 9 f f f f t f f f t f f f t f f f f f f f f f t f f f f f + +#step 493 +#outs 10 10 9 9 9 9 9 f f f f t f t f t f t f t f f f f f t f f f f f t f f f + +#step 494 +#outs 10 10 10 9 9 10 9 f f t f f f t f t f f f t f f f t f f f f f t f f f f f + +#step 495 +#outs 10 11 10 9 10 10 9 f f f f f f t f f f f f t f f f f f f f t f f f f f t f + +#step 496 +#outs 10 11 10 10 10 10 10 t f f f t f t f t f t f t f t f f f f f t f f f t f t f + +#step 497 +#outs 11 11 10 11 10 11 11 t f f f t f f f t f f f t f f f f f t f f f f f f f t f + +#step 498 +#outs 11 11 11 11 10 11 12 t f t f t f f f t f f f f f f f t f f f f f t f f f f f + +#step 499 +#outs 11 12 11 11 11 11 12 t f f f t f t f t f t f f f f f f f t f t f t f f f f f + +#step 500 +#outs 11 12 12 12 12 11 12 t f f f t f t f f f t f f f f f f f t f t f f f t f f f +#q diff --git a/test/bfs-spanning-tree/Makefile b/test/bfs-spanning-tree/Makefile index c4c6a7ec78e2cbade7b2091e2c4b56d0ff29cc0f..09fa60a0b0c42a05ed37f33e0557cb729f5bc282 100644 --- a/test/bfs-spanning-tree/Makefile +++ b/test/bfs-spanning-tree/Makefile @@ -1,9 +1,15 @@ -# Time-stamp: <modified the 04/11/2020 (at 11:24) by Erwan Jahier> +# Time-stamp: <modified the 04/05/2021 (at 11:10) by Erwan Jahier> -test: test0 test2 lurette0 +test: test0 test2 lurette0 + $(sasa) -rif -l 200 fig51_noinit.dot -sd -seed 42 > fig51_noinit.rif && \ + diff -I "# on" -I " version " -B -u -i -w fig51_noinit.rif.exp fig51_noinit.rif > test.res + [ ! -s test.res ] && make clean + +utest: fig51_noinit.rif + cp fig51_noinit.rif fig51_noinit.rif.exp ; true + test0: fig51_noinit.cmxs - $(sasa) -rif -l 200 fig51_noinit.dot -sd DECO_PATTERN="0:root.ml 1-:p.ml" -include ../Makefile.dot @@ -29,11 +35,16 @@ lurette0: fig51_noinit.cmxs fig51_noinit.lut -env "sasa fig51_noinit.dot -custd -rif" \ -sut "lutin fig51_noinit.lut -n distributed" -# rdbg -lurette is broken from ocaml 4.08; but lurette works fine +rdbg-lurette1:rdbg-lurette1.rif +rdbg-lurette1.rif: fig51.cmxs fig51.lut fig51_oracle.lus + rdbg -lurette -o rdbg-lurette1.rif \ + -env "$(sasa) fig51.dot -dd -rif" \ + -oracle "lv6 fig51_oracle.lus -n oracle" + lurette1:lurette1.rif lurette1.rif: fig51.cmxs fig51.lut fig51_oracle.lus - rdbg -lurette -o lurette1.rif \ - -env "$(sasa) fig51.dot -dd -rif" \ + lurette -o lurette1.rif \ + -env "$(sasa) fig51.dot -dd -rif" \ -oracle "lv6 fig51_oracle.lus -n oracle" lurette: lurette0 diff --git a/test/bfs-spanning-tree/fig51_noinit.rif.exp b/test/bfs-spanning-tree/fig51_noinit.rif.exp new file mode 100644 index 0000000000000000000000000000000000000000..60d965f3c3ce57f242c1851c89efc8fbdbb27767 --- /dev/null +++ b/test/bfs-spanning-tree/fig51_noinit.rif.exp @@ -0,0 +1,13 @@ +#inputs +#outputs "root_d":int "root_par":int "p1_d":int "p1_par":int "p2_d":int "p2_par":int "p3_d":int "p3_par":int "p4_d":int "p4_par":int "p5_d":int "p5_par":int "p6_d":int "p6_par":int "p7_d":int "p7_par":int "Enab_root_CD":bool "Enab_root_CP":bool "Enab_p1_CD":bool "Enab_p1_CP":bool "Enab_p2_CD":bool "Enab_p2_CP":bool "Enab_p3_CD":bool "Enab_p3_CP":bool "Enab_p4_CD":bool "Enab_p4_CP":bool "Enab_p5_CD":bool "Enab_p5_CP":bool "Enab_p6_CD":bool "Enab_p6_CP":bool "Enab_p7_CD":bool "Enab_p7_CP":bool "root_CD":bool "root_CP":bool "p1_CD":bool "p1_CP":bool "p2_CD":bool "p2_CP":bool "p3_CD":bool "p3_CP":bool "p4_CD":bool "p4_CP":bool "p5_CD":bool "p5_CP":bool "p6_CD":bool "p6_CP":bool "p7_CD":bool "p7_CP":bool + + 0 -1 0 1 0 0 0 1 2 1 0 0 0 1 1 0 f f t f t f t f t f t f t f f f f f t f t f t f t f t f t f f f + 0 -1 1 1 1 0 1 1 1 1 1 0 1 1 1 0 f f f f t f t f t f t f t f f f f f f f t f t f t f t f t f f f + 0 -1 1 1 2 0 2 1 2 1 2 0 2 1 1 0 f f f f f t t f t f t f f f f f f f f f f t t f t f t f f f f f + 0 -1 1 1 2 2 3 1 3 1 3 0 2 1 1 0 f f f f f f f f f f f f f f f f f f f f f t t f t f t f f f f f + +#This algo is silent after 15 moves, 3 steps, 4 rounds. + +q +#quit +%! \ No newline at end of file diff --git a/test/coloring/Makefile b/test/coloring/Makefile index ece5ffcfd7f707c519f0dd1e8f1ccd217d361431..40cb20b8ff346bfa74ad81eb446a9a215c253e7d 100644 --- a/test/coloring/Makefile +++ b/test/coloring/Makefile @@ -1,18 +1,28 @@ -# Time-stamp: <modified the 02/12/2020 (at 11:15) by Erwan Jahier> +# Time-stamp: <modified the 04/05/2021 (at 11:11) by Erwan Jahier> sasa=$(DIR)/bin/sasa -l 100 test: ring.cmxs coloring.rif coloring2.rif lurette + rm -f test.res && \ + diff -I "# on" -I " version " -B -u -i -w coloring.rif.exp coloring.rif > test.res && \ + diff -I "# on" -I " version " -B -u -i -w coloring2.rif.exp coloring2.rif >> test.res + [ ! -s test.res ] && make clean DECO_PATTERN="0-:p.ml" -include ../Makefile.dot coloring.rif: ring.cmxs - $(sasa) -l 200 ring.dot > $@ + $(sasa) -l 200 ring.dot -seed 42 > $@ coloring2.rif: grid4.cmxs - $(sasa) -l 200 grid4.dot > $@ + $(sasa) -l 200 grid4.dot -seed 42 > $@ + +utest1: coloring.rif + cp coloring.rif coloring.rif.exp ; true +utest2: coloring2.rif + cp coloring2.rif coloring2.rif.exp ; true +utest: utest1 utest2 sim2chrogtk: coloring.rif sim2chrogtk -screenrealheight 2000 -ecran -in $< > /dev/null diff --git a/test/coloring/coloring.rif.exp b/test/coloring/coloring.rif.exp new file mode 100644 index 0000000000000000000000000000000000000000..9bdef0fb950e9bc321de30ab07ca75fb19416cfe --- /dev/null +++ b/test/coloring/coloring.rif.exp @@ -0,0 +1,29 @@ +# Automatically generated by /home/jahier/.opam/4.10.0/bin/sasa version "4.3.27-1-g4eb78d9" ("4eb78d9") +# on crevetete the 4/5/2021 at 10:04:50 +#sasa -l 200 ring.dot -seed 42 + +#seed 42 +#inputs +#outputs "p1_c":int "p2_c":int "p3_c":int "p4_c":int "p5_c":int "p6_c":int "p7_c":int "Enab_p1_conflict":bool "Enab_p2_conflict":bool "Enab_p3_conflict":bool "Enab_p4_conflict":bool "Enab_p5_conflict":bool "Enab_p6_conflict":bool "Enab_p7_conflict":bool "p1_conflict":bool "p2_conflict":bool "p3_conflict":bool "p4_conflict":bool "p5_conflict":bool "p6_conflict":bool "p7_conflict":bool potential:real + + +#step 0 +#outs 0 1 1 1 1 1 0 t t t t t t t t t t f f f f 10. + +#step 1 +#outs 2 2 0 1 1 1 0 t t f t t t f f f f t t t f 6. + +#step 2 +#outs 2 2 0 2 0 2 0 t t f f f f f t t f f f f f 2. + +#step 3 +#outs 1 1 0 2 0 2 0 t t f f f f f t f f f f f f 2. + +#step 4 +#outs 2 1 0 2 0 2 0 f f f f f f f t f f f f f f 0. + +This algo is silent after 9 moves, 4 steps, 3 rounds. + +q +#quit +%! \ No newline at end of file diff --git a/test/coloring/coloring2.rif.exp b/test/coloring/coloring2.rif.exp new file mode 100644 index 0000000000000000000000000000000000000000..7b0043f0cebe3ead6e489f5ba0087eba1a59392d --- /dev/null +++ b/test/coloring/coloring2.rif.exp @@ -0,0 +1,32 @@ +# Automatically generated by /home/jahier/.opam/4.10.0/bin/sasa version "4.3.27-1-g4eb78d9" ("4eb78d9") +# on crevetete the 4/5/2021 at 10:04:50 +#sasa -l 200 grid4.dot -seed 42 + +#seed 42 +#inputs +#outputs "p0_c":int "p1_c":int "p2_c":int "p3_c":int "p4_c":int "p5_c":int "p6_c":int "p7_c":int "p8_c":int "p9_c":int "p10_c":int "p11_c":int "p12_c":int "p13_c":int "p14_c":int "p15_c":int "Enab_p0_conflict":bool "Enab_p1_conflict":bool "Enab_p2_conflict":bool "Enab_p3_conflict":bool "Enab_p4_conflict":bool "Enab_p5_conflict":bool "Enab_p6_conflict":bool "Enab_p7_conflict":bool "Enab_p8_conflict":bool "Enab_p9_conflict":bool "Enab_p10_conflict":bool "Enab_p11_conflict":bool "Enab_p12_conflict":bool "Enab_p13_conflict":bool "Enab_p14_conflict":bool "Enab_p15_conflict":bool "p0_conflict":bool "p1_conflict":bool "p2_conflict":bool "p3_conflict":bool "p4_conflict":bool "p5_conflict":bool "p6_conflict":bool "p7_conflict":bool "p8_conflict":bool "p9_conflict":bool "p10_conflict":bool "p11_conflict":bool "p12_conflict":bool "p13_conflict":bool "p14_conflict":bool "p15_conflict":bool potential:real + + +#step 0 +#outs 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 t t t t t t t t t t t t t t t t t f f f f f f t f f f f t t t f 48. + +#step 1 +#outs 1 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 f t t t t t t f t t t t t t t t f f f f t t f f f f f t t f f t 30. + +#step 2 +#outs 1 0 0 0 2 1 0 1 0 0 0 2 2 1 1 2 f t t t f f t f t t t t f t t t f t f t f f f f t t f f f f f f 16. + +#step 3 +#outs 1 2 0 2 2 1 0 1 1 2 0 2 2 1 1 2 f f t f f f t f f f t t f t t t f f f f f f t f f f f f f t t f 8. + +#step 4 +#outs 1 2 0 2 2 1 2 1 1 2 0 2 2 0 3 2 f f f f f f f f f f f t f f f t f f f f f f f f f f f t f f f t 2. + +#step 5 +#outs 1 2 0 2 2 1 2 1 1 2 0 3 2 0 3 0 f f f f f f f f f f f f f f f f f f f f f f f f f f f t f f f t 0. + +This algo is silent after 19 moves, 5 steps, 2 rounds. + +q +#quit +%! \ No newline at end of file diff --git a/test/coloring/config.ml b/test/coloring/config.ml index aa5fd985aaae3bb14c7ed2859797d3d1b58e479b..2c5a01377797e92ce421d60589af1653f0cf2701 100644 --- a/test/coloring/config.ml +++ b/test/coloring/config.ml @@ -10,5 +10,6 @@ let clash_number pidl get = float_of_int !clash let potential = Some clash_number +(* let potential = None *) let legitimate = None let fault = None diff --git a/test/dfs/Makefile b/test/dfs/Makefile index 2ed9914d4c77bd8621c48111b7abdc366b0a0f6a..2b7428644f381b8275ce4eeb15687bde969fdc6c 100644 --- a/test/dfs/Makefile +++ b/test/dfs/Makefile @@ -1,9 +1,14 @@ -# Time-stamp: <modified the 24/03/2020 (at 11:35) by Erwan Jahier> +# Time-stamp: <modified the 04/05/2021 (at 11:11) by Erwan Jahier> test: test0 lurette0 rdbg_test + $(sasa) -rif -l 200 g.dot -sd -seed 42 > g.rif && \ + diff -I "# on" -I " version " -B -u -i -w g.rif.exp g.rif > test.res + [ ! -s test.res ] && make clean +utest: g.rif + cp g.rif g.rif.exp ; true + test0: g.cmxs g.lut - $(sasa) -rif -l 200 g.dot -sd DECO_PATTERN="0:root.ml 1-:p.ml" -include ../Makefile.dot diff --git a/test/dfs/g.rif.exp b/test/dfs/g.rif.exp new file mode 100644 index 0000000000000000000000000000000000000000..ebb87045d7b9df2c774e41aa6963e54cfcf1858e --- /dev/null +++ b/test/dfs/g.rif.exp @@ -0,0 +1,23 @@ +#inputs +#outputs "p1_path0":int "p1_path1":int "p1_path2":int "p1_path3":int "p1_path4":int "p1_path5":int "p1_path6":int "p1_path7":int "p1_path8":int "p1_path9":int "p1_par":int "p2_path0":int "p2_path1":int "p2_path2":int "p2_path3":int "p2_path4":int "p2_path5":int "p2_path6":int "p2_path7":int "p2_path8":int "p2_path9":int "p2_par":int "p3_path0":int "p3_path1":int "p3_path2":int "p3_path3":int "p3_path4":int "p3_path5":int "p3_path6":int "p3_path7":int "p3_path8":int "p3_path9":int "p3_par":int "p4_path0":int "p4_path1":int "p4_path2":int "p4_path3":int "p4_path4":int "p4_path5":int "p4_path6":int "p4_path7":int "p4_path8":int "p4_path9":int "p4_par":int "p5_path0":int "p5_path1":int "p5_path2":int "p5_path3":int "p5_path4":int "p5_path5":int "p5_path6":int "p5_path7":int "p5_path8":int "p5_path9":int "p5_par":int "p6_path0":int "p6_path1":int "p6_path2":int "p6_path3":int "p6_path4":int "p6_path5":int "p6_path6":int "p6_path7":int "p6_path8":int "p6_path9":int "p6_par":int "p7_path0":int "p7_path1":int "p7_path2":int "p7_path3":int "p7_path4":int "p7_path5":int "p7_path6":int "p7_path7":int "p7_path8":int "p7_path9":int "p7_par":int "p8_path0":int "p8_path1":int "p8_path2":int "p8_path3":int "p8_path4":int "p8_path5":int "p8_path6":int "p8_path7":int "p8_path8":int "p8_path9":int "p8_par":int "p9_path0":int "p9_path1":int "p9_path2":int "p9_path3":int "p9_path4":int "p9_path5":int "p9_path6":int "p9_path7":int "p9_path8":int "p9_path9":int "p9_par":int "p10_path0":int "p10_path1":int "p10_path2":int "p10_path3":int "p10_path4":int "p10_path5":int "p10_path6":int "p10_path7":int "p10_path8":int "p10_path9":int "p10_par":int "Enab_p1_update_path":bool "Enab_p1_compute_parent":bool "Enab_p2_update_path":bool "Enab_p2_compute_parent":bool "Enab_p3_update_path":bool "Enab_p3_compute_parent":bool "Enab_p4_update_path":bool "Enab_p4_compute_parent":bool "Enab_p5_update_path":bool "Enab_p5_compute_parent":bool "Enab_p6_update_path":bool "Enab_p6_compute_parent":bool "Enab_p7_update_path":bool "Enab_p7_compute_parent":bool "Enab_p8_update_path":bool "Enab_p8_compute_parent":bool "Enab_p9_update_path":bool "Enab_p9_compute_parent":bool "Enab_p10_update_path":bool "Enab_p10_compute_parent":bool "p1_update_path":bool "p1_compute_parent":bool "p2_update_path":bool "p2_compute_parent":bool "p3_update_path":bool "p3_compute_parent":bool "p4_update_path":bool "p4_compute_parent":bool "p5_update_path":bool "p5_compute_parent":bool "p6_update_path":bool "p6_compute_parent":bool "p7_update_path":bool "p7_compute_parent":bool "p8_update_path":bool "p8_compute_parent":bool "p9_update_path":bool "p9_compute_parent":bool "p10_update_path":bool "p10_compute_parent":bool + + -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -10 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 t f t f f f t f t f t f t f t f t f t f t f t f f f t f t f t f t f t f t f t f + -1 3 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -10 -1 1 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 1 -1 -1 -1 -1 -1 -1 -1 -1 1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 1 t f t f f f t f t f f t t f t f t f t f t f t f f f t f t f f t t f t f t f t f + -1 0 3 -1 -1 -1 -1 -1 -1 -1 0 -1 0 0 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -10 -1 0 1 -1 -1 -1 -1 -1 -1 -1 0 -1 0 0 -1 -1 -1 -1 -1 -1 -1 1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 2 -1 0 1 -1 -1 -1 -1 -1 -1 -1 1 -1 0 1 -1 -1 -1 -1 -1 -1 -1 0 -1 0 0 -1 -1 -1 -1 -1 -1 -1 1 -1 0 0 -1 -1 -1 -1 -1 -1 -1 1 t f t f f f t f t f f f f f t f t f f t t f t f f f t f t f f f f f t f t f f t + -1 0 0 3 -1 -1 -1 -1 -1 -1 0 -1 0 0 0 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -10 -1 0 0 1 -1 -1 -1 -1 -1 -1 0 -1 0 0 0 -1 -1 -1 -1 -1 -1 1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 2 -1 0 1 -1 -1 -1 -1 -1 -1 -1 1 -1 0 0 1 -1 -1 -1 -1 -1 -1 0 -1 0 0 1 -1 -1 -1 -1 -1 -1 1 -1 0 0 -1 -1 -1 -1 -1 -1 -1 0 t f t f f f t f t f f f t f t f f t f f t f t f f f t f t f f f t f t f f t f f + -1 0 0 0 3 -1 -1 -1 -1 -1 0 -1 0 0 0 0 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -10 -1 0 0 0 1 -1 -1 -1 -1 -1 0 -1 0 0 0 0 -1 -1 -1 -1 -1 1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 2 -1 0 0 1 1 -1 -1 -1 -1 -1 1 -1 0 0 1 1 -1 -1 -1 -1 -1 0 -1 0 0 1 -1 -1 -1 -1 -1 -1 0 -1 0 0 -1 -1 -1 -1 -1 -1 -1 0 t f t f f f t f t f f f t f f f f f f f t f t f f f t f t f f f t f f f f f f f + -1 0 0 0 0 3 -1 -1 -1 -1 0 -1 0 0 0 0 0 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -10 -1 0 0 0 0 1 -1 -1 -1 -1 0 -1 0 0 0 0 0 -1 -1 -1 -1 1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 2 -1 0 0 1 1 1 -1 -1 -1 -1 1 -1 0 0 1 1 -1 -1 -1 -1 -1 0 -1 0 0 1 -1 -1 -1 -1 -1 -1 0 -1 0 0 -1 -1 -1 -1 -1 -1 -1 0 t f t f f f t f t f f f f t f f f f f f t f t f f f t f t f f f f t f f f f f f + -1 0 0 0 0 0 3 -1 -1 -1 0 -1 0 0 0 0 0 0 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -10 -1 0 0 0 0 0 1 -1 -1 -1 0 -1 0 0 0 0 0 0 -1 -1 -1 1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 2 -1 0 0 1 1 1 -1 -1 -1 -1 0 -1 0 0 1 1 -1 -1 -1 -1 -1 0 -1 0 0 1 -1 -1 -1 -1 -1 -1 0 -1 0 0 -1 -1 -1 -1 -1 -1 -1 0 t f t f f f t f t f f f f f f f f f f f t f t f f f t f t f f f f f f f f f f f + -1 0 0 0 0 0 0 3 -1 -1 0 -1 0 0 0 0 0 0 0 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -10 -1 0 0 0 0 0 0 1 -1 -1 0 -1 0 0 0 0 0 0 0 -1 -1 1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 2 -1 0 0 1 1 1 -1 -1 -1 -1 0 -1 0 0 1 1 -1 -1 -1 -1 -1 0 -1 0 0 1 -1 -1 -1 -1 -1 -1 0 -1 0 0 -1 -1 -1 -1 -1 -1 -1 0 t f t f f f t f t f f f f f f f f f f f t f t f f f t f t f f f f f f f f f f f + -1 0 0 0 0 0 0 0 3 -1 0 -1 0 0 0 0 0 0 0 0 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -10 -1 0 0 0 0 0 0 0 1 -1 0 -1 0 0 0 0 0 0 0 0 -1 1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 2 -1 0 0 1 1 1 -1 -1 -1 -1 0 -1 0 0 1 1 -1 -1 -1 -1 -1 0 -1 0 0 1 -1 -1 -1 -1 -1 -1 0 -1 0 0 -1 -1 -1 -1 -1 -1 -1 0 t f t f f f t f t f f f f f f f f f f f t f t f f f t f t f f f f f f f f f f f + -1 0 0 0 0 0 0 0 0 3 0 -1 0 0 0 0 0 0 0 0 0 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -10 -1 0 0 0 0 0 0 0 0 1 0 -1 0 0 0 0 0 0 0 0 0 1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 2 -1 0 0 1 1 1 -1 -1 -1 -1 0 -1 0 0 1 1 -1 -1 -1 -1 -1 0 -1 0 0 1 -1 -1 -1 -1 -1 -1 0 -1 0 0 -1 -1 -1 -1 -1 -1 -1 0 t f t f f f t f t f f f f f f f f f f f t f t f f f t f t f f f f f f f f f f f + 0 0 0 0 0 0 0 0 0 3 0 -1 2 -1 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -10 -1 1 -1 -1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 0 0 1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 2 -1 0 0 1 1 1 -1 -1 -1 -1 0 -1 0 0 1 1 -1 -1 -1 -1 -1 0 -1 0 0 1 -1 -1 -1 -1 -1 -1 0 -1 0 0 -1 -1 -1 -1 -1 -1 -1 0 t f t f f f f t t f f f f f f f f f f f t f t f f f f t t f f f f f f f f f f f + -1 2 3 -1 -1 -1 -1 -1 -1 -1 0 -1 1 1 -1 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -10 -1 1 -1 -1 -1 -1 -1 -1 -1 -1 2 -1 1 0 -1 -1 -1 -1 -1 -1 -1 1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 2 -1 0 0 1 1 1 -1 -1 -1 -1 0 -1 0 0 1 1 -1 -1 -1 -1 -1 0 -1 0 0 1 -1 -1 -1 -1 -1 -1 0 -1 0 0 -1 -1 -1 -1 -1 -1 -1 0 t f t f f f f f f f f f f f f f f f f f t f t f f f f f f f f f f f f f f f f f + -1 1 1 3 -1 -1 -1 -1 -1 -1 0 -1 1 0 0 -1 -1 -1 -1 -1 -1 3 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -10 -1 1 -1 -1 -1 -1 -1 -1 -1 -1 2 -1 1 0 -1 -1 -1 -1 -1 -1 -1 1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 2 -1 0 0 1 1 1 -1 -1 -1 -1 0 -1 0 0 1 1 -1 -1 -1 -1 -1 0 -1 0 0 1 -1 -1 -1 -1 -1 -1 0 -1 0 0 -1 -1 -1 -1 -1 -1 -1 0 t f f t f f f f f f f f f f f f f f f f t f f t f f f f f f f f f f f f f f f f + -1 1 0 0 3 -1 -1 -1 -1 -1 0 -1 1 0 0 -1 -1 -1 -1 -1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -10 -1 1 -1 -1 -1 -1 -1 -1 -1 -1 2 -1 1 0 -1 -1 -1 -1 -1 -1 -1 1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 2 -1 0 0 1 1 1 -1 -1 -1 -1 0 -1 0 0 1 1 -1 -1 -1 -1 -1 0 -1 0 0 1 -1 -1 -1 -1 -1 -1 0 -1 0 0 -1 -1 -1 -1 -1 -1 -1 0 f f f f f f f f f f f f f f f f f f f f t f f t f f f f f f f f f f f f f f f f + +#This algo is silent after 66 moves, 13 steps, 14 rounds. + +q +#quit +%! \ No newline at end of file diff --git a/test/dijkstra-ring/Makefile b/test/dijkstra-ring/Makefile index f6d0d7aafc14e5a54fc9448cd6dae60c5fb20683..cb07b2fd89f7d325e32cfea4b13d2638764b6ce7 100644 --- a/test/dijkstra-ring/Makefile +++ b/test/dijkstra-ring/Makefile @@ -1,8 +1,14 @@ -# Time-stamp: <modified the 19/11/2020 (at 15:04) by Erwan Jahier> +# Time-stamp: <modified the 04/05/2021 (at 11:11) by Erwan Jahier> test: ring.cmxs lurette1 rdbg_test - $(sasa) ring.dot + $(sasa) ring.dot -seed 42 > ring.rif && \ + diff -I "# on" -I " version " -B -u -i -w ring.rif.exp ring.rif > test.res + [ ! -s test.res ] && make clean + +utest: ring.rif + cp ring.rif ring.rif.exp ; true + DECO_PATTERN="0:root.ml 1-:p.ml" -include ../Makefile.dot diff --git a/test/dijkstra-ring/ring.rif.exp b/test/dijkstra-ring/ring.rif.exp new file mode 100644 index 0000000000000000000000000000000000000000..91bc50d196e678eab31f8c7569600e69e00d9b9b --- /dev/null +++ b/test/dijkstra-ring/ring.rif.exp @@ -0,0 +1,36 @@ +# Automatically generated by /home/jahier/.opam/4.10.0/bin/sasa version "4.3.27-1-g4eb78d9" ("4eb78d9") +# on crevetete the 4/5/2021 at 10:27:26 +#sasa ring.dot -seed 42 + +#seed 42 +#inputs +#outputs "root_c":int "p2_c":int "p3_c":int "p4_c":int "p5_c":int "p6_c":int "p7_c":int "p8_c":int "Enab_root_T":bool "Enab_p2_T":bool "Enab_p3_T":bool "Enab_p4_T":bool "Enab_p5_T":bool "Enab_p6_T":bool "Enab_p7_T":bool "Enab_p8_T":bool "root_T":bool "p2_T":bool "p3_T":bool "p4_T":bool "p5_T":bool "p6_T":bool "p7_T":bool "p8_T":bool + + +#step 0 +#outs 1 3 3 2 2 1 1 0 f f t f t f t t f f f f f f t f + +#step 1 +#outs 1 3 3 2 2 1 0 0 f f t f t t f t f f f f t t f t + +#step 2 +#outs 1 3 3 2 1 0 0 1 f f t t t f t f f f f f f f t f + +#step 3 +#outs 1 3 3 2 1 0 1 1 f f t t t t f f f f t t t f f f + +#step 4 +#outs 1 3 2 1 0 0 1 1 f t t t f t f f f f f f f t f f + +#step 5 +#outs 1 3 2 1 0 1 1 1 f t t t t f f f f t t f f f f f + +#step 6 +#outs 1 2 1 1 0 1 1 1 f t f t t f f f f f f f t f f f + +#step 7 +#outs 1 2 1 1 1 1 1 1 f t f f f f f f f f f f t f f f + +#This algo reached a legitimate configuration after 12 moves, 7 steps, 1 round. + +#quit diff --git a/test/lustre/utils.lus b/test/lustre/utils.lus index 1ada4177c69a2708670604a09c0d0cf3666bd0e4..01360ad1d2de556b40a8275c67e89cf42dda2e01 100644 --- a/test/lustre/utils.lus +++ b/test/lustre/utils.lus @@ -37,7 +37,7 @@ let tel ----------------------------------------------------------------------------- -function implies_list(A,B:bool^m) returns (res:bool^m); +function implies_list<<const m:int>>(A,B:bool^m) returns (res:bool^m); let res = map<<=>,m>>(A,B) ; tel diff --git a/test/toy-example-a5sf/Makefile b/test/toy-example-a5sf/Makefile index e4f9bdc5be4c159b577cae4d255b2e93ab7a84fb..3299d6eccc556515862477e5ba4002ec866a99c6 100644 --- a/test/toy-example-a5sf/Makefile +++ b/test/toy-example-a5sf/Makefile @@ -1,9 +1,16 @@ -# Time-stamp: <modified the 12/10/2020 (at 16:40) by Erwan Jahier> +# Time-stamp: <modified the 04/05/2021 (at 11:11) by Erwan Jahier> test: test1 test2 + sasa te.dot -seed 42 > te.rif && \ + diff -I "# on" -I " version " -B -u -i -w te.rif.exp te.rif > test.res + [ ! -s test.res ] && make clean + test1: te.cmxs - sasa te.dot + +utest: te.rif + cp te.rif te.rif.exp ; true + test2:te.cmxs sasa -gcd te.dot diff --git a/test/toy-example-a5sf/config.ml b/test/toy-example-a5sf/config.ml new file mode 100644 index 0000000000000000000000000000000000000000..c88eefac2eefdfa8121aa8ea2c4249e06d3d57f3 --- /dev/null +++ b/test/toy-example-a5sf/config.ml @@ -0,0 +1,41 @@ +open Algo +open P +open State + +let (isEnabledS: pid -> (pid -> ('a * 'a neighbor list)) -> bool) = + fun id get -> ((fst (get id))).sub <> (((fst (get id))).input + (sum_sub (snd (get id)))) + +let (isEnabledR: pid -> (pid -> ('a * 'a neighbor list)) -> bool) = + fun id get -> + let id_v, id_nl = get id in + if id_v.par = -1 then (id_v.res <> id_v.sub) else + let par = state (List.nth id_nl id_v.par) in + let p_par_res = (fst (get par.pid)).res in + (id_v.res <> max [p_par_res; id_v.sub] 0) + +let (loc_pot: pid -> pid list -> (pid -> ('a * 'a neighbor list)) -> int) = + fun p pidl get -> + if isEnabledS p get then 1 + vn*(vn-1) + int_of_string (String.sub p 1 ((String.length p) - 1)) + else if isEnabledR p get then 1 + (vn - (int_of_string (String.sub p 1 ((String.length p) - 1)))) + else 0 + +let rec (sum_loc_pots: pid list -> pid list -> (pid -> ('a * 'a neighbor list)) -> int) = + fun pidl pidl_mem get -> + match pidl with + [] -> 0 + | p::listp -> (loc_pot p pidl_mem get) + (sum_loc_pots listp pidl_mem get) + +let (pf: pid list -> (pid -> ('a * ('a neighbor * pid) list)) -> float) = + fun pidl get -> + let get pid = + let v, l = get pid in + v, fst (List.split l) + in + float_of_int (sum_loc_pots pidl pidl get) + +let potential = Some pf + + + +let legitimate = None (* None => only silent configuration are legitimate *) +let fault = None (* None => the simulation stop once a legitimate configuration is reached *) diff --git a/test/toy-example-a5sf/te.rif.exp b/test/toy-example-a5sf/te.rif.exp new file mode 100644 index 0000000000000000000000000000000000000000..8c5fede478303783e38f52ee0622695b4a72cb6b --- /dev/null +++ b/test/toy-example-a5sf/te.rif.exp @@ -0,0 +1,86 @@ +# Automatically generated by /home/jahier/.opam/4.10.0/bin/sasa version "4.3.27-1-g4eb78d9" ("4eb78d9") +# on crevetete the 4/5/2021 at 11:05:21 +#sasa te.dot -seed 42 + +#seed 42 +#inputs +#outputs "p1_input":int "p1_sub":int "p1_res":int "p2_input":int "p2_sub":int "p2_res":int "p3_input":int "p3_sub":int "p3_res":int "p4_input":int "p4_sub":int "p4_res":int "p5_input":int "p5_sub":int "p5_res":int "p6_input":int "p6_sub":int "p6_res":int "p7_input":int "p7_sub":int "p7_res":int "Enab_p1_S":bool "Enab_p1_RR":bool "Enab_p1_RP":bool "Enab_p2_S":bool "Enab_p2_RR":bool "Enab_p2_RP":bool "Enab_p3_S":bool "Enab_p3_RR":bool "Enab_p3_RP":bool "Enab_p4_S":bool "Enab_p4_RR":bool "Enab_p4_RP":bool "Enab_p5_S":bool "Enab_p5_RR":bool "Enab_p5_RP":bool "Enab_p6_S":bool "Enab_p6_RR":bool "Enab_p6_RP":bool "Enab_p7_S":bool "Enab_p7_RR":bool "Enab_p7_RP":bool "p1_S":bool "p1_RR":bool "p1_RP":bool "p2_S":bool "p2_RR":bool "p2_RP":bool "p3_S":bool "p3_RR":bool "p3_RP":bool "p4_S":bool "p4_RR":bool "p4_RP":bool "p5_S":bool "p5_RR":bool "p5_RP":bool "p6_S":bool "p6_RR":bool "p6_RP":bool "p7_S":bool "p7_RR":bool "p7_RP":bool potential:real + + +#step 0 +#outs 1 2 2 1 1 2 1 0 0 1 2 0 1 0 0 1 4 0 1 0 0 f f f f f f t f f t f f t f f t f f t f f f f f f f f f f f t f f f f f f f f t f f 240. + +#step 1 +#outs 1 2 2 1 1 2 1 0 0 1 1 0 1 0 0 1 4 0 1 1 0 f f f f f f t f f f f t t f f t f f f f t f f f f f f t f f f f t f f f f f f f f f 148. + +#step 2 +#outs 1 2 2 1 1 2 1 2 0 1 1 1 1 0 0 1 4 0 1 1 0 f f f t f f f f t f f f t f f t f f f f t f f f f f f f f f f f f f f f t f f f f t 148. + +#step 3 +#outs 1 2 2 1 1 2 1 2 0 1 1 1 1 0 0 1 2 0 1 1 1 f f f t f f f f t f f f t f f f f t f f f f f f f f f f f t f f f f f f f f f f f f 100. + +#step 4 +#outs 1 2 2 1 1 2 1 2 2 1 1 1 1 0 0 1 2 0 1 1 1 f f f t f f f f f f f t t f f f f t f f f f f f t f f f f f f f f t f f f f t f f f 99. + +#step 5 +#outs 1 2 2 1 3 2 1 2 2 1 1 1 1 3 0 1 2 2 1 1 1 t f f f f t f f f t f f f f t f f f f f t f f f f f f f f f f f f f f f f f f f f t 101. + +#step 6 +#outs 1 2 2 1 3 2 1 2 2 1 1 1 1 3 0 1 2 2 1 1 2 t f f f f t f f f t f f f f t f f f f f f t f f f f f f f f f f f f f t f f f f f f 100. + +#step 7 +#outs 1 4 2 1 3 2 1 2 2 1 1 1 1 3 3 1 2 2 1 1 2 f t f f f t f f f t f f f f f f f t f f f f f f f f f f f f t f f f f f f f t f f f 62. + +#step 8 +#outs 1 4 2 1 3 2 1 2 2 1 4 1 1 3 3 1 2 3 1 1 2 f t f f f t t f f f f t f f f f f f f f t f t f f f f f f f f f t f f f f f f f f f 64. + +#step 9 +#outs 1 4 4 1 3 2 1 2 2 1 4 4 1 3 3 1 2 3 1 1 2 f f f f f t t f f f f f f f t f f f f f t f f f f f t t f f f f f f f t f f f f f t 56. + +#step 10 +#outs 1 4 4 1 3 4 1 5 2 1 4 4 1 3 4 1 2 3 1 1 3 f f f t f f f f t f f f f f f f f t f f f f f f t f f f f f f f f f f f f f t f f f 52. + +#step 11 +#outs 1 4 4 1 6 4 1 5 2 1 4 4 1 3 4 1 2 4 1 1 3 t f f f f t f f t f f f f f f f f f f f t t f f f f t f f t f f f f f f f f f f f f 56. + +#step 12 +#outs 1 7 4 1 6 6 1 5 5 1 4 4 1 3 4 1 2 4 1 1 3 f t f f f f f f t f f t f f f f f f f f t f t f f f f f f t f f t f f f f f f f f t 17. + +#step 13 +#outs 1 7 7 1 6 6 1 5 6 1 4 5 1 3 4 1 2 4 1 1 4 f f f f f t f f f f f t f f t f f f f f f f f f f f f f f f f f t f f t f f f f f f 13. + +#step 14 +#outs 1 7 7 1 6 6 1 5 6 1 4 6 1 3 5 1 2 4 1 1 4 f f f f f t f f f f f f f f t f f t f f f f f f f f t f f f f f f f f f f f t f f f 11. + +#step 15 +#outs 1 7 7 1 6 7 1 5 6 1 4 6 1 3 5 1 2 5 1 1 4 f f f f f f f f t f f f f f t f f f f f t f f f f f f f f f f f f f f t f f f f f f 9. + +#step 16 +#outs 1 7 7 1 6 7 1 5 6 1 4 6 1 3 6 1 2 5 1 1 4 f f f f f f f f t f f f f f f f f t f f t f f f f f f f f t f f f f f f f f f f f t 8. + +#step 17 +#outs 1 7 7 1 6 7 1 5 7 1 4 6 1 3 6 1 2 5 1 1 5 f f f f f f f f f f f t f f f f f t f f f f f f f f f f f f f f t f f f f f f f f f 6. + +#step 18 +#outs 1 7 7 1 6 7 1 5 7 1 4 7 1 3 6 1 2 5 1 1 5 f f f f f f f f f f f f f f t f f t f f f f f f f f f f f f f f f f f f f f t f f f 5. + +#step 19 +#outs 1 7 7 1 6 7 1 5 7 1 4 7 1 3 6 1 2 6 1 1 5 f f f f f f f f f f f f f f t f f f f f t f f f f f f f f f f f f f f t f f f f f f 4. + +#step 20 +#outs 1 7 7 1 6 7 1 5 7 1 4 7 1 3 7 1 2 6 1 1 5 f f f f f f f f f f f f f f f f f t f f t f f f f f f f f f f f f f f f f f f f f t 3. + +#step 21 +#outs 1 7 7 1 6 7 1 5 7 1 4 7 1 3 7 1 2 6 1 1 6 f f f f f f f f f f f f f f f f f t f f f f f f f f f f f f f f f f f f f f t f f f 2. + +#step 22 +#outs 1 7 7 1 6 7 1 5 7 1 4 7 1 3 7 1 2 7 1 1 6 f f f f f f f f f f f f f f f f f f f f t f f f f f f f f f f f f f f f f f f f f t 1. + +#step 23 +#outs 1 7 7 1 6 7 1 5 7 1 4 7 1 3 7 1 2 7 1 1 7 f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f f t 0. + +This algo is silent after 43 moves, 23 steps, 15 rounds. + +q +#quit +%! \ No newline at end of file diff --git a/tools/gg/classicGraph.ml b/tools/gg/classicGraph.ml index 7f729fd86de65e0b3b6f202224cedfa1d5a48989..303c1fa65d8904e358e12249843c76d35fb02e50 100644 --- a/tools/gg/classicGraph.ml +++ b/tools/gg/classicGraph.ml @@ -3,79 +3,103 @@ open Topology open Ggcore open List -type node_succ_t = (string, (int * string) list) Hashtbl.t +type node_succ_t = (string, int * string) Hashtbl.t +type node_pred_t = (string, string) Hashtbl.t + +(* Add symmetric edges when not directed *) +let update_tbl directed succ pred = + if not directed then ( + Hashtbl.iter + (fun n1 (_, n2) -> + if not (List.mem (1,n1) (Hashtbl.find_all succ n2)) then + Hashtbl.add succ n2 (1,n1)) + (Hashtbl.copy succ); + Hashtbl.iter + (fun n1 n2 -> + if not (List.mem n1 (Hashtbl.find_all pred n2)) then + Hashtbl.add pred n2 n1) + (Hashtbl.copy pred); + ) let nid_list_remove : (node_id list -> node_id -> (int*node_id) list) = fun l e -> - rev (fold_left (fun acc elem -> if(elem <> e) then (1,elem)::acc else acc ) [] l) - + (* remove e from l, and add the weight 1 to elements of l *) + rev (fold_left (fun acc elem -> + if(elem <> e) then (1,elem)::acc else acc ) [] l) let (gen_clique: bool -> int -> Topology.t) = fun directed nb -> let (node_succ:node_succ_t) = Hashtbl.create nb + and (node_pred:node_pred_t) = Hashtbl.create nb and nodes = create_nodes "p" (0,nb) in List.iter - (fun node_id -> Hashtbl.replace node_succ node_id (nid_list_remove nodes node_id)) + (fun node_id -> + List.iter + (fun x -> + if (snd x) < node_id then ( + Hashtbl.add node_succ node_id x; + Hashtbl.add node_pred (snd x) node_id + ) + ) + (nid_list_remove nodes node_id)) nodes; let nl = id_to_empty_nodes nodes in + update_tbl directed node_succ node_pred; { nodes = nl; - succ = (fun n -> try Hashtbl.find node_succ n with Not_found -> []); + succ = (fun n -> Hashtbl.find_all node_succ n); + pred = (fun n -> Hashtbl.find_all node_pred n); of_id = get_of_id nl; directed = directed; attributes = [] } - let (gen_star: bool -> int -> Topology.t) = fun directed nb -> - let (node_succ:node_succ_t) = Hashtbl.create nb and nodes = "root"::(create_nodes "p" (1,nb)) in - let first = hd nodes in - List.iter - (fun node -> - Hashtbl.replace node_succ node - (if node = first then nid_list_remove nodes node else [(1,first)])) nodes; - let nl = id_to_empty_nodes nodes in + let (node_succ:node_succ_t) = Hashtbl.create nb in + let (node_pred:node_pred_t) = Hashtbl.create nb in + let nodes = create_nodes "p" (1,nb) in + + List.iter (fun n -> Hashtbl.add node_succ "root" (1,n)) nodes; + List.iter (fun n -> Hashtbl.add node_pred n "root") nodes; + update_tbl directed node_succ node_pred; + let nl = id_to_empty_nodes ("root"::nodes) in { nodes = nl; - succ = (fun n -> try Hashtbl.find node_succ n with Not_found -> []); + succ = (fun n -> Hashtbl.find_all node_succ n); + pred = (fun n -> Hashtbl.find_all node_pred n); of_id = get_of_id nl; directed = directed; attributes = [] } -let rec list_iter3 f l1 l2 l3 = - match (l1, l2, l3) with - ([], [], []) -> () - | (a1::l1, a2::l2, a3::l3) -> f a1 a2 a3; list_iter3 f l1 l2 l3 - | (_, _, _) -> invalid_arg "list_iter3" - - -let neighbours_ring : bool -> (node_id list -> (node_id -> (int * node_id) list)) = - fun dir nodes -> - let node_succ:node_succ_t = Hashtbl.create (length nodes) in - let nodes2, nodes3 = match nodes with - | n1::n2::t -> (n2::t)@[n1], t@[n1;n2] +let neighbours_ring dir nodes = + let nb = length nodes in + let node_succ:node_succ_t = Hashtbl.create nb in + let (node_pred:node_pred_t) = Hashtbl.create nb in + let nodes2 = match nodes with + | n1::t -> t@[n1] | _ -> assert false in - list_iter3 (fun n1 n2 n3 -> - if dir then - Hashtbl.replace node_succ n2 [1,n3] - else - Hashtbl.replace node_succ n2 [(1,n3);(1,n1)] + List.iter2 (fun n1 n2 -> + Hashtbl.add node_succ n1 (1,n2); + Hashtbl.add node_pred n2 n1 ) - nodes nodes2 nodes3; - (fun n -> try Hashtbl.find node_succ n with Not_found -> []) - + nodes nodes2 ; + update_tbl dir node_succ node_pred; + (fun n -> Hashtbl.find_all node_succ n), + (fun n -> Hashtbl.find_all node_pred n) let (gen_ring: bool -> int -> Topology.t) = fun directed nb -> let nodes = (create_nodes "p" (0,nb)) in let nl = id_to_empty_nodes nodes in + let succ, pred = neighbours_ring directed nodes in { nodes = nl; - succ = neighbours_ring directed nodes; + succ = succ; + pred = pred; of_id = get_of_id nl; directed = directed; attributes = [] @@ -87,7 +111,10 @@ let (gen_grid: bool -> int -> int -> Topology.t) = Printf.eprintf "Computing a %ix%i grid...\n" length width; flush stderr; let nb = length*width in - let nodes = (create_nodes "p" (0,nb)) and table = Hashtbl.create nb in + let nodes = (create_nodes "p" (0,nb)) + and succ_t = Hashtbl.create nb + and pred_t = Hashtbl.create nb + in for i=0 to length-1 do for j=0 to width-1 do let n_id = (List.nth nodes (j*length + i)) in @@ -97,53 +124,65 @@ let (gen_grid: bool -> int -> int -> Topology.t) = let bdown = if(j=(width-1)) then 0 else 1 in for ip=bl to br do for jp=bup to bdown do - if not ((ip=0 && jp=0) || (ip=jp) || (ip = -jp)) then - (Hashtbl.replace table n_id - ((1,(List.nth nodes ((j+jp)*length + i+ip)))::( - try Hashtbl.find table n_id with Not_found -> [])); ) else () + let n_id2 = List.nth nodes ((j+jp)*length + i+ip) in + if not ((ip=0 && jp=0) || (ip=jp) || (ip = -jp)) && (n_id<n_id2) + then ( + Hashtbl.add succ_t n_id (1, n_id2); + Hashtbl.add pred_t n_id2 n_id + ) done; done; done; done; let nl = id_to_empty_nodes nodes in + update_tbl directed succ_t pred_t; Printf.eprintf "Computing a %ix%i grid: Done!\n" length width;flush stderr; { nodes = nl; - succ = (fun nid -> (try Hashtbl.find table nid with Not_found -> [])); + succ = (fun nid -> Hashtbl.find_all succ_t nid); + pred = (fun nid -> Hashtbl.find_all pred_t nid); of_id = get_of_id nl; directed = directed; attributes = [] } -let rec link_hypercube_nodes : (node_id array -> node_succ_t -> unit) = - fun na n_s -> - let len = Array.length na in let mid = len / 2 in +let rec link_hypercube_nodes : + (node_id array -> node_succ_t -> node_pred_t -> unit) = + fun na n_s n_p -> + let len = Array.length na in + let mid = len / 2 in if len > 1 then - let n1 = (Array.sub na 0 mid) and n2 = (Array.sub na mid mid) in - link_hypercube_nodes n1 n_s; - link_hypercube_nodes n2 n_s; - Array.iter2 (fun node1 node2 -> - Hashtbl.replace n_s node1 - (( 1,node2)::(try Hashtbl.find n_s node1 with Not_found -> [])); - Hashtbl.replace n_s node2 - ((1,node1)::(try Hashtbl.find n_s node2 with Not_found -> [])) + let n1 = (Array.sub na 0 mid) + and n2 = (Array.sub na mid mid) in + link_hypercube_nodes n1 n_s n_p; + link_hypercube_nodes n2 n_s n_p; + Array.iter2 (fun node1 node2 -> + if node1 < node2 then ( + Hashtbl.add n_s node1 (1, node2) + ) ) n1 n2 -let neighbours_hyper_cube : (node_id list -> (node_id -> (int * node_id) list)) = - fun nl -> +let (neighbours_hyper_cube : bool -> node_id list -> + (node_id -> (int * node_id) list) * (node_id -> node_id list)) = + fun dir nl -> let na = Array.of_list nl in let (node_succ:node_succ_t) = Hashtbl.create (Array.length na) in - link_hypercube_nodes na node_succ; - (fun n -> try Hashtbl.find node_succ n with Not_found -> []) + let (node_pred:node_pred_t) = Hashtbl.create (Array.length na) in + link_hypercube_nodes na node_succ node_pred; + update_tbl dir node_succ node_pred; + (fun n -> Hashtbl.find_all node_succ n), + (fun n -> Hashtbl.find_all node_pred n) let gen_hyper_cube : (bool -> int -> Topology.t) = fun directed dim -> let nb = int_of_float (2. ** (float_of_int dim)) in let nodes = (create_nodes "p" (0,nb)) in let nl = id_to_empty_nodes nodes in + let succ, pred = neighbours_hyper_cube directed nodes in { nodes = nl; - succ = neighbours_hyper_cube nodes; + succ = succ; + pred = pred; of_id = get_of_id nl; directed = directed; attributes = [] diff --git a/tools/gg/ggcore.ml b/tools/gg/ggcore.ml index ddcaef5b7dcf6ee906b297383e27d35154a628dd..6429315435fd46484f6e7ad07e44c7af4cea1dfb 100644 --- a/tools/gg/ggcore.ml +++ b/tools/gg/ggcore.ml @@ -2,6 +2,7 @@ open Sasacore.Topology type node_ofId_t = (string, node) Hashtbl.t +(* TODO: should be tail-recursive+tmp is a poor name *) let rec create_nodes : (string -> int*int -> node_id list) = (* Create names from a generic name *) fun name (start,finish) -> diff --git a/tools/gg/ggcore.mli b/tools/gg/ggcore.mli index f87e17374b028c689c7a988eb2095dfbd325630e..ad0b56586e3240efcf3f7c333129902b3a7e0569 100644 --- a/tools/gg/ggcore.mli +++ b/tools/gg/ggcore.mli @@ -3,7 +3,8 @@ open Sasacore.Topology (** Create a name (i.d. node ID) list from a generic name *) val create_nodes : (string -> int*int -> node_id list) -(** creates a list of nodes, each having an ID from the list given in argument, and no file or init value. *) +(** creates a list of nodes, each having an ID from the list given in + argument, and no file or init value. *) val id_to_empty_nodes : (node_id list -> node list) (** create a function to get a node from it's ID *) diff --git a/tools/gg/graphGen.ml b/tools/gg/graphGen.ml index d01f2d1cf29636e0efe8883b0720be6c45821282..c7f17afffe7cf05f4e311064de5352e104361317 100644 --- a/tools/gg/graphGen.ml +++ b/tools/gg/graphGen.ml @@ -10,7 +10,9 @@ open Sasacore exception Incorrect_attribute let min_max = ref None -let connected_cyclic = ref None +let connected = ref None +let cyclic = ref None +let tree = ref None let height:int option ref = ref None let generate_du_dur graph plan_udg t : unit = @@ -81,8 +83,8 @@ let compute_attr : (Topology.t -> string list -> (string * string) list) = ) *) -let all_attr : (Topology.t -> (string * string) list) = - fun g -> +let all_attr : bool -> (Topology.t -> (string * string) list) = + fun diameter g -> [ "min_deg", string_of_int (match !min_max with | None -> ( @@ -103,43 +105,44 @@ let all_attr : (Topology.t -> (string * string) list) = snd x) | Some x -> snd x); "is_connected", string_of_bool ( - match !connected_cyclic with + match !connected with | None -> ( Printf.eprintf "Computing the connection...\n"; flush stderr; - let x = Topology.is_connected_and_cyclic g in - connected_cyclic := Some x; - fst x) - | Some x -> fst x ); + let x = Topology.is_connected g in + connected := Some x; + x) + | Some x -> x ); "is_cyclic", string_of_bool - (match !connected_cyclic with + (match !cyclic with | None -> ( Printf.eprintf "Computing the cyclicity...\n"; flush stderr; - let x = Topology.is_connected_and_cyclic g in - connected_cyclic := Some x; - snd x) - | Some x -> snd x ); + let x = Topology.is_cyclic g in + cyclic := Some x; + x) + | Some x -> x ); "is_tree", string_of_bool - (match !connected_cyclic with + (match !tree with | None -> ( Printf.eprintf "Computing the tree-ness...\n"; flush stderr; - let x = Topology.is_connected_and_cyclic g in - connected_cyclic := Some x; - (fst x) && not (snd x)) - | Some x -> (fst x) && (snd x) ); + let x = Topology.is_tree g in + tree := Some x; + x + ) + | Some x -> x + ); "links_number", string_of_int ( Printf.eprintf "Computing the link_number...\n"; flush stderr; Topology.get_nb_link g); - (* - "diameter", string_of_int ( + ] @ (if not diameter then [] else + ["diameter", string_of_int ( Printf.eprintf "Computing the diameter...\n"; flush stderr; - Diameter.get g) - *) - ] + Diameter.get g) + ]) let to_dot_string : (Topology.t -> string -> (string * string) list -> string) = @@ -263,7 +266,7 @@ let () = ( | _ -> (Printf.fprintf stderr "Unexpected outcome. Command line : %s\n" (String.concat " " (Array.to_list Sys.argv)); assert false) in - if t.connected && not (fst (Topology.is_connected_and_cyclic g)) then + if t.connected && not (Topology.is_connected g) then if !trials > max_trials then None else (incr trials;gen_graph ()) else Some g @@ -275,7 +278,7 @@ let () = ( exit 2 | Some g -> g in - make_dot g t.outputFile (all_attr g); + make_dot g t.outputFile (all_attr t.diameter g); if (t.outputFile <> "" && not t.silent) then Printf.printf "Done.\nOutput file : '%s'\n" t.outputFile ) diff --git a/tools/gg/graphGen_arg.ml b/tools/gg/graphGen_arg.ml index b1ca3ab57a46910f51641b3ca6311e3e2938ce03..ee7b3ec2f1cb4bd16598041826b107ab759052b0 100644 --- a/tools/gg/graphGen_arg.ml +++ b/tools/gg/graphGen_arg.ml @@ -35,6 +35,7 @@ type t = { mutable silent : bool; mutable connected : bool; mutable directed : bool; + mutable diameter : bool; mutable _args : (string * Arg.spec * string) list; mutable _man : (string * (string list * action) list) list; @@ -69,8 +70,8 @@ let (make_args : unit -> t) = tree_edge = InTree; n = -1; grid = { - width = 0; - height = 0; + width = 4; + height = 4; }; er = 0.3; ba = 2; @@ -86,6 +87,7 @@ let (make_args : unit -> t) = silent = false; connected = false; directed = false; + diameter = false; _args = []; _man = []; @@ -299,6 +301,10 @@ let (mkoptab : string array -> t -> unit) = (Arg.Unit (fun () -> args.connected <- true)) [(["Try again until a connected graph is generated"],"void")]; + mkopt args ["--diameter"] + (Arg.Unit (fun () -> args.diameter <- true)) + [(["Compute the graph diameter and put it in the graph attributes"],"void")]; + mkopt args ["--directed";"-dir"] (Arg.Unit (fun () -> match args.action with | "ring" -> args.directed <- true diff --git a/tools/gg/graphGen_arg.mli b/tools/gg/graphGen_arg.mli index def2cdad10a6124068f1e060fba9b8e6a26f0eee..9fda7860830937a5ea579598cc0c6bf50f1d99f7 100644 --- a/tools/gg/graphGen_arg.mli +++ b/tools/gg/graphGen_arg.mli @@ -33,6 +33,7 @@ type t = { mutable silent : bool; mutable connected : bool; mutable directed : bool; + mutable diameter : bool; mutable _args : (string * Arg.spec * string) list; mutable _man : (string * (string list * action) list) list; diff --git a/tools/gg/randomGraph.ml b/tools/gg/randomGraph.ml index 5b4df62f9e0125bff439de2e2a2a96a25e42de25..1f766262397a40a1a1ffdd3798c2342fec1e3a61 100644 --- a/tools/gg/randomGraph.ml +++ b/tools/gg/randomGraph.ml @@ -3,98 +3,137 @@ open Topology open Ggcore open List -type node_succ_t = (node_id, (int * node_id) list) Hashtbl.t +type node_succ_t = (node_id, int * node_id) Hashtbl.t +type node_pred_t = (node_id, node_id) Hashtbl.t type probability = float (*between 0 and 1*) +(* Add symmetric edges when not directed *) +let update_tbl directed succ pred = + if not directed then ( + Hashtbl.iter + (fun n1 (_, n2) -> + if not (List.mem (1,n1) (Hashtbl.find_all succ n2)) then + Hashtbl.add succ n2 (1,n1)) + (Hashtbl.copy succ); + Hashtbl.iter + (fun n1 n2 -> + if not (List.mem n1 (Hashtbl.find_all pred n2)) then + Hashtbl.add pred n2 n1) + (Hashtbl.copy pred); + ) + + let gen_ER : (bool -> int -> probability -> Topology.t) = fun directed nb p -> - let (node_succ:node_succ_t) = Hashtbl.create nb - and nodes = create_nodes "p" (0,nb) + let (node_succ:node_succ_t) = Hashtbl.create nb in + let (node_pred:node_pred_t) = Hashtbl.create nb in + let nodes = create_nodes "p" (0,nb) in + let succ n = Hashtbl.find_all node_succ n in + let pred n = Hashtbl.find_all node_pred n in + let add_succ n m = + Hashtbl.add node_succ n (1,m); + Hashtbl.add node_pred m n in - let succ n = try Hashtbl.find node_succ n with Not_found -> [] in - let add_succ n m = Hashtbl.replace node_succ n ((1,m)::(succ n)) in iteri (fun i n -> iteri (fun j m -> if not directed then ( - if i < j && (Random.float 1.) < p then ( - add_succ n m; - add_succ m n - ); - ) else ( - if i <> j && (Random.float 1.) < p then - add_succ n m; - ) + if i < j && (Random.float 1.) < p then add_succ n m) + else ( + if i <> j && (Random.float 1.) < p then add_succ n m) ) nodes ) nodes; let nl = id_to_empty_nodes nodes in - { + update_tbl directed node_succ node_pred; + { nodes = nl; succ = succ; + pred = pred; of_id = get_of_id nl; directed = directed; attributes = [] } - -let rec init_m_nodes : (int -> node_succ_t -> node_id list -> node_id list) = - fun i node_succ -> - function - | (node::tail) -> +(* split the list, the 1st one having the first m nodes *) +let get_m_nodes m nodes = + let rec f i acc nodes = + match nodes with + | [] -> assert false + | (node::tail) -> if i > 0 then - (Hashtbl.replace node_succ node []; - init_m_nodes (i-1) node_succ tail) - else node::tail - | _ -> assert false + f (i-1) (node::acc) tail + else + List.rev acc, nodes + in + f m [] nodes -let (neighbours_BA : node_id list -> int -> node_succ_t -> - (node_id -> (int * node_id) list)) = - fun nodes m node_succ -> +let (neighbours_BA : node_id list -> int -> node_succ_t -> node_pred_t -> + ((node_id -> (int * node_id) list) * (node_id -> node_id list))) = + fun nodes m node_succ node_pred -> let d_tot = 2 * m in - let nodes = init_m_nodes m node_succ nodes in + let m_nodes, nodes = get_m_nodes m nodes in + List.iter (fun n -> + Hashtbl.remove node_succ n; + Hashtbl.remove node_pred n; + ) + m_nodes; match nodes with | [] -> assert false | head::nodes -> - Hashtbl.replace node_succ head - (Hashtbl.fold - (fun n _ succ -> - Hashtbl.replace node_succ n [(1,head)]; - (1,n)::succ) node_succ [] - ); - (*init terminée. On a un graph connexe pour les m+1 premiers points, - nl ne contient que les points non ajoutés*) + List.iter (fun n -> + Hashtbl.add node_succ n (1,head); + Hashtbl.add node_succ head (1,n); + Hashtbl.add node_pred head n ; + Hashtbl.add node_pred n head + ) + m_nodes; + (*init terminée. On a un graph connexe pour les m premiers points, + nodes ne contient que les points non ajoutés*) ignore ( fold_left (fun deg_tot node -> - let deg_temp = deg_tot in - let succ = ref [] in - let deg_temp = ref deg_temp in + let succ = ref [] in (* hold the m new links for node *) + let deg_ref = ref deg_tot in for _ = 0 to m-1 do (*for each edge to create*) - let ran = Random.int !deg_temp in + let ran = Random.int !deg_ref in + let visited = ref [] in ignore ( Hashtbl.fold - (fun n_id n_succ r -> - if r >= 0 && not (List.mem (1,n_id) !succ) then - let r = r - (length n_succ) in - if r < 0 then ( + (fun n_id _ r -> + let skip = List.mem n_id !visited in + if not skip then visited := n_id::!visited; + (* skip is used to make sure n_id is considered once *) + if (r >= 0 && not skip) then ( + let n_succ = Hashtbl.find_all node_succ n_id in + let d_n_id = length n_succ in + let r = r - d_n_id in + if r < 0 && not skip then ( succ := (1,n_id)::!succ; - Hashtbl.replace node_succ n_id - ((1,node)::n_succ); - deg_temp := !deg_temp - length n_succ + deg_ref := !deg_ref - d_n_id ); r + ) else r ) - node_succ ran); + node_succ + ran); done; - Hashtbl.replace node_succ node !succ; + assert (length !succ = m); + List.iter (fun s -> + Hashtbl.add node_succ node s; + Hashtbl.add node_succ (snd s) (1,node); + Hashtbl.add node_pred (snd s) node ; + Hashtbl.add node_pred node (snd s) + ) + !succ; (deg_tot + (2 * m)) ) d_tot nodes ); - (fun n -> try Hashtbl.find node_succ n with Not_found -> []) + (fun n -> Hashtbl.find_all node_succ n), + (fun n -> Hashtbl.find_all node_pred n) let gen_BA : (bool -> int -> int -> Topology.t) = fun directed nb m -> @@ -102,8 +141,9 @@ let gen_BA : (bool -> int -> int -> Topology.t) = Printf.eprintf "A Barabasi–Albert graph cannot be directed\n%!"; exit 2 ); - let (node_succ:node_succ_t) = Hashtbl.create nb - and nodes = create_nodes "p" (0,nb) in + let (node_succ:node_succ_t) = Hashtbl.create nb in + let (node_pred:node_pred_t) = Hashtbl.create nb in + let nodes = create_nodes "p" (0,nb) in if nb < m + 1 then (Printf.eprintf "Error: with -m %d, the node number needs to be at least %d (it is %d).\n%!" @@ -111,17 +151,20 @@ let gen_BA : (bool -> int -> int -> Topology.t) = exit 2 ); let nl = id_to_empty_nodes nodes in + let succ, pred = neighbours_BA nodes m node_succ node_pred in { nodes = nl; - succ = neighbours_BA nodes m node_succ; + succ = succ; + pred = pred; of_id = get_of_id nl; directed = directed; attributes = [] } -let pre_rand_tree : (GraphGen_arg.tree_edge -> node_succ_t -> node_id list -> - (node_id -> (int * node_id) list)) = - fun tree_edge node_succ -> +let (pre_rand_tree : bool -> GraphGen_arg.tree_edge -> node_succ_t -> + node_pred_t -> node_id list -> + ((node_id -> (int * node_id) list) * (node_id -> node_id list))) = + fun dir tree_edge node_succ node_pred -> function | [] -> failwith "Tree Error : You need at least one nodes in your tree" | h::t -> @@ -132,28 +175,35 @@ let pre_rand_tree : (GraphGen_arg.tree_edge -> node_succ_t -> node_id list -> - up edges - both *) - if tree_edge <> GraphGen_arg.OutTree then - (Hashtbl.replace node_succ no - ((1,elem)::(try Hashtbl.find node_succ no with Not_found -> []))); - if tree_edge <> GraphGen_arg.InTree then - Hashtbl.replace node_succ elem - ((1,no)::(try Hashtbl.find node_succ elem with Not_found -> [])); + if tree_edge <> GraphGen_arg.OutTree then ( + Hashtbl.add node_succ no (1,elem); + Hashtbl.add node_pred elem no + ); + if tree_edge <> GraphGen_arg.InTree then ( + Hashtbl.add node_succ elem (1,no); + Hashtbl.add node_pred no elem + ); (elem::acc) ) [h] (t)); - (fun n -> try Hashtbl.find node_succ n with Not_found -> []) + update_tbl dir node_succ node_pred; + (fun n -> Hashtbl.find_all node_succ n), + (fun n -> Hashtbl.find_all node_pred n) let (rand_tree: GraphGen_arg.tree_edge -> bool -> int -> Topology.t) = fun tree_edge directed nb -> - let (node_succ:node_succ_t) = Hashtbl.create nb - and nodes = "root"::(create_nodes "p" (1,nb-1)) in - let nl = id_to_empty_nodes nodes in - { - nodes = nl; - succ = (pre_rand_tree tree_edge node_succ nodes); - of_id = get_of_id nl; - directed = directed; - attributes = [] - } + let (node_succ:node_succ_t) = Hashtbl.create nb in + let (node_pred:node_pred_t) = Hashtbl.create nb in + let nodes = "root"::(create_nodes "p" (1,nb-1)) in + let nl = id_to_empty_nodes nodes in + let succ, pred = pre_rand_tree directed tree_edge node_succ node_pred nodes in + { + nodes = nl; + succ = succ; + pred = pred; + of_id = get_of_id nl; + directed = directed; + attributes = [] + } type node_udg = node_id*float*float @@ -171,30 +221,35 @@ let (dist_udg: node_udg -> node_udg -> float) = let gen_qudg : (bool -> int -> float -> float -> float -> float -> float -> (Topology.t * plan_udg)) = fun directed nb x y r0 r1 p -> - let (node_succ:node_succ_t) = Hashtbl.create nb and nodes = create_nodes "p" (0,nb) in + let (node_succ:node_succ_t) = Hashtbl.create nb in + let (node_pred:node_pred_t) = Hashtbl.create nb in + let nodes = create_nodes "p" (0,nb) in let pl = (make_plan_udg nodes x y) in List.iter (fun n_udg -> - let (node, _, _) = n_udg in - List.iter (fun elem -> - let (n,_,_) = elem and dist = dist_udg n_udg elem in - - if node <> n && (dist <= r0 || (dist <= r1 && Random.float 1. <= p)) - (* e.q. if the node is : (within the radius r0) - or : (within the radius r1, with a brobability of p) *) - then ( - Hashtbl.replace node_succ node - ((1,n)::(try Hashtbl.find node_succ node with Not_found -> [])) - ) - ) pl - ) pl; + let (node, _, _) = n_udg in + List.iter (fun elem -> + let (n,_,_) = elem and dist = dist_udg n_udg elem in + if node <> n && + (dist <= r0 || (dist <= r1 && Random.float 1. <= p)) + (* e.g. if the node is : (within the radius r0) + or : (within the radius r1, with a probability of p) *) + then ( + Hashtbl.add node_succ node (1,n); + Hashtbl.add node_pred n node; + ) + ) pl + ) pl; let nl = id_to_empty_nodes nodes in + update_tbl directed node_succ node_pred; { nodes = nl; - succ =(fun n -> (try Hashtbl.find node_succ n with Not_found -> [])); + succ = (fun n -> Hashtbl.find_all node_succ n); + pred = (fun n -> Hashtbl.find_all node_pred n); of_id = get_of_id nl; directed = directed; attributes = [] },pl -let gen_udg : (bool -> int -> float -> float -> float -> (Topology.t * plan_udg)) = +let (gen_udg : bool -> int -> float -> float -> float -> + (Topology.t * plan_udg)) = fun directed nb x y r -> (gen_qudg directed nb x y r 0. 0.) diff --git a/tools/gg/randomGraph.mli b/tools/gg/randomGraph.mli index 63e5009441f23c8568b3fa2e7d1460c8a98a9460..90bdfcdd99ecbb559847525663524609382a3c1a 100644 --- a/tools/gg/randomGraph.mli +++ b/tools/gg/randomGraph.mli @@ -9,28 +9,31 @@ type plan_udg = node_udg list of n nodes and of probability p for each possible edge to appear. *) val gen_ER : bool -> int -> probability -> Topology.t -(** [gen_BA n m] generate a graph using Barabasi–Albert model, - of n nodes and with m edges added for each new node. - m has to be lower than n. - The initialization is a star of m+1 nodes, with the (m+1)th node being the root. - Barabasi–Albert model is used for the remaining nodes *) +(** [gen_BA n m] generate a graph using Barabasi–Albert model, of n + nodes and with m edges added for each new node. m has to be lower + than n. + + The initialization is a star of m+1 nodes, with the (m+1)th node + being the root. Barabasi–Albert model is used for the remaining + nodes *) val gen_BA : bool -> int -> int -> Topology.t (** [rand_tree n] generate a random tree of n nodes *) val rand_tree: GraphGen_arg.tree_edge -> bool -> int -> Topology.t -(** [gen_udg nb x y r] generate a graph using the Unit Disc Graph model, of n nodes. - w and h are the width and the height of the area in which the nodes are randomly disposed, - and r is the radius around each node, in which all the other nodes will be neighbors. - *) +(** [gen_udg nb x y r] generate a graph using the Unit Disc Graph + model, of n nodes. w and h are the width and the height of the + area in which the nodes are randomly disposed, and r is the radius + around each node, in which all the other nodes will be neighbors. + *) val gen_udg : bool -> int -> float -> float -> float -> (Topology.t * plan_udg) -(** [gen_qudg nb x y r0 r1 p] generate a graph using the Quasi Unit Disc Graph model, of n nodes. - w and h are the width and the height of the area in which the nodes are randomly disposed. - r0, r1 and p are three values to determine if two nodes, at a distance d of each other, - are neighbors. If d <= r0, they are neighbors. Otherwise, if d <= r1, - they have a probability of p of being neighbors. - *) +(** [gen_qudg nb x y r0 r1 p] generate a graph using the Quasi Unit + Disc Graph model, of n nodes. w and h are the width and the height + of the area in which the nodes are randomly disposed. r0, r1 and p + are three values to determine if two nodes, at a distance d of each + other, are neighbors. If d <= r0, they are neighbors. Otherwise, if + d <= r1, they have a probability of p of being neighbors. *) val gen_qudg: bool -> int -> float -> float -> float -> float -> float -> (Topology.t * plan_udg) diff --git a/tools/simca/coloring_campaign.ml b/tools/simca/coloring_campaign.ml index 6902c24440915cf648ef8e5d1d98b34c5d5cad9e..55c593398dd39417b2641466502e83fd17964af0 100644 --- a/tools/simca/coloring_campaign.ml +++ b/tools/simca/coloring_campaign.ml @@ -8,9 +8,6 @@ let algos = ["../../test/alea-coloring-alt"; "../../test/alea-coloring-unif"; "../../test/alea-coloring"] let daemons = ["-sd";"-lcd";"-dd"] -(* let cliques = List.init 25 (fun n -> Clique (20*(n+1))) (* [20; 40; ...; 500] *) *) -(* let rings = List.init 25 (fun n -> Ring (400*(n+1))) (* [400; 800; ...; 10000] *) *) -(* let er = List.init 25 (fun n -> ER (10*(n+1), 0.4)) (* [10; 20; ...; 250] *) *) let rings = List.init 10 (fun n -> Ring (500*(n+1))) (* [500; 1000; ...; 5000] *) let cliques = List.init 10 (fun n -> Clique (30*(n+1))) (* [30; 60; ...; 300] *) let er = List.init 10 (fun n -> ER (30*(n+1), 0.4)) (* [30; 60; ...; 300] *) @@ -27,5 +24,3 @@ let gen_pdf () = parse_log ["Col-a3","alea-coloring-alt"] gl daemons; List.iter (fun n -> sh ("./gen_pdf_paper.r "^n^".data coloring4zpaper")) gl; List.iter (fun n -> sh ("./gen_pdf.r "^n^".data coloring")) gl - - diff --git a/tools/simca/nonreg_test_campaign.ml b/tools/simca/nonreg_test_campaign.ml index a841859452d63ea83b486593da6d4ee994672517..bc24c4c6c8530eb40288334dbd2db0025dcf4b99 100644 --- a/tools/simca/nonreg_test_campaign.ml +++ b/tools/simca/nonreg_test_campaign.ml @@ -27,5 +27,3 @@ let gen_pdf () = parse_log ["Smallest When Activated","alea-coloring"] gl daemons; parse_log ["Always the Biggest", "alea-coloring-alt"] gl daemons; List.iter (fun n -> sh ("./gen_pdf.r "^n^".data nonreg")) gl - -