CBMC
arith_tools.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_ARITH_TOOLS_H
11 #define CPROVER_UTIL_ARITH_TOOLS_H
12 
13 #include "invariant.h"
14 #include "mp_arith.h"
15 #include "optional.h"
16 #include "std_expr.h"
17 
18 #include <limits>
19 
20 class typet;
21 
26 bool to_integer(const constant_exprt &expr, mp_integer &int_value);
27 
31 template <typename Target, typename = void>
32 struct numeric_castt final
33 {
34 };
35 
37 template <>
39 {
41  {
42  if(expr.id() != ID_constant)
43  return {};
44  else
45  return operator()(to_constant_expr(expr));
46  }
47 
49  {
50  mp_integer out;
51  if(to_integer(expr, out))
52  return {};
53  else
54  return out;
55  }
56 };
57 
59 template <typename T>
60 struct numeric_castt<T,
61  typename std::enable_if<std::is_integral<T>::value>::type>
62 {
63 private:
64  // Unchecked conversion from mp_integer when T is signed
65  template <typename U = T,
66  typename std::enable_if<std::is_signed<U>::value, int>::type = 0>
67  static auto get_val(const mp_integer &mpi) -> decltype(mpi.to_long())
68  {
69  return mpi.to_long();
70  }
71 
72  // Unchecked conversion from mp_integer when T is unsigned
73  template <typename U = T,
74  typename std::enable_if<!std::is_signed<U>::value, int>::type = 0>
75  static auto get_val(const mp_integer &mpi) -> decltype(mpi.to_ulong())
76  {
77  return mpi.to_ulong();
78  }
79 
80 public:
81  // Conversion from mp_integer to integral type T
83  {
84  static_assert(
85  std::numeric_limits<T>::max() <=
86  std::numeric_limits<decltype(get_val(mpi))>::max() &&
87  std::numeric_limits<T>::min() >=
88  std::numeric_limits<decltype(get_val(mpi))>::min(),
89  "Numeric cast only works for types smaller than long long");
90 
91  if(
92  mpi <= std::numeric_limits<T>::max() &&
93  mpi >= std::numeric_limits<T>::min())
94  // to_long converts to long long which is the largest signed numeric type
95  return static_cast<T>(get_val(mpi));
96  else
97  return {};
98  }
99 
100  // Conversion from expression
101  optionalt<T> operator()(const exprt &expr) const
102  {
103  if(expr.id() == ID_constant)
104  return numeric_castt<T>{}(to_constant_expr(expr));
105  else
106  return {};
107  }
108 
109  // Conversion from expression
111  {
112  if(auto mpi_opt = numeric_castt<mp_integer>{}(expr))
113  return numeric_castt<T>{}(*mpi_opt);
114  else
115  return {};
116  }
117 };
118 
124 template <typename Target>
126 {
127  return numeric_castt<Target>{}(arg);
128 }
129 
135 template <typename Target>
136 Target numeric_cast_v(const mp_integer &arg)
137 {
138  const auto maybe = numeric_castt<Target>{}(arg);
139  INVARIANT(maybe, "mp_integer should be convertible to target integral type");
140  return *maybe;
141 }
142 
148 template <typename Target>
149 Target numeric_cast_v(const constant_exprt &arg)
150 {
151  const auto maybe = numeric_castt<Target>{}(arg);
153  maybe,
154  "expression should be convertible to target integral type",
156  return *maybe;
157 }
158 
159 // PRECONDITION(false) in case of unsupported type
160 constant_exprt from_integer(const mp_integer &int_value, const typet &type);
161 
162 // ceil(log2(size))
163 std::size_t address_bits(const mp_integer &size);
164 
165 mp_integer power(const mp_integer &base, const mp_integer &exponent);
166 
167 void mp_min(mp_integer &a, const mp_integer &b);
168 void mp_max(mp_integer &a, const mp_integer &b);
169 
170 bool get_bvrep_bit(
171  const irep_idt &src,
172  std::size_t width,
173  std::size_t bit_index);
174 
175 irep_idt
176 make_bvrep(const std::size_t width, const std::function<bool(std::size_t)> f);
177 
178 irep_idt integer2bvrep(const mp_integer &, std::size_t width);
179 mp_integer bvrep2integer(const irep_idt &, std::size_t width, bool is_signed);
180 
181 #endif // CPROVER_UTIL_ARITH_TOOLS_H
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
mp_integer
BigInt mp_integer
Definition: smt_terms.h:17
mp_arith.h
to_integer
bool to_integer(const constant_exprt &expr, mp_integer &int_value)
Convert a constant expression expr to an arbitrary-precision integer.
Definition: arith_tools.cpp:20
typet
The type of an expression, extends irept.
Definition: type.h:28
optional.h
is_signed
bool is_signed(const typet &t)
Convenience function – is the type signed?
Definition: util.cpp:45
invariant.h
exprt
Base class for all expressions.
Definition: expr.h:55
get_bvrep_bit
bool get_bvrep_bit(const irep_idt &src, std::size_t width, std::size_t bit_index)
Get a bit with given index from bit-vector representation.
Definition: arith_tools.cpp:262
numeric_castt
Numerical cast provides a unified way of converting from one numerical type to another.
Definition: arith_tools.h:32
numeric_castt< mp_integer >
Convert expression to mp_integer.
Definition: arith_tools.h:38
INVARIANT_WITH_DIAGNOSTICS
#define INVARIANT_WITH_DIAGNOSTICS(CONDITION, REASON,...)
Same as invariant, with one or more diagnostics attached Diagnostics can be of any type that has a sp...
Definition: invariant.h:437
numeric_castt< T, typename std::enable_if< std::is_integral< T >::value >::type >::operator()
optionalt< T > operator()(const mp_integer &mpi) const
Definition: arith_tools.h:82
integer2bvrep
irep_idt integer2bvrep(const mp_integer &, std::size_t width)
convert an integer to bit-vector representation with given width This uses two's complement for negat...
Definition: arith_tools.cpp:380
numeric_castt< T, typename std::enable_if< std::is_integral< T >::value >::type >::get_val
static auto get_val(const mp_integer &mpi) -> decltype(mpi.to_long())
Definition: arith_tools.h:67
numeric_castt< T, typename std::enable_if< std::is_integral< T >::value >::type >::operator()
optionalt< T > operator()(const exprt &expr) const
Definition: arith_tools.h:101
from_integer
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
Definition: arith_tools.cpp:100
numeric_castt< T, typename std::enable_if< std::is_integral< T >::value >::type >::operator()
optionalt< T > operator()(const constant_exprt &expr) const
Definition: arith_tools.h:110
irept::id
const irep_idt & id() const
Definition: irep.h:396
numeric_cast_v
Target numeric_cast_v(const mp_integer &arg)
Convert an mp_integer to integral type Target An invariant will fail if the conversion is not possibl...
Definition: arith_tools.h:136
bvrep2integer
mp_integer bvrep2integer(const irep_idt &, std::size_t width, bool is_signed)
convert a bit-vector representation (possibly signed) to integer
Definition: arith_tools.cpp:402
optionalt
nonstd::optional< T > optionalt
Definition: optional.h:35
numeric_castt< T, typename std::enable_if< std::is_integral< T >::value >::type >::get_val
static auto get_val(const mp_integer &mpi) -> decltype(mpi.to_ulong())
Definition: arith_tools.h:75
mp_min
void mp_min(mp_integer &a, const mp_integer &b)
Definition: arith_tools.cpp:246
irep_pretty_diagnosticst
Definition: irep.h:502
numeric_castt< mp_integer >::operator()
optionalt< mp_integer > operator()(const exprt &expr) const
Definition: arith_tools.h:40
INVARIANT
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition: invariant.h:423
address_bits
std::size_t address_bits(const mp_integer &size)
ceil(log2(size))
Definition: arith_tools.cpp:177
mp_max
void mp_max(mp_integer &a, const mp_integer &b)
Definition: arith_tools.cpp:252
numeric_castt< mp_integer >::operator()
optionalt< mp_integer > operator()(const constant_exprt &expr) const
Definition: arith_tools.h:48
constant_exprt
A constant literal expression.
Definition: std_expr.h:2941
numeric_cast
optionalt< Target > numeric_cast(const exprt &arg)
Converts an expression to any integral type.
Definition: arith_tools.h:125
std_expr.h
make_bvrep
irep_idt make_bvrep(const std::size_t width, const std::function< bool(std::size_t)> f)
construct a bit-vector representation from a functor
Definition: arith_tools.cpp:306
to_constant_expr
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
Definition: std_expr.h:2992
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