(* Time-stamp: <modified the 14/06/2019 (at 13:46) by Erwan Jahier> *)

(** Process programmer API *)

(* val copy_value : value -> value *)

type 'v local_env

val empty_env: 'v local_env
val set : 'v local_env -> string -> 'v -> 'v local_env
val get : 'v local_env -> string -> 'v 

(** Types of value *)
type varT = string
type vars = (string * varT) list 

type 'v neighbor = {
  lenv:  'v local_env;
  n_vars: vars;
  pid: unit -> string; (* Returns the pid of the neigbhor. This info
                          is not available in all modes (e.g.,
                          anonymous) *)
  reply: unit -> int; 
  (* Returns the channel number that let this neighbor access to the
     content of the process, if the neighbor can access to the
     process.  Returns -1 if the neigbor can not access to the
     process, which can happen in directed graphs only.  This info is
     not available in all modes *)
}

type action = string (* label *)
type 'v enable_fun = 'v neighbor list -> 'v local_env -> action list
type 'v step_fun   = 'v neighbor list -> 'v local_env -> action -> 'v local_env

(** Those 3 registering functions must be called! *)
type algo_id = string
val reg_vars : algo_id -> vars -> unit
val reg_enable : algo_id  -> 'v enable_fun -> unit
val reg_step : algo_id  -> 'v step_fun -> unit

(** raised by sasa if one of the function above is not called *)
exception Unregistred of string * string

(** This one is not mandatory.  The initialisation done in the dot
   file have priority over this one.  *)
val reg_init_vars : algo_id -> ('v neighbor list -> 'v local_env) -> unit

(** Mandatory in custom mode only. *)
val reg_actions : algo_id -> action list -> unit
val reg_value_to_string : ('v -> string) -> unit
val reg_value_to_data : ('v -> Data.t) -> unit
val reg_copy_value : ('v -> 'v) -> unit

(** util(s) *)
(** Global infos *)

val card : unit -> int
(* val degree : unit -> int *)
(* val diameter : unit -> int *)
  

(**/**)
(** functions below are not part of the API *)
val copy_local_env : vars -> 'v local_env -> 'v local_env
val string_of_local_env : vars -> 'v local_env -> string
val rif_of_local_env : vars -> 'v local_env -> string
val sl_of_local_env : vars -> string -> 'v local_env -> (string * 'v) list


val vart_to_rif_decl: varT -> string -> (string * string) list
val vart_to_rif_string: varT -> string -> string
val verbose_level: int ref
val set_card : int -> unit
(* val set_degree :  int -> unit *)
(* val set_diameter : int -> unit *)

(** the following functions are used by sasa *)
val get_vars   : algo_id -> vars
val get_enable : algo_id -> 'v enable_fun
val get_step   : algo_id -> 'v step_fun 
val get_init_vars : algo_id -> (string * varT) list -> 'v neighbor list -> 'v local_env
val get_actions   : algo_id -> action list
val get_value_to_string : unit -> ('v -> string)
val get_value_to_data : unit -> ('v -> Data.v)
val get_copy_value : unit -> ('v -> 'v)