6 #include <boost/multiprecision/cpp_int.hpp>
23 boost::multiprecision::cpp_int value = 0;
25 for (
auto i = 0u; i < number.size(); i++)
27 if ((number[i] == BooleanFunction::Value::X) || (number[i] == BooleanFunction::Value::Z))
29 return ERR(
"Cannot translate the number to a constant value as it is undefined.");
32 if (number[i] == BooleanFunction::Value::ONE)
34 boost::multiprecision::bit_set(value, i);
57 return ERR(
"could not reduce into SMT-Lib v2 string: arity of node '" + node.
to_string() +
"' does not match number of parameters");
65 return OK(std::string(
"(_ bv") +
str.get() +
" " + std::to_string(node.
size) +
")");
68 return ERR(
"could not reduce into SMT-Lib v2 string: unable to translate constant '" + node.
to_string() +
"'");
71 return OK(std::to_string(node.
index));
76 return OK(
"(bvand " + p[0] +
" " + p[1] +
")");
78 return OK(
"(bvor " + p[0] +
" " + p[1] +
")");
80 return OK(
"(bvnot " + p[0] +
")");
82 return OK(
"(bvxor " + p[0] +
" " + p[1] +
")");
85 return OK(
"(bvadd " + p[0] +
" " + p[1] +
")");
87 return OK(
"(bvsub " + p[0] +
" " + p[1] +
")");
89 return OK(
"(bvmul " + p[0] +
" " + p[1] +
")");
91 return OK(
"(bvsdiv " + p[0] +
" " + p[1] +
")");
93 return OK(
"(bvudiv " + p[0] +
" " + p[1] +
")");
95 return OK(
"(bvsrem " + p[0] +
" " + p[1] +
")");
97 return OK(
"(bvurem " + p[0] +
" " + p[1] +
")");
100 return OK(
"(concat " + p[0] +
" " + p[1] +
")");
102 return OK(
"((_ extract " + p[2] +
" " + p[1] +
") " + p[0] +
")");
104 return OK(
"((_ zero_extend " + std::to_string(node.
size -
function.get_nodes().at(index - 2).index) +
") " + p[0] +
")");
106 return OK(
"((_ sign_extend " + std::to_string(node.
size -
function.get_nodes().at(index - 2).index) +
") " + p[0] +
")");
109 return OK(
"(bvshl " + p[0] +
" (_ bv" + p[1] +
" " + std::to_string(node.
size) +
"))");
111 return OK(
"(bvlshr " + p[0] +
" (_ bv" + p[1] +
" " + std::to_string(node.
size) +
"))");
113 return OK(
"(bvashr " + p[0] +
" (_ bv" + p[1] +
" " + std::to_string(node.
size) +
"))");
115 return OK(
"((_ rotate_left " + p[1] +
") " + p[0] +
")");
117 return OK(
"((_ rotate_right " + p[1] +
") " + p[0] +
")");
120 return OK(
"(ite (= " + p[0] +
" " + p[1] +
") (_ bv1 " + std::to_string(node.
size) +
") (_ bv0 " + std::to_string(node.
size) +
"))");
122 return OK(
"(ite (bvslt " + p[0] +
" " + p[1] +
") (_ bv1 " + std::to_string(node.
size) +
") (_ bv0 " + std::to_string(node.
size) +
"))");
124 return OK(
"(ite (bvsle " + p[0] +
" " + p[1] +
") (_ bv1 " + std::to_string(node.
size) +
") (_ bv0 " + std::to_string(node.
size) +
"))");
126 return OK(
"(ite (bvule " + p[0] +
" " + p[1] +
") (_ bv1 " + std::to_string(node.
size) +
") (_ bv0 " + std::to_string(node.
size) +
"))");
128 return OK(
"(ite (bvult " + p[0] +
" " + p[1] +
") (_ bv1 " + std::to_string(node.
size) +
") (_ bv0 " + std::to_string(node.
size) +
"))");
130 return OK(
"(ite (= " + p[0] +
" (_ bv1 1)) " + p[1] +
" " + p[2] +
")");
133 return ERR(
"could not reduce into SMT-Lib v2 string: not implemented for given node type");
139 std::vector<std::string> stack;
140 for (
auto index = 0ul; index <
function.length(); index++)
142 const auto& node =
function.get_nodes().at(index);
143 std::vector<std::string> operands;
144 std::move(stack.end() -
static_cast<i64>(node.get_arity()), stack.end(), std::back_inserter(operands));
145 stack.erase(stack.end() -
static_cast<i64>(node.get_arity()), stack.end());
147 if (
auto reduction =
reduce_to_smt2(node, std::move(operands), index,
function); reduction.is_ok())
149 stack.emplace_back(reduction.get());
153 return ERR_APPEND(reduction.get_error(),
"could not translate Boolean function to SMT-Lib v2 string: reduction to SMT-Lib v2 string failed");
157 switch (stack.size())
160 return OK(stack.back());
162 return ERR(
"could not translate Boolean function to SMT-Lib v2 string: stack is imbalanced");
#define ERR_APPEND(prev_error, message)
Result< std::string > translate_to_smt2(const BooleanFunction &function)
Result< std::string > reduce_to_smt2(const BooleanFunction::Node &node, std::vector< std::string > &&p, size_t index, const BooleanFunction &function)
Result< std::string > const2str(const std::vector< BooleanFunction::Value > &number)
std::vector< BooleanFunction::Value > constant
The (optional) constant value of the node.
u16 type
The type of the node.
u16 size
The bit-size of the node.
std::string variable
The (optional) variable name of the node.
std::string to_string() const
u16 index
The (optional) index value of the node.
static constexpr u16 Constant
static constexpr u16 Srem
static constexpr u16 Udiv
static constexpr u16 Sdiv
static constexpr u16 Urem
static constexpr u16 Lshr
static constexpr u16 Sext
static constexpr u16 Ashr
static constexpr u16 Index
static constexpr u16 Concat
static constexpr u16 Slice
static constexpr u16 Zext
static constexpr u16 Variable