Skip to content

Commit 5164a50

Browse files
authored
Merge pull request #8509 from diffblue/simplify_power
simplify x^0 and x^1
2 parents 57be2aa + 8b0bef0 commit 5164a50

File tree

6 files changed

+67
-20
lines changed

6 files changed

+67
-20
lines changed

src/util/mathematical_expr.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ Author: Daniel Kroening, [email protected]
77
\*******************************************************************/
88

99
#include "mathematical_expr.h"
10+
11+
#include "arith_tools.h"
1012
#include "mathematical_types.h"
1113

1214
function_application_exprt::function_application_exprt(
@@ -49,3 +51,9 @@ lambda_exprt::lambda_exprt(const variablest &_variables, const exprt &_where)
4951
lambda_type(_variables, _where))
5052
{
5153
}
54+
55+
power_exprt::power_exprt(const mp_integer &_base, const exprt &_exp)
56+
: power_exprt{from_integer(_base, _exp.type()), _exp}
57+
{
58+
PRECONDITION(base().is_not_nil());
59+
}

src/util/mathematical_expr.h

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,29 @@ class power_exprt : public binary_exprt
9797
: binary_exprt(_base, ID_power, _exp)
9898
{
9999
}
100+
101+
// convenience helper
102+
power_exprt(const mp_integer &_base, const exprt &_exp);
103+
104+
const exprt &base() const
105+
{
106+
return op0();
107+
}
108+
109+
exprt &base()
110+
{
111+
return op0();
112+
}
113+
114+
const exprt &exponent() const
115+
{
116+
return op1();
117+
}
118+
119+
exprt &exponent()
120+
{
121+
return op1();
122+
}
100123
};
101124

102125
template <>
@@ -105,11 +128,6 @@ inline bool can_cast_expr<power_exprt>(const exprt &base)
105128
return base.id() == ID_power;
106129
}
107130

108-
inline void validate_expr(const power_exprt &value)
109-
{
110-
validate_operands(value, 2, "Power must have two operands");
111-
}
112-
113131
/// \brief Cast an exprt to a \ref power_exprt
114132
///
115133
/// \a expr must be known to be \ref power_exprt.
@@ -119,18 +137,16 @@ inline void validate_expr(const power_exprt &value)
119137
inline const power_exprt &to_power_expr(const exprt &expr)
120138
{
121139
PRECONDITION(expr.id() == ID_power);
122-
const power_exprt &ret = static_cast<const power_exprt &>(expr);
123-
validate_expr(ret);
124-
return ret;
140+
power_exprt::check(expr);
141+
return static_cast<const power_exprt &>(expr);
125142
}
126143

127144
/// \copydoc to_power_expr(const exprt &)
128145
inline power_exprt &to_power_expr(exprt &expr)
129146
{
130147
PRECONDITION(expr.id() == ID_power);
131-
power_exprt &ret = static_cast<power_exprt &>(expr);
132-
validate_expr(ret);
133-
return ret;
148+
power_exprt::check(expr);
149+
return static_cast<power_exprt &>(expr);
134150
}
135151

136152
/// \brief Falling factorial power

