Commit 5a3641ec authored by François Bobot's avatar François Bobot

new prover identification: remove id

       Remove the id in prover that is used only for command-line, use
       instead the name,version,alternative of the prover. One can
       also use regular expression (start with ^).

       "Alt-Ergo,0.92,with arrays" corresponds only to one prover
       "Alt-Ergo,^0\.9.*,with arrays" correspond to all the Alt-Ergo prover with arrays which version match "0\.9.*"
       "Alt-Ergo" is the same thing than "Alt-Ergo,^,^"
       "Alt-Ergo,0.92," corresponds only to one prover with the alternate fields empty
       "Alt-Ergo,,with arrays" corresponds to "Alt-Ergo,^,with arrays" since the version is never empty.

       Provers identification are case sensitive even if it is
       currently more complicated for the user because
       case-insensitiveness is not sufficient. Specifiying "alt-ergo"
       for "Alt-Ergo,^,^" is great, but not if there is more than one
       match. A more general system of shortcut would be more
       appropriate.
parent 043a5bcd
......@@ -87,10 +87,10 @@ bad_programs () {
valid_goals () {
for f in $1/*.mlw; do
echo -n " "$f"... "
if $pgml -L modules -t 10 -P alt-ergo $f | grep -q -v Valid; then
if $pgml -L modules -t 10 -P Alt-Ergo $f | grep -q -v Valid; then
echo "valid test $f failed!"
echo "$pgml -P alt-ergo $f"
$pgml -L modules -t 10 -P alt-ergo $f
$pgml -L modules -t 10 -P Alt-Ergo $f
exit 1
else
echo "ok"
......
......@@ -76,12 +76,15 @@ let main : Whyconf.main = Whyconf.get_main config
let provers : Whyconf.config_prover Whyconf.Mprover.t =
Whyconf.get_provers config
(* the [prover alt-ergo] section of the config file *)
(* One prover named Alt-Ergo in the config file *)
let alt_ergo : Whyconf.config_prover =
try
Whyconf.prover_by_id config "alt-ergo"
let fp = Whyconf.parse_filter_prover "Alt-Ergo" in
(** all the prover that have the name "Alt-Ergo" *)
let provers = Whyconf.filter_provers config fp in
snd (Whyconf.Mprover.choose provers)
with Whyconf.ProverNotFound _ ->
eprintf "Prover alt-ergo not installed or not configured@.";
eprintf "Prover Alt-Ergo not installed or not configured@.";
exit 0
(*
......
......@@ -56,7 +56,8 @@ let rec goal whyconf env path dbgoal wgoal =
let prover_name = Db.prover_name prover_id in
let driver, extra, command =
try
let p = Whyconf.prover_by_id whyconf prover_name in
let p = Whyconf.filter_one_prover whyconf
(Whyconf.parse_filter_prover prover_name) in
p.Whyconf.driver, p.Whyconf.extra_drivers,
String.concat " " (p.Whyconf.command :: p.Whyconf.extra_options)
with
......
......@@ -76,12 +76,9 @@ let read_tools absf wc map (name,section) =
(* provers *)
let provers = get_stringl ~default:[] section "prover" in
let find_provers s =
try let p = prover_by_id wc s in
s, p.driver, p.extra_drivers,
String.concat " " (p.command :: p.extra_options)
with
(* TODO add exceptions pehaps inside rc.ml in fact*)
| Not_found -> eprintf "Prover %s not found.@." s; exit 1 in
let p = filter_one_prover wc (parse_filter_prover s) in
s, p.driver, p.extra_drivers,
String.concat " " (p.command :: p.extra_options) in
let provers = List.map find_provers provers in
let provers =
try
......
......@@ -252,8 +252,8 @@ let () =
if !opt_list_provers then begin
opt_list := true;
let config = read_config !opt_config in
let print fmt prover pc = fprintf fmt "%s (%a)@\n"
pc.id print_prover prover in
let print fmt prover pc = fprintf fmt "%a (%a)@\n"
print_prover_parsable_format pc.prover print_prover prover in
let print fmt m = Mprover.iter (print fmt) m in
let provers = get_provers config in
printf "@[<hov 2>Known provers:@\n%a@]@." print provers
......@@ -343,7 +343,7 @@ let () =
let map_prover s =
let prover = prover_by_id config s in
let prover = filter_one_prover config (parse_filter_prover s) in
{ B.tval = {B.tool_name = "cmdline"; prover_name = s; tool_db = None};
ttrans = [Trans.identity,None];
tdriver = load_driver env prover.driver prover.extra_drivers;
......
......@@ -3,7 +3,7 @@ Require Export ZArith.
Open Scope Z_scope.
Require Export List.
Ltac ae := why3 "alt-ergo".
Ltac ae := why3 "Alt-Ergo".
Section S0.
Variable a:Set->Set.
......
......@@ -63,7 +63,17 @@ let get_prover s =
try
Hashtbl.find provers s
with Not_found ->
let cp = Whyconf.prover_by_id config s in
let filter_prover = Whyconf.parse_filter_prover s in
let cp = try Whyconf.filter_one_prover config filter_prover
with Whyconf.ProverAmbiguity (wc,fp,provers) ->
let provers = Mprover.filter (fun _ p -> not p.interactive) provers in
if Mprover.is_num_elt 1 provers then
snd (Mprover.choose provers)
else if Mprover.is_empty provers then
raise (Whyconf.ProverNotFound (wc,fp))
else
raise (Whyconf.ProverAmbiguity (wc,fp,provers))
in
let drv = Driver.load_driver env cp.driver cp.extra_drivers in
Hashtbl.add provers s (cp, drv);
cp, drv
......@@ -1097,6 +1107,9 @@ let tr_top_decl = function
| _, Lib.ClosedSection _
| _, Lib.FrozenState _ -> ()
let pr_fp fp =
pr_str (Pp.string_of_wnl Whyconf.print_filter_prover_no_regexp fp)
let why3tac ?(timelimit=timelimit) s gl =
(* print_dep Format.err_formatter; *)
let concl_type = pf_type_of gl (pf_concl gl) in
......@@ -1126,14 +1139,31 @@ let why3tac ?(timelimit=timelimit) s gl =
| NotFO ->
if debug then Printexc.print_backtrace stderr; flush stderr;
error "Not a first order goal"
| Whyconf.ProverNotFound (_, s) ->
| Whyconf.ProverNotFound (_, fp) ->
let pl =
Mprover.fold (fun _ p l -> if not p.interactive then p.id :: l else l)
Mprover.fold (fun prover p l -> if not p.interactive
then (Pp.string_of_wnl Whyconf.print_prover prover) :: l
else l)
(get_provers config) [] in
let msg = pr_str "No such prover `" ++ pr_str s ++ pr_str "'." ++
let msg = pr_str "No such prover `"
++ pr_fp fp
++ pr_str "'." ++
pr_spc () ++ pr_str "Available provers are:" ++ pr_fnl () ++
prlist (fun s -> pr_str s ++ pr_fnl ()) (List.rev pl) in
errorlabstrm "Whyconf.ProverNotFound" msg
| Whyconf.ProverAmbiguity (_, fp,provers) ->
let pl = Mprover.keys provers in
let pl = List.map (Pp.string_of_wnl Whyconf.print_prover) pl in
let msg = pr_str "More than one prover corresponding to `" ++
pr_fp fp ++ pr_str "'." ++
pr_spc () ++ pr_str "Corresponding provers are:" ++ pr_fnl () ++
prlist (fun s -> pr_str s ++ pr_fnl ()) (List.rev pl) in
errorlabstrm "Whyconf.ProverAmbiguity" msg
| Whyconf.ParseFilterProver s ->
let msg = pr_str "Syntax error prover identification '" ++
pr_str s ++ pr_str "' : name[,version[,alternative]|,,alternative]" in
errorlabstrm "Whyconf.ParseFilterProver" msg
| e ->
Printexc.print_backtrace stderr; flush stderr;
Format.eprintf "@[exception: %a@]@." Exn_printer.exn_printer e;
......
......@@ -88,8 +88,7 @@ let prover_keys =
let load_prover kind (id,section) =
check_exhaustive section prover_keys;
let reg_map = List.rev_map
(fun s -> if s.[0] = '^' then Str.regexp s else Str.regexp_string s) in
let reg_map = List.rev_map why3_regexp_of_string in
{ kind = kind;
prover_id = id;
prover_name = get_string section "name";
......@@ -218,9 +217,7 @@ let ask_prover_version env exec_name version_switch =
Hashtbl.replace env.prover_output (exec_name,version_switch) res;
res
let check_version version schema =
Str.string_match schema version 0
&& Str.match_end () = String.length version
let check_version version schema = Str.string_match schema version 0
let known_version env exec_name =
Hashtbl.replace env.prover_unknown_version exec_name None
......@@ -256,19 +253,7 @@ let add_prover_with_uniq_id prover provers =
(** find an unique prover triplet *)
let prover_id = find_prover_altern provers prover.Wc.prover in
let prover = {prover with Wc.prover = prover_id} in
(** find an unique id *)
let test id _ p = p.Wc.id = id in
if not (Mprover.exists (test prover.Wc.id) provers)
then Mprover.add prover.Wc.prover prover provers
else
let rec aux i =
let prover_id = sprintf "%s_%i" prover.Wc.id i in
if not (Mprover.exists (test prover_id) provers)
then Mprover.add prover.Wc.prover
{prover with id = prover_id} provers
else aux (i+1) in
aux 2
Mprover.add prover_id prover provers
let detect_exec env main data acc exec_name =
let s = ask_prover_version env exec_name data.version_switch in
......@@ -319,7 +304,6 @@ let detect_exec env main data acc exec_name =
prover_altern = data.prover_altern} in
let prover_config =
{prover = prover;
id = data.prover_id;
command = c;
driver = Filename.concat (datadir main) data.prover_driver;
editor = data.prover_editor;
......@@ -412,11 +396,7 @@ let add_prover_binary config id path =
Wc.prover_altern =
Util.concat_non_empty " " [p.prover.Wc.prover_altern;alt] } in
find_prover_altern provers prover_id in
let p_new = {p with prover = prover_id} in
let alt = sanitizer char_to_alnumus char_to_alnumus
(get_suffix p.prover.Wc.prover_altern
prover_id.Wc.prover_altern) in
let p_new = { p_new with id = p.id ^ "-" ^ alt } in
add_prover_with_uniq_id p_new provers in
let p = {p with prover = prover_id} in
add_prover_with_uniq_id p provers in
let provers = Mprover.fold fold detected provers in
set_provers config provers
......@@ -42,6 +42,9 @@ let magicnumber = 12
exception WrongMagicNumber
let why3_regexp_of_string s = (** define a regexp in why3 *)
if s.[0] = '^' then Str.regexp s else Str.regexp ("^"^Str.quote s^"$")
(* lib and shared dirs *)
let default_loadpath =
......@@ -66,6 +69,11 @@ let print_prover fmt p =
p.prover_name p.prover_version
(if p.prover_altern = "" then "" else " ") p.prover_altern
let print_prover_parsable_format fmt p =
Format.fprintf fmt "%s,%s,%s"
p.prover_name p.prover_version p.prover_altern
module Prover = struct
type t = prover
let compare s1 s2 =
......@@ -109,7 +117,6 @@ type prover_upgrade_policy =
type config_prover = {
prover : prover;
id : string;
command : string;
driver : string;
in_place: bool;
......@@ -226,21 +233,21 @@ let set_main rc main =
exception NonUniqueId
let set_prover _ prover (ids,family) =
if Sstr.mem prover.id ids then raise NonUniqueId;
let set_prover _ prover family =
let section = empty_section in
let section = set_string section "name" prover.prover.prover_name in
let section = set_string section "command" prover.command in
let section = set_string section "driver" prover.driver in
let section = set_string section "version" prover.prover.prover_version in
let section = set_string ~default:"" section "alternative" prover.prover.prover_altern in
let section =
set_string ~default:"" section "alternative"prover.prover.prover_altern in
let section = set_string section "editor" prover.editor in
let section = set_bool section "interactive" prover.interactive in
let section = set_bool section "in_place" prover.in_place in
(Sstr.add prover.id ids,(prover.id,section)::family)
("config", section)::family
let set_provers rc provers =
let _,family = Mprover.fold set_prover provers (Sstr.empty,[]) in
let family = Mprover.fold set_prover provers [] in
set_family rc "prover" family
let set_editor id editor (ids, family) =
......@@ -284,7 +291,7 @@ let set_policies rc policy =
let absolute_filename = Sysutil.absolutize_filename
let load_prover dirname provers (id,section) =
let load_prover dirname provers (_,section) =
let name = get_string section "name" in
let version = get_string ~default:"" section "version" in
let altern = get_string ~default:"" section "alternative" in
......@@ -295,8 +302,7 @@ let load_prover dirname provers (id,section) =
}
in
Mprover.add prover
{ id = id;
prover = prover;
{ prover = prover;
command = get_string section "command";
driver = absolute_filename dirname (get_string section "driver");
in_place = get_bool ~default:false section "in_place";
......@@ -369,15 +375,6 @@ let read_config_rc conf_file =
exception ConfigFailure of string (* filename *) * string
let () = Exn_printer.register (fun fmt e -> match e with
| ConfigFailure (f, s) ->
Format.fprintf fmt "error in config file %s: %s" f s
| WrongMagicNumber ->
Format.fprintf fmt "outdated config file; rerun why3config"
| NonUniqueId ->
Format.fprintf fmt "InternalError : two provers share the same id"
| _ -> raise e)
let get_config (filename,rc) =
let dirname = Filename.dirname filename in
let rc, main =
......@@ -416,38 +413,135 @@ let read_config conf_file =
Format.bprintf b "%a" Exn_printer.exn_printer e;
raise (ConfigFailure (fst filenamerc, Buffer.contents b))
(** filter prover *)
type filter_prover =
{ filter_name : Str.regexp; filter_desc_name : string;
filter_version : Str.regexp; filter_desc_version : string;
filter_altern : Str.regexp; filter_desc_altern : string;
}
let mk_filter_prover ?(version="^") ?(altern="^") ~name =
let reg = why3_regexp_of_string in
{ filter_name = reg name ; filter_desc_name = name;
filter_version = reg version ; filter_desc_version = version;
filter_altern = reg altern ; filter_desc_altern = altern}
let print_filter_prover fmt fp =
fprintf fmt "%s,%s,%s"
fp.filter_desc_name fp.filter_desc_version fp.filter_desc_altern
let print_filter_prover_no_regexp fmt fp =
let all s = s = "^" in
fprintf fmt "%s%s%s"
fp.filter_desc_name
(if all fp.filter_desc_version then
(if all fp.filter_desc_altern then "" else ",")
else "," ^ fp.filter_desc_version)
(if all fp.filter_desc_altern then ""
else ("," ^ fp.filter_desc_altern))
exception ProverNotFound of config * filter_prover
exception ProverAmbiguity of config * filter_prover * config_prover Mprover.t
exception ParseFilterProver of string
let parse_filter_prover s =
let sl = Util.split_string_rev s ',' in
let match_all = Str.regexp "" in
let reg = why3_regexp_of_string in
(* reverse order *)
match sl with
| [name] ->
{filter_name = reg name ; filter_desc_name = name;
filter_version = match_all ; filter_desc_version = "^";
filter_altern = match_all ; filter_desc_altern = "^"}
| [version;name] ->
{filter_name = reg name ; filter_desc_name = name;
filter_version = reg version ; filter_desc_version = version;
filter_altern = match_all ; filter_desc_altern = "^"}
| [altern;"";name] ->
{filter_name = reg name ; filter_desc_name = name;
filter_version = match_all ; filter_desc_version = "^";
filter_altern = reg altern ; filter_desc_altern = altern}
| [altern;version;name] ->
{filter_name = reg name ; filter_desc_name = name;
filter_version = reg version ; filter_desc_version = version;
filter_altern = reg altern ; filter_desc_altern = altern}
| _ -> raise (ParseFilterProver s)
let filter_prover fp p =
let check schema s = Str.string_match schema s 0 in
check fp.filter_name p.prover_name
&& check fp.filter_version p.prover_version
&& check fp.filter_altern p.prover_altern
let filter_provers whyconf fp =
Mprover.filter (fun p _ -> filter_prover fp p) whyconf.provers
let filter_one_prover config fp =
let provers = Mprover.filter (fun k _ -> filter_prover fp k)
config.provers in
if Mprover.is_num_elt 1 provers then
snd (Mprover.choose provers)
else if Mprover.is_empty provers then
raise $ ProverNotFound (config,fp)
else
raise $ ProverAmbiguity (config,fp,provers)
(** merge config *)
let merge_config config filename =
let dirname = Filename.dirname filename in
let rc = Rc.from_file filename in
(** modify main *)
let main = match get_section rc "main" with
| None -> config.main
| Some rc ->
let loadpath = (List.map (absolute_filename dirname)
(get_stringl ~default:[] rc "loadpath")) @ config.main.loadpath in
let plugins = (get_stringl ~default:[] rc "plugin") @ config.main.plugins in
let plugins =
(get_stringl ~default:[] rc "plugin") @ config.main.plugins in
{ config.main with loadpath = loadpath; plugins = plugins } in
let provers = get_family rc "prover" in
(** modify provers *)
let create_filter_prover section =
let name = get_string section "name" in
let version = get_string ~default:"^" section "version" in
let altern = get_string ~default:"^" section "alternative" in
{ filter_name = why3_regexp_of_string name;
filter_version = why3_regexp_of_string version;
filter_altern = why3_regexp_of_string altern;
filter_desc_name = ""; filter_desc_version = ""; filter_desc_altern = "";
} in
let prover_modifiers = get_family rc "prover_modifiers" in
let prover_modifiers =
List.map (fun (_,sec) -> create_filter_prover sec, sec) prover_modifiers in
(** add provers *)
let provers = List.fold_left
(fun provers (id, section) ->
try
let key,c = Mprover.choose (Mprover.filter (fun _ p -> p.id = id) provers) in
let opt = (get_stringl ~default:[] section "option") @ c.extra_options in
let drv = (List.map (absolute_filename dirname)
(get_stringl ~default:[] section "driver")) @ c.extra_drivers in
Mprover.add key { c with extra_options = opt ; extra_drivers = drv } provers
with
Not_found -> load_prover dirname provers (id, section)
) config.provers provers in
let editors = get_family rc "editor" in
(fun provers (fp, section) ->
Mprover.mapi (fun p c ->
if not (filter_prover fp p) then c
else
let opt = get_stringl ~default:[] section "option" in
let drv = List.map (absolute_filename dirname)
(get_stringl ~default:[] section "driver") in
{ c with
extra_options = opt @ c.extra_options;
extra_drivers = drv @ c.extra_drivers })
provers
) config.provers prover_modifiers in
let provers =
List.fold_left (load_prover dirname) provers (get_family rc "prover") in
(** modify editors *)
let editor_modifiers = get_family rc "editor_modifiers" in
let editors = List.fold_left
(fun editors (id, section) ->
try
let c = Meditor.find id editors in
let opt = (get_stringl ~default:[] section "option") @ c.editor_options in
Meditor.add id { c with editor_options = opt } editors
with
Not_found -> load_editor editors (id, section)
) config.editors editors in
Meditor.change (function
| None -> None
| Some c ->
let opt = get_stringl ~default:[] section "option" in
Some { c with editor_options = opt @ c.editor_options }) id editors
) config.editors editor_modifiers in
(** add editors *)
let editors = List.fold_left load_editor editors (get_family rc "editor") in
{ config with main = main; provers = provers; editors = editors }
let save_config config =
......@@ -503,25 +597,6 @@ let get_conf_file config = config.conf_file
let is_prover_known whyconf prover =
Mprover.mem prover (get_provers whyconf)
exception ProverNotFound of config * string
let prover_by_id whyconf id =
let potentials =
Mprover.filter (fun _ p -> p.id = id) whyconf.provers in
match Mprover.keys potentials with
| [] -> raise (ProverNotFound(whyconf,id))
| [_] -> snd (Mprover.choose potentials)
| _ -> assert false (** by the verification done by set_provers *)
let () = Exn_printer.register
(fun fmt exn ->
match exn with
| ProverNotFound (config,s) ->
fprintf fmt "Prover '%s' not found in %s@."
s (get_conf_file config)
| e -> raise e
)
let get_editors c = c.editors
let editor_by_id whyconf id =
......@@ -542,3 +617,24 @@ let set_section config name section = assert (name <> "main");
let set_family config name section = assert (name <> "prover");
{config with config = set_family config.config name section}
let () = Exn_printer.register (fun fmt e -> match e with
| ConfigFailure (f, s) ->
Format.fprintf fmt "error in config file %s: %s" f s
| WrongMagicNumber ->
Format.fprintf fmt "outdated config file; rerun why3config"
| NonUniqueId ->
Format.fprintf fmt "InternalError : two provers share the same id"
| ProverNotFound (config,fp) ->
fprintf fmt "No prover in %s corresponds to %a@."
(get_conf_file config) print_filter_prover fp
| ProverAmbiguity (config,fp,provers ) ->
fprintf fmt "More than one prover in %s correspond to %a: %a@."
(get_conf_file config) print_filter_prover fp
(Pp.print_iter2 Mprover.iter Pp.space Pp.nothing print_prover Pp.nothing)
provers
| ParseFilterProver s ->
fprintf fmt
"Syntax error prover identification '%s' : \
name[,version[,alternative]|,,alternative]" s
| _ -> raise e)
......@@ -45,7 +45,8 @@ val read_config : string option -> config
the built-in default_config with default configuration filename *)
val merge_config : config -> string -> config
(** [merge_config config filename] merge the content of [filename] into [config] *)
(** [merge_config config filename] merge the content of [filename]
into [config]( *)
val save_config : config -> unit
(** [save_config config] save the configuration *)
......@@ -96,6 +97,8 @@ type prover =
(** record of necessary data for a given external prover *)
val print_prover : Format.formatter -> prover -> unit
val print_prover_parsable_format : Format.formatter -> prover -> unit
(** Printer for prover *)
module Prover : Util.OrderedHash with type t = prover
module Mprover : Stdlib.Map.S with type key = prover
......@@ -106,7 +109,6 @@ module Hprover : Hashtbl.S with type key = prover
type config_prover = {
prover : prover; (* unique name for session *)
id : string; (* unique name for command line *)
command : string; (* "exec why-limit %t %m alt-ergo %f" *)
driver : string; (* "/usr/local/share/why/drivers/ergo-spec.drv" *)
in_place: bool; (* verification should be performed in-place *)
......@@ -127,12 +129,6 @@ val set_provers : config -> config_prover Mprover.t -> config
val is_prover_known : config -> prover -> bool
(** test if a prover is detected *)
exception ProverNotFound of config * string
val prover_by_id : config -> string -> config_prover
(** return the configuration of the prover if found, otherwise return
ProverNotFound *)
type config_editor = {
editor_name : string;
editor_command : string;
......@@ -173,6 +169,44 @@ val get_policies : config -> prover_upgrade_policy Mprover.t
val set_policies : config -> prover_upgrade_policy Mprover.t -> config
(** filter prover *)
type filter_prover
val mk_filter_prover :
?version:string -> ?altern:string -> name:string -> filter_prover
val print_filter_prover :
Format.formatter -> filter_prover -> unit
val print_filter_prover_no_regexp :
Format.formatter -> filter_prover -> unit
val parse_filter_prover : string -> filter_prover
(** parse the string representing a filter_prover:
- "name,version,altern"
- "name,version" -> "name,version,^.*"
- "name,,altern" -> "name,^.*,altern"
- "name" -> "name,^.*,^.*"
regexp must start with ^. Partial match will be used.
*)
val filter_prover : filter_prover -> prover -> bool
(** test if the prover match the filter prover *)
val filter_provers : config -> filter_prover -> config_prover Mprover.t
(** test if the prover match the filter prover *)
exception ProverNotFound of config * filter_prover
exception ProverAmbiguity of config * filter_prover * config_prover Mprover.t
exception ParseFilterProver of string
val filter_one_prover : config -> filter_prover -> config_prover
(** find the uniq prover that verify the filter. If it doesn't exists
raise ProverNotFound or raise ProverAmbiguity *)
val why3_regexp_of_string : string -> Str.regexp
(** {2 For accesing other parts of the configuration } *)
(** Access to the Rc.t *)
......
......@@ -265,9 +265,8 @@ let () = try
opt_list := true;
let config = read_config !opt_config in
let config = List.fold_left merge_config config !opt_extra in
let print fmt prover pc = fprintf fmt "%s (%a)@\n"
pc.id print_prover prover in
let print fmt m = Mprover.iter (print fmt) m in
let print = Pp.print_iter2 Mprover.iter Pp.newline Pp.nothing
print_prover Pp.nothing in
let provers = get_provers config in
printf "@[<hov 2>Known provers:@\n%a@]@." print provers
end;
......@@ -328,9 +327,11 @@ let () = try
if !opt_memlimit = None then opt_memlimit := Some (Whyconf.memlimit main);
begin match !opt_prover with
| Some s ->
let prover = Whyconf.prover_by_id config s in
opt_command := Some (String.concat " " (prover.command :: prover.extra_options));
opt_driver := Some (prover.driver, prover.extra_drivers)
let filter_prover = Whyconf.parse_filter_prover s in
let prover = Whyconf.filter_one_prover config filter_prover in
opt_command :=
Some (String.concat " " (prover.command :: prover.extra_options));
opt_driver := Some (prover.driver, prover.extra_drivers)
| None ->
()