Commit 4f5a18d5 authored by erwan's avatar erwan

Update: monadisation of Lutin, part 7

Rationale: make rdbg time traveling work.
parent a45b468e
......@@ -63,7 +63,7 @@ let huge_weight = W_huge
type raise_desc = string
(** GOTO *)
type stable_state = CoTraceExp.t
type stable_state = Expand.tbl CoTraceExp.t
(* type cond = CoAlgExp.t list *)
type cond = Guard.t
......@@ -112,7 +112,7 @@ let make_config state = { data = None; control = state }
(** STATE MANAGMENT *)
type state_info =
SS_stable of CoTraceExp.t
SS_stable of Expand.tbl CoTraceExp.t
| SS_transient
| SS_final of string
......@@ -127,7 +127,7 @@ type trans = {
}
module TraceMap = struct
include Map.Make(struct type t = CoTraceExp.t let compare = compare end)
include Map.Make(struct type t = Expand.tbl CoTraceExp.t let compare = compare end)
end
module ConfigMap = struct
......@@ -152,7 +152,7 @@ type t = {
(* Gestion des puits *)
nb_sinks : int;
_state2trace : CoTraceExp.t StringMap.t ;
_state2trace : Expand.tbl CoTraceExp.t StringMap.t ;
_trace2state : string TraceMap.t ;
_config2ttree : ttree ConfigMap.t;
......@@ -348,7 +348,7 @@ let dump_cont str tt x = (
let gentrans
(xenv : Expand.t)
(data : Guard.store option) (* data env = inputs + pres *)
(x : CoTraceExp.t) (* control = lutin trace *)
(x : Expand.tbl CoTraceExp.t) (* control = lutin trace *)
= (
(*-------------------------------------------*)
(* Correspondance id de trace -> trace exp
......@@ -362,7 +362,7 @@ let gentrans
(*-------------------------------------------*)
let rec rec_gentrans
(data : Guard.store option) (* data env = inputs + pres *)
(x : CoTraceExp.t)
(x : Expand.tbl CoTraceExp.t)
(acc : cond)
(cont : callback)
= (
......@@ -814,7 +814,7 @@ printf " DEST: %s\n" tr.dest;
printf "]\n"
)
let new_stable_state (it: t) (e : CoTraceExp.t) = (
let new_stable_state (it: t) (e : Expand.tbl CoTraceExp.t) = (
let ssi = it.nb_stables in
let res = sprintf "state%d" ssi in
let it = { it with
......
......@@ -53,7 +53,7 @@ type trans = {
EXPANSEE correspondant à l'état, c'est pas forcement tres
lisible => juste pour le debug ... *)
type state_info =
SS_stable of CoTraceExp.t
SS_stable of Expand.tbl CoTraceExp.t
| SS_transient
| SS_final of string
......@@ -81,7 +81,7 @@ val init : Expand.t -> t
(* Construit TOUT l'automate *)
val make : Expand.t -> t
val get_state_def : t -> string -> CoTraceExp.t
val get_state_def : t -> string -> Expand.tbl CoTraceExp.t
val get_state_info : t -> string -> state_info
......
......@@ -37,6 +37,14 @@ end
type snt = (sol_nb * sol_nb) BddMap.t
type t = snt * Formula_to_bdd.t
let tbl_to_string (snt,f2b) =
(BddMap.fold
(fun bdd (sn1, sn2) acc ->
Printf.sprintf "%s; %i->%s,%s" acc
(Bdd.size bdd) (string_of_sol_nb sn1) (string_of_sol_nb sn2)
) snt "|bdd|->sol_number_left, sol_number_rigth: "
) ^ "\n" ^
(Formula_to_bdd.tbl_to_string f2b)
exception No_numeric_solution of t
let (clear : t -> t) =
......
......@@ -16,6 +16,7 @@
*)
type t
val tbl_to_string : t -> string
exception No_numeric_solution of t
......
......@@ -44,41 +44,35 @@ let new_escope () = []
type src_info = CoIdent.scope_stack
type t =
type 't t =
| TE_eps
| TE_ref of CoIdent.t
| TE_constraint of CoAlgExp.t * src_info
| TE_fby of t * t
| TE_prio of t list
| TE_para of t list
| TE_choice of (t * CoAlgExp.t option) list
| TE_dyn_choice of int * ((int * t) list)
| TE_noeps of t
| TE_loop of t
| TE_omega of t
(* version pour génération d'automates complets *)
| TE_loopi of int * CoAlgExp.t * CoAlgExp.t * t * src_info
| TE_loopa of int * CoAlgExp.t * CoAlgExp.t option * t * src_info
| TE_fby of 't t * 't t
| TE_prio of 't t list
| TE_para of 't t list
| TE_choice of ('t t * CoAlgExp.t option) list
| TE_dyn_choice of int * ((int * 't t) list)
| TE_noeps of 't t
| TE_loop of 't t
| TE_omega of 't t
| TE_loopi of int * CoAlgExp.t * CoAlgExp.t * 't t * src_info
| TE_loopa of int * CoAlgExp.t * CoAlgExp.t option * 't t * src_info
(* internal loop with inline weigth computer + compteur *)
| TE_dyn_loop of (int -> int * int) * int * t
| TE_assert of CoAlgExp.t * t * src_info
| TE_strong_assert of CoAlgExp.t * t * src_info
(* Takes a list (id,val) *)
| TE_exist of escope * t
| TE_dyn_loop of (int -> int * int) * int * 't t
| TE_assert of CoAlgExp.t * 't t * src_info
| TE_strong_assert of CoAlgExp.t * 't t * src_info
| TE_exist of escope * 't t
| TE_raise of string
| TE_try of t * t option
| TE_catch of string * t * t option
(* internal run (not running) *)
| TE_erun of string * escope * CoAlgExp.t list * t
(* internal run (running) *)
| TE_dyn_erun of string * Reactive.prg * CoIdent.t list * CoAlgExp.t list * t
| TE_dyn_erun_ldbg of string * Reactive.prg_ldbg * CoIdent.t list * CoAlgExp.t list * t
(* internal run (not running) *)
| TE_run of string * CoAlgExp.t * escope * CoAlgExp.t list * t * src_info
(* internal run (running) *)
| TE_dyn_run of string * Reactive.prg * CoAlgExp.t * escope * CoAlgExp.t list * t * src_info
| TE_dyn_run_ldbg of string * Reactive.prg_ldbg * CoAlgExp.t * escope * CoAlgExp.t list * t * src_info
| TE_try of 't t * 't t option
| TE_catch of string * 't t * 't t option
(* internal run *)
| TE_erun of string * escope * CoAlgExp.t list * 't t
| TE_dyn_erun of string * Reactive.prg * CoIdent.t list * CoAlgExp.t list * 't t
| TE_dyn_erun_ldbg of string * 't Reactive.prg_ldbg * CoIdent.t list * CoAlgExp.t list * 't t
| TE_run of string * CoAlgExp.t * escope * CoAlgExp.t list * 't t * src_info
| TE_dyn_run of string * Reactive.prg * CoAlgExp.t * escope * CoAlgExp.t list * 't t * src_info
| TE_dyn_run_ldbg of string * 't Reactive.prg_ldbg * CoAlgExp.t * escope * CoAlgExp.t list * 't t * src_info
(** Batterie de créateurs *)
......@@ -89,10 +83,10 @@ let of_run runid andexp scop args e si = TE_run (runid, andexp, List.rev scop, a
let of_constraint (ea : CoAlgExp.t) (si:src_info) = ( TE_constraint (ea,si) )
let of_ref (s : CoIdent.t) = ( TE_ref s )
let of_loop (e : t) = (TE_loop e)
let of_omega (e : t) = (TE_omega e)
let of_noeps (e : t) = (TE_noeps e)
let of_fby (e1 : t) (e2 : t) = (TE_fby (e1,e2))
let of_loop (e : 't t) = (TE_loop e)
let of_omega (e : 't t) = (TE_omega e)
let of_noeps (e : 't t) = (TE_noeps e)
let of_fby (e1 : 't t) (e2 : 't t) = (TE_fby (e1,e2))
let of_choice lst = TE_choice lst
let of_prio lst = TE_prio lst
let of_para lst = TE_para lst
......
......@@ -23,35 +23,35 @@ val new_escope : unit -> escope
val add_escope : escope -> (CoIdent.t * CoAlgExp.t option) -> escope
type src_info = CoIdent.scope_stack
type t =
type 't t =
| TE_eps
| TE_ref of CoIdent.t
| TE_constraint of CoAlgExp.t * src_info
| TE_fby of t * t
| TE_prio of t list
| TE_para of t list
| TE_choice of (t * CoAlgExp.t option) list
| TE_dyn_choice of int * ((int * t) list)
| TE_noeps of t
| TE_loop of t
| TE_omega of t
| TE_loopi of int * CoAlgExp.t * CoAlgExp.t * t * src_info
| TE_loopa of int * CoAlgExp.t * CoAlgExp.t option * t * src_info
| TE_fby of 't t * 't t
| TE_prio of 't t list
| TE_para of 't t list
| TE_choice of ('t t * CoAlgExp.t option) list
| TE_dyn_choice of int * ((int * 't t) list)
| TE_noeps of 't t
| TE_loop of 't t
| TE_omega of 't t
| TE_loopi of int * CoAlgExp.t * CoAlgExp.t * 't t * src_info
| TE_loopa of int * CoAlgExp.t * CoAlgExp.t option * 't t * src_info
(* internal loop with inline weigth computer + compteur *)
| TE_dyn_loop of (int -> int * int) * int * t
| TE_assert of CoAlgExp.t * t * src_info
| TE_strong_assert of CoAlgExp.t * t * src_info
| TE_exist of escope * t
| TE_dyn_loop of (int -> int * int) * int * 't t
| TE_assert of CoAlgExp.t * 't t * src_info
| TE_strong_assert of CoAlgExp.t * 't t * src_info
| TE_exist of escope * 't t
| TE_raise of string
| TE_try of t * t option
| TE_catch of string * t * t option
| TE_try of 't t * 't t option
| TE_catch of string * 't t * 't t option
(* internal run *)
| TE_erun of string * escope * CoAlgExp.t list * t
| TE_dyn_erun of string * Reactive.prg * CoIdent.t list * CoAlgExp.t list * t
| TE_dyn_erun_ldbg of string * Reactive.prg_ldbg * CoIdent.t list * CoAlgExp.t list * t
| TE_run of string * CoAlgExp.t * escope * CoAlgExp.t list * t * src_info
| TE_dyn_run of string * Reactive.prg * CoAlgExp.t * escope * CoAlgExp.t list * t * src_info
| TE_dyn_run_ldbg of string * Reactive.prg_ldbg * CoAlgExp.t * escope * CoAlgExp.t list * t * src_info
| TE_erun of string * escope * CoAlgExp.t list * 't t
| TE_dyn_erun of string * Reactive.prg * CoIdent.t list * CoAlgExp.t list * 't t
| TE_dyn_erun_ldbg of string * 't Reactive.prg_ldbg * CoIdent.t list * CoAlgExp.t list * 't t
| TE_run of string * CoAlgExp.t * escope * CoAlgExp.t list * 't t * src_info
| TE_dyn_run of string * Reactive.prg * CoAlgExp.t * escope * CoAlgExp.t list * 't t * src_info
| TE_dyn_run_ldbg of string * 't Reactive.prg_ldbg * CoAlgExp.t * escope * CoAlgExp.t list * 't t * src_info
(** Réinitialisation du module
pour les compteurs de loop (au cas où) ? *)
......@@ -65,44 +65,44 @@ val nb_loops : unit -> int
(** Batterie de créateurs *)
val of_erun : string -> escope -> CoAlgExp.t list -> t -> t
val of_erun : string -> escope -> CoAlgExp.t list -> 't t -> 't t
(* 2nd arg is an expression AND(x = x') *)
val of_run : string -> CoAlgExp.t -> escope -> CoAlgExp.t list -> t -> src_info -> t
val of_run : string -> CoAlgExp.t -> escope -> CoAlgExp.t list -> 't t -> src_info -> 't t
val of_constraint : CoAlgExp.t -> src_info -> t
val of_constraint : CoAlgExp.t -> src_info -> 't t
val of_ref : CoIdent.t -> t
val of_ref : CoIdent.t -> 't t
val of_loop : t -> t
val of_omega : t -> t
val of_loop : 't t -> 't t
val of_omega : 't t -> 't t
val of_loope : CoAlgExp.t -> t -> src_info -> t
val of_loope : CoAlgExp.t -> 't t -> src_info -> 't t
val of_loopi : CoAlgExp.t -> CoAlgExp.t -> t -> src_info -> t
val of_loopi : CoAlgExp.t -> CoAlgExp.t -> 't t -> src_info -> 't t
val of_loopa : CoAlgExp.t -> CoAlgExp.t option -> t -> src_info -> t
val of_loopa : CoAlgExp.t -> CoAlgExp.t option -> 't t -> src_info -> 't t
val of_fby : t -> t -> t
val of_fby : 't t -> 't t -> 't t
val of_prio : t list -> t
val of_prio : 't t list -> 't t
val of_para : t list -> t
val of_para : 't t list -> 't t
val of_choice : (t * CoAlgExp.t option ) list -> t
val of_choice : ('t t * CoAlgExp.t option ) list -> 't t
val of_assert : CoAlgExp.t -> t -> src_info -> t
val of_strong_assert : CoAlgExp.t -> t -> src_info -> t
val of_assert : CoAlgExp.t -> 't t -> src_info -> 't t
val of_strong_assert : CoAlgExp.t -> 't t -> src_info -> 't t
val of_exist : escope -> t -> t
val of_exist : escope -> 't t -> 't t
val of_raise : string -> t
val of_raise : string -> 't t
val of_catch : string -> t -> t option -> t
val of_catch : string -> 't t -> 't t option -> 't t
val of_try : t -> t option -> t
val of_try : 't t -> 't t option -> 't t
(** Pretty print *)
val dump : t -> unit
val dumps : t -> string
val dump : 't t -> unit
val dumps : 't t -> string
......@@ -123,14 +123,6 @@ type alias_info = {
ai_src : CoIdent.src_stack
}
(**
Trace : L'info contient juste l'expression associée
à la définition.
*)
type trace_info = {
ti_def_exp : CoTraceExp.t;
ti_src : CoIdent.src_stack ;
}
(**
Exception : pas grand chose à stocker : c'est juste un ident ...
......@@ -242,6 +234,36 @@ type t = {
(* global pack info, should be in some global struct shared by several t *)
gxlist : Syntaxe.except_info list;
}
and tbl = {
arg_opt: MainArg.t;
expanded_code: t;
(* translation CoIdent -> Exp.var is done once *)
in_vars: Exp.var list;
out_vars: Exp.var list;
loc_vars: Exp.var list;
(* (partial) initial values of global vars (ins/outs *)
init_pres: Value.OfIdent.t;
id2var_tab: Exp.var Util.StringMap.t;
(* REQUIRED BY SolveR.solve_formula *)
(* list of names for outputs ... *)
out_var_names: string list;
(* ... formula (and) for bool vars ... *)
bool_vars_to_gen: Exp.formula;
(* ... and var list for nums ! *)
num_vars_to_gen: Exp.var list;
snt: Solver.t;
}
(**
Trace : L'info contient juste l'expression associée
à la définition.
*)
and trace_info = {
ti_def_exp : tbl CoTraceExp.t;
ti_src : CoIdent.src_stack ;
}
(* get a run def *)
let get_run_expanded_code it rid = StringMap.find rid it.runtab
......@@ -612,7 +634,7 @@ ATTENTION:
new_trace enchaîne les deux !
*)
let create_trace (zeres: t) (i : Syntaxe.ident) (tgtid : CoIdent.t )
(edef : CoTraceExp.t) (sstack : CoIdent.scope_stack)
(edef : tbl CoTraceExp.t) (sstack : CoIdent.scope_stack)
: t =
let src = get_src_stack i.src sstack None in
{ zeres with
......@@ -620,7 +642,7 @@ let create_trace (zeres: t) (i : Syntaxe.ident) (tgtid : CoIdent.t )
}
let new_trace (zeres: t) (i : Syntaxe.ident) (tgtid : CoIdent.t )
(edef : CoTraceExp.t) (sstack : CoIdent.scope_stack) :t =
(edef : tbl CoTraceExp.t) (sstack : CoIdent.scope_stack) :t =
let zeres = create_trace zeres i tgtid edef sstack in
add_trace_target_id zeres i tgtid
......@@ -842,7 +864,7 @@ and
(env : CheckEnv.t)
(sstack : scope_stack)
(id : Syntaxe.ident)
(e:Syntaxe.val_exp) : CoTraceExp.t * t
(e:Syntaxe.val_exp) : tbl CoTraceExp.t * t
= (
(* info associée à id au cours du check *)
let info = CheckEnv.get_binding env id in
......@@ -1111,7 +1133,7 @@ and
(sstack : scope_stack)
(id : Syntaxe.ident)
(args : Syntaxe.val_exp list)
(e : Syntaxe.val_exp) : CoTraceExp.t * t
(e : Syntaxe.val_exp) : tbl CoTraceExp.t * t
= (
(* info associée à id au cours du check *)
let info = CheckEnv.get_binding env id in
......@@ -1397,7 +1419,7 @@ and
(i, te, iexp, None), zeres
and
treat_trace (zeres: t) (env : CheckEnv.t) (sstack : scope_stack) (e : Syntaxe.val_exp)
: CoTraceExp.t * t
: tbl CoTraceExp.t * t
= (
match e.it with
(* certainement cast implicite bool -> trace *)
......
......@@ -19,8 +19,6 @@ index
----------------------------------------------------------*)
(** Le type "résultat d'expansion" est abstrait *)
type t
(** Les paramètres de l'expansion sont :
-------------------------------------------------------
......@@ -34,7 +32,6 @@ type t
- Le node "main" (string)
-------------------------------------------------------
*)
val make : CheckEnv.t -> Syntaxe.package -> string -> t
(** Le résultat de l'expansion consiste en 3 tables indexées
par des idents cibles (CoIdent.t) :
......@@ -67,7 +64,10 @@ type support_info = {
si_init : CoAlgExp.t option ;
si_range : (CoAlgExp.t *CoAlgExp.t) option ;
}
(** Le type "résultat d'expansion" est abstrait *)
(* type t *)
and t
open Util
(* support_info that are actually used in pre's *)
val support_tab : t -> support_info StringMap.t
......@@ -105,11 +105,34 @@ val get_run_expanded_code : t -> CoIdent.t -> t
(** Info et table des alias trace *)
type trace_info = {
ti_def_exp : CoTraceExp.t;
type tbl = {
arg_opt: MainArg.t;
expanded_code: t;
(* translation CoIdent -> Exp.var is done once *)
in_vars: Exp.var list;
out_vars: Exp.var list;
loc_vars: Exp.var list;
(* (partial) initial values of global vars (ins/outs *)
init_pres: Value.OfIdent.t;
id2var_tab: Exp.var Util.StringMap.t;
(* REQUIRED BY SolveR.solve_formula *)
(* list of names for outputs ... *)
out_var_names: string list;
(* ... formula (and) for bool vars ... *)
bool_vars_to_gen: Exp.formula;
(* ... and var list for nums ! *)
num_vars_to_gen: Exp.var list;
snt: Solver.t;
}
and trace_info = {
ti_def_exp : tbl CoTraceExp.t;
ti_src : CoIdent.src_stack ;
}
val make : CheckEnv.t -> Syntaxe.package -> string -> t
val trace_tab : t -> trace_info StringMap.t
val get_trace_info : t -> CoIdent.t -> trace_info
......
......@@ -125,7 +125,7 @@ let init () =
bdd_tbl_global = FormulaMap.empty ;
}
let to_string t =
let tbl_to_string t =
Printf.sprintf " {
index_cpt=%i;
free_index_list = %s;
......@@ -783,12 +783,12 @@ and
let (f : t -> Var.env_in -> Var.env -> string -> int -> Exp.formula -> t * Bdd.t) =
fun t input memory ctx_msg vl f ->
let x1, x2, _ = translate_do t input memory ctx_msg vl f in
if vl > 0 then (
if vl > 1 then (
Printf.eprintf ">>> supp(Formula_to_bdd.f(%s)) = [%s] \n %s\n"
((formula_to_string f))
(String.concat ","
(List.map string_of_int (Bdd.list_of_support (Bdd.support x2))))
(to_string t);
(tbl_to_string t);
flush stderr
);
x1, x2
......
......@@ -13,6 +13,7 @@
type t
val init : unit -> t
val tbl_to_string : t -> string
val f : t -> Var.env_in -> Var.env -> string -> int -> Exp.formula -> t * Bdd.t
(** [Formula_to_bdd.f input memory ctx_msg verbosity_level f]
......
This diff is collapsed.
......@@ -92,7 +92,7 @@ val make_pre : Var.env_in -> Var.env_out -> Var.env_loc -> Var.env
type ctx = Event.t
type e = Event.t
val step: t -> control_state -> data_state -> t * control_state * data_state
val step_ldbg: ctx -> string -> t -> control_state -> data_state ->
val step_rdbg: ctx -> string -> t -> control_state -> data_state ->
(ctx -> t -> control_state -> data_state -> e) -> e
......
(* Time-stamp: <modified the 16/04/2019 (at 16:36) by Erwan Jahier> *)
(* Time-stamp: <modified the 25/04/2019 (at 10:21) by Erwan Jahier> *)
(**********************************************************************************)
type vars = (string * Data.t) list
......@@ -73,7 +73,7 @@ let make argv =
cont (to_subst_list lut_out new_ds.LutExe.outs) ctx
in
data_state := { !data_state with LutExe.ins = to_vals sl };
LutExe.step_ldbg ctx node !tables !ctrl_state !data_state cont_lut_step
LutExe.step_rdbg ctx node !tables !ctrl_state !data_state cont_lut_step
in
let mems_in =
List.fold_left
......
......@@ -2,19 +2,19 @@
(* abstract reactive program *)
type prg = DoStep of (Value.t list -> Value.t list * prg)
let step p = match p with DoStep _p -> _p
let step p = match p with DoStep p -> p
type ctx = Event.t
type e = Event.t
type prg_ldbg =
DoStep_ldbg of (ctx -> Value.t list -> (ctx -> prg_ldbg -> Value.t list -> e) ->
(ctx -> e) -> (ctx -> string -> e) -> e)
type 't prg_ldbg =
DoStep_ldbg of (ctx -> 't -> Value.t list ->
(ctx -> 't -> 't prg_ldbg -> Value.t list -> e) ->
(ctx -> 't -> e) -> (ctx -> 't -> string -> e) -> e)
let (step_ldbg : ctx -> prg_ldbg -> Value.t list
-> (ctx -> prg_ldbg -> Value.t list -> e)
-> (ctx -> e) -> (ctx -> string -> e) -> e) =
fun ctx p vl cont fail_cont ->
match p with DoStep_ldbg _p -> _p ctx vl cont fail_cont
let (step_ldbg : ctx -> 't -> 't prg_ldbg -> Value.t list
-> (ctx -> 't -> 't prg_ldbg -> Value.t list -> e)
-> (ctx -> 't -> e) -> (ctx -> 't -> string -> e) -> e) =
fun ctx t p vl cont fail_cont ->
match p with DoStep_ldbg p -> p ctx t vl cont fail_cont
......@@ -7,13 +7,15 @@ val step : prg -> Value.t list -> (Value.t list * prg)
type ctx = Event.t
type e = Event.t
type prg_ldbg =
DoStep_ldbg of (ctx -> Value.t list -> (ctx -> prg_ldbg -> Value.t list -> e) ->
(ctx -> e) -> (ctx -> string -> e) -> e)
val step_ldbg : ctx -> prg_ldbg -> Value.t list
-> (ctx -> prg_ldbg -> Value.t list -> e)
-> (ctx -> e) -> (ctx -> string -> e) -> e
type 't prg_ldbg =
DoStep_ldbg of (ctx -> 't -> Value.t list ->
(ctx -> 't -> 't prg_ldbg -> Value.t list -> e) ->
(ctx -> 't -> e) -> (ctx -> 't -> string -> e) -> e)
val step_ldbg : ctx -> 't -> 't prg_ldbg -> Value.t list
-> (ctx -> 't -> 't prg_ldbg -> Value.t list -> e)
-> (ctx -> 't -> e) -> (ctx -> 't -> string -> e) -> e
......@@ -25,6 +25,7 @@ let add_snt_entry = Bddd.add_snt_entry
let init = Bddd.init_snt
type t = Bddd.t
let tbl_to_string = Bddd.tbl_to_string
(****************************************************************************)
(****************************************************************************)
......
......@@ -30,6 +30,8 @@
(* The solver monad *)
type t = Bddd.t (* should be abstract! *)
val init : unit -> t
val tbl_to_string : t -> string
val is_satisfiable : t ->
Var.env_in -> Var.env -> int -> string -> Exp.formula -> string -> t * bool
(** [is_satisfiable input memory verbose_level msg f] suceeds iff the
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment