Skip to content

Commit fa96e87

Browse files
committed
[smt]: proper selection of SMT variant
Why3 can define several variants (e.g. counterexamples, noBV). Currently, EasyCrypt select the first variant that comes in the prover list. From now on, the default variant (= empty name) is selected by default. It is also possible to provide the desired in the prover name (syntax = "prover[variant]", e.g. "Z3[noBV]"). This is compatible with the version selection (e.g. "Z3[noBV]@4.8")
1 parent 6a29c79 commit fa96e87

File tree

5 files changed

+54
-17
lines changed

5 files changed

+54
-17
lines changed

examples/ChaChaPoly/chacha_poly.ec

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,9 +1691,8 @@ section PROOFS.
16911691
swap 13 9; wp; conseq (_: true) => />; 1: smt(); islossless.
16921692
while true (size p2).
16931693
+ move=> z; wp; conseq (_: true) => //=; 2: by islossless.
1694-
move => &hr; elim (p2{hr}) => //.
1695-
clear &hr.
1696-
smt (size_drop size_eq0 gt0_block_size).
1694+
move => &hr; elim (p2{hr}) => //= => {&hr}.
1695+
smt (size_drop size_ge0 size_eq0 gt0_block_size).
16971696
by auto; smt (size_ge0 size_eq0 dpoly_out_ll).
16981697
+ by proc; inline *; sp 1 1; if; auto => /> *; smt(get_setE mem_set).
16991698
+ by move=> &2 _; islossless.

src/ec.ml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,15 @@ let print_config config =
7070

7171
(* Print list of known provers *)
7272
begin
73-
let string_of_prover prover =
73+
let string_of_prover (prover : EcProvers.prover) =
7474
let fullname =
75-
Printf.sprintf "%s@%s"
76-
prover.EcProvers.pr_name
77-
(EcProvers.Version.to_string prover.EcProvers.pr_version) in
75+
Format.asprintf "%s%t@%s"
76+
prover.pr_name
77+
(fun fmt ->
78+
if not (String.is_empty prover.pr_alt) then
79+
Format.fprintf fmt "[%s]" prover.pr_alt)
80+
(EcProvers.Version.to_string prover.pr_version)
81+
in
7882

7983
match prover.EcProvers.pr_evicted with
8084
| None -> fullname

src/ecProvers.ml

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,13 @@ end = struct
5050
compare v1.v_extra v2.v_extra
5151

5252
let to_string (v : version) =
53-
Printf.sprintf "%d.%d.%d.%s"
54-
v.v_major v.v_minor v.v_subminor v.v_extra
53+
let parts = [v.v_major; v.v_minor; v.v_subminor] in
54+
let parts = List.map string_of_int parts in
55+
let parts =
56+
let extra = if String.is_empty v.v_extra then None else Some v.v_extra in
57+
ofold (fun extra parts -> parts @ [extra]) parts extra in
58+
59+
String.concat "." parts
5560
end
5661

5762
module VP = Version
@@ -108,6 +113,7 @@ let evictions : prover_eviction_test list = [
108113
type prover = {
109114
pr_name : string;
110115
pr_version : Version.version;
116+
pr_alt : string;
111117
pr_evicted : (prover_eviction * bool) option;
112118
}
113119

@@ -156,6 +162,7 @@ end = struct
156162
{ pr_prover =
157163
{ pr_name = name;
158164
pr_version = Version.parse version;
165+
pr_alt = p.Whyconf.prover_altern;
159166
pr_evicted = None; };
160167
pr_config = config;
161168
pr_driver = driver; }
@@ -166,6 +173,15 @@ end = struct
166173
(fun p c acc -> load_prover p c :: acc)
167174
(Whyconf.get_provers config) [] in
168175

176+
let provers =
177+
let key_of_prover (p : why3prover) =
178+
let p = p.pr_prover in
179+
(p.pr_name, p.pr_version, p.pr_alt) in
180+
181+
List.sort
182+
(fun p1 p2 -> compare (key_of_prover p1) (key_of_prover p2))
183+
provers in
184+
169185
let provers =
170186
List.map (fun prover ->
171187
let prinfo = prover.pr_prover in
@@ -212,6 +228,7 @@ exception UnknownProver of string
212228

213229
type parsed_pname = {
214230
prn_name : string;
231+
prn_alt : string;
215232
prn_version : Version.version option;
216233
prn_ovrevict : bool;
217234
}
@@ -228,19 +245,32 @@ let parse_prover_name name =
228245

229246
let version = omap Version.parse version in
230247

231-
if name <> "" && name.[0] = '!'
232-
then { prn_name = String.sub name 1 (String.length name - 1);
233-
prn_version = version;
234-
prn_ovrevict = true; }
235-
else { prn_name = name;
236-
prn_version = version;
237-
prn_ovrevict = false; }
248+
let ovrevict, name =
249+
if name <> "" && name.[0] = '!' then
250+
true, String.sub name 1 (String.length name - 1)
251+
else false, name in
252+
253+
let name, alt =
254+
let re = EcRegexp.regexp "^(.*)\\[(.*)\\]$" in
255+
match EcRegexp.exec (`C re) name with
256+
| None ->
257+
name, ""
258+
| Some m ->
259+
let name = oget (EcRegexp.Match.group m 1) in
260+
let alt = oget (EcRegexp.Match.group m 2) in
261+
name, alt in
262+
263+
{ prn_name = name;
264+
prn_version = version;
265+
prn_alt = alt;
266+
prn_ovrevict = ovrevict; }
238267

239268
let get_prover (rawname : string) =
240269
let name = parse_prover_name rawname in
241270

242271
let test p =
243272
p.pr_prover.pr_name = name.prn_name
273+
&& p.pr_prover.pr_alt = name.prn_alt
244274
&& (name.prn_ovrevict || not (is_evicted p.pr_prover)) in
245275

246276
let provers = List.filter test (Config.provers ()) in
@@ -399,6 +429,7 @@ let run_prover
399429
EcUtils.try_finally (fun () ->
400430
try
401431
let { pr_config = pr; pr_driver = dr; } = get_prover prover in
432+
402433
let pc =
403434
let command = pr.Whyconf.command in
404435

src/ecProvers.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type prover_eviction = [
3030
type prover = {
3131
pr_name : string;
3232
pr_version : Version.version;
33+
pr_alt : string;
3334
pr_evicted : (prover_eviction * bool) option;
3435
}
3536

@@ -58,6 +59,7 @@ val known : evicted:bool -> prover list
5859
(* -------------------------------------------------------------------- *)
5960
type parsed_pname = {
6061
prn_name : string;
62+
prn_alt : string;
6163
prn_version : Version.version option;
6264
prn_ovrevict : bool;
6365
}

theories/distributions/DInterval.ec

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ have uniq_s: uniq s; first apply: uniq_flatten_map.
6969
by move => x y _ _ /=; apply/addrI.
7070
- move=> x y /mem_range rg_x /mem_range rg_y /hasP /=.
7171
case=> j [/mapP[/= k [/mem_range rg_k]] ->>].
72-
by case/mapP=> l [/mem_range rg_l] {rg_x} {rg_y} /#.
72+
case/mapP=> l [/mem_range rg_l] {rg_x} {rg_y}.
73+
smt(IntDiv.euclideU).
7374
- by apply: range_uniq.
7475
have mem_s: forall x, (x \in s) <=> (x \in range 0 p).
7576
- move=> x; rewrite mem_range; split.

0 commit comments

Comments
 (0)