//
// Arguments: (k1, ..., kn), non-zero reals
// ---------------------
- // Conclusion: (>< (* k t1) (* k t2))
+ // Conclusion: (>< t1 t2)
// where >< is the fusion of the combination of the ><i, (flipping each it
// its ki is negative). >< is always one of <, <=
// NB: this implies that lower bounds must have negative ki,
// and upper bounds must have positive ki.
- // t1 is the sum of the polynomials.
- // t2 is the sum of the constants.
+ // t1 is the sum of the scaled polynomials (k_1 * poly_1 + ... + k_n * poly_n)
+ // t2 is the sum of the scaled constants (k_1 * const_1 + ... + k_n * const_n)
ARITH_SCALE_SUM_UPPER_BOUNDS,
+ // ======== Sum Upper Bounds
+ // Children: (P1, ... , Pn)
+ // where each Pi has form (><i, Li, Ri)
+ // for ><i in {<, <=, ==}
+ // Conclusion: (>< L R)
+ // where >< is < if any ><i is <, and <= otherwise.
+ // L is (+ L1 ... Ln)
+ // R is (+ R1 ... Rn)
+ ARITH_SUM_UB,
// ======== Tightening Strict Integer Upper Bounds
// Children: (P:(< i c))
// where i has integer type.
void ExtProofRuleChecker::registerTo(ProofChecker* pc)
{
pc->registerChecker(PfRule::ARITH_MULT_SIGN, this);
- pc->registerChecker(PfRule::ARITH_MULT_POS, this);
- pc->registerChecker(PfRule::ARITH_MULT_NEG, this);
pc->registerChecker(PfRule::ARITH_MULT_TANGENT, this);
}
default: Assert(false); return Node();
}
}
- else if (id == PfRule::ARITH_MULT_POS)
- {
- Assert(children.empty());
- Assert(args.size() == 2);
- Node mult = args[0];
- Kind rel = args[1].getKind();
- Assert(rel == Kind::EQUAL || rel == Kind::DISTINCT || rel == Kind::LT
- || rel == Kind::LEQ || rel == Kind::GT || rel == Kind::GEQ);
- Node lhs = args[1][0];
- Node rhs = args[1][1];
- return nm->mkNode(
- Kind::IMPLIES,
- nm->mkAnd(std::vector<Node>{nm->mkNode(Kind::GT, mult, zero), args[1]}),
- nm->mkNode(rel,
- nm->mkNode(Kind::MULT, mult, lhs),
- nm->mkNode(Kind::MULT, mult, rhs)));
- }
- else if (id == PfRule::ARITH_MULT_NEG)
- {
- Assert(children.empty());
- Assert(args.size() == 2);
- Node mult = args[0];
- Kind rel = args[1].getKind();
- Assert(rel == Kind::EQUAL || rel == Kind::DISTINCT || rel == Kind::LT
- || rel == Kind::LEQ || rel == Kind::GT || rel == Kind::GEQ);
- Kind rel_inv = (rel == Kind::DISTINCT ? rel : reverseRelationKind(rel));
- Node lhs = args[1][0];
- Node rhs = args[1][1];
- return nm->mkNode(
- Kind::IMPLIES,
- nm->mkAnd(std::vector<Node>{nm->mkNode(Kind::LT, mult, zero), args[1]}),
- nm->mkNode(rel_inv,
- nm->mkNode(Kind::MULT, mult, lhs),
- nm->mkNode(Kind::MULT, mult, rhs)));
- }
else if (id == PfRule::ARITH_MULT_TANGENT)
{
Assert(children.empty());
void ArithProofRuleChecker::registerTo(ProofChecker* pc)
{
pc->registerChecker(PfRule::ARITH_SCALE_SUM_UPPER_BOUNDS, this);
+ pc->registerChecker(PfRule::ARITH_SUM_UB, this);
pc->registerChecker(PfRule::ARITH_TRICHOTOMY, this);
pc->registerChecker(PfRule::INT_TIGHT_UB, this);
pc->registerChecker(PfRule::INT_TIGHT_LB, this);
pc->registerChecker(PfRule::ARITH_OP_ELIM_AXIOM, this);
+
+ pc->registerChecker(PfRule::ARITH_MULT_POS, this);
+ pc->registerChecker(PfRule::ARITH_MULT_NEG, this);
// trusted rules
pc->registerTrustedChecker(PfRule::INT_TRUST, this, 2);
}
const std::vector<Node>& children,
const std::vector<Node>& args)
{
+ NodeManager* nm = NodeManager::currentNM();
+ auto zero = nm->mkConst<Rational>(0);
if (Debug.isOn("arith::pf::check"))
{
Debug("arith::pf::check") << "Arith PfRule:" << id << std::endl;
}
switch (id)
{
+ case PfRule::ARITH_MULT_POS:
+ {
+ Assert(children.empty());
+ Assert(args.size() == 2);
+ Node mult = args[0];
+ Kind rel = args[1].getKind();
+ Assert(rel == Kind::EQUAL || rel == Kind::DISTINCT || rel == Kind::LT
+ || rel == Kind::LEQ || rel == Kind::GT || rel == Kind::GEQ);
+ Node lhs = args[1][0];
+ Node rhs = args[1][1];
+ return nm->mkNode(Kind::IMPLIES,
+ nm->mkAnd(std::vector<Node>{
+ nm->mkNode(Kind::GT, mult, zero), args[1]}),
+ nm->mkNode(rel,
+ nm->mkNode(Kind::MULT, mult, lhs),
+ nm->mkNode(Kind::MULT, mult, rhs)));
+ }
+ case PfRule::ARITH_MULT_NEG:
+ {
+ Assert(children.empty());
+ Assert(args.size() == 2);
+ Node mult = args[0];
+ Kind rel = args[1].getKind();
+ Assert(rel == Kind::EQUAL || rel == Kind::DISTINCT || rel == Kind::LT
+ || rel == Kind::LEQ || rel == Kind::GT || rel == Kind::GEQ);
+ Kind rel_inv = (rel == Kind::DISTINCT ? rel : reverseRelationKind(rel));
+ Node lhs = args[1][0];
+ Node rhs = args[1][1];
+ return nm->mkNode(Kind::IMPLIES,
+ nm->mkAnd(std::vector<Node>{
+ nm->mkNode(Kind::LT, mult, zero), args[1]}),
+ nm->mkNode(rel_inv,
+ nm->mkNode(Kind::MULT, mult, lhs),
+ nm->mkNode(Kind::MULT, mult, rhs)));
+ }
+ case PfRule::ARITH_SUM_UB:
+ {
+ if (children.size() < 2)
+ {
+ return Node::null();
+ }
+
+ // Whether a strict inequality is in the sum.
+ bool strict = false;
+ NodeBuilder<> leftSum(Kind::PLUS);
+ NodeBuilder<> rightSum(Kind::PLUS);
+ for (size_t i = 0; i < children.size(); ++i)
+ {
+ // Adjust strictness
+ switch (children[i].getKind())
+ {
+ case Kind::LT:
+ {
+ strict = true;
+ break;
+ }
+ case Kind::LEQ:
+ case Kind::EQUAL:
+ {
+ break;
+ }
+ default:
+ {
+ Debug("arith::pf::check")
+ << "Bad kind: " << children[i].getKind() << std::endl;
+ return Node::null();
+ }
+ }
+ leftSum << children[i][0];
+ rightSum << children[i][1];
+ }
+ Node r = nm->mkNode(strict ? Kind::LT : Kind::LEQ,
+ leftSum.constructNode(),
+ rightSum.constructNode());
+ return r;
+ }
case PfRule::ARITH_SCALE_SUM_UPPER_BOUNDS:
{
// Children: (P1:l1, ..., Pn:ln)
}
// Whether a strict inequality is in the sum.
- auto nm = NodeManager::currentNM();
bool strict = false;
NodeBuilder<> leftSum(Kind::PLUS);
NodeBuilder<> rightSum(Kind::PLUS);
{
Rational originalBound = children[0][1].getConst<Rational>();
Rational newBound = leastIntGreaterThan(originalBound);
- auto nm = NodeManager::currentNM();
Node rational = nm->mkConst<Rational>(newBound);
return nm->mkNode(kind::GEQ, children[0][0], rational);
}
{
Rational originalBound = children[0][1].getConst<Rational>();
Rational newBound = greatestIntLessThan(originalBound);
- auto nm = NodeManager::currentNM();
Node rational = nm->mkConst<Rational>(newBound);
return nm->mkNode(kind::LEQ, children[0][0], rational);
}