TNode var = d_partialModel.asNode(x);
Integer floor_d = d.floor();
- //Node eq = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::EQUAL, var, mkRationalNode(floor_d+1)));
- //Node diseq = eq.notNode();
-
- Node ub = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::LEQ, var, mkRationalNode(floor_d)));
- Node lb = ub.notNode();
-
+ Node lem;
+ NodeManager* nm = NodeManager::currentNM();
+ if (options::brabTest())
+ {
+ Trace("integers") << "branch-round-and-bound enabled" << endl;
+ Integer ceil_d = d.ceiling();
+ Rational f = r - floor_d;
+ // Multiply by -1 to get abs value.
+ Rational c = (r - ceil_d) * (-1);
+ Integer nearest = (c > f) ? floor_d : ceil_d;
+
+ // Prioritize trying a simple rounding of the real solution first,
+ // it that fails, fall back on original branch and bound strategy.
+ Node ub = Rewriter::rewrite(
+ nm->mkNode(kind::LEQ, var, mkRationalNode(nearest - 1)));
+ Node lb = Rewriter::rewrite(
+ nm->mkNode(kind::GEQ, var, mkRationalNode(nearest + 1)));
+ lem = nm->mkNode(kind::OR, ub, lb);
+ Node eq = Rewriter::rewrite(
+ nm->mkNode(kind::EQUAL, var, mkRationalNode(nearest)));
+ Node literal = d_containing.getValuation().ensureLiteral(eq);
+ d_containing.getOutputChannel().requirePhase(literal, true);
+ lem = nm->mkNode(kind::OR, literal, lem);
+ }
+ else
+ {
+ Node ub =
+ Rewriter::rewrite(nm->mkNode(kind::LEQ, var, mkRationalNode(floor_d)));
+ Node lb = ub.notNode();
+ lem = nm->mkNode(kind::OR, ub, lb);
+ }
- //Node lem = NodeManager::currentNM()->mkNode(kind::OR, eq, diseq);
- Node lem = NodeManager::currentNM()->mkNode(kind::OR, ub, lb);
Trace("integers") << "integers: branch & bound: " << lem << endl;
if(isSatLiteral(lem[0])) {
Debug("integers") << " " << lem[0] << " == " << getSatValue(lem[0]) << endl;
--- /dev/null
+; COMMAND-LINE: --arith-brab
+; COMMAND-LINE: --no-arith-brab
+; EXPECT: sat
+(set-logic ALL)
+
+(declare-fun x1 () Real)
+(declare-fun y1 () Real)
+(declare-fun m1 () Real)
+(declare-fun b1 () Real)
+
+(declare-fun x () Int)
+(declare-fun y () Int)
+
+(assert (= y1 (+ b1 (* m1 x1))))
+(assert (= x1 (/ m1 (- y1 b1))))
+(assert (= b1 1.25))
+(assert (= m1 (/ 1 3)))
+
+(assert (and (> x x1) (> y y1)))
+
+(check-sat)
+(exit)
+