Skip to content

Commit 375f208

Browse files
committed
Simplify: sort operands for commutative, but not associative operations
Testing floating-point equality is expensive, and thus warrants handling special cases (even if they might be rare) in the simplifier. This (simplistic) test would take 5 seconds with CaDiCaL as SAT back-end when not performing simplification.
1 parent 9e5434b commit 375f208

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <assert.h>
2+
#include <math.h>
3+
4+
int main()
5+
{
6+
float a;
7+
float b;
8+
// We could do "if (isnormal(a) && isnormal(b))", but __CPROVER_isnanf(a+b)
9+
// will permit solving this entirely via the simplifier, if, and only if, the
10+
// equality is successfully simplified (despite the different order of
11+
// operands).
12+
assert(__CPROVER_isnanf(a + b) || a + b == b + a);
13+
}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
main.c
3+
4+
(Starting CEGAR Loop|VCC\(s\), 0 remaining after simplification$)
5+
^VERIFICATION SUCCESSFUL$
6+
^EXIT=0$
7+
^SIGNAL=0$
8+
--
9+
^warning: ignoring
10+
--
11+
This requires simplification of commutative, but not associative operations.

src/util/simplify_expr_floatbv.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Author: Daniel Kroening, [email protected]
1616
#include "invariant.h"
1717
#include "namespace.h"
1818
#include "simplify_expr.h"
19+
#include "simplify_utils.h"
1920
#include "std_expr.h"
2021

2122
simplify_exprt::resultt<>
@@ -361,7 +362,15 @@ simplify_exprt::simplify_ieee_float_relation(const binary_relation_exprt &expr)
361362
UNREACHABLE;
362363
}
363364

364-
if(expr.lhs() == expr.rhs())
365+
// addition and multiplication are commutative, but not associative
366+
exprt lhs_sorted = expr.lhs();
367+
if(lhs_sorted.id() == ID_floatbv_plus || lhs_sorted.id() == ID_floatbv_mult)
368+
sort_operands(lhs_sorted.operands());
369+
exprt rhs_sorted = expr.rhs();
370+
if(rhs_sorted.id() == ID_floatbv_plus || rhs_sorted.id() == ID_floatbv_mult)
371+
sort_operands(rhs_sorted.operands());
372+
373+
if(lhs_sorted == rhs_sorted)
365374
{
366375
// x!=x is the same as saying isnan(op)
367376
exprt isnan = isnan_exprt(expr.lhs());

0 commit comments

Comments
 (0)