src/util/simplify_expr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2962,7 +2962,7 @@ simplify_exprt::resultt<> simplify_exprt::simplify_node(const exprt &node)
29622962
}
29632963
else if(expr.id()==ID_power)
29642964
{
2965-
r = simplify_power(to_binary_expr(expr));
2965+
r = simplify_power(to_power_expr(expr));
29662966
}
29672967
else if(expr.id()==ID_plus)
29682968
{

src/util/simplify_expr_class.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class plus_exprt;
6464
class pointer_object_exprt;
6565
class pointer_offset_exprt;
6666
class popcount_exprt;
67+
class power_exprt;
6768
class prophecy_pointer_in_range_exprt;
6869
class prophecy_r_or_w_ok_exprt;
6970
class refined_string_exprt;
@@ -163,7 +164,7 @@ class simplify_exprt
163164
[[nodiscard]] resultt<>
164165
simplify_floatbv_typecast(const floatbv_typecast_exprt &);
165166
[[nodiscard]] resultt<> simplify_shifts(const shift_exprt &);
166-
[[nodiscard]] resultt<> simplify_power(const binary_exprt &);
167+
[[nodiscard]] resultt<> simplify_power(const power_exprt &);
167168
[[nodiscard]] resultt<> simplify_bitwise(const multi_ary_exprt &);
168169
[[nodiscard]] resultt<> simplify_if_preorder(const if_exprt &expr);
169170
[[nodiscard]] resultt<> simplify_if(const if_exprt &);

src/util/simplify_expr_int.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Author: Daniel Kroening, [email protected]
1616
#include "fixedbv.h"
1717
#include "ieee_float.h"
1818
#include "invariant.h"
19+
#include "mathematical_expr.h"
1920
#include "mathematical_types.h"
2021
#include "namespace.h"
2122
#include "pointer_expr.h"
@@ -1120,18 +1121,24 @@ simplify_exprt::simplify_shifts(const shift_exprt &expr)
11201121
}
11211122

11221123
simplify_exprt::resultt<>
1123-
simplify_exprt::simplify_power(const binary_exprt &expr)
1124+
simplify_exprt::simplify_power(const power_exprt &expr)
11241125
{
11251126
if(!is_number(expr.type()))
11261127
return unchanged(expr);
11271128

1128-
const auto base = numeric_cast<mp_integer>(expr.op0());
1129-
const auto exponent = numeric_cast<mp_integer>(expr.op1());
1129+
const auto base = numeric_cast<mp_integer>(expr.base());
1130+
const auto exponent = numeric_cast<mp_integer>(expr.exponent());
11301131

1131-
if(!base.has_value())
1132+
if(!exponent.has_value())
11321133
return unchanged(expr);
11331134

1134-
if(!exponent.has_value())
1135+
if(exponent.value() == 0)
1136+
return from_integer(1, expr.type());
1137+
1138+
if(exponent.value() == 1)
1139+
return expr.base();
1140+
1141+
if(!base.has_value())
11351142
return unchanged(expr);
11361143

11371144
mp_integer result = power(*base, *exponent);

unit/util/simplify_expr.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@ Author: Michael Tautschnig
66
77
\*******************************************************************/
88

9-
#include <testing-utils/use_catch.h>
10-
119
#include <util/arith_tools.h>
1210
#include <util/bitvector_expr.h>
1311
#include <util/byte_operators.h>
1412
#include <util/c_types.h>
1513
#include <util/cmdline.h>
1614
#include <util/config.h>
15+
#include <util/mathematical_expr.h>
1716
#include <util/namespace.h>
1817
#include <util/pointer_expr.h>
1918
#include <util/pointer_predicates.h>
@@ -22,6 +21,8 @@ Author: Michael Tautschnig
2221
#include <util/std_expr.h>
2322
#include <util/symbol_table.h>
2423

24+
#include <testing-utils/use_catch.h>
25+
2526
TEST_CASE("Simplify pointer_offset(address of array index)", "[core][util]")
2627
{
2728
config.set_arch("none");
@@ -571,3 +572,17 @@ TEST_CASE("Simplify bitxor", "[core][util]")
571572
false_c_bool);
572573
}
573574
}
575+
576+
TEST_CASE("Simplify power", "[core][util]")
577+
{
578+
const symbol_tablet symbol_table;
579+
const namespacet ns{symbol_table};
580+
581+
SECTION("Simplification for power")
582+
{
583+
symbol_exprt a{"a", integer_typet{}};
584+
585+
REQUIRE(
586+
simplify_expr(power_exprt{a, from_integer(1, integer_typet{})}, ns) == a);
587+
}
588+
}

0 commit comments

Comments
 (0)