Skip to content

Commit c0a4ba0

Browse files
committed
Reduce var_eq witness invariants from quadratic to linear
1 parent 1369d99 commit c0a4ba0

File tree

2 files changed

+17
-39
lines changed

2 files changed

+17
-39
lines changed

src/analyses/varEq.ml

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,23 @@ struct
2121
fold (fun s a ->
2222
if B.mem MyCFG.unknown_exp s then
2323
a
24-
else
25-
let module B_prod = BatSet.Make2 (Exp) (Exp) in
26-
let s_prod = B_prod.cartesian_product s s in
27-
let i = B_prod.Product.fold (fun (x, y) a ->
28-
if Exp.compare x y < 0 && not (InvariantCil.exp_contains_tmp x) && not (InvariantCil.exp_contains_tmp y) && InvariantCil.exp_is_in_scope scope x && InvariantCil.exp_is_in_scope scope y then (* each equality only one way, no self-equalities *)
29-
let eq = BinOp (Eq, x, y, intType) in
24+
else (
25+
let s' = B.filter (fun x -> not (InvariantCil.exp_contains_tmp x) && InvariantCil.exp_is_in_scope scope x) s in
26+
if B.cardinal s' >= 2 then (
27+
(* instead of returning quadratically many pairwise equalities from a cluster,
28+
output linear number of equalities with just one expression *)
29+
let lhs = B.choose s' in (* choose arbitrary expression for lhs *)
30+
let rhss = B.remove lhs s' in (* and exclude it from rhs-s (no point in reflexive equality) *)
31+
let i = B.fold (fun rhs a ->
32+
let eq = BinOp (Eq, lhs, rhs, intType) in
3033
Invariant.(a && of_exp eq)
31-
else
32-
a
33-
) s_prod (Invariant.top ())
34-
in
35-
Invariant.(a && i)
34+
) rhss (Invariant.top ())
35+
in
36+
Invariant.(a && i)
37+
)
38+
else (* cannot output any equalities between just 0 or 1 usable expressions *)
39+
a
40+
)
3641
) ss (Invariant.top ())
3742
end
3843

tests/regression/56-witness/71-var_eq-invariants.t

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
dead: 0
55
total lines: 3
66
[Info][Witness] witness generation summary:
7-
location invariants: 6
7+
location invariants: 3
88
loop invariants: 0
99
flow-insensitive invariants: 0
1010
total generation entries: 1
@@ -41,30 +41,3 @@ With 4 equal variables, there should be just 3 var_eq invariants, not 6.
4141
function: main
4242
value: a == d
4343
format: c_expression
44-
- invariant:
45-
type: location_invariant
46-
location:
47-
file_name: 71-var_eq-invariants.c
48-
line: 6
49-
column: 3
50-
function: main
51-
value: b == c
52-
format: c_expression
53-
- invariant:
54-
type: location_invariant
55-
location:
56-
file_name: 71-var_eq-invariants.c
57-
line: 6
58-
column: 3
59-
function: main
60-
value: b == d
61-
format: c_expression
62-
- invariant:
63-
type: location_invariant
64-
location:
65-
file_name: 71-var_eq-invariants.c
66-
line: 6
67-
column: 3
68-
function: main
69-
value: c == d
70-
format: c_expression

0 commit comments

Comments
 (0)