This is required to avoid failures in the planned refactoring of check-models.
This removes the SMT-LIB 2.5 semantics option for bvdiv/bvrem.
It still remains to merge the BITVECTOR_UDIV / BITVECTOR_UDIV_TOTAL kinds, calling the total version "BITVECTOR_UDIV", and analogously for UREM.
FYI @barrettcw
default = "true"
help = "lift equivalence with one-bit bit-vectors to be boolean operations"
-[[option]]
- name = "bitvectorDivByZeroConst"
- category = "regular"
- long = "bv-div-zero-const"
- type = "bool"
- default = "true"
- help = "always return -1 on (bvudiv s 0) and s on (bvurem s 0)"
-
[[option]]
name = "bvExtractArithRewrite"
category = "expert"
options::bitvectorAlgebraicSolver.set(true);
}
- // Language-based defaults
- if (!options::bitvectorDivByZeroConst.wasSetByUser())
- {
- // Bitvector-divide-by-zero changed semantics in SMT LIB 2.6, thus we
- // set this option if the input format is SMT LIB 2.6. We also set this
- // option if we are sygus, since we assume SMT LIB 2.6 semantics for sygus.
- options::bitvectorDivByZeroConst.set(
- !language::isInputLang_smt2_5(options::inputLanguage(), true));
- }
bool is_sygus = language::isInputLangSygus(options::inputLanguage());
if (options::bitblastMode() == options::BitblastMode::EAGER)
// eliminated altogether (or otherwise fail at preprocessing).
|| (logic.isTheoryEnabled(THEORY_ARITH) && !logic.isLinear()
&& options::solveIntAsBV() == 0)
- // If division/mod-by-zero is not treated as a constant value in BV, we
- // need UF.
- || (logic.isTheoryEnabled(THEORY_BV)
- && !options::bitvectorDivByZeroConst())
// FP requires UF since there are multiple operators that are partially
// defined (see http://smtlib.cs.uiowa.edu/papers/BTRW15.pdf for more
// details).
options::cegqiSingleInvMode.set(options::CegqiSingleInvMode::NONE);
}
}
- // do not allow partial functions
- if (!options::bitvectorDivByZeroConst())
- {
- if (options::bitvectorDivByZeroConst.wasSetByUser())
- {
- throw OptionException(
- "--no-bv-div-zero-const is not supported with SyGuS");
- }
- Notice()
- << "SmtEngine: setting bv-div-zero-const to true to support SyGuS"
- << std::endl;
- options::bitvectorDivByZeroConst.set(true);
- }
if (!options::dtRewriteErrorSel.wasSetByUser())
{
options::dtRewriteErrorSel.set(true);
NodeManager* nm = NodeManager::currentNM();
unsigned width = node.getType().getBitVectorSize();
- if (options::bitvectorDivByZeroConst())
- {
- Kind kind = node.getKind() == kind::BITVECTOR_UDIV
- ? kind::BITVECTOR_UDIV_TOTAL
- : kind::BITVECTOR_UREM_TOTAL;
- ret = nm->mkNode(kind, node[0], node[1]);
- break;
- }
-
- TNode num = node[0], den = node[1];
- Node den_eq_0 = nm->mkNode(kind::EQUAL, den, utils::mkZero(width));
- Node divTotalNumDen = nm->mkNode(node.getKind() == kind::BITVECTOR_UDIV
- ? kind::BITVECTOR_UDIV_TOTAL
- : kind::BITVECTOR_UREM_TOTAL,
- num,
- den);
- Node divByZero = getUFDivByZero(node.getKind(), width);
- Node divByZeroNum = nm->mkNode(kind::APPLY_UF, divByZero, num);
- ret = nm->mkNode(kind::ITE, den_eq_0, divByZeroNum, divTotalNumDen);
+ Kind kind = node.getKind() == kind::BITVECTOR_UDIV
+ ? kind::BITVECTOR_UDIV_TOTAL
+ : kind::BITVECTOR_UREM_TOTAL;
+ ret = nm->mkNode(kind, node[0], node[1]);
+ break;
}
break;
Node abs_b =
nm->mkNode(kind::ITE, b_lt_0, nm->mkNode(kind::BITVECTOR_NEG, b), b);
- Node a_udiv_b =
- nm->mkNode(options::bitvectorDivByZeroConst() ? kind::BITVECTOR_UDIV_TOTAL
- : kind::BITVECTOR_UDIV,
- abs_a,
- abs_b);
+ Node a_udiv_b = nm->mkNode(kind::BITVECTOR_UDIV_TOTAL, abs_a, abs_b);
Node neg_result = nm->mkNode(kind::BITVECTOR_NEG, a_udiv_b);
Node condition = nm->mkNode(kind::XOR, a_lt_0, b_lt_0);
Node abs_b =
nm->mkNode(kind::ITE, b_lt_0, nm->mkNode(kind::BITVECTOR_NEG, b), b);
- Node a_udiv_b =
- nm->mkNode(options::bitvectorDivByZeroConst() ? kind::BITVECTOR_UDIV_TOTAL
- : kind::BITVECTOR_UDIV,
- abs_a,
- abs_b);
+ Node a_udiv_b = nm->mkNode(kind::BITVECTOR_UDIV_TOTAL, abs_a, abs_b);
Node neg_result = nm->mkNode(kind::BITVECTOR_NEG, a_udiv_b);
Node result = nm->mkNode(kind::ITE, a_lt_0.xorNode(b_lt_0), neg_result, a_udiv_b);
Node abs_b =
nm->mkNode(kind::ITE, b_lt_0, nm->mkNode(kind::BITVECTOR_NEG, b), b);
- Node a_urem_b =
- nm->mkNode(options::bitvectorDivByZeroConst() ? kind::BITVECTOR_UREM_TOTAL
- : kind::BITVECTOR_UREM,
- abs_a,
- abs_b);
+ Node a_urem_b = nm->mkNode(kind::BITVECTOR_UREM_TOTAL, abs_a, abs_b);
Node neg_result = nm->mkNode(kind::BITVECTOR_NEG, a_urem_b);
Node result = nm->mkNode(kind::ITE, a_lt_0, neg_result, a_urem_b);
nm->mkNode(kind::ITE, a_lt_0, nm->mkNode(kind::BITVECTOR_NEG, a), a);
Node abs_b =
nm->mkNode(kind::ITE, b_lt_0, nm->mkNode(kind::BITVECTOR_NEG, b), b);
- Node a_urem_b =
- nm->mkNode(options::bitvectorDivByZeroConst() ? kind::BITVECTOR_UREM_TOTAL
- : kind::BITVECTOR_UREM,
- abs_a,
- abs_b);
+ Node a_urem_b = nm->mkNode(kind::BITVECTOR_UREM_TOTAL, abs_a, abs_b);
Node neg_result = nm->mkNode(kind::BITVECTOR_NEG, a_urem_b);
Node result = nm->mkNode(kind::ITE, a_lt_0, neg_result, a_urem_b);
template <>
inline bool RewriteRule<UgtUrem>::applies(TNode node)
{
- return (options::bitvectorDivByZeroConst()
- && node.getKind() == kind::BITVECTOR_UGT
+ return (node.getKind() == kind::BITVECTOR_UGT
&& node[0].getKind() == kind::BITVECTOR_UREM_TOTAL
&& node[0][1] == node[1]);
}
RewriteResponse TheoryBVRewriter::RewriteUdiv(TNode node, bool prerewrite){
Node resultNode = node;
- if(node[1].isConst() && node[1].getConst<BitVector>().getValue() != 0) {
- return RewriteUdivTotal(node, prerewrite);
- }
-
- return RewriteResponse(REWRITE_DONE, resultNode);
+ return RewriteUdivTotal(node, prerewrite);
}
RewriteResponse TheoryBVRewriter::RewriteUrem(TNode node, bool prerewrite){
Node resultNode = node;
- if(node[1].isConst() && node[1].getConst<BitVector>().getValue() != 0) {
- return RewriteUremTotal(node, prerewrite);
- }
-
- return RewriteResponse(REWRITE_DONE, resultNode);
+ return RewriteUremTotal(node, prerewrite);
}
RewriteResponse TheoryBVRewriter::RewriteUdivTotal(TNode node, bool prerewrite){
-; EXPECT: sat
-(set-info :smt-lib-version 2.5)
+; EXPECT: unsat
(set-logic QF_BV)
-(set-info :status sat)
+(set-info :status unsat)
(declare-fun x () (_ BitVec 8))
(declare-fun y () (_ BitVec 8))
-; COMMAND-LINE: --bv-div-zero-const --no-check-unsat-cores
+; COMMAND-LINE: --no-check-unsat-cores
(set-logic QF_BV)
(set-info :status unsat)
(declare-const x (_ BitVec 4))
-; COMMAND-LINE: --no-bv-div-zero-const --no-check-unsat-cores
-; COMMAND-LINE: --bv-solver=simple --no-bv-div-zero-const --no-check-unsat-cores
+; COMMAND-LINE: --no-check-unsat-cores
+; COMMAND-LINE: --bv-solver=simple --no-check-unsat-cores
(set-logic QF_BV)
-(set-info :status sat)
+(set-info :status unsat)
(declare-const x (_ BitVec 4))
(declare-const y (_ BitVec 4))
(assert (not (= (bvugt (bvurem y x) x) (ite (= x #x0) (bvugt y #x0) false))))
-; COMMAND-LINE: -q
-; EXPECT: sat
(set-logic AUFBV)
-(set-info :status sat)
-(set-option :bv-div-zero-const false)
+(set-info :status unsat)
(set-option :fmf-bound-int true)
(set-option :uf-ho true)
(declare-fun _substvar_20_ () Bool)
-; COMMAND-LINE: --cegqi-bv --cegqi-bv-ineq=keep --no-cegqi-full --bv-div-zero-const
+; COMMAND-LINE: --cegqi-bv --cegqi-bv-ineq=keep --no-cegqi-full
; EXPECT: unsat
(set-logic BV)
(set-info :status unsat)
-; COMMAND-LINE: --cegqi-bv --cegqi-bv-ineq=keep --no-cegqi-full --bv-div-zero-const -q
+; COMMAND-LINE: --cegqi-bv --cegqi-bv-ineq=keep --no-cegqi-full -q
; EXPECT: sat
(set-logic BV)
(set-info :status sat)