void PseudoBooleanProcessor::learnGeqSub(Node geq) { Assert(geq.getKind() == kind::GEQ); const bool negated = false; bool success = decomposeAssertion(geq, negated); if (!success) { Debug("pbs::rewrites") << "failed " << std::endl; return; } Assert(d_off.value().isIntegral()); Integer off = d_off.value().ceiling(); // \sum pos >= \sum neg + off // for now special case everything we want // target easy clauses if (d_pos.size() == 1 && d_neg.size() == 1 && off.isZero()) { // x >= y // |- (y >= 1) => (x >= 1) Node x = d_pos.front(); Node y = d_neg.front(); Node xGeq1 = mkGeqOne(x); Node yGeq1 = mkGeqOne(y); Node imp = yGeq1.impNode(xGeq1); addSub(geq, imp); } else if (d_pos.size() == 0 && d_neg.size() == 2 && off.isNegativeOne()) { // 0 >= (x + y -1) // |- 1 >= x + y // |- (or (not (x >= 1)) (not (y >= 1))) Node x = d_neg[0]; Node y = d_neg[1]; Node xGeq1 = mkGeqOne(x); Node yGeq1 = mkGeqOne(y); Node cases = (xGeq1.notNode()).orNode(yGeq1.notNode()); addSub(geq, cases); } else if (d_pos.size() == 2 && d_neg.size() == 1 && off.isZero()) { // (x + y) >= z // |- (z >= 1) => (or (x >= 1) (y >=1 )) Node x = d_pos[0]; Node y = d_pos[1]; Node z = d_neg[0]; Node xGeq1 = mkGeqOne(x); Node yGeq1 = mkGeqOne(y); Node zGeq1 = mkGeqOne(z); NodeManager* nm = NodeManager::currentNM(); Node dis = nm->mkNode(kind::OR, zGeq1.notNode(), xGeq1, yGeq1); addSub(geq, dis); } }
Polynom Converter::ToPolynom(const Integer &integer) { Polynom result; if(!integer.isZero()) { uint numberDigits = integer.getNumberBytes() / result.getDigitSizeInBytes() + ((integer.getNumberBytes() % result.getDigitSizeInBytes()) != 0); result.setNumberDigits(numberDigits); result._digits[result._numberDigits-1] = 0; std::memcpy(result._digits, integer._digits, integer.getNumberBytes()); } return result; }
Rational::Rational(const Integer numerator, const Integer denominator) { assert(!denominator.isZero()); if (numerator.isOne() || denominator.isOne()) { // Avoid computing GCD if possible m_numerator = numerator; m_denominator = denominator; } else { Integer gcd = Arithmetic::GCD(&numerator, &denominator); m_numerator = Integer::Division(numerator, gcd).quotient; m_denominator = Integer::Division(denominator, gcd).quotient; } if (m_numerator.isNegative() && m_denominator.isNegative()) { m_numerator.setNegative(false); m_denominator.setNegative(false); } else if (m_denominator.isNegative()) { m_numerator.setNegative(true); m_denominator.setNegative(false); } }