CBMC
convert_expr_to_smt.cpp
Go to the documentation of this file.
1 // Author: Diffblue Ltd.
2 
3 #include <util/arith_tools.h>
4 #include <util/bitvector_expr.h>
5 #include <util/byte_operators.h>
6 #include <util/c_types.h>
7 #include <util/config.h>
8 #include <util/expr.h>
9 #include <util/expr_cast.h>
10 #include <util/expr_util.h>
11 #include <util/floatbv_expr.h>
12 #include <util/mathematical_expr.h>
13 #include <util/pointer_expr.h>
15 #include <util/range.h>
16 #include <util/std_expr.h>
17 #include <util/string_constant.h>
18 
24 
25 #include <functional>
26 #include <numeric>
27 
37 using sub_expression_mapt =
38  std::unordered_map<exprt, smt_termt, irep_full_hash>;
39 
52 template <typename factoryt>
54  const multi_ary_exprt &expr,
55  const sub_expression_mapt &converted,
56  const factoryt &factory)
57 {
58  PRECONDITION(expr.operands().size() >= 2);
59  const auto operand_terms =
60  make_range(expr.operands()).map([&](const exprt &expr) {
61  return converted.at(expr);
62  });
63  return std::accumulate(
64  ++operand_terms.begin(),
65  operand_terms.end(),
66  *operand_terms.begin(),
67  factory);
68 }
69 
74 template <typename target_typet>
75 static bool operands_are_of_type(const exprt &expr)
76 {
77  return std::all_of(
78  expr.operands().cbegin(), expr.operands().cend(), [](const exprt &operand) {
79  return can_cast_type<target_typet>(operand.type());
80  });
81 }
82 
84 {
85  return smt_bool_sortt{};
86 }
87 
89 {
90  return smt_bit_vector_sortt{type.get_width()};
91 }
92 
94 {
95  return smt_array_sortt{
98 }
99 
101 {
102  if(const auto bool_type = type_try_dynamic_cast<bool_typet>(type))
103  {
104  return convert_type_to_smt_sort(*bool_type);
105  }
106  if(const auto bitvector_type = type_try_dynamic_cast<bitvector_typet>(type))
107  {
108  return convert_type_to_smt_sort(*bitvector_type);
109  }
110  if(const auto array_type = type_try_dynamic_cast<array_typet>(type))
111  {
112  return convert_type_to_smt_sort(*array_type);
113  }
114  UNIMPLEMENTED_FEATURE("Generation of SMT formula for type: " + type.pretty());
115 }
116 
117 static smt_termt convert_expr_to_smt(const symbol_exprt &symbol_expr)
118 {
119  return smt_identifier_termt{symbol_expr.get_identifier(),
120  convert_type_to_smt_sort(symbol_expr.type())};
121 }
122 
124  const nondet_symbol_exprt &nondet_symbol,
125  const sub_expression_mapt &converted)
126 {
127  // A nondet_symbol is a reference to an unconstrained function. This function
128  // will already have been added as a dependency.
129  return smt_identifier_termt{
130  nondet_symbol.get_identifier(),
131  convert_type_to_smt_sort(nondet_symbol.type())};
132 }
133 
135 static smt_termt make_not_zero(const smt_termt &input, const typet &source_type)
136 {
137  if(input.get_sort().cast<smt_bool_sortt>())
138  return input;
139  if(const auto bit_vector_sort = input.get_sort().cast<smt_bit_vector_sortt>())
140  {
142  input, smt_bit_vector_constant_termt{0, *bit_vector_sort});
143  }
144  UNREACHABLE;
145 }
146 
149  const smt_termt &from_term,
150  const typet &from_type,
151  const bitvector_typet &to_type)
152 {
153  const std::size_t c_bool_width = to_type.get_width();
155  make_not_zero(from_term, from_type),
156  smt_bit_vector_constant_termt{1, c_bool_width},
157  smt_bit_vector_constant_termt{0, c_bool_width});
158 }
159 
160 static std::function<std::function<smt_termt(smt_termt)>(std::size_t)>
162 {
167  UNREACHABLE;
168 }
169 
171  const smt_termt &from_term,
172  const bitvector_typet &from_type,
173  const bitvector_typet &to_type)
174 {
175  if(const auto to_fixedbv_type = type_try_dynamic_cast<fixedbv_typet>(to_type))
176  {
178  "Generation of SMT formula for type cast to fixed-point bitvector "
179  "type: " +
180  to_type.pretty());
181  }
182  if(const auto to_floatbv_type = type_try_dynamic_cast<floatbv_typet>(to_type))
183  {
185  "Generation of SMT formula for type cast to floating-point bitvector "
186  "type: " +
187  to_type.pretty());
188  }
189  const std::size_t from_width = from_type.get_width();
190  const std::size_t to_width = to_type.get_width();
191  if(to_width == from_width)
192  return from_term;
193  if(to_width < from_width)
194  return smt_bit_vector_theoryt::extract(to_width - 1, 0)(from_term);
195  const std::size_t extension_size = to_width - from_width;
196  return extension_for_type(from_type)(extension_size)(from_term);
197 }
198 
201 {
203  const typet &from_type;
206 
208  const smt_termt &from_term,
209  const typet &from_type,
210  const bitvector_typet &to_type)
212  {
213  }
214 
215  void visit(const smt_bool_sortt &) override
216  {
219  }
220 
221  void visit(const smt_bit_vector_sortt &) override
222  {
223  if(const auto bitvector = type_try_dynamic_cast<bitvector_typet>(from_type))
225  else
227  "Generation of SMT formula for type cast to bit vector from type: " +
228  from_type.pretty());
229  }
230 
231  void visit(const smt_array_sortt &) override
232  {
234  "Generation of SMT formula for type cast to bit vector from type: " +
235  from_type.pretty());
236  }
237 };
238 
240  const smt_termt &from_term,
241  const typet &from_type,
242  const bitvector_typet &to_type)
243 {
245  from_term, from_type, to_type};
246  from_term.get_sort().accept(converter);
247  POSTCONDITION(converter.result);
248  return *converter.result;
249 }
250 
252  const typecast_exprt &cast,
253  const sub_expression_mapt &converted)
254 {
255  const auto &from_term = converted.at(cast.op());
256  const typet &from_type = cast.op().type();
257  const typet &to_type = cast.type();
258  if(const auto bool_type = type_try_dynamic_cast<bool_typet>(to_type))
259  return make_not_zero(from_term, cast.op().type());
260  if(const auto c_bool_type = type_try_dynamic_cast<c_bool_typet>(to_type))
261  return convert_c_bool_cast(from_term, from_type, *c_bool_type);
262  if(const auto bit_vector = type_try_dynamic_cast<bitvector_typet>(to_type))
263  return convert_bit_vector_cast(from_term, from_type, *bit_vector);
265  "Generation of SMT formula for type cast expression: " + cast.pretty());
266 }
267 
269  const floatbv_typecast_exprt &float_cast,
270  const sub_expression_mapt &converted)
271 {
273  "Generation of SMT formula for floating point type cast expression: " +
274  float_cast.pretty());
275 }
276 
278  const struct_exprt &struct_construction,
279  const sub_expression_mapt &converted)
280 {
282  "Generation of SMT formula for struct construction expression: " +
283  struct_construction.pretty());
284 }
285 
287  const union_exprt &union_construction,
288  const sub_expression_mapt &converted)
289 {
291  "Generation of SMT formula for union construction expression: " +
292  union_construction.pretty());
293 }
294 
296 {
299 
301  : member_input{input}
302  {
303  }
304 
305  void visit(const smt_bool_sortt &) override
306  {
308  }
309 
310  void visit(const smt_bit_vector_sortt &bit_vector_sort) override
311  {
312  const auto &width = bit_vector_sort.bit_width();
313  // We get the value using a non-signed interpretation, as smt bit vector
314  // terms do not carry signedness.
315  const auto value = bvrep2integer(member_input.get_value(), width, false);
316  result = smt_bit_vector_constant_termt{value, bit_vector_sort};
317  }
318 
319  void visit(const smt_array_sortt &array_sort) override
320  {
322  "Conversion of array SMT literal " + array_sort.pretty());
323  }
324 };
325 
326 static smt_termt convert_expr_to_smt(const constant_exprt &constant_literal)
327 {
328  if(is_null_pointer(constant_literal))
329  {
330  const size_t bit_width =
331  type_checked_cast<pointer_typet>(constant_literal.type()).get_width();
332  // An address of 0 encodes an object identifier of 0 for the NULL object
333  // and an offset of 0 into the object.
334  const auto address = 0;
335  return smt_bit_vector_constant_termt{address, bit_width};
336  }
337  if(constant_literal.type() == integer_typet{})
338  {
339  // This is converting integer constants into bit vectors for use with
340  // bit vector based smt logics. As bit vector widths are not specified for
341  // non bit vector types, this chooses a width based on the minimum needed
342  // to hold the integer constant value.
343  const auto value = numeric_cast_v<mp_integer>(constant_literal);
344  return smt_bit_vector_constant_termt{value, address_bits(value + 1)};
345  }
346  const auto sort = convert_type_to_smt_sort(constant_literal.type());
347  sort_based_literal_convertert converter(constant_literal);
348  sort.accept(converter);
349  return *converter.result;
350 }
351 
353  const concatenation_exprt &concatenation,
354  const sub_expression_mapt &converted)
355 {
357  "Generation of SMT formula for concatenation expression: " +
358  concatenation.pretty());
359 }
360 
362  const bitand_exprt &bitwise_and_expr,
363  const sub_expression_mapt &converted)
364 {
365  if(operands_are_of_type<integer_bitvector_typet>(bitwise_and_expr))
366  {
368  bitwise_and_expr, converted, smt_bit_vector_theoryt::make_and);
369  }
370  else
371  {
373  "Generation of SMT formula for bitwise and expression: " +
374  bitwise_and_expr.pretty());
375  }
376 }
377 
379  const bitor_exprt &bitwise_or_expr,
380  const sub_expression_mapt &converted)
381 {
382  if(operands_are_of_type<integer_bitvector_typet>(bitwise_or_expr))
383  {
385  bitwise_or_expr, converted, smt_bit_vector_theoryt::make_or);
386  }
387  else
388  {
390  "Generation of SMT formula for bitwise or expression: " +
391  bitwise_or_expr.pretty());
392  }
393 }
394 
396  const bitxor_exprt &bitwise_xor,
397  const sub_expression_mapt &converted)
398 {
399  if(operands_are_of_type<integer_bitvector_typet>(bitwise_xor))
400  {
403  }
404  else
405  {
407  "Generation of SMT formula for bitwise xor expression: " +
408  bitwise_xor.pretty());
409  }
410 }
411 
413  const bitnot_exprt &bitwise_not,
414  const sub_expression_mapt &converted)
415 {
416  const bool operand_is_bitvector =
418 
419  if(operand_is_bitvector)
420  {
421  return smt_bit_vector_theoryt::make_not(converted.at(bitwise_not.op()));
422  }
423  else
424  {
426  "Generation of SMT formula for bitnot_exprt: " + bitwise_not.pretty());
427  }
428 }
429 
431  const unary_minus_exprt &unary_minus,
432  const sub_expression_mapt &converted)
433 {
434  const bool operand_is_bitvector =
436  if(operand_is_bitvector)
437  {
438  return smt_bit_vector_theoryt::negate(converted.at(unary_minus.op()));
439  }
440  else
441  {
443  "Generation of SMT formula for unary minus expression: " +
444  unary_minus.pretty());
445  }
446 }
447 
449  const unary_plus_exprt &unary_plus,
450  const sub_expression_mapt &converted)
451 {
453  "Generation of SMT formula for unary plus expression: " +
454  unary_plus.pretty());
455 }
456 
458  const sign_exprt &is_negative,
459  const sub_expression_mapt &converted)
460 {
462  "Generation of SMT formula for \"is negative\" expression: " +
463  is_negative.pretty());
464 }
465 
467  const if_exprt &if_expression,
468  const sub_expression_mapt &converted)
469 {
471  converted.at(if_expression.cond()),
472  converted.at(if_expression.true_case()),
473  converted.at(if_expression.false_case()));
474 }
475 
477  const and_exprt &and_expression,
478  const sub_expression_mapt &converted)
479 {
481  and_expression, converted, smt_core_theoryt::make_and);
482 }
483 
485  const or_exprt &or_expression,
486  const sub_expression_mapt &converted)
487 {
489  or_expression, converted, smt_core_theoryt::make_or);
490 }
491 
493  const xor_exprt &xor_expression,
494  const sub_expression_mapt &converted)
495 {
497  xor_expression, converted, smt_core_theoryt::make_xor);
498 }
499 
501  const implies_exprt &implies,
502  const sub_expression_mapt &converted)
503 {
505  converted.at(implies.op0()), converted.at(implies.op1()));
506 }
507 
509  const not_exprt &logical_not,
510  const sub_expression_mapt &converted)
511 {
512  return smt_core_theoryt::make_not(converted.at(logical_not.op()));
513 }
514 
516  const equal_exprt &equal,
517  const sub_expression_mapt &converted)
518 {
520  converted.at(equal.op0()), converted.at(equal.op1()));
521 }
522 
524  const notequal_exprt &not_equal,
525  const sub_expression_mapt &converted)
526 {
528  converted.at(not_equal.op0()), converted.at(not_equal.op1()));
529 }
530 
532  const ieee_float_equal_exprt &float_equal,
533  const sub_expression_mapt &converted)
534 {
536  "Generation of SMT formula for floating point equality expression: " +
537  float_equal.pretty());
538 }
539 
541  const ieee_float_notequal_exprt &float_not_equal,
542  const sub_expression_mapt &converted)
543 {
545  "Generation of SMT formula for floating point not equal expression: " +
546  float_not_equal.pretty());
547 }
548 
549 template <typename unsigned_factory_typet, typename signed_factory_typet>
551  const binary_relation_exprt &binary_relation,
552  const unsigned_factory_typet &unsigned_factory,
553  const signed_factory_typet &signed_factory,
554  const sub_expression_mapt &converted)
555 {
556  PRECONDITION(binary_relation.lhs().type() == binary_relation.rhs().type());
557  const auto &lhs = converted.at(binary_relation.lhs());
558  const auto &rhs = converted.at(binary_relation.rhs());
559  const typet operand_type = binary_relation.lhs().type();
560  if(can_cast_type<pointer_typet>(operand_type))
561  {
562  // The code here is operating under the assumption that the comparison
563  // operands have types for which the comparison makes sense.
564 
565  // We already know this is the case given that we have followed
566  // the if statement branch, but including the same check here
567  // for consistency (it's cheap).
568  const auto lhs_type_is_pointer =
569  can_cast_type<pointer_typet>(binary_relation.lhs().type());
570  const auto rhs_type_is_pointer =
571  can_cast_type<pointer_typet>(binary_relation.rhs().type());
572  INVARIANT(
573  lhs_type_is_pointer && rhs_type_is_pointer,
574  "pointer comparison requires that both operand types are pointers.");
575  return unsigned_factory(lhs, rhs);
576  }
577  else if(lhs.get_sort().cast<smt_bit_vector_sortt>())
578  {
579  if(can_cast_type<unsignedbv_typet>(operand_type))
580  return unsigned_factory(lhs, rhs);
581  if(can_cast_type<signedbv_typet>(operand_type))
582  return signed_factory(lhs, rhs);
583  }
584 
586  "Generation of SMT formula for relational expression: " +
587  binary_relation.pretty());
588 }
589 
591  const exprt &expr,
592  const sub_expression_mapt &converted)
593 {
594  if(const auto greater_than = expr_try_dynamic_cast<greater_than_exprt>(expr))
595  {
597  *greater_than,
600  converted);
601  }
602  if(
603  const auto greater_than_or_equal =
604  expr_try_dynamic_cast<greater_than_or_equal_exprt>(expr))
605  {
607  *greater_than_or_equal,
610  converted);
611  }
612  if(const auto less_than = expr_try_dynamic_cast<less_than_exprt>(expr))
613  {
615  *less_than,
618  converted);
619  }
620  if(
621  const auto less_than_or_equal =
622  expr_try_dynamic_cast<less_than_or_equal_exprt>(expr))
623  {
625  *less_than_or_equal,
628  converted);
629  }
630  return {};
631 }
632 
634  const plus_exprt &plus,
635  const sub_expression_mapt &converted,
636  const type_size_mapt &pointer_sizes)
637 {
638  if(std::all_of(
639  plus.operands().cbegin(), plus.operands().cend(), [](exprt operand) {
640  return can_cast_type<integer_bitvector_typet>(operand.type());
641  }))
642  {
644  plus, converted, smt_bit_vector_theoryt::add);
645  }
646  else if(can_cast_type<pointer_typet>(plus.type()))
647  {
648  INVARIANT(
649  plus.operands().size() == 2,
650  "We are only handling a binary version of plus when it has a pointer "
651  "operand");
652 
653  exprt pointer;
654  exprt scalar;
655  for(auto &operand : plus.operands())
656  {
657  if(can_cast_type<pointer_typet>(operand.type()))
658  {
659  pointer = operand;
660  }
661  else
662  {
663  scalar = operand;
664  }
665  }
666 
667  // We need to ensure that we follow this code path only if the expression
668  // our assumptions about the structure of the addition expression hold.
669  INVARIANT(
671  "An addition expression with both operands being pointers when they are "
672  "not dereferenced is malformed");
673 
675  *type_try_dynamic_cast<pointer_typet>(pointer.type());
676  const auto base_type = pointer_type.base_type();
677  const auto pointer_size = pointer_sizes.at(base_type);
678 
680  converted.at(pointer),
681  smt_bit_vector_theoryt::multiply(converted.at(scalar), pointer_size));
682  }
683  else
684  {
686  "Generation of SMT formula for plus expression: " + plus.pretty());
687  }
688 }
689 
691  const minus_exprt &minus,
692  const sub_expression_mapt &converted,
693  const type_size_mapt &pointer_sizes)
694 {
695  const bool both_operands_bitvector =
698 
699  const bool lhs_is_pointer = can_cast_type<pointer_typet>(minus.lhs().type());
700  const bool rhs_is_pointer = can_cast_type<pointer_typet>(minus.rhs().type());
701 
702  const bool both_operands_pointers = lhs_is_pointer && rhs_is_pointer;
703 
704  // We don't really handle this - we just compute this to fall
705  // into an if-else branch that gives proper error handling information.
706  const bool one_operand_pointer = lhs_is_pointer || rhs_is_pointer;
707 
708  if(both_operands_bitvector)
709  {
711  converted.at(minus.lhs()), converted.at(minus.rhs()));
712  }
713  else if(both_operands_pointers)
714  {
715  const auto lhs_base_type = to_pointer_type(minus.lhs().type()).base_type();
716  const auto rhs_base_type = to_pointer_type(minus.rhs().type()).base_type();
717  INVARIANT(
718  lhs_base_type == rhs_base_type,
719  "only pointers of the same object type can be subtracted.");
722  converted.at(minus.lhs()), converted.at(minus.rhs())),
723  pointer_sizes.at(lhs_base_type));
724  }
725  else if(one_operand_pointer)
726  {
727  // It's semantically void to have an expression `3 - a` where `a`
728  // is a pointer.
729  INVARIANT(
730  lhs_is_pointer,
731  "minus expressions of pointer and integer expect lhs to be the pointer");
732  const auto lhs_base_type = to_pointer_type(minus.lhs().type()).base_type();
733 
735  converted.at(minus.lhs()),
737  converted.at(minus.rhs()), pointer_sizes.at(lhs_base_type)));
738  }
739  else
740  {
742  "Generation of SMT formula for minus expression: " + minus.pretty());
743  }
744 }
745 
747  const div_exprt &divide,
748  const sub_expression_mapt &converted)
749 {
750  const smt_termt &lhs = converted.at(divide.lhs());
751  const smt_termt &rhs = converted.at(divide.rhs());
752 
753  const bool both_operands_bitvector =
756 
757  const bool both_operands_unsigned =
760 
761  if(both_operands_bitvector)
762  {
763  if(both_operands_unsigned)
764  {
766  }
767  else
768  {
769  return smt_bit_vector_theoryt::signed_divide(lhs, rhs);
770  }
771  }
772  else
773  {
775  "Generation of SMT formula for divide expression: " + divide.pretty());
776  }
777 }
778 
780  const ieee_float_op_exprt &float_operation,
781  const sub_expression_mapt &converted)
782 {
783  // This case includes the floating point plus, minus, division and
784  // multiplication operations.
786  "Generation of SMT formula for floating point operation expression: " +
787  float_operation.pretty());
788 }
789 
791  const mod_exprt &truncation_modulo,
792  const sub_expression_mapt &converted)
793 {
794  const smt_termt &lhs = converted.at(truncation_modulo.lhs());
795  const smt_termt &rhs = converted.at(truncation_modulo.rhs());
796 
797  const bool both_operands_bitvector =
798  can_cast_type<integer_bitvector_typet>(truncation_modulo.lhs().type()) &&
799  can_cast_type<integer_bitvector_typet>(truncation_modulo.rhs().type());
800 
801  const bool both_operands_unsigned =
802  can_cast_type<unsignedbv_typet>(truncation_modulo.lhs().type()) &&
803  can_cast_type<unsignedbv_typet>(truncation_modulo.rhs().type());
804 
805  if(both_operands_bitvector)
806  {
807  if(both_operands_unsigned)
808  {
810  }
811  else
812  {
814  }
815  }
816  else
817  {
819  "Generation of SMT formula for remainder (modulus) expression: " +
820  truncation_modulo.pretty());
821  }
822 }
823 
825  const euclidean_mod_exprt &euclidean_modulo,
826  const sub_expression_mapt &converted)
827 {
829  "Generation of SMT formula for euclidean modulo expression: " +
830  euclidean_modulo.pretty());
831 }
832 
834  const mult_exprt &multiply,
835  const sub_expression_mapt &converted)
836 {
837  if(std::all_of(
838  multiply.operands().cbegin(),
839  multiply.operands().cend(),
840  [](exprt operand) {
841  return can_cast_type<integer_bitvector_typet>(operand.type());
842  }))
843  {
845  multiply, converted, smt_bit_vector_theoryt::multiply);
846  }
847  else
848  {
850  "Generation of SMT formula for multiply expression: " +
851  multiply.pretty());
852  }
853 }
854 
855 #ifndef CPROVER_INVARIANT_DO_NOT_CHECK
856 static mp_integer power2(unsigned exponent)
857 {
858  mp_integer result;
859  result.setPower2(exponent);
860  return result;
861 }
862 #endif
863 
872  const address_of_exprt &address_of,
873  const sub_expression_mapt &converted,
874  const smt_object_mapt &object_map)
875 {
876  const auto type = type_try_dynamic_cast<pointer_typet>(address_of.type());
877  INVARIANT(
878  type, "Result of the address_of operator should have pointer type.");
879  const auto base = find_object_base_expression(address_of);
880  const auto object = object_map.find(base);
881  INVARIANT(
882  object != object_map.end(),
883  "Objects should be tracked before converting their address to SMT terms");
884  const std::size_t object_id = object->second.unique_id;
885  INVARIANT(
886  object_id < power2(config.bv_encoding.object_bits),
887  "There should be sufficient bits to encode unique object identifier.");
888  const smt_termt object_bit_vector =
890  INVARIANT(
891  type->get_width() > config.bv_encoding.object_bits,
892  "Pointer should be wider than object_bits in order to allow for offset "
893  "encoding.");
894  const size_t offset_bits = type->get_width() - config.bv_encoding.object_bits;
895  if(
896  const auto symbol =
897  expr_try_dynamic_cast<symbol_exprt>(address_of.object()))
898  {
899  const smt_bit_vector_constant_termt offset{0, offset_bits};
900  return smt_bit_vector_theoryt::concat(object_bit_vector, offset);
901  }
903  "Generation of SMT formula for address of expression: " +
904  address_of.pretty());
905 }
906 
908  const array_of_exprt &array_of,
909  const sub_expression_mapt &converted)
910 {
911  // This function is unreachable as the `array_of_exprt` nodes are already
912  // fully converted by the incremental decision procedure functions
913  // (smt2_incremental_decision_proceduret::define_array_function).
915 }
916 
918  const array_comprehension_exprt &array_comprehension,
919  const sub_expression_mapt &converted)
920 {
922  "Generation of SMT formula for array comprehension expression: " +
923  array_comprehension.pretty());
924 }
925 
927  const index_exprt &index_of,
928  const sub_expression_mapt &converted)
929 {
930  const smt_termt &array = converted.at(index_of.array());
931  const smt_termt &index = converted.at(index_of.index());
932  return smt_array_theoryt::select(array, index);
933 }
934 
935 template <typename factoryt, typename shiftt>
937  const factoryt &factory,
938  const shiftt &shift,
939  const sub_expression_mapt &converted)
940 {
941  const smt_termt &first_operand = converted.at(shift.op0());
942  const smt_termt &second_operand = converted.at(shift.op1());
943  const auto first_bit_vector_sort =
944  first_operand.get_sort().cast<smt_bit_vector_sortt>();
945  const auto second_bit_vector_sort =
946  second_operand.get_sort().cast<smt_bit_vector_sortt>();
947  INVARIANT(
948  first_bit_vector_sort && second_bit_vector_sort,
949  "Shift expressions are expected to have bit vector operands.");
950  const std::size_t first_width = first_bit_vector_sort->bit_width();
951  const std::size_t second_width = second_bit_vector_sort->bit_width();
952  if(first_width > second_width)
953  {
954  return factory(
955  first_operand,
956  extension_for_type(shift.op1().type())(first_width - second_width)(
957  second_operand));
958  }
959  else if(first_width < second_width)
960  {
961  return factory(
962  extension_for_type(shift.op0().type())(second_width - first_width)(
963  first_operand),
964  second_operand);
965  }
966  else
967  {
968  return factory(first_operand, second_operand);
969  }
970 }
971 
973  const shift_exprt &shift,
974  const sub_expression_mapt &converted)
975 {
976  // TODO: Dispatch for rotation expressions. A `shift_exprt` can be a rotation.
977  if(const auto left_shift = expr_try_dynamic_cast<shl_exprt>(shift))
978  {
979  return convert_to_smt_shift(
980  smt_bit_vector_theoryt::shift_left, *left_shift, converted);
981  }
982  if(const auto right_logical_shift = expr_try_dynamic_cast<lshr_exprt>(shift))
983  {
984  return convert_to_smt_shift(
986  *right_logical_shift,
987  converted);
988  }
989  if(const auto right_arith_shift = expr_try_dynamic_cast<ashr_exprt>(shift))
990  {
991  return convert_to_smt_shift(
993  *right_arith_shift,
994  converted);
995  }
997  "Generation of SMT formula for shift expression: " + shift.pretty());
998 }
999 
1001  const exprt &old,
1002  const exprt &index,
1003  const exprt &new_value,
1004  const sub_expression_mapt &converted)
1005 {
1006  const smt_termt &old_array_term = converted.at(old);
1007  const smt_termt &index_term = converted.at(index);
1008  const smt_termt &value_term = converted.at(new_value);
1009  return smt_array_theoryt::store(old_array_term, index_term, value_term);
1010 }
1011 
1013  const with_exprt &with,
1014  const sub_expression_mapt &converted)
1015 {
1016  if(const auto array_type = type_try_dynamic_cast<array_typet>(with.type()))
1017  {
1019  with.old(), with.where(), with.new_value(), converted);
1020  }
1021  // 'with' expression is also used to update struct fields, but for now we do
1022  // not support them, so we fail.
1024  "Generation of SMT formula for with expression: " + with.pretty());
1025 }
1026 
1028  const update_exprt &update,
1029  const sub_expression_mapt &converted)
1030 {
1032  "Generation of SMT formula for update expression: " + update.pretty());
1033 }
1034 
1036  const member_exprt &member_extraction,
1037  const sub_expression_mapt &converted)
1038 {
1040  "Generation of SMT formula for member extraction expression: " +
1041  member_extraction.pretty());
1042 }
1043 
1045  const is_dynamic_object_exprt &is_dynamic_object,
1046  const sub_expression_mapt &converted)
1047 {
1049  "Generation of SMT formula for is dynamic object expression: " +
1050  is_dynamic_object.pretty());
1051 }
1052 
1054  const is_invalid_pointer_exprt &is_invalid_pointer,
1055  const smt_object_mapt &object_map,
1056  const sub_expression_mapt &converted)
1057 {
1058  const exprt &pointer_expr(to_unary_expr(is_invalid_pointer).op());
1059  const bitvector_typet *pointer_type =
1060  type_try_dynamic_cast<bitvector_typet>(pointer_expr.type());
1061  INVARIANT(pointer_type, "Pointer object should have a bitvector-based type.");
1062  const std::size_t object_bits = config.bv_encoding.object_bits;
1063  const std::size_t width = pointer_type->get_width();
1064  INVARIANT(
1065  width >= object_bits,
1066  "Width should be at least as big as the number of object bits.");
1067 
1068  const auto extract_op = smt_bit_vector_theoryt::extract(
1069  width - 1, width - object_bits)(converted.at(pointer_expr));
1070 
1071  const auto &invalid_pointer = object_map.at(make_invalid_pointer_expr());
1072 
1073  const smt_termt invalid_pointer_address = smt_bit_vector_constant_termt(
1074  invalid_pointer.unique_id, config.bv_encoding.object_bits);
1075 
1076  return smt_core_theoryt::equal(invalid_pointer_address, extract_op);
1077 }
1078 
1080  const string_constantt &string_constant,
1081  const sub_expression_mapt &converted)
1082 {
1084  "Generation of SMT formula for string constant expression: " +
1085  string_constant.pretty());
1086 }
1087 
1089  const extractbit_exprt &extract_bit,
1090  const sub_expression_mapt &converted)
1091 {
1093  "Generation of SMT formula for extract bit expression: " +
1094  extract_bit.pretty());
1095 }
1096 
1098  const extractbits_exprt &extract_bits,
1099  const sub_expression_mapt &converted)
1100 {
1101  const smt_termt &from = converted.at(extract_bits.src());
1102  const auto upper_value = numeric_cast<std::size_t>(extract_bits.upper());
1103  const auto lower_value = numeric_cast<std::size_t>(extract_bits.lower());
1104  if(upper_value && lower_value)
1105  return smt_bit_vector_theoryt::extract(*upper_value, *lower_value)(from);
1107  "Generation of SMT formula for extract bits expression: " +
1108  extract_bits.pretty());
1109 }
1110 
1112  const replication_exprt &replication,
1113  const sub_expression_mapt &converted)
1114 {
1116  "Generation of SMT formula for bit vector replication expression: " +
1117  replication.pretty());
1118 }
1119 
1121  const byte_extract_exprt &byte_extraction,
1122  const sub_expression_mapt &converted)
1123 {
1125  "Generation of SMT formula for byte extract expression: " +
1126  byte_extraction.pretty());
1127 }
1128 
1130  const byte_update_exprt &byte_update,
1131  const sub_expression_mapt &converted)
1132 {
1134  "Generation of SMT formula for byte update expression: " +
1135  byte_update.pretty());
1136 }
1137 
1139  const abs_exprt &absolute_value_of,
1140  const sub_expression_mapt &converted)
1141 {
1143  "Generation of SMT formula for absolute value of expression: " +
1144  absolute_value_of.pretty());
1145 }
1146 
1148  const isnan_exprt &is_nan_expr,
1149  const sub_expression_mapt &converted)
1150 {
1152  "Generation of SMT formula for is not a number expression: " +
1153  is_nan_expr.pretty());
1154 }
1155 
1157  const isfinite_exprt &is_finite_expr,
1158  const sub_expression_mapt &converted)
1159 {
1161  "Generation of SMT formula for is finite expression: " +
1162  is_finite_expr.pretty());
1163 }
1164 
1166  const isinf_exprt &is_infinite_expr,
1167  const sub_expression_mapt &converted)
1168 {
1170  "Generation of SMT formula for is infinite expression: " +
1171  is_infinite_expr.pretty());
1172 }
1173 
1175  const isnormal_exprt &is_normal_expr,
1176  const sub_expression_mapt &converted)
1177 {
1179  "Generation of SMT formula for is infinite expression: " +
1180  is_normal_expr.pretty());
1181 }
1182 
1187 {
1188  const auto bit_vector_sort = input.get_sort().cast<smt_bit_vector_sortt>();
1189  INVARIANT(
1190  bit_vector_sort,
1191  "Most significant bit can only be extracted from bit vector terms.");
1192  const size_t most_significant_bit_index = bit_vector_sort->bit_width() - 1;
1193  const auto extract_most_significant_bit = smt_bit_vector_theoryt::extract(
1194  most_significant_bit_index, most_significant_bit_index);
1195  return smt_core_theoryt::equal(
1196  extract_most_significant_bit(input), smt_bit_vector_constant_termt{1, 1});
1197 }
1198 
1200  const plus_overflow_exprt &plus_overflow,
1201  const sub_expression_mapt &converted)
1202 {
1203  const smt_termt &left = converted.at(plus_overflow.lhs());
1204  const smt_termt &right = converted.at(plus_overflow.rhs());
1205  if(operands_are_of_type<unsignedbv_typet>(plus_overflow))
1206  {
1207  const auto add_carry_bit = smt_bit_vector_theoryt::zero_extend(1);
1209  smt_bit_vector_theoryt::add(add_carry_bit(left), add_carry_bit(right)));
1210  }
1211  if(operands_are_of_type<signedbv_typet>(plus_overflow))
1212  {
1213  // Overflow has occurred if the operands have the same sign and adding them
1214  // gives a result of the opposite sign.
1215  const smt_termt msb_left = most_significant_bit_is_set(left);
1216  const smt_termt msb_right = most_significant_bit_is_set(right);
1218  smt_core_theoryt::equal(msb_left, msb_right),
1220  msb_left,
1222  }
1224  "Generation of SMT formula for plus overflow expression: " +
1225  plus_overflow.pretty());
1226 }
1227 
1229  const minus_overflow_exprt &minus_overflow,
1230  const sub_expression_mapt &converted)
1231 {
1232  const smt_termt &left = converted.at(minus_overflow.lhs());
1233  const smt_termt &right = converted.at(minus_overflow.rhs());
1234  if(operands_are_of_type<unsignedbv_typet>(minus_overflow))
1235  {
1236  return smt_bit_vector_theoryt::unsigned_less_than(left, right);
1237  }
1238  if(operands_are_of_type<signedbv_typet>(minus_overflow))
1239  {
1240  // Overflow has occurred if the operands have the opposing signs and
1241  // subtracting them gives a result having the same signedness as the
1242  // right-hand operand. For example the following would be overflow for cases
1243  // for 8 bit wide bit vectors -
1244  // -128 - 1 == 127
1245  // 127 - (-1) == -128
1246  const smt_termt msb_left = most_significant_bit_is_set(left);
1247  const smt_termt msb_right = most_significant_bit_is_set(right);
1249  smt_core_theoryt::distinct(msb_left, msb_right),
1251  msb_right,
1253  smt_bit_vector_theoryt::subtract(left, right))));
1254  }
1256  "Generation of SMT formula for minus overflow expression: " +
1257  minus_overflow.pretty());
1258 }
1259 
1261  const mult_overflow_exprt &mult_overflow,
1262  const sub_expression_mapt &converted)
1263 {
1264  PRECONDITION(mult_overflow.lhs().type() == mult_overflow.rhs().type());
1265  const auto &operand_type = mult_overflow.lhs().type();
1266  const smt_termt &left = converted.at(mult_overflow.lhs());
1267  const smt_termt &right = converted.at(mult_overflow.rhs());
1268  if(
1269  const auto unsigned_type =
1270  type_try_dynamic_cast<unsignedbv_typet>(operand_type))
1271  {
1272  const std::size_t width = unsigned_type->get_width();
1273  const auto extend = smt_bit_vector_theoryt::zero_extend(width);
1275  smt_bit_vector_theoryt::multiply(extend(left), extend(right)),
1276  smt_bit_vector_constant_termt{power(2, width), width * 2});
1277  }
1278  if(
1279  const auto signed_type =
1280  type_try_dynamic_cast<signedbv_typet>(operand_type))
1281  {
1282  const smt_termt msb_left = most_significant_bit_is_set(left);
1283  const smt_termt msb_right = most_significant_bit_is_set(right);
1284  const std::size_t width = signed_type->get_width();
1285  const auto extend = smt_bit_vector_theoryt::sign_extend(width);
1286  const auto multiplication =
1287  smt_bit_vector_theoryt::multiply(extend(left), extend(right));
1289  multiplication,
1290  smt_bit_vector_constant_termt{power(2, width - 1), width * 2});
1291  const auto too_small = smt_bit_vector_theoryt::signed_less_than(
1292  multiplication,
1294  smt_bit_vector_constant_termt{power(2, width - 1), width * 2}));
1296  smt_core_theoryt::equal(msb_left, msb_right), too_large, too_small);
1297  }
1299  "Generation of SMT formula for multiply overflow expression: " +
1300  mult_overflow.pretty());
1301 }
1302 
1305  const sub_expression_mapt &converted)
1306 {
1307  const auto type =
1308  type_try_dynamic_cast<bitvector_typet>(pointer_object.type());
1309  INVARIANT(type, "Pointer object should have a bitvector-based type.");
1310  const auto converted_expr = converted.at(pointer_object.pointer());
1311  const std::size_t width = type->get_width();
1312  const std::size_t object_bits = config.bv_encoding.object_bits;
1313  INVARIANT(
1314  width >= object_bits,
1315  "Width should be at least as big as the number of object bits.");
1316  const std::size_t ext = width - object_bits;
1317  const auto extract_op = smt_bit_vector_theoryt::extract(
1318  width - 1, width - object_bits)(converted_expr);
1319  if(ext > 0)
1320  {
1321  return smt_bit_vector_theoryt::zero_extend(ext)(extract_op);
1322  }
1323  return extract_op;
1324 }
1325 
1328  const sub_expression_mapt &converted)
1329 {
1330  const auto type =
1331  type_try_dynamic_cast<bitvector_typet>(pointer_offset.type());
1332  INVARIANT(type, "Pointer offset should have a bitvector-based type.");
1333  const auto converted_expr = converted.at(pointer_offset.pointer());
1334  const std::size_t width = type->get_width();
1335  std::size_t offset_bits = width - config.bv_encoding.object_bits;
1336  if(offset_bits > width)
1337  offset_bits = width;
1338  const auto extract_op =
1339  smt_bit_vector_theoryt::extract(offset_bits - 1, 0)(converted_expr);
1340  if(width > offset_bits)
1341  {
1342  return smt_bit_vector_theoryt::zero_extend(width - offset_bits)(extract_op);
1343  }
1344  return extract_op;
1345 }
1346 
1348  const shl_overflow_exprt &shl_overflow,
1349  const sub_expression_mapt &converted)
1350 {
1352  "Generation of SMT formula for shift left overflow expression: " +
1353  shl_overflow.pretty());
1354 }
1355 
1357  const array_exprt &array_construction,
1358  const sub_expression_mapt &converted)
1359 {
1360  // This function is unreachable as the `array_exprt` nodes are already fully
1361  // converted by the incremental decision procedure functions
1362  // (smt2_incremental_decision_proceduret::define_array_function).
1364 }
1365 
1367  const literal_exprt &literal,
1368  const sub_expression_mapt &converted)
1369 {
1371  "Generation of SMT formula for literal expression: " + literal.pretty());
1372 }
1373 
1375  const forall_exprt &for_all,
1376  const sub_expression_mapt &converted)
1377 {
1379  "Generation of SMT formula for for all expression: " + for_all.pretty());
1380 }
1381 
1383  const exists_exprt &exists,
1384  const sub_expression_mapt &converted)
1385 {
1387  "Generation of SMT formula for exists expression: " + exists.pretty());
1388 }
1389 
1391  const vector_exprt &vector,
1392  const sub_expression_mapt &converted)
1393 {
1395  "Generation of SMT formula for vector expression: " + vector.pretty());
1396 }
1397 
1400  const sub_expression_mapt &converted,
1401  const smt_object_sizet::make_applicationt &call_object_size)
1402 {
1403  const smt_termt &pointer = converted.at(object_size.pointer());
1404  const auto pointer_sort = pointer.get_sort().cast<smt_bit_vector_sortt>();
1405  INVARIANT(
1406  pointer_sort, "Pointers should be encoded as bit vector sorted terms.");
1407  const std::size_t pointer_width = pointer_sort->bit_width();
1408  return call_object_size(
1409  std::vector<smt_termt>{smt_bit_vector_theoryt::extract(
1410  pointer_width - 1,
1411  pointer_width - config.bv_encoding.object_bits)(pointer)});
1412 }
1413 
1414 static smt_termt
1416 {
1418  "Generation of SMT formula for let expression: " + let.pretty());
1419 }
1420 
1422  const bswap_exprt &byte_swap,
1423  const sub_expression_mapt &converted)
1424 {
1426  "Generation of SMT formula for byte swap expression: " +
1427  byte_swap.pretty());
1428 }
1429 
1431  const popcount_exprt &population_count,
1432  const sub_expression_mapt &converted)
1433 {
1435  "Generation of SMT formula for population count expression: " +
1436  population_count.pretty());
1437 }
1438 
1440  const count_leading_zeros_exprt &count_leading_zeros,
1441  const sub_expression_mapt &converted)
1442 {
1444  "Generation of SMT formula for count leading zeros expression: " +
1445  count_leading_zeros.pretty());
1446 }
1447 
1449  const count_trailing_zeros_exprt &count_trailing_zeros,
1450  const sub_expression_mapt &converted)
1451 {
1453  "Generation of SMT formula for byte swap expression: " +
1454  count_trailing_zeros.pretty());
1455 }
1456 
1458  const exprt &expr,
1459  const sub_expression_mapt &converted,
1460  const smt_object_mapt &object_map,
1461  const type_size_mapt &pointer_sizes,
1462  const smt_object_sizet::make_applicationt &call_object_size)
1463 {
1464  if(const auto symbol = expr_try_dynamic_cast<symbol_exprt>(expr))
1465  {
1466  return convert_expr_to_smt(*symbol);
1467  }
1468  if(const auto nondet = expr_try_dynamic_cast<nondet_symbol_exprt>(expr))
1469  {
1470  return convert_expr_to_smt(*nondet, converted);
1471  }
1472  if(const auto cast = expr_try_dynamic_cast<typecast_exprt>(expr))
1473  {
1474  return convert_expr_to_smt(*cast, converted);
1475  }
1476  if(
1477  const auto float_cast = expr_try_dynamic_cast<floatbv_typecast_exprt>(expr))
1478  {
1479  return convert_expr_to_smt(*float_cast, converted);
1480  }
1481  if(const auto struct_construction = expr_try_dynamic_cast<struct_exprt>(expr))
1482  {
1483  return convert_expr_to_smt(*struct_construction, converted);
1484  }
1485  if(const auto union_construction = expr_try_dynamic_cast<union_exprt>(expr))
1486  {
1487  return convert_expr_to_smt(*union_construction, converted);
1488  }
1489  if(const auto constant_literal = expr_try_dynamic_cast<constant_exprt>(expr))
1490  {
1491  return convert_expr_to_smt(*constant_literal);
1492  }
1493  if(
1494  const auto concatenation = expr_try_dynamic_cast<concatenation_exprt>(expr))
1495  {
1496  return convert_expr_to_smt(*concatenation, converted);
1497  }
1498  if(const auto bitwise_and_expr = expr_try_dynamic_cast<bitand_exprt>(expr))
1499  {
1500  return convert_expr_to_smt(*bitwise_and_expr, converted);
1501  }
1502  if(const auto bitwise_or_expr = expr_try_dynamic_cast<bitor_exprt>(expr))
1503  {
1504  return convert_expr_to_smt(*bitwise_or_expr, converted);
1505  }
1506  if(const auto bitwise_xor = expr_try_dynamic_cast<bitxor_exprt>(expr))
1507  {
1508  return convert_expr_to_smt(*bitwise_xor, converted);
1509  }
1510  if(const auto bitwise_not = expr_try_dynamic_cast<bitnot_exprt>(expr))
1511  {
1512  return convert_expr_to_smt(*bitwise_not, converted);
1513  }
1514  if(const auto unary_minus = expr_try_dynamic_cast<unary_minus_exprt>(expr))
1515  {
1516  return convert_expr_to_smt(*unary_minus, converted);
1517  }
1518  if(const auto unary_plus = expr_try_dynamic_cast<unary_plus_exprt>(expr))
1519  {
1520  return convert_expr_to_smt(*unary_plus, converted);
1521  }
1522  if(const auto is_negative = expr_try_dynamic_cast<sign_exprt>(expr))
1523  {
1524  return convert_expr_to_smt(*is_negative, converted);
1525  }
1526  if(const auto if_expression = expr_try_dynamic_cast<if_exprt>(expr))
1527  {
1528  return convert_expr_to_smt(*if_expression, converted);
1529  }
1530  if(const auto and_expression = expr_try_dynamic_cast<and_exprt>(expr))
1531  {
1532  return convert_expr_to_smt(*and_expression, converted);
1533  }
1534  if(const auto or_expression = expr_try_dynamic_cast<or_exprt>(expr))
1535  {
1536  return convert_expr_to_smt(*or_expression, converted);
1537  }
1538  if(const auto xor_expression = expr_try_dynamic_cast<xor_exprt>(expr))
1539  {
1540  return convert_expr_to_smt(*xor_expression, converted);
1541  }
1542  if(const auto implies = expr_try_dynamic_cast<implies_exprt>(expr))
1543  {
1544  return convert_expr_to_smt(*implies, converted);
1545  }
1546  if(const auto logical_not = expr_try_dynamic_cast<not_exprt>(expr))
1547  {
1548  return convert_expr_to_smt(*logical_not, converted);
1549  }
1550  if(const auto equal = expr_try_dynamic_cast<equal_exprt>(expr))
1551  {
1552  return convert_expr_to_smt(*equal, converted);
1553  }
1554  if(const auto not_equal = expr_try_dynamic_cast<notequal_exprt>(expr))
1555  {
1556  return convert_expr_to_smt(*not_equal, converted);
1557  }
1558  if(
1559  const auto float_equal =
1560  expr_try_dynamic_cast<ieee_float_equal_exprt>(expr))
1561  {
1562  return convert_expr_to_smt(*float_equal, converted);
1563  }
1564  if(
1565  const auto float_not_equal =
1566  expr_try_dynamic_cast<ieee_float_notequal_exprt>(expr))
1567  {
1568  return convert_expr_to_smt(*float_not_equal, converted);
1569  }
1570  if(
1571  const auto converted_relational =
1572  try_relational_conversion(expr, converted))
1573  {
1574  return *converted_relational;
1575  }
1576  if(const auto plus = expr_try_dynamic_cast<plus_exprt>(expr))
1577  {
1578  return convert_expr_to_smt(*plus, converted, pointer_sizes);
1579  }
1580  if(const auto minus = expr_try_dynamic_cast<minus_exprt>(expr))
1581  {
1582  return convert_expr_to_smt(*minus, converted, pointer_sizes);
1583  }
1584  if(const auto divide = expr_try_dynamic_cast<div_exprt>(expr))
1585  {
1586  return convert_expr_to_smt(*divide, converted);
1587  }
1588  if(
1589  const auto float_operation =
1590  expr_try_dynamic_cast<ieee_float_op_exprt>(expr))
1591  {
1592  return convert_expr_to_smt(*float_operation, converted);
1593  }
1594  if(const auto truncation_modulo = expr_try_dynamic_cast<mod_exprt>(expr))
1595  {
1596  return convert_expr_to_smt(*truncation_modulo, converted);
1597  }
1598  if(
1599  const auto euclidean_modulo =
1600  expr_try_dynamic_cast<euclidean_mod_exprt>(expr))
1601  {
1602  return convert_expr_to_smt(*euclidean_modulo, converted);
1603  }
1604  if(const auto multiply = expr_try_dynamic_cast<mult_exprt>(expr))
1605  {
1606  return convert_expr_to_smt(*multiply, converted);
1607  }
1608 #if 0
1609  else if(expr.id() == ID_floatbv_rem)
1610  {
1611  convert_floatbv_rem(to_binary_expr(expr));
1612  }
1613 #endif
1614  if(const auto address_of = expr_try_dynamic_cast<address_of_exprt>(expr))
1615  {
1616  return convert_expr_to_smt(*address_of, converted, object_map);
1617  }
1618  if(const auto array_of = expr_try_dynamic_cast<array_of_exprt>(expr))
1619  {
1620  return convert_expr_to_smt(*array_of, converted);
1621  }
1622  if(
1623  const auto array_comprehension =
1624  expr_try_dynamic_cast<array_comprehension_exprt>(expr))
1625  {
1626  return convert_expr_to_smt(*array_comprehension, converted);
1627  }
1628  if(const auto index = expr_try_dynamic_cast<index_exprt>(expr))
1629  {
1630  return convert_expr_to_smt(*index, converted);
1631  }
1632  if(const auto shift = expr_try_dynamic_cast<shift_exprt>(expr))
1633  {
1634  return convert_expr_to_smt(*shift, converted);
1635  }
1636  if(const auto with = expr_try_dynamic_cast<with_exprt>(expr))
1637  {
1638  return convert_expr_to_smt(*with, converted);
1639  }
1640  if(const auto update = expr_try_dynamic_cast<update_exprt>(expr))
1641  {
1642  return convert_expr_to_smt(*update, converted);
1643  }
1644  if(const auto member_extraction = expr_try_dynamic_cast<member_exprt>(expr))
1645  {
1646  return convert_expr_to_smt(*member_extraction, converted);
1647  }
1648  else if(
1649  const auto pointer_offset =
1650  expr_try_dynamic_cast<pointer_offset_exprt>(expr))
1651  {
1652  return convert_expr_to_smt(*pointer_offset, converted);
1653  }
1654  else if(
1655  const auto pointer_object =
1656  expr_try_dynamic_cast<pointer_object_exprt>(expr))
1657  {
1658  return convert_expr_to_smt(*pointer_object, converted);
1659  }
1660  if(
1661  const auto is_dynamic_object =
1662  expr_try_dynamic_cast<is_dynamic_object_exprt>(expr))
1663  {
1664  return convert_expr_to_smt(*is_dynamic_object, converted);
1665  }
1666  if(
1667  const auto is_invalid_pointer =
1668  expr_try_dynamic_cast<is_invalid_pointer_exprt>(expr))
1669  {
1670  return convert_expr_to_smt(*is_invalid_pointer, object_map, converted);
1671  }
1672  if(const auto string_constant = expr_try_dynamic_cast<string_constantt>(expr))
1673  {
1674  return convert_expr_to_smt(*string_constant, converted);
1675  }
1676  if(const auto extract_bit = expr_try_dynamic_cast<extractbit_exprt>(expr))
1677  {
1678  return convert_expr_to_smt(*extract_bit, converted);
1679  }
1680  if(const auto extract_bits = expr_try_dynamic_cast<extractbits_exprt>(expr))
1681  {
1682  return convert_expr_to_smt(*extract_bits, converted);
1683  }
1684  if(const auto replication = expr_try_dynamic_cast<replication_exprt>(expr))
1685  {
1686  return convert_expr_to_smt(*replication, converted);
1687  }
1688  if(
1689  const auto byte_extraction =
1690  expr_try_dynamic_cast<byte_extract_exprt>(expr))
1691  {
1692  return convert_expr_to_smt(*byte_extraction, converted);
1693  }
1694  if(const auto byte_update = expr_try_dynamic_cast<byte_update_exprt>(expr))
1695  {
1696  return convert_expr_to_smt(*byte_update, converted);
1697  }
1698  if(const auto absolute_value_of = expr_try_dynamic_cast<abs_exprt>(expr))
1699  {
1700  return convert_expr_to_smt(*absolute_value_of, converted);
1701  }
1702  if(const auto is_nan_expr = expr_try_dynamic_cast<isnan_exprt>(expr))
1703  {
1704  return convert_expr_to_smt(*is_nan_expr, converted);
1705  }
1706  if(const auto is_finite_expr = expr_try_dynamic_cast<isfinite_exprt>(expr))
1707  {
1708  return convert_expr_to_smt(*is_finite_expr, converted);
1709  }
1710  if(const auto is_infinite_expr = expr_try_dynamic_cast<isinf_exprt>(expr))
1711  {
1712  return convert_expr_to_smt(*is_infinite_expr, converted);
1713  }
1714  if(const auto is_normal_expr = expr_try_dynamic_cast<isnormal_exprt>(expr))
1715  {
1716  return convert_expr_to_smt(*is_normal_expr, converted);
1717  }
1718  if(
1719  const auto plus_overflow = expr_try_dynamic_cast<plus_overflow_exprt>(expr))
1720  {
1721  return convert_expr_to_smt(*plus_overflow, converted);
1722  }
1723  if(
1724  const auto minus_overflow =
1725  expr_try_dynamic_cast<minus_overflow_exprt>(expr))
1726  {
1727  return convert_expr_to_smt(*minus_overflow, converted);
1728  }
1729  if(
1730  const auto mult_overflow = expr_try_dynamic_cast<mult_overflow_exprt>(expr))
1731  {
1732  return convert_expr_to_smt(*mult_overflow, converted);
1733  }
1734  if(const auto shl_overflow = expr_try_dynamic_cast<shl_overflow_exprt>(expr))
1735  {
1736  return convert_expr_to_smt(*shl_overflow, converted);
1737  }
1738  if(const auto array_construction = expr_try_dynamic_cast<array_exprt>(expr))
1739  {
1740  return convert_expr_to_smt(*array_construction, converted);
1741  }
1742  if(const auto literal = expr_try_dynamic_cast<literal_exprt>(expr))
1743  {
1744  return convert_expr_to_smt(*literal, converted);
1745  }
1746  if(const auto for_all = expr_try_dynamic_cast<forall_exprt>(expr))
1747  {
1748  return convert_expr_to_smt(*for_all, converted);
1749  }
1750  if(const auto exists = expr_try_dynamic_cast<exists_exprt>(expr))
1751  {
1752  return convert_expr_to_smt(*exists, converted);
1753  }
1754  if(const auto vector = expr_try_dynamic_cast<vector_exprt>(expr))
1755  {
1756  return convert_expr_to_smt(*vector, converted);
1757  }
1758  if(const auto object_size = expr_try_dynamic_cast<object_size_exprt>(expr))
1759  {
1760  return convert_expr_to_smt(*object_size, converted, call_object_size);
1761  }
1762  if(const auto let = expr_try_dynamic_cast<let_exprt>(expr))
1763  {
1764  return convert_expr_to_smt(*let, converted);
1765  }
1766  INVARIANT(
1767  expr.id() != ID_constraint_select_one,
1768  "constraint_select_one is not expected in smt conversion: " +
1769  expr.pretty());
1770  if(const auto byte_swap = expr_try_dynamic_cast<bswap_exprt>(expr))
1771  {
1772  return convert_expr_to_smt(*byte_swap, converted);
1773  }
1774  if(const auto population_count = expr_try_dynamic_cast<popcount_exprt>(expr))
1775  {
1776  return convert_expr_to_smt(*population_count, converted);
1777  }
1778  if(
1779  const auto count_leading_zeros =
1780  expr_try_dynamic_cast<count_leading_zeros_exprt>(expr))
1781  {
1782  return convert_expr_to_smt(*count_leading_zeros, converted);
1783  }
1784  if(
1785  const auto count_trailing_zeros =
1786  expr_try_dynamic_cast<count_trailing_zeros_exprt>(expr))
1787  {
1788  return convert_expr_to_smt(*count_trailing_zeros, converted);
1789  }
1790 
1792  "Generation of SMT formula for unknown kind of expression: " +
1793  expr.pretty());
1794 }
1795 
1796 #ifndef CPROVER_INVARIANT_DO_NOT_CHECK
1797 template <typename functiont>
1799 {
1800  explicit at_scope_exitt(functiont exit_function)
1802  {
1803  }
1805  {
1806  exit_function();
1807  }
1808  functiont exit_function;
1809 };
1810 
1811 template <typename functiont>
1813 {
1814  return at_scope_exitt<functiont>(exit_function);
1815 }
1816 #endif
1817 
1819 {
1820  expr.visit_pre([](exprt &expr) {
1821  const auto address_of_expr = expr_try_dynamic_cast<address_of_exprt>(expr);
1822  if(!address_of_expr)
1823  return;
1824  const auto array_index_expr =
1825  expr_try_dynamic_cast<index_exprt>(address_of_expr->object());
1826  if(!array_index_expr)
1827  return;
1828  expr = plus_exprt{
1830  array_index_expr->array(),
1831  type_checked_cast<pointer_typet>(address_of_expr->type())},
1832  array_index_expr->index()};
1833  });
1834  return expr;
1835 }
1836 
1838  const exprt &expr,
1839  const smt_object_mapt &object_map,
1840  const type_size_mapt &pointer_sizes,
1842 {
1843 #ifndef CPROVER_INVARIANT_DO_NOT_CHECK
1844  static bool in_conversion = false;
1845  INVARIANT(
1846  !in_conversion,
1847  "Conversion of expr to smt should be non-recursive. "
1848  "Re-entrance found in conversion of " +
1849  expr.pretty(1, 0));
1850  in_conversion = true;
1851  const auto end_conversion = at_scope_exit([&]() { in_conversion = false; });
1852 #endif
1853  sub_expression_mapt sub_expression_map;
1854  const auto lowered_expr = lower_address_of_array_index(expr);
1855  lowered_expr.visit_post([&](const exprt &expr) {
1856  const auto find_result = sub_expression_map.find(expr);
1857  if(find_result != sub_expression_map.cend())
1858  return;
1860  expr, sub_expression_map, object_map, pointer_sizes, object_size);
1861  sub_expression_map.emplace_hint(find_result, expr, std::move(term));
1862  });
1863  return std::move(sub_expression_map.at(lowered_expr));
1864 }
with_exprt
Operator to update elements in structs and arrays.
Definition: std_expr.h:2423
UNREACHABLE
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:503
sort_based_cast_to_bit_vector_convertert::visit
void visit(const smt_array_sortt &) override
Definition: convert_expr_to_smt.cpp:231
at_scope_exitt::exit_function
functiont exit_function
Definition: convert_expr_to_smt.cpp:1808
configt::bv_encodingt::object_bits
std::size_t object_bits
Definition: config.h:336
lower_address_of_array_index
exprt lower_address_of_array_index(exprt expr)
Lower the address_of(array[idx]) sub expressions in expr to idx + address_of(array),...
Definition: convert_expr_to_smt.cpp:1818
sort_based_cast_to_bit_vector_convertert::sort_based_cast_to_bit_vector_convertert
sort_based_cast_to_bit_vector_convertert(const smt_termt &from_term, const typet &from_type, const bitvector_typet &to_type)
Definition: convert_expr_to_smt.cpp:207
most_significant_bit_is_set
static smt_termt most_significant_bit_is_set(const smt_termt &input)
Constructs a term which is true if the most significant bit of input is set.
Definition: convert_expr_to_smt.cpp:1186
to_unary_expr
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
Definition: std_expr.h:361
multi_ary_exprt
A base class for multi-ary expressions Associativity is not specified.
Definition: std_expr.h:856
make_not_zero
static smt_termt make_not_zero(const smt_termt &input, const typet &source_type)
Makes a term which is true if input is not 0 / false.
Definition: convert_expr_to_smt.cpp:135
exists
mini_bddt exists(const mini_bddt &u, const unsigned var)
Definition: miniBDD.cpp:556
sort_based_cast_to_bit_vector_convertert::result
optionalt< smt_termt > result
Definition: convert_expr_to_smt.cpp:205
sort_based_literal_convertert
Definition: convert_expr_to_smt.cpp:295
extractbits_exprt::lower
exprt & lower()
Definition: bitvector_expr.h:479
mp_integer
BigInt mp_integer
Definition: smt_terms.h:17
pointer_object
exprt pointer_object(const exprt &p)
Definition: pointer_predicates.cpp:23
binary_exprt::rhs
exprt & rhs()
Definition: std_expr.h:623
sort_based_cast_to_bit_vector_convertert::to_type
const bitvector_typet & to_type
Definition: convert_expr_to_smt.cpp:204
byte_update_exprt
Expression corresponding to op() where the bytes starting at position offset (given in number of byte...
Definition: byte_operators.h:77
configt::bv_encoding
struct configt::bv_encodingt bv_encoding
count_trailing_zeros_exprt
The count trailing zeros (counting the number of zero bits starting from the least-significant bit) e...
Definition: bitvector_expr.h:1067
smt_identifier_termt
Stores identifiers in unescaped and unquoted form.
Definition: smt_terms.h:91
arith_tools.h
nondet_symbol_exprt
Expression to hold a nondeterministic choice.
Definition: std_expr.h:241
address_of_exprt::object
exprt & object()
Definition: pointer_expr.h:380
UNIMPLEMENTED_FEATURE
#define UNIMPLEMENTED_FEATURE(FEATURE)
Definition: invariant.h:517
forall_exprt
A forall expression.
Definition: mathematical_expr.h:337
smt_bit_vector_theoryt::signed_greater_than_or_equal
static const smt_function_application_termt::factoryt< signed_greater_than_or_equalt > signed_greater_than_or_equal
Definition: smt_bit_vector_theory.h:180
nondet_symbol_exprt::get_identifier
const irep_idt & get_identifier() const
Definition: std_expr.h:270
sort_based_cast_to_bit_vector_convertert::visit
void visit(const smt_bool_sortt &) override
Definition: convert_expr_to_smt.cpp:215
typet
The type of an expression, extends irept.
Definition: type.h:28
irept::pretty
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
Definition: irep.cpp:495
smt_bit_vector_theoryt::add
static const smt_function_application_termt::factoryt< addt > add
Definition: smt_bit_vector_theory.h:188
to_floatbv_type
const floatbv_typet & to_floatbv_type(const typet &type)
Cast a typet to a floatbv_typet.
Definition: bitvector_types.h:367
smt_core_theoryt::distinct
static const smt_function_application_termt::factoryt< distinctt > distinct
Makes applications of the function which returns true iff its two arguments are not identical.
Definition: smt_core_theory.h:67
smt_bit_vector_theory.h
if_exprt
The trinary if-then-else operator.
Definition: std_expr.h:2322
convert_expr_to_smt
static smt_termt convert_expr_to_smt(const symbol_exprt &symbol_expr)
Definition: convert_expr_to_smt.cpp:117
make_bitvector_resize_cast
static smt_termt make_bitvector_resize_cast(const smt_termt &from_term, const bitvector_typet &from_type, const bitvector_typet &to_type)
Definition: convert_expr_to_smt.cpp:170
is_dynamic_object_exprt
Evaluates to true if the operand is a pointer to a dynamic object.
Definition: pointer_expr.h:320
pointer_predicates.h
smt_bit_vector_theoryt::make_not
static const smt_function_application_termt::factoryt< nott > make_not
Definition: smt_bit_vector_theory.h:47
convert_to_smt_shift
static smt_termt convert_to_smt_shift(const factoryt &factory, const shiftt &shift, const sub_expression_mapt &converted)
Definition: convert_expr_to_smt.cpp:936
c_bool_type
typet c_bool_type()
Definition: c_types.cpp:118
smt_termt
Definition: smt_terms.h:20
xor_exprt
Boolean XOR.
Definition: std_expr.h:2241
with_exprt::new_value
exprt & new_value()
Definition: std_expr.h:2454
smt_core_theoryt::make_or
static const smt_function_application_termt::factoryt< ort > make_or
Definition: smt_core_theory.h:41
smt_bit_vector_theoryt::concat
static const smt_function_application_termt::factoryt< concatt > concat
Definition: smt_bit_vector_theory.h:17
and_exprt
Boolean AND.
Definition: std_expr.h:2070
exists_exprt
An exists expression.
Definition: mathematical_expr.h:379
union_exprt
Union constructor from single element.
Definition: std_expr.h:1707
smt_core_theory.h
integer_typet
Unbounded, signed integers (mathematical integers, not bitvectors)
Definition: mathematical_types.h:21
smt_core_theoryt::make_xor
static const smt_function_application_termt::factoryt< xort > make_xor
Definition: smt_core_theory.h:49
plus_exprt
The plus expression Associativity is not specified.
Definition: std_expr.h:946
string_constant.h
smt_bit_vector_sortt
Definition: smt_sorts.h:83
exprt
Base class for all expressions.
Definition: expr.h:55
smt_array_theoryt::select
static const smt_function_application_termt::factoryt< selectt > select
Definition: smt_array_theory.h:20
smt_core_theoryt::make_not
static const smt_function_application_termt::factoryt< nott > make_not
Definition: smt_core_theory.h:17
dispatch_expr_to_smt_conversion
static smt_termt dispatch_expr_to_smt_conversion(const exprt &expr, const sub_expression_mapt &converted, const smt_object_mapt &object_map, const type_size_mapt &pointer_sizes, const smt_object_sizet::make_applicationt &call_object_size)
Definition: convert_expr_to_smt.cpp:1457
binary_exprt::lhs
exprt & lhs()
Definition: std_expr.h:613
smt_sortt::cast
const sub_classt * cast() const &
at_scope_exitt::at_scope_exitt
at_scope_exitt(functiont exit_function)
Definition: convert_expr_to_smt.cpp:1800
from_type
std::string from_type(const namespacet &ns, const irep_idt &identifier, const typet &type)
Definition: language_util.cpp:51
sign_exprt
Sign of an expression Predicate is true if _op is negative, false otherwise.
Definition: std_expr.h:538
can_cast_type< signedbv_typet >
bool can_cast_type< signedbv_typet >(const typet &type)
Check whether a reference to a typet is a signedbv_typet.
Definition: bitvector_types.h:228
bool_typet
The Boolean type.
Definition: std_types.h:35
concatenation_exprt
Concatenation of bit-vector operands.
Definition: bitvector_expr.h:607
vector_exprt
Vector constructor from list of elements.
Definition: std_expr.h:1671
exprt::is_true
bool is_true() const
Return whether the expression is a constant representing true.
Definition: expr.cpp:34
div_exprt
Division.
Definition: std_expr.h:1096
symbol_exprt
Expression to hold a symbol (variable)
Definition: std_expr.h:112
convert_array_update_to_smt
static smt_termt convert_array_update_to_smt(const exprt &old, const exprt &index, const exprt &new_value, const sub_expression_mapt &converted)
Definition: convert_expr_to_smt.cpp:1000
string_constantt
Definition: string_constant.h:14
object_size_exprt
Expression for finding the size (in bytes) of the object a pointer points to.
Definition: pointer_expr.h:1006
equal_exprt
Equality.
Definition: std_expr.h:1305
sort_based_literal_convertert::result
optionalt< smt_termt > result
Definition: convert_expr_to_smt.cpp:298
smt_bit_vector_theoryt::logical_shift_right
static const smt_function_application_termt::factoryt< logical_shift_rightt > logical_shift_right
Definition: smt_bit_vector_theory.h:267
UNHANDLED_CASE
#define UNHANDLED_CASE
Definition: invariant.h:526
power2
static mp_integer power2(unsigned exponent)
Definition: convert_expr_to_smt.cpp:856
can_cast_type< pointer_typet >
bool can_cast_type< pointer_typet >(const typet &type)
Check whether a reference to a typet is a pointer_typet.
Definition: pointer_expr.h:66
smt_core_theoryt::implies
static const smt_function_application_termt::factoryt< impliest > implies
Definition: smt_core_theory.h:25
replication_exprt
Bit-vector replication.
Definition: bitvector_expr.h:535
if_exprt::false_case
exprt & false_case()
Definition: std_expr.h:2360
isfinite_exprt
Evaluates to true if the operand is finite.
Definition: floatbv_expr.h:175
notequal_exprt
Disequality.
Definition: std_expr.h:1364
shl_overflow_exprt
Definition: bitvector_expr.h:854
extractbits_exprt::upper
exprt & upper()
Definition: bitvector_expr.h:474
to_fixedbv_type
const fixedbv_typet & to_fixedbv_type(const typet &type)
Cast a typet to a fixedbv_typet.
Definition: bitvector_types.h:305
smt_bit_vector_sortt::bit_width
std::size_t bit_width() const
Definition: smt_sorts.cpp:60
to_binary_expr
const binary_exprt & to_binary_expr(const exprt &expr)
Cast an exprt to a binary_exprt.
Definition: std_expr.h:660
expr.h
euclidean_mod_exprt
Boute's Euclidean definition of Modulo – to match SMT-LIB2.
Definition: std_expr.h:1235
struct_exprt
Struct constructor from list of elements.
Definition: std_expr.h:1818
c_bool_typet
The C/C++ Booleans.
Definition: c_types.h:74
address_bits
std::size_t address_bits(const mp_integer &size)
ceil(log2(size))
Definition: arith_tools.cpp:177
ieee_float_notequal_exprt
IEEE floating-point disequality.
Definition: floatbv_expr.h:311
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
smt_sortt::accept
void accept(smt_sort_const_downcast_visitort &) const
Definition: smt_sorts.cpp:95
convert_multiary_operator_to_terms
static smt_termt convert_multiary_operator_to_terms(const multi_ary_exprt &expr, const sub_expression_mapt &converted, const factoryt &factory)
Converts operator expressions with 2 or more operands to terms expressed as binary operator applicati...
Definition: convert_expr_to_smt.cpp:53
smt_bit_vector_theoryt::signed_less_than_or_equal
static const smt_function_application_termt::factoryt< signed_less_than_or_equalt > signed_less_than_or_equal
Definition: smt_bit_vector_theory.h:161
with_exprt::old
exprt & old()
Definition: std_expr.h:2434
byte_operators.h
Expression classes for byte-level operators.
smt_bit_vector_theoryt::extract
static smt_function_application_termt::factoryt< extractt > extract(std::size_t i, std::size_t j)
Makes a factory for extract function applications.
Definition: smt_bit_vector_theory.cpp:79
bitxor_exprt
Bit-wise XOR.
Definition: bitvector_expr.h:159
bitor_exprt
Bit-wise OR.
Definition: bitvector_expr.h:124
mult_overflow_exprt
Definition: bitvector_expr.h:835
or_exprt
Boolean OR.
Definition: std_expr.h:2178
smt_bit_vector_theoryt::sign_extend
static smt_function_application_termt::factoryt< sign_extendt > sign_extend(std::size_t i)
Definition: smt_bit_vector_theory.cpp:788
smt_bit_vector_theoryt::unsigned_divide
static const smt_function_application_termt::factoryt< unsigned_dividet > unsigned_divide
Definition: smt_bit_vector_theory.h:213
smt_bit_vector_theoryt::make_xor
static const smt_function_application_termt::factoryt< xort > make_xor
Definition: smt_bit_vector_theory.h:87
floatbv_typecast_exprt
Semantic type conversion from/to floating-point formats.
Definition: floatbv_expr.h:18
convert_bit_vector_cast
static smt_termt convert_bit_vector_cast(const smt_termt &from_term, const typet &from_type, const bitvector_typet &to_type)
Definition: convert_expr_to_smt.cpp:239
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
smt_sortt
Definition: smt_sorts.h:17
symbol_exprt::get_identifier
const irep_idt & get_identifier() const
Definition: std_expr.h:142
literal_exprt
Definition: literal_expr.h:17
array_of_exprt
Array constructor from single element.
Definition: std_expr.h:1497
smt_bit_vector_theoryt::multiply
static const smt_function_application_termt::factoryt< multiplyt > multiply
Definition: smt_bit_vector_theory.h:204
smt_bool_sortt
Definition: smt_sorts.h:77
smt_sort_const_downcast_visitort
Definition: smt_sorts.h:100
sort_based_cast_to_bit_vector_convertert::visit
void visit(const smt_bit_vector_sortt &) override
Definition: convert_expr_to_smt.cpp:221
pointer_expr.h
operands_are_of_type
static bool operands_are_of_type(const exprt &expr)
Ensures that all operands of the argument expression have related types.
Definition: convert_expr_to_smt.cpp:75
extractbits_exprt::src
exprt & src()
Definition: bitvector_expr.h:469
sort_based_cast_to_bit_vector_convertert::from_type
const typet & from_type
Definition: convert_expr_to_smt.cpp:203
smt_termt::get_sort
const smt_sortt & get_sort() const
Definition: smt_terms.cpp:35
mult_exprt
Binary multiplication Associativity is not specified.
Definition: std_expr.h:1051
to_pointer_type
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
Definition: pointer_expr.h:79
sort_based_literal_convertert::visit
void visit(const smt_bool_sortt &) override
Definition: convert_expr_to_smt.cpp:305
smt_core_theoryt::if_then_else
static const smt_function_application_termt::factoryt< if_then_elset > if_then_else
Definition: smt_core_theory.h:82
index_exprt::index
exprt & index()
Definition: std_expr.h:1450
pointer_object_exprt
A numerical identifier for the object a pointer points to.
Definition: pointer_expr.h:947
pointer_type
pointer_typet pointer_type(const typet &subtype)
Definition: c_types.cpp:253
plus_overflow_exprt
Definition: bitvector_expr.h:797
unary_minus_exprt
The unary minus expression.
Definition: std_expr.h:422
index_exprt::array
exprt & array()
Definition: std_expr.h:1440
smt_bit_vector_theoryt::signed_remainder
static const smt_function_application_termt::factoryt< signed_remaindert > signed_remainder
Definition: smt_bit_vector_theory.h:240
object_size
exprt object_size(const exprt &pointer)
Definition: pointer_predicates.cpp:33
irept::id
const irep_idt & id() const
Definition: irep.h:396
find_object_base_expression
exprt find_object_base_expression(const address_of_exprt &address_of)
The model of addresses we use consists of a unique object identifier and an offset.
Definition: object_tracking.cpp:17
range.h
abs_exprt
Absolute value.
Definition: std_expr.h:378
floatbv_expr.h
unary_plus_exprt
The unary plus expression.
Definition: std_expr.h:471
unary_exprt::op
const exprt & op() const
Definition: std_expr.h:326
bitand_exprt
Bit-wise AND.
Definition: bitvector_expr.h:194
smt_bit_vector_theoryt::make_or
static const smt_function_application_termt::factoryt< ort > make_or
Definition: smt_bit_vector_theory.h:63
optionalt
nonstd::optional< T > optionalt
Definition: optional.h:35
smt_function_application_termt::factoryt< smt_command_functiont >
pointer_offset
exprt pointer_offset(const exprt &pointer)
Definition: pointer_predicates.cpp:38
smt_sortt::pretty
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
Definition: irep.cpp:495
smt_bit_vector_theoryt::unsigned_remainder
static const smt_function_application_termt::factoryt< unsigned_remaindert > unsigned_remainder
Definition: smt_bit_vector_theory.h:231
smt_bit_vector_theoryt::shift_left
static const smt_function_application_termt::factoryt< shift_leftt > shift_left
Definition: smt_bit_vector_theory.h:258
minus_exprt
Binary minus.
Definition: std_expr.h:1005
update_exprt
Operator to update elements in structs and arrays.
Definition: std_expr.h:2607
config
configt config
Definition: config.cpp:25
smt_core_theoryt::make_and
static const smt_function_application_termt::factoryt< andt > make_and
Definition: smt_core_theory.h:33
bitvector_typet::get_width
std::size_t get_width() const
Definition: std_types.h:876
smt_array_sortt
Definition: smt_sorts.h:90
bitnot_exprt
Bit-wise negation of bit-vectors.
Definition: bitvector_expr.h:81
extractbit_exprt
Extracts a single bit of a bit-vector operand.
Definition: bitvector_expr.h:380
smt_bit_vector_theoryt::unsigned_less_than
static const smt_function_application_termt::factoryt< unsigned_less_thant > unsigned_less_than
Definition: smt_bit_vector_theory.h:113
member_exprt
Extract member of struct or union.
Definition: std_expr.h:2793
expr_util.h
Deprecated expression utility functions.
bvrep2integer
mp_integer bvrep2integer(const irep_idt &src, std::size_t width, bool is_signed)
convert a bit-vector representation (possibly signed) to integer
Definition: arith_tools.cpp:402
bitwise_xor
mp_integer bitwise_xor(const mp_integer &a, const mp_integer &b)
bitwise 'xor' of two nonnegative integers
Definition: mp_arith.cpp:239
shift_exprt
A base class for shift and rotate operators.
Definition: bitvector_expr.h:229
smt_bit_vector_theoryt::zero_extend
static smt_function_application_termt::factoryt< zero_extendt > zero_extend(std::size_t i)
Definition: smt_bit_vector_theory.cpp:759
extension_for_type
static std::function< std::function< smt_termt(smt_termt)>std::size_t)> extension_for_type(const typet &type)
Definition: convert_expr_to_smt.cpp:161
POSTCONDITION
#define POSTCONDITION(CONDITION)
Definition: invariant.h:479
can_cast_type< unsignedbv_typet >
bool can_cast_type< unsignedbv_typet >(const typet &type)
Check whether a reference to a typet is a unsignedbv_typet.
Definition: bitvector_types.h:178
array_typet
Arrays with given size.
Definition: std_types.h:762
sort_based_literal_convertert::member_input
const constant_exprt & member_input
Definition: convert_expr_to_smt.cpp:297
if_exprt::true_case
exprt & true_case()
Definition: std_expr.h:2350
smt_bit_vector_theoryt::signed_less_than
static const smt_function_application_termt::factoryt< signed_less_thant > signed_less_than
Definition: smt_bit_vector_theory.h:151
sub_expression_mapt
std::unordered_map< exprt, smt_termt, irep_full_hash > sub_expression_mapt
Post order visitation is used in order to construct the the smt terms bottom upwards without using re...
Definition: convert_expr_to_smt.cpp:38
bitvector_typet
Base class of fixed-width bit-vector types.
Definition: std_types.h:864
isinf_exprt
Evaluates to true if the operand is infinite.
Definition: floatbv_expr.h:131
smt_bit_vector_theoryt::unsigned_greater_than_or_equal
static const smt_function_application_termt::factoryt< unsigned_greater_than_or_equalt > unsigned_greater_than_or_equal
Definition: smt_bit_vector_theory.h:142
pointer_offset_exprt
The offset (in bytes) of a pointer relative to the object.
Definition: pointer_expr.h:889
at_scope_exitt
Definition: convert_expr_to_smt.cpp:1798
smt_bit_vector_theoryt::unsigned_less_than_or_equal
static const smt_function_application_termt::factoryt< unsigned_less_than_or_equalt > unsigned_less_than_or_equal
Definition: smt_bit_vector_theory.h:123
smt_object_mapt
std::unordered_map< exprt, decision_procedure_objectt, irep_hash > smt_object_mapt
Mapping from an object's base expression to the set of information about it which we track.
Definition: object_tracking.h:89
if_exprt::cond
exprt & cond()
Definition: std_expr.h:2340
binary_relation_exprt
A base class for relations, i.e., binary predicates whose two operands have the same type.
Definition: std_expr.h:706
expr_cast.h
Templated functions to cast to specific exprt-derived classes.
smt_bit_vector_theoryt::negate
static const smt_function_application_termt::factoryt< negatet > negate
Arithmetic negation in two's complement.
Definition: smt_bit_vector_theory.h:249
pointer_typet::base_type
const typet & base_type() const
The type of the data what we point to.
Definition: pointer_expr.h:35
smt_bit_vector_theoryt::make_and
static const smt_function_application_termt::factoryt< andt > make_and
Definition: smt_bit_vector_theory.h:55
smt_bit_vector_theoryt::subtract
static const smt_function_application_termt::factoryt< subtractt > subtract
Definition: smt_bit_vector_theory.h:196
byte_extract_exprt
Expression of type type extracted from some object op starting at position offset (given in number of...
Definition: byte_operators.h:28
exprt::visit_pre
void visit_pre(std::function< void(exprt &)>)
Definition: expr.cpp:245
power
mp_integer power(const mp_integer &base, const mp_integer &exponent)
A multi-precision implementation of the power operator.
Definition: arith_tools.cpp:195
smt_bool_literal_termt
Definition: smt_terms.h:76
sort_based_literal_convertert::visit
void visit(const smt_bit_vector_sortt &bit_vector_sort) override
Definition: convert_expr_to_smt.cpp:310
smt_core_theoryt::equal
static const smt_function_application_termt::factoryt< equalt > equal
Definition: smt_core_theory.h:57
config.h
smt_array_theoryt::store
static const smt_function_application_termt::factoryt< storet > store
Definition: smt_array_theory.h:34
try_relational_conversion
static optionalt< smt_termt > try_relational_conversion(const exprt &expr, const sub_expression_mapt &converted)
Definition: convert_expr_to_smt.cpp:590
ieee_float_op_exprt
IEEE floating-point operations These have two data operands (op0 and op1) and one rounding mode (op2)...
Definition: floatbv_expr.h:363
bswap_exprt
The byte swap expression.
Definition: bitvector_expr.h:18
at_scope_exitt::~at_scope_exitt
~at_scope_exitt()
Definition: convert_expr_to_smt.cpp:1804
convert_c_bool_cast
static smt_termt convert_c_bool_cast(const smt_termt &from_term, const typet &from_type, const bitvector_typet &to_type)
Returns a cast to C bool expressed in smt terms.
Definition: convert_expr_to_smt.cpp:148
implies_exprt
Boolean implication.
Definition: std_expr.h:2133
make_invalid_pointer_expr
exprt make_invalid_pointer_expr()
Create the invalid pointer constant.
Definition: object_tracking.cpp:12
extractbits_exprt
Extracts a sub-range of a bit-vector operand.
Definition: bitvector_expr.h:447
exprt::operands
operandst & operands()
Definition: expr.h:94
is_null_pointer
bool is_null_pointer(const constant_exprt &expr)
Returns true if expr has a pointer type and a value NULL; it also returns true when expr has value ze...
Definition: expr_util.cpp:315
minus_overflow_exprt
Definition: bitvector_expr.h:816
index_exprt
Array index operator.
Definition: std_expr.h:1409
is_invalid_pointer_exprt
Definition: pointer_predicates.h:37
address_of_exprt
Operator to return the address of an object.
Definition: pointer_expr.h:370
INVARIANT
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition: invariant.h:423
greater_than
binary_relation_exprt greater_than(exprt lhs, exprt rhs)
Definition: string_expr.h:25
popcount_exprt
The popcount (counting the number of bits set to 1) expression.
Definition: bitvector_expr.h:650
typecast_exprt
Semantic type conversion.
Definition: std_expr.h:2016
pointer_typet
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
Definition: pointer_expr.h:23
smt_bit_vector_constant_termt
Definition: smt_terms.h:116
convert_relational_to_smt
static smt_termt convert_relational_to_smt(const binary_relation_exprt &binary_relation, const unsigned_factory_typet &unsigned_factory, const signed_factory_typet &signed_factory, const sub_expression_mapt &converted)
Definition: convert_expr_to_smt.cpp:550
array_comprehension_exprt
Expression to define a mapping from an argument (index) to elements.
Definition: std_expr.h:3350
type_size_mapt
std::unordered_map< typet, smt_termt, irep_full_hash > type_size_mapt
Definition: type_size_mapping.h:17
constant_exprt
A constant literal expression.
Definition: std_expr.h:2941
ieee_float_equal_exprt
IEEE-floating-point equality.
Definition: floatbv_expr.h:263
sort_based_cast_to_bit_vector_convertert::from_term
const smt_termt & from_term
Definition: convert_expr_to_smt.cpp:202
binary_exprt::op1
exprt & op1()
Definition: expr.h:128
std_expr.h
can_cast_type< integer_bitvector_typet >
bool can_cast_type< integer_bitvector_typet >(const typet &type)
Check whether a reference to a typet is an integer_bitvector_typet.
Definition: bitvector_types.h:128
smt_bit_vector_theoryt::signed_greater_than
static const smt_function_application_termt::factoryt< signed_greater_thant > signed_greater_than
Definition: smt_bit_vector_theory.h:170
less_than
binary_relation_exprt less_than(exprt lhs, exprt rhs)
Definition: string_expr.h:48
constant_exprt::get_value
const irep_idt & get_value() const
Definition: std_expr.h:2950
array_typet::index_type
typet index_type() const
The type of the index expressions into any instance of this type.
Definition: std_types.cpp:33
with_exprt::where
exprt & where()
Definition: std_expr.h:2444
sort_based_literal_convertert::sort_based_literal_convertert
sort_based_literal_convertert(const constant_exprt &input)
Definition: convert_expr_to_smt.cpp:300
smt_array_theory.h
convert_type_to_smt_sort
static smt_sortt convert_type_to_smt_sort(const bool_typet &type)
Definition: convert_expr_to_smt.cpp:83
array_exprt
Array constructor from list of elements.
Definition: std_expr.h:1562
sort_based_cast_to_bit_vector_convertert
Definition: convert_expr_to_smt.cpp:199
make_range
ranget< iteratort > make_range(iteratort begin, iteratort end)
Definition: range.h:524
c_types.h
isnormal_exprt
Evaluates to true if the operand is a normal number.
Definition: floatbv_expr.h:219
smt_bit_vector_theoryt::unsigned_greater_than
static const smt_function_application_termt::factoryt< unsigned_greater_thant > unsigned_greater_than
Definition: smt_bit_vector_theory.h:132
let_exprt
A let expression.
Definition: std_expr.h:3141
smt_bit_vector_theoryt::arithmetic_shift_right
static const smt_function_application_termt::factoryt< arithmetic_shift_rightt > arithmetic_shift_right
Definition: smt_bit_vector_theory.h:276
literal_expr.h
bitvector_expr.h
sort_based_literal_convertert::visit
void visit(const smt_array_sortt &array_sort) override
Definition: convert_expr_to_smt.cpp:319
binary_exprt::op0
exprt & op0()
Definition: expr.h:125
smt_bit_vector_theoryt::signed_divide
static const smt_function_application_termt::factoryt< signed_dividet > signed_divide
Definition: smt_bit_vector_theory.h:222
at_scope_exit
at_scope_exitt< functiont > at_scope_exit(functiont exit_function)
Definition: convert_expr_to_smt.cpp:1812
mod_exprt
Modulo defined as lhs-(rhs * truncate(lhs/rhs)).
Definition: std_expr.h:1167
convert_expr_to_smt.h
count_leading_zeros_exprt
The count leading zeros (counting the number of zero bits starting from the most-significant bit) exp...
Definition: bitvector_expr.h:974
array_typet::element_type
const typet & element_type() const
The type of the elements of the array.
Definition: std_types.h:785
isnan_exprt
Evaluates to true if the operand is NaN.
Definition: floatbv_expr.h:87
mathematical_expr.h
not_exprt
Boolean negation.
Definition: std_expr.h:2277