Newer
Older

erwan
committed
(* Time-stamp: <modified the 27/03/2019 (at 17:28) by Erwan Jahier> *)

erwan
committed
open Sasacore
let (update_env_with_init : Env.t -> Process.t list -> Algo.neighbor list list -> Env.t) =
fun e pl neighbors ->
let (aux: Env.t -> Process.t -> Algo.neighbor list -> Env.t) =
fun e p nl ->
List.fold_left
(fun e (n,_t) -> Env.set e p.pid n (p.init nl n))
e
p.variables
let (reply: Topology.t -> string -> string -> int) =
fun g source target ->
let rec f i = function

erwan
committed
| [] -> (-1) (* may happen in directed graphs *)
| x::t -> if x=source then i else f (i+1) t
in
f 0 (g.succ target)
let (get_neighors: Topology.t -> Process.t -> Topology.neighbor list) =
fun g p ->
let source_id = p.Process.pid in
let idl = g.succ source_id in
let algo_id = Filename.chop_suffix node.file ".cmxs" in
{
Topology.n_id = node.id;
Topology.n_vars = Algo.get_vars algo_id;
Topology.n_reply = reply g source_id id;
}
)
idl
let (dump_process: Process.t * Topology.neighbor list -> unit) =
fun (p,nl) ->
let pvars = StringOf.algo_vars p.variables in
let neighbors = List.map StringOf.topology_neighbor nl in
Printf.printf "process %s\n\tvars:%s\n\tneighors: \n\t\t%s\n" p.pid pvars
(String.concat "\n\t\t" neighbors)
let (update_env: Env.t -> Process.t * Algo.local_env -> Env.t) =
fun e (p, lenv) ->
List.fold_left
(fun e (n,_) -> Env.set e p.pid n (lenv n))
e
p.variables
open Process
let (to_algo_neighbor: Env.t -> Topology.neighbor -> Algo.neighbor) =
fun e n ->
{
lenv= Env.get e n.Topology.n_id;
n_vars = n.Topology.n_vars;
(* XXX For the 2 fields above, check the graph kind (anonymous,
identified, etc. *)
pid = (fun () -> n.n_id);
reply = (fun () -> n.n_reply);
let (print_step : int -> int -> SasArg.t -> Env.t -> Process.t list -> string ->
string -> unit) =
fun n i args e pl activate_val enable_val ->
if args.rif then (
if args.demon = Demon.Custom then (
(* in custom mode, to be able to talk with lurette, this should not be
printed on stdout
*)
Printf.eprintf "\n#step %s\n" (string_of_int (n-i+1)) ;
Printf.eprintf "%s #outs " activate_val; flush stderr
) else (
Printf.printf "\n#step %s\n" (string_of_int (n-i+1)) ;
Printf.printf "%s #outs " activate_val; flush stdout
Printf.printf "%s %s\n" (StringOf.env_rif e pl) enable_val;
flush stdout
)
else (
Printf.eprintf "step %s: %s %s\n"
(string_of_int (n-i+1)) (StringOf.env e pl) activate_val;
exception Silent of int
let (simustep: int -> int -> SasArg.t -> Process.t list -> string ->
(Process.t * Topology.neighbor list) list -> Env.t -> Env.t * string) =
fun n i args pl activate_val pl_n e ->
(* 1: Get enable processes *)
let all = List.fold_left
(fun acc (p,nl) ->
let nl4algo = List.map (to_algo_neighbor e) nl in
let lenv = Env.get e p.pid in
let al = p.enable nl4algo lenv in
let al = List.map (fun a -> p,nl,a) al in
assert (List.length pl = List.length all);
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)
pl
all
in
let enable_val =
String.concat " " (List.map (fun b -> if b then "t" else "f")
(List.flatten enab_ll))
in
if (List.flatten all = []) then (
print_step n i args e pl activate_val enable_val;
print_step n i args e pl activate_val enable_val;
Demon.f (args.verbose > 1) args.demon pl all enab_ll
(* 2: Do the steps *)
let lenv_list =
List.map (fun (p,nl,a) ->
let nl4algo = List.map (to_algo_neighbor e) nl in
let lenv = Env.get e p.pid in
p, p.step nl4algo lenv a)
(* 3: update the env *)
ne, next_activate_val
type t = SasArg.t * Process.t list * (Process.t * Topology.neighbor list) list * Env.t
let (make : string array -> t) =
fun argv ->
let args =
try SasArg.parse argv;
with
Failure(e) ->
output_string stdout e;
flush stdout ;
exit 2
| e ->
output_string stdout (Printexc.to_string e);
flush stdout;
exit 2
in
try
let dot_file = args.topo in
let g = Topology.read dot_file in
let nl = g.nodes in
let nstrl = List.map (fun n -> n.Topology.id) nl in
let nstr = String.concat "," nstrl in
Algo.verbose_level := args.verbose;
Random.init args.seed;
if !Algo.verbose_level > 0 then Printf.eprintf "nodes: %s\nedges:\n" nstr;
let pl = List.map (Process.make (args.demon=Custom)) nl in
let neighors = List.map (get_neighors g) pl in
let algo_neighors = List.map (List.map (to_algo_neighbor e)) neighors in
let e = update_env_with_init e pl algo_neighors in
if !Algo.verbose_level > 0 then List.iter dump_process pl_n;
if args.gen_lutin then (
let fn = (Filename.remove_extension args.topo) ^ ".lut" in
Printf.eprintf "%s already exists: rename it to proceed.\n" fn;
flush stderr; exit 1
Printf.fprintf oc "%s" (GenLutin.f pl);
flush oc;
close_out oc;
exit 0);
if args.rif then (
Printf.printf "%s" (Mypervasives.entete "#" SasaVersion.str SasaVersion.sha);
if args.demon <> Demon.Custom then
Printf.printf "#seed %i\n" args.seed;
Printf.printf "#inputs %s\n"
(if args.demon = Demon.Custom then (
let f p = List.map
(fun a -> "\""^p.pid ^(if a="" then "" else "_")^a^ "\":bool")
p.actions
in
String.concat " " (List.flatten (List.map f pl))
Printf.printf "#outputs %s\n" (StringOf.env_rif_decl pl);
if args.demon <> Demon.Custom then (
Printf.printf "The pseudo-random engine is used with seed %i\n" args.seed;
if args.ifi then (
List.iter
(fun p -> List.iter
(fun a -> ignore (RifRead.bool (args.verbose > 1) p a)) p.actions)
pl;
Printf.eprintf "Ignoring the first vectors of sasa inputs\n"; flush stderr;
);