CBMC
simplify_expr_class.h
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
9 
10 #ifndef CPROVER_UTIL_SIMPLIFY_EXPR_CLASS_H
11 #define CPROVER_UTIL_SIMPLIFY_EXPR_CLASS_H
12 
13 // #define DEBUG_ON_DEMAND
14 #ifdef DEBUG_ON_DEMAND
15 #include <sys/stat.h>
16 #endif
17 
18 #include <set>
19 
20 #include "expr.h"
21 #include "mp_arith.h"
22 #include "type.h"
23 // #define USE_LOCAL_REPLACE_MAP
24 #ifdef USE_LOCAL_REPLACE_MAP
25 #include "replace_expr.h"
26 #endif
27 
28 class abs_exprt;
29 class address_of_exprt;
30 class array_exprt;
31 class binary_exprt;
34 class bitnot_exprt;
35 class bitreverse_exprt;
36 class bswap_exprt;
37 class byte_extract_exprt;
38 class byte_update_exprt;
42 class dereference_exprt;
43 class div_exprt;
44 class exprt;
45 class extractbit_exprt;
46 class extractbits_exprt;
51 class if_exprt;
52 class index_exprt;
53 class lambda_exprt;
54 class member_exprt;
55 class minus_exprt;
56 class mod_exprt;
57 class multi_ary_exprt;
58 class mult_exprt;
59 class namespacet;
60 class not_exprt;
61 class object_size_exprt;
63 class plus_exprt;
66 class popcount_exprt;
67 class power_exprt;
71 class shift_exprt;
72 class sign_exprt;
73 class typecast_exprt;
74 class unary_exprt;
75 class unary_minus_exprt;
77 class unary_plus_exprt;
78 class update_exprt;
79 class with_exprt;
80 class zero_extend_exprt;
81 
83 {
84 public:
85  explicit simplify_exprt(const namespacet &_ns):
86  do_simplify_if(true),
87  ns(_ns)
88 #ifdef DEBUG_ON_DEMAND
89  , debug_on(false)
90 #endif
91  {
92 #ifdef DEBUG_ON_DEMAND
93  struct stat f;
94  debug_on=stat("SIMP_DEBUG", &f)==0;
95 #endif
96  }
97 
98  virtual ~simplify_exprt()
99  {
100  }
101 
103 
104  template <typename T = exprt>
105  struct resultt
106  {
107  bool has_changed() const
108  {
109  return expr_changed == CHANGED;
110  }
111 
113  {
115  UNCHANGED
117 
118  T expr;
119 
121  operator T() const
122  {
123  return expr;
124  }
125 
128  // NOLINTNEXTLINE(runtime/explicit)
129  resultt(T _expr) : expr_changed(CHANGED), expr(std::move(_expr))
130  {
131  }
132 
133  resultt(expr_changedt _expr_changed, T _expr)
134  : expr_changed(_expr_changed), expr(std::move(_expr))
135  {
136  }
137  };
138 
139  [[nodiscard]] static resultt<> unchanged(exprt expr)
140  {
141  return resultt<>(resultt<>::UNCHANGED, std::move(expr));
142  }
143 
144  [[nodiscard]] static resultt<> changed(resultt<> result)
145  {
147  return result;
148  }
149 
150  // These below all return 'true' if the simplification wasn't applicable.
151  // If false is returned, the expression has changed.
152  [[nodiscard]] resultt<> simplify_typecast(const typecast_exprt &);
153  [[nodiscard]] resultt<> simplify_typecast_preorder(const typecast_exprt &);
154  [[nodiscard]] resultt<> simplify_extractbit(const extractbit_exprt &);
155  [[nodiscard]] resultt<> simplify_extractbits(const extractbits_exprt &);
157  [[nodiscard]] resultt<> simplify_zero_extend(const zero_extend_exprt &);
158  [[nodiscard]] resultt<> simplify_mult(const mult_exprt &);
159  [[nodiscard]] resultt<> simplify_div(const div_exprt &);
160  [[nodiscard]] resultt<> simplify_mod(const mod_exprt &);
161  [[nodiscard]] resultt<> simplify_plus(const plus_exprt &);
162  [[nodiscard]] resultt<> simplify_minus(const minus_exprt &);
163  [[nodiscard]] resultt<> simplify_floatbv_op(const ieee_float_op_exprt &);
164  [[nodiscard]] resultt<>
166  [[nodiscard]] resultt<> simplify_shifts(const shift_exprt &);
167  [[nodiscard]] resultt<> simplify_power(const power_exprt &);
168  [[nodiscard]] resultt<> simplify_bitwise(const multi_ary_exprt &);
169  [[nodiscard]] resultt<> simplify_if_preorder(const if_exprt &expr);
170  [[nodiscard]] resultt<> simplify_if(const if_exprt &);
171  [[nodiscard]] resultt<> simplify_bitnot(const bitnot_exprt &);
172  [[nodiscard]] resultt<> simplify_not(const not_exprt &);
173  [[nodiscard]] resultt<> simplify_boolean(const exprt &);
174  [[nodiscard]] resultt<> simplify_inequality(const binary_relation_exprt &);
175  [[nodiscard]] resultt<>
177  [[nodiscard]] resultt<> simplify_lambda(const lambda_exprt &);
178  [[nodiscard]] resultt<> simplify_with(const with_exprt &);
179  [[nodiscard]] resultt<> simplify_update(const update_exprt &);
180  [[nodiscard]] resultt<> simplify_index(const index_exprt &);
181  [[nodiscard]] resultt<> simplify_index_preorder(const index_exprt &);
182  [[nodiscard]] resultt<> simplify_member(const member_exprt &);
183  [[nodiscard]] resultt<> simplify_member_preorder(const member_exprt &);
184  [[nodiscard]] resultt<> simplify_byte_update(const byte_update_exprt &);
185  [[nodiscard]] resultt<> simplify_byte_extract(const byte_extract_exprt &);
186  [[nodiscard]] resultt<>
189  [[nodiscard]] resultt<>
191  [[nodiscard]] resultt<> simplify_object_size(const object_size_exprt &);
192  [[nodiscard]] resultt<> simplify_is_dynamic_object(const unary_exprt &);
193  [[nodiscard]] resultt<> simplify_is_invalid_pointer(const unary_exprt &);
194  [[nodiscard]] resultt<> simplify_object(const exprt &);
195  [[nodiscard]] resultt<> simplify_unary_minus(const unary_minus_exprt &);
196  [[nodiscard]] resultt<> simplify_unary_plus(const unary_plus_exprt &);
197  [[nodiscard]] resultt<> simplify_dereference(const dereference_exprt &);
198  [[nodiscard]] resultt<>
200  [[nodiscard]] resultt<> simplify_address_of(const address_of_exprt &);
202  [[nodiscard]] resultt<> simplify_bswap(const bswap_exprt &);
203  [[nodiscard]] resultt<> simplify_isinf(const unary_exprt &);
204  [[nodiscard]] resultt<> simplify_isnan(const unary_exprt &);
205  [[nodiscard]] resultt<> simplify_isnormal(const unary_exprt &);
206  [[nodiscard]] resultt<> simplify_abs(const abs_exprt &);
207  [[nodiscard]] resultt<> simplify_sign(const sign_exprt &);
208  [[nodiscard]] resultt<> simplify_popcount(const popcount_exprt &);
209  [[nodiscard]] resultt<> simplify_complex(const unary_exprt &);
210 
214  [[nodiscard]] resultt<>
216 
221 
226  [[nodiscard]] resultt<>
228 
231  [[nodiscard]] resultt<>
233 
235  [[nodiscard]] resultt<> simplify_clz(const count_leading_zeros_exprt &);
236 
238  [[nodiscard]] resultt<> simplify_ctz(const count_trailing_zeros_exprt &);
239 
241  [[nodiscard]] resultt<> simplify_bitreverse(const bitreverse_exprt &);
242 
244  [[nodiscard]] resultt<> simplify_ffs(const find_first_set_exprt &);
245 
247  [[nodiscard]] resultt<>
249 
251  [[nodiscard]] resultt<>
253 
254  // auxiliary
255  bool simplify_if_implies(
256  exprt &expr, const exprt &cond, bool truth, bool &new_truth);
257  bool simplify_if_recursive(exprt &expr, const exprt &cond, bool truth);
258  bool simplify_if_conj(exprt &expr, const exprt &cond);
259  bool simplify_if_disj(exprt &expr, const exprt &cond);
260  bool simplify_if_branch(exprt &trueexpr, exprt &falseexpr, const exprt &cond);
261  bool simplify_if_cond(exprt &expr);
262  [[nodiscard]] resultt<> simplify_address_of_arg(const exprt &);
263  [[nodiscard]] resultt<>
265  [[nodiscard]] resultt<>
267  [[nodiscard]] resultt<>
269  [[nodiscard]] resultt<>
271  [[nodiscard]] resultt<>
273 
274  // main recursion
275  [[nodiscard]] resultt<> simplify_node(const exprt &);
276  [[nodiscard]] resultt<> simplify_node_preorder(const exprt &);
277  [[nodiscard]] resultt<> simplify_rec(const exprt &);
278 
279  virtual bool simplify(exprt &expr);
280 
281 protected:
282  const namespacet &ns;
283 #ifdef DEBUG_ON_DEMAND
284  bool debug_on;
285 #endif
286 #ifdef USE_LOCAL_REPLACE_MAP
287  replace_mapt local_replace_map;
288 #endif
289 
290 };
291 
292 #endif // CPROVER_UTIL_SIMPLIFY_EXPR_CLASS_H
Absolute value.
Definition: std_expr.h:442
Operator to return the address of an object.
Definition: pointer_expr.h:540
Array constructor from list of elements.
Definition: std_expr.h:1621
A base class for binary expressions.
Definition: std_expr.h:638
A Boolean expression returning true, iff operation kind would result in an overflow when applied to o...
A base class for relations, i.e., binary predicates whose two operands have the same type.
Definition: std_expr.h:762
Bit-wise negation of bit-vectors.
Reverse the order of bits in a bit-vector.
The byte swap expression.
Expression of type type extracted from some object op starting at position offset (given in number of...
Expression corresponding to op() where the bytes starting at position offset (given in number of byte...
Concatenation of bit-vector operands.
The count leading zeros (counting the number of zero bits starting from the most-significant bit) exp...
The count trailing zeros (counting the number of zero bits starting from the least-significant bit) e...
Operator to dereference a pointer.
Definition: pointer_expr.h:834
Division.
Definition: std_expr.h:1157
Base class for all expressions.
Definition: expr.h:56
Extracts a single bit of a bit-vector operand.
Extracts a sub-range of a bit-vector operand.
Returns one plus the index of the least-significant one bit, or zero if the operand is zero.
Semantic type conversion from/to floating-point formats.
Definition: floatbv_expr.h:19
Application of (mathematical) function.
IEEE floating-point operations These have two data operands (op0 and op1) and one rounding mode (op2)...
Definition: floatbv_expr.h:364
The trinary if-then-else operator.
Definition: std_expr.h:2380
Array index operator.
Definition: std_expr.h:1470
A (mathematical) lambda expression.
Extract member of struct or union.
Definition: std_expr.h:2854
Binary minus.
Definition: std_expr.h:1061
Modulo defined as lhs-(rhs * truncate(lhs/rhs)).
Definition: std_expr.h:1228
Binary multiplication Associativity is not specified.
Definition: std_expr.h:1107
A base class for multi-ary expressions Associativity is not specified.
Definition: std_expr.h:912
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:94
Boolean negation.
Definition: std_expr.h:2337
Expression for finding the size (in bytes) of the object a pointer points to.
An expression returning both the result of the arithmetic operation under wrap-around semantics as we...
The plus expression Associativity is not specified.
Definition: std_expr.h:1002
A numerical identifier for the object a pointer points to.
The offset (in bytes) of a pointer relative to the object.
The popcount (counting the number of bits set to 1) expression.
Exponentiation.
pointer_in_range (see pointer_in_range_exprt) with prophecy expressions to encode whether a pointer r...
Definition: pointer_expr.h:453
A base class for a predicate that indicates that an address range is ok to read or write or both.
A base class for shift and rotate operators.
Sign of an expression Predicate is true if _op is negative, false otherwise.
Definition: std_expr.h:596
resultt simplify_isnan(const unary_exprt &)
resultt simplify_bitwise(const multi_ary_exprt &)
const namespacet & ns
resultt simplify_inequality_address_of(const binary_relation_exprt &)
resultt simplify_div(const div_exprt &)
resultt simplify_byte_extract(const byte_extract_exprt &)
resultt simplify_bitreverse(const bitreverse_exprt &)
Try to simplify bit-reversing to a constant expression.
resultt simplify_abs(const abs_exprt &)
bool simplify_if_conj(exprt &expr, const exprt &cond)
resultt simplify_isnormal(const unary_exprt &)
resultt simplify_dereference(const dereference_exprt &)
resultt simplify_bitnot(const bitnot_exprt &)
resultt simplify_zero_extend(const zero_extend_exprt &)
resultt simplify_prophecy_r_or_w_ok(const prophecy_r_or_w_ok_exprt &)
Try to simplify prophecy_{r,w,rw}_ok to a constant expression.
bool simplify_if_disj(exprt &expr, const exprt &cond)
resultt simplify_member_preorder(const member_exprt &)
resultt simplify_popcount(const popcount_exprt &)
static resultt changed(resultt<> result)
resultt simplify_dereference_preorder(const dereference_exprt &)
resultt simplify_unary_pointer_predicate_preorder(const unary_exprt &)
resultt simplify_address_of(const address_of_exprt &)
resultt simplify_if(const if_exprt &)
resultt simplify_node(const exprt &)
resultt simplify_node_preorder(const exprt &)
resultt simplify_prophecy_pointer_in_range(const prophecy_pointer_in_range_exprt &)
Try to simplify prophecy_pointer_in_range to a constant expression.
resultt simplify_overflow_unary(const unary_overflow_exprt &)
Try to simplify overflow-unary-.
bool simplify_if_recursive(exprt &expr, const exprt &cond, bool truth)
resultt simplify_minus(const minus_exprt &)
resultt simplify_extractbit(const extractbit_exprt &)
resultt simplify_rec(const exprt &)
resultt simplify_shifts(const shift_exprt &)
resultt simplify_index_preorder(const index_exprt &)
bool simplify_if_cond(exprt &expr)
resultt simplify_typecast(const typecast_exprt &)
simplify_exprt(const namespacet &_ns)
resultt simplify_pointer_object(const pointer_object_exprt &)
resultt simplify_boolean(const exprt &)
resultt simplify_object(const exprt &)
resultt simplify_mult(const mult_exprt &)
resultt simplify_floatbv_typecast(const floatbv_typecast_exprt &)
bool simplify_if_branch(exprt &trueexpr, exprt &falseexpr, const exprt &cond)
resultt simplify_inequality_rhs_is_constant(const binary_relation_exprt &)
resultt simplify_address_of_arg(const exprt &)
virtual ~simplify_exprt()
resultt simplify_with(const with_exprt &)
resultt simplify_inequality(const binary_relation_exprt &)
simplifies inequalities !=, <=, <, >=, >, and also ==
resultt simplify_not(const not_exprt &)
resultt simplify_isinf(const unary_exprt &)
resultt simplify_overflow_binary(const binary_overflow_exprt &)
Try to simplify overflow-+, overflow-*, overflow–, overflow-shl.
resultt simplify_function_application(const function_application_exprt &)
Attempt to simplify mathematical function applications if we have enough information to do so.
resultt simplify_index(const index_exprt &)
resultt simplify_bswap(const bswap_exprt &)
resultt simplify_member(const member_exprt &)
resultt simplify_inequality_pointer_object(const binary_relation_exprt &)
static resultt unchanged(exprt expr)
resultt simplify_byte_update(const byte_update_exprt &)
resultt simplify_extractbits(const extractbits_exprt &)
Simplifies extracting of bits from a constant.
resultt simplify_update(const update_exprt &)
resultt simplify_is_invalid_pointer(const unary_exprt &)
resultt simplify_mod(const mod_exprt &)
resultt simplify_complex(const unary_exprt &)
resultt simplify_pointer_offset(const pointer_offset_exprt &)
resultt simplify_plus(const plus_exprt &)
virtual bool simplify(exprt &expr)
resultt simplify_inequality_no_constant(const binary_relation_exprt &)
resultt simplify_unary_plus(const unary_plus_exprt &)
resultt simplify_overflow_result(const overflow_result_exprt &)
Try to simplify overflow_result-+, overflow_result-*, overflow_result–, overflow_result-shl,...
resultt simplify_ffs(const find_first_set_exprt &)
Try to simplify find-first-set to a constant expression.
resultt simplify_if_preorder(const if_exprt &expr)
resultt simplify_byte_extract_preorder(const byte_extract_exprt &)
resultt simplify_is_dynamic_object(const unary_exprt &)
bool simplify_if_implies(exprt &expr, const exprt &cond, bool truth, bool &new_truth)
resultt simplify_power(const power_exprt &)
resultt simplify_object_size(const object_size_exprt &)
resultt simplify_lambda(const lambda_exprt &)
resultt simplify_concatenation(const concatenation_exprt &)
resultt simplify_floatbv_op(const ieee_float_op_exprt &)
resultt simplify_inequality_both_constant(const binary_relation_exprt &)
simplifies inequalities for the case in which both sides of the inequality are constants
resultt simplify_ctz(const count_trailing_zeros_exprt &)
Try to simplify count-trailing-zeros to a constant expression.
resultt simplify_clz(const count_leading_zeros_exprt &)
Try to simplify count-leading-zeros to a constant expression.
resultt simplify_ieee_float_relation(const binary_relation_exprt &)
resultt simplify_typecast_preorder(const typecast_exprt &)
resultt simplify_sign(const sign_exprt &)
resultt simplify_unary_minus(const unary_minus_exprt &)
Semantic type conversion.
Definition: std_expr.h:2073
Generic base class for unary expressions.
Definition: std_expr.h:361
The unary minus expression.
Definition: std_expr.h:484
A Boolean expression returning true, iff operation kind would result in an overflow when applied to t...
The unary plus expression.
Definition: std_expr.h:531
Operator to update elements in structs and arrays.
Definition: std_expr.h:2665
Operator to update elements in structs and arrays.
Definition: std_expr.h:2481
zero extension The operand is converted to the given type by either a) truncating if the new type is ...
resultt
The result of goto verifying.
Definition: properties.h:45
std::unordered_map< exprt, exprt, irep_hash > replace_mapt
Definition: replace_expr.h:22
resultt(expr_changedt _expr_changed, T _expr)
resultt(T _expr)
conversion from expression, thus not 'explicit' marks the expression as "CHANGED"
enum simplify_exprt::resultt::expr_changedt expr_changed
Defines typet, type_with_subtypet and type_with_subtypest.