| 2077 | } |
| 2078 | |
| 2079 | std::pair<smtutil::Expression, smtutil::Expression> SMTEncoder::divModWithSlacks( |
| 2080 | smtutil::Expression _left, |
| 2081 | smtutil::Expression _right, |
| 2082 | IntegerType const& _type |
| 2083 | ) |
| 2084 | { |
| 2085 | if (m_settings.divModNoSlacks) |
| 2086 | return {_left / _right, _left % _right}; |
| 2087 | |
| 2088 | IntegerType const* intType = &_type; |
| 2089 | std::string suffix = "div_mod_" + std::to_string(m_context.newUniqueId()); |
| 2090 | smt::SymbolicIntVariable dSymb(intType, intType, "d_" + suffix, m_context); |
| 2091 | smt::SymbolicIntVariable rSymb(intType, intType, "r_" + suffix, m_context); |
| 2092 | auto d = dSymb.currentValue(); |
| 2093 | auto r = rSymb.currentValue(); |
| 2094 | |
| 2095 | // x / y = d and x % y = r iff d * y + r = x and |
| 2096 | // either x >= 0 and 0 <= r < abs(y) (or just 0 <= r < y for unsigned) |
| 2097 | // or x < 0 and -abs(y) < r <= 0 |
| 2098 | m_context.addAssertion(((d * _right) + r) == _left); |
| 2099 | if (_type.isSigned()) |
| 2100 | m_context.addAssertion( |
| 2101 | (_left >= 0 && 0 <= r && (_right == 0 || r < smtutil::abs(_right))) || |
| 2102 | (_left < 0 && ((_right == 0 || 0 - smtutil::abs(_right) < r) && r <= 0)) |
| 2103 | ); |
| 2104 | else // unsigned version |
| 2105 | m_context.addAssertion(0 <= r && (_right == 0 || r < _right)); |
| 2106 | |
| 2107 | auto divResult = smtutil::Expression::ite(_right == 0, 0, d); |
| 2108 | auto modResult = smtutil::Expression::ite(_right == 0, 0, r); |
| 2109 | return {divResult, modResult}; |
| 2110 | } |
| 2111 | |
| 2112 | void SMTEncoder::assignment(Expression const& _left, smtutil::Expression const& _right) |
| 2113 | { |
nothing calls this directly
no test coverage detected