}
}
+ /////////////////////////////////////////////////////////////////////////////
+ // Theory widening
+ //
+ // Some theories imply the use of other theories to handle certain operators,
+ // e.g. UF to handle partial functions.
+ /////////////////////////////////////////////////////////////////////////////
+ bool needsUf = false;
// strings require LIA, UF; widen the logic
if (logic.isTheoryEnabled(THEORY_STRINGS))
{
LogicInfo log(logic.getUnlockedCopy());
// Strings requires arith for length constraints, and also UF
- if (!logic.isTheoryEnabled(THEORY_UF))
- {
- Trace("smt") << "because strings are enabled, also enabling UF"
- << std::endl;
- log.enableTheory(THEORY_UF);
- }
+ needsUf = true;
if (!logic.isTheoryEnabled(THEORY_ARITH) || logic.isDifferenceLogic()
|| !logic.areIntegersUsed())
{
- Trace("smt") << "because strings are enabled, also enabling linear "
- "integer arithmetic"
- << std::endl;
+ Notice()
+ << "Enabling linear integer arithmetic because strings are enabled"
+ << std::endl;
log.enableTheory(THEORY_ARITH);
log.enableIntegers();
log.arithOnlyLinear();
logic = log;
logic.lock();
}
- if (logic.isTheoryEnabled(THEORY_ARRAYS)
+ if (needsUf
+ // Arrays, datatypes and sets permit Boolean terms and thus require UF
+ || logic.isTheoryEnabled(THEORY_ARRAYS)
|| logic.isTheoryEnabled(THEORY_DATATYPES)
- || logic.isTheoryEnabled(THEORY_SETS))
+ || logic.isTheoryEnabled(THEORY_SETS)
+ // Non-linear arithmetic requires UF to deal with division/mod because
+ // their expansion introduces UFs for the division/mod-by-zero case.
+ || (logic.isTheoryEnabled(THEORY_ARITH) && !logic.isLinear())
+ // 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).
+ || logic.isTheoryEnabled(THEORY_FP))
{
if (!logic.isTheoryEnabled(THEORY_UF))
{
LogicInfo log(logic.getUnlockedCopy());
- Trace("smt") << "because a theory that permits Boolean terms is enabled, "
- "also enabling UF"
- << std::endl;
+ Notice() << "Enabling UF because " << logic << " requires it."
+ << std::endl;
log.enableTheory(THEORY_UF);
logic = log;
logic.lock();
}
}
+ /////////////////////////////////////////////////////////////////////////////
// by default, symmetry breaker is on only for non-incremental QF_UF
if (!options::ufSymmetryBreaker.wasSetByUser())
theory::Theory* t = d_smt.d_theoryEngine->theoryOf(node);
Assert(t != NULL);
- LogicRequest req(d_smt);
- node = t->expandDefinition(req, n);
+ node = t->expandDefinition(n);
}
// the partial functions can fall through, in which case we still
d_internal->preRegisterTerm(n);
}
-Node TheoryArith::expandDefinition(LogicRequest &logicRequest, Node node) {
- return d_internal->expandDefinition(logicRequest, node);
+Node TheoryArith::expandDefinition(Node node)
+{
+ return d_internal->expandDefinition(node);
}
void TheoryArith::setMasterEqualityEngine(eq::EqualityEngine* eq) {
*/
void preRegisterTerm(TNode n) override;
- Node expandDefinition(LogicRequest& logicRequest, Node node) override;
+ Node expandDefinition(Node node) override;
void setMasterEqualityEngine(eq::EqualityEngine* eq) override;
return d_rowTracking[ridx];
}
-
-Node TheoryArithPrivate::expandDefinition(LogicRequest &logicRequest, Node node) {
+Node TheoryArithPrivate::expandDefinition(Node node)
+{
NodeManager* nm = NodeManager::currentNM();
// eliminate here since the rewritten form of these may introduce division
Node ret = nm->mkNode(kind::DIVISION_TOTAL, num, den);
if (!den.isConst() || den.getConst<Rational>().sgn() == 0)
{
- Node divByZeroNum =
- getArithSkolemApp(logicRequest, num, ArithSkolemId::DIV_BY_ZERO);
+ Node divByZeroNum = getArithSkolemApp(num, ArithSkolemId::DIV_BY_ZERO);
Node denEq0 = nm->mkNode(kind::EQUAL, den, nm->mkConst(Rational(0)));
ret = nm->mkNode(kind::ITE, denEq0, divByZeroNum, ret);
}
Node ret = nm->mkNode(kind::INTS_DIVISION_TOTAL, num, den);
if (!den.isConst() || den.getConst<Rational>().sgn() == 0)
{
- Node intDivByZeroNum = getArithSkolemApp(
- logicRequest, num, ArithSkolemId::INT_DIV_BY_ZERO);
+ Node intDivByZeroNum =
+ getArithSkolemApp(num, ArithSkolemId::INT_DIV_BY_ZERO);
Node denEq0 = nm->mkNode(kind::EQUAL, den, nm->mkConst(Rational(0)));
ret = nm->mkNode(kind::ITE, denEq0, intDivByZeroNum, ret);
}
Node ret = nm->mkNode(kind::INTS_MODULUS_TOTAL, num, den);
if (!den.isConst() || den.getConst<Rational>().sgn() == 0)
{
- Node modZeroNum =
- getArithSkolemApp(logicRequest, num, ArithSkolemId::MOD_BY_ZERO);
+ Node modZeroNum = getArithSkolemApp(num, ArithSkolemId::MOD_BY_ZERO);
Node denEq0 = nm->mkNode(kind::EQUAL, den, nm->mkConst(Rational(0)));
ret = nm->mkNode(kind::ITE, denEq0, modZeroNum, ret);
}
Node lem;
if (k == kind::SQRT)
{
- Node skolemApp =
- getArithSkolemApp(logicRequest, node[0], ArithSkolemId::SQRT);
+ Node skolemApp = getArithSkolemApp(node[0], ArithSkolemId::SQRT);
Node uf = skolemApp.eqNode(var);
Node nonNeg = nm->mkNode(
kind::AND, nm->mkNode(kind::MULT, var, var).eqNode(node[0]), uf);
Unreachable();
}
-Node TheoryArithPrivate::getArithSkolem(LogicRequest& logicRequest,
- ArithSkolemId asi)
+Node TheoryArithPrivate::getArithSkolem(ArithSkolemId asi)
{
std::map<ArithSkolemId, Node>::iterator it = d_arith_skolem.find(asi);
if (it == d_arith_skolem.end())
nm->mkFunctionType(tn, tn),
desc,
NodeManager::SKOLEM_EXACT_NAME);
- logicRequest.widenLogic(THEORY_UF);
}
d_arith_skolem[asi] = skolem;
return skolem;
return it->second;
}
-Node TheoryArithPrivate::getArithSkolemApp(LogicRequest& logicRequest,
- Node n,
- ArithSkolemId asi)
+Node TheoryArithPrivate::getArithSkolemApp(Node n, ArithSkolemId asi)
{
- Node skolem = getArithSkolem(logicRequest, asi);
+ Node skolem = getArithSkolem(asi);
if (!options::arithNoPartialFun())
{
skolem = NodeManager::currentNM()->mkNode(APPLY_UF, skolem, n);
* Does non-context dependent setup for a node connected to a theory.
*/
void preRegisterTerm(TNode n);
- Node expandDefinition(LogicRequest &logicRequest, Node node);
+ Node expandDefinition(Node node);
void setMasterEqualityEngine(eq::EqualityEngine* eq);
/** get arithmetic skolem
*
* Returns the Skolem in the above map for the given id, creating it if it
- * does not already exist. If a Skolem function is created, the logic is
- * widened to include UF.
+ * does not already exist.
*/
- Node getArithSkolem(LogicRequest& logicRequest, ArithSkolemId asi);
+ Node getArithSkolem(ArithSkolemId asi);
/** get arithmetic skolem application
*
* By default, this returns the term f( n ), where f is the Skolem function
* If the option arithNoPartialFun is enabled, this returns f, where f is
* the Skolem constant for the identifier asi.
*/
- Node getArithSkolemApp(LogicRequest& logicRequest, Node n, ArithSkolemId asi);
+ Node getArithSkolemApp(Node n, ArithSkolemId asi);
/**
* Maps for Skolems for to-integer, real/integer div-by-k, and inverse
tm->setSemiEvaluatedKind(kind::BITVECTOR_ACKERMANNIZE_UREM);
}
-Node TheoryBV::expandDefinition(LogicRequest &logicRequest, Node node) {
+Node TheoryBV::expandDefinition(Node node)
+{
Debug("bitvector-expandDefinition") << "TheoryBV::expandDefinition(" << node << ")" << std::endl;
switch (node.getKind()) {
Node divByZero = getBVDivByZero(node.getKind(), width);
Node divByZeroNum = nm->mkNode(kind::APPLY_UF, divByZero, num);
node = nm->mkNode(kind::ITE, den_eq_0, divByZeroNum, divTotalNumDen);
- logicRequest.widenLogic(THEORY_UF);
return node;
}
break;
Unreachable();
}
-
void TheoryBV::preRegisterTerm(TNode node) {
d_calledPreregister = true;
Debug("bitvector-preregister") << "TheoryBV::preRegister(" << node << ")" << std::endl;
void finishInit() override;
- Node expandDefinition(LogicRequest& logicRequest, Node node) override;
+ Node expandDefinition(Node node) override;
void preRegisterTerm(TNode n) override;
}
}
-Node TheoryDatatypes::expandDefinition(LogicRequest &logicRequest, Node n) {
+Node TheoryDatatypes::expandDefinition(Node n)
+{
NodeManager* nm = NodeManager::currentNM();
switch (n.getKind())
{
bool needsCheckLastEffort() override;
void preRegisterTerm(TNode n) override;
void finishInit() override;
- Node expandDefinition(LogicRequest& logicRequest, Node n) override;
+ Node expandDefinition(Node n) override;
Node ppRewrite(TNode n) override;
void presolve() override;
void addSharedTerm(TNode t) override;
return nm->mkNode(kind::APPLY_UF, fun, node[0]);
}
-void TheoryFp::enableUF(LogicRequest &lr)
-{
- if (!this->d_expansionRequested) {
- // Needed for conversions to/from real and min/max
- lr.widenLogic(THEORY_UF);
- // THEORY_BV has to be enabled when the logic is set
- this->d_expansionRequested = true;
- }
- return;
-}
-
Node TheoryFp::abstractRealToFloat(Node node)
{
Assert(node.getKind() == kind::FLOATINGPOINT_TO_FP_REAL);
return uf;
}
-Node TheoryFp::expandDefinition(LogicRequest &lr, Node node)
+Node TheoryFp::expandDefinition(Node node)
{
Trace("fp-expandDefinition") << "TheoryFp::expandDefinition(): " << node
<< std::endl;
res = removeToFPGeneric::removeToFPGeneric(node);
} else if (node.getKind() == kind::FLOATINGPOINT_MIN) {
- enableUF(lr);
res = NodeManager::currentNM()->mkNode(kind::FLOATINGPOINT_MIN_TOTAL,
node[0], node[1], minUF(node));
} else if (node.getKind() == kind::FLOATINGPOINT_MAX) {
- enableUF(lr);
res = NodeManager::currentNM()->mkNode(kind::FLOATINGPOINT_MAX_TOTAL,
node[0], node[1], maxUF(node));
} else if (node.getKind() == kind::FLOATINGPOINT_TO_UBV) {
- enableUF(lr);
FloatingPointToUBV info = node.getOperator().getConst<FloatingPointToUBV>();
FloatingPointToUBVTotal newInfo(info);
toUBVUF(node));
} else if (node.getKind() == kind::FLOATINGPOINT_TO_SBV) {
- enableUF(lr);
FloatingPointToSBV info = node.getOperator().getConst<FloatingPointToSBV>();
FloatingPointToSBVTotal newInfo(info);
toSBVUF(node));
} else if (node.getKind() == kind::FLOATINGPOINT_TO_REAL) {
- enableUF(lr);
res = NodeManager::currentNM()->mkNode(kind::FLOATINGPOINT_TO_REAL_TOTAL,
node[0], toRealUF(node));
// Do nothing
}
- // We will need to enable UF to abstract these in ppRewrite
- if (res.getKind() == kind::FLOATINGPOINT_TO_REAL_TOTAL
- || res.getKind() == kind::FLOATINGPOINT_TO_FP_REAL)
- {
- enableUF(lr);
- }
-
if (res != node) {
Trace("fp-expandDefinition") << "TheoryFp::expandDefinition(): " << node
<< " rewritten to " << res << std::endl;
TheoryRewriter* getTheoryRewriter() override { return &d_rewriter; }
- Node expandDefinition(LogicRequest& lr, Node node) override;
+ Node expandDefinition(Node node) override;
void preRegisterTerm(TNode node) override;
void addSharedTerm(TNode node) override;
context::CDO<bool> d_conflict;
context::CDO<Node> d_conflictNode;
- /** Uninterpretted functions for partially defined functions. **/
- void enableUF(LogicRequest& lr);
-
typedef context::CDHashMap<TypeNode, Node, TypeNodeHashFunction>
ComparisonUFMap;
d_internal->preRegisterTerm(node);
}
-Node TheorySets::expandDefinition(LogicRequest &logicRequest, Node n) {
+Node TheorySets::expandDefinition(Node n)
+{
Kind nk = n.getKind();
if (nk == UNIVERSE_SET || nk == COMPLEMENT || nk == JOIN_IMAGE
|| nk == COMPREHENSION)
throw LogicException(ss.str());
}
}
- return d_internal->expandDefinition(logicRequest, n);
+ return d_internal->expandDefinition(n);
}
Theory::PPAssertStatus TheorySets::ppAssert(TNode in, SubstitutionMap& outSubstitutions) {
Node getModelValue(TNode) override;
std::string identify() const override { return "THEORY_SETS"; }
void preRegisterTerm(TNode node) override;
- Node expandDefinition(LogicRequest& logicRequest, Node n) override;
+ Node expandDefinition(Node n) override;
PPAssertStatus ppAssert(TNode in, SubstitutionMap& outSubstitutions) override;
void presolve() override;
void propagate(Effort) override;
}
}
-Node TheorySetsPrivate::expandDefinition(LogicRequest& logicRequest, Node n)
+Node TheorySetsPrivate::expandDefinition(Node n)
{
Debug("sets-proc") << "expandDefinition : " << n << std::endl;
return n;
* Another option to fix this is to make TheoryModel::getValue more general
* so that it makes theory-specific calls to evaluate interpreted symbols.
*/
- Node expandDefinition(LogicRequest &logicRequest, Node n);
+ Node expandDefinition(Node n);
Theory::PPAssertStatus ppAssert(TNode in, SubstitutionMap& outSubstitutions);
}
}
-Node TheoryStrings::expandDefinition(LogicRequest &logicRequest, Node node) {
+Node TheoryStrings::expandDefinition(Node node)
+{
Trace("strings-exp-def") << "TheoryStrings::expandDefinition : " << node << std::endl;
if (node.getKind() == STRING_FROM_CODE)
/** preregister term */
void preRegisterTerm(TNode n) override;
/** Expand definition */
- Node expandDefinition(LogicRequest& logicRequest, Node n) override;
+ Node expandDefinition(Node n) override;
/** Check at effort e */
void check(Effort e) override;
/** needs check last effort */
virtual void finishInit() { }
/**
- * Some theories have kinds that are effectively definitions and
- * should be expanded before they are handled. Definitions allow
- * a much wider range of actions than the normal forms given by the
- * rewriter; they can enable other theories and create new terms.
- * However no assumptions can be made about subterms having been
- * expanded or rewritten. Where possible rewrite rules should be
- * used, definitions should only be used when rewrites are not
- * possible, for example in handling under-specified operations
- * using partially defined functions.
+ * Some theories have kinds that are effectively definitions and should be
+ * expanded before they are handled. Definitions allow a much wider range of
+ * actions than the normal forms given by the rewriter. However no
+ * assumptions can be made about subterms having been expanded or rewritten.
+ * Where possible rewrite rules should be used, definitions should only be
+ * used when rewrites are not possible, for example in handling
+ * under-specified operations using partially defined functions.
*
* Some theories like sets use expandDefinition as a "context
* independent preRegisterTerm". This is required for cases where
* a theory wants to be notified about a term before preprocessing
* and simplification but doesn't necessarily want to rewrite it.
*/
- virtual Node expandDefinition(LogicRequest &logicRequest, Node node) {
+ virtual Node expandDefinition(Node node)
+ {
// by default, do nothing
return node;
}
* @param assertion the normalized assertion being sent
* @param originalAssertion the actual assertion that was sent
* @param toTheoryId the theory that is on the receiving end
- * @param fromTheoryId the theory that sent the assertino
+ * @param fromTheoryId the theory that sent the assertion
* @return true if a new assertion, false if theory already got it
*/
bool markPropagation(TNode assertion, TNode originalAssertions, theory::TheoryId toTheoryId, theory::TheoryId fromTheoryId);
case THEORY_FP: out << "THEORY_FP"; break;
case THEORY_ARRAYS: out << "THEORY_ARRAYS"; break;
case THEORY_DATATYPES: out << "THEORY_DATATYPES"; break;
+ case THEORY_SAT_SOLVER: out << "THEORY_SAT_SOLVER"; break;
case THEORY_SEP: out << "THEORY_SEP"; break;
case THEORY_SETS: out << "THEORY_SETS"; break;
case THEORY_STRINGS: out << "THEORY_STRINGS"; break;
return node.getKind()==kind::APPLY_UF ? 0 : 1;
}
-Node TheoryUF::expandDefinition(LogicRequest &logicRequest, Node node) {
+Node TheoryUF::expandDefinition(Node node)
+{
Trace("uf-exp-def") << "TheoryUF::expandDefinition: expanding definition : "
<< node << std::endl;
if( node.getKind()==kind::HO_APPLY ){
void finishInit() override;
void check(Effort) override;
- Node expandDefinition(LogicRequest& logicRequest, Node node) override;
+ Node expandDefinition(Node node) override;
void preRegisterTerm(TNode term) override;
Node explain(TNode n) override;
regress0/nl/issue3719.smt2
regress0/nl/issue3729-cm-solved-tf.smt2
regress0/nl/issue3959.smt2
+ regress0/nl/issue3971.smt2
+ regress0/nl/issue3991.smt2
regress0/nl/issue4007-rint-uf.smt2
regress0/nl/magnitude-wrong-1020-m.smt2
regress0/nl/mult-po.smt2
--- /dev/null
+; COMMAND-LINE: --incremental
+; EXPECT: sat
+; EXPECT: unsat
+; EXPECT: unsat
+; EXPECT: unsat
+; EXPECT: unsat
+(set-logic QF_NIA)
+(declare-const v0 Bool)
+(declare-const v1 Bool)
+(declare-const v2 Bool)
+(declare-const v3 Bool)
+(declare-const i4 Int)
+(declare-const i5 Int)
+(declare-const i6 Int)
+(declare-const i7 Int)
+(declare-const i8 Int)
+(declare-const i9 Int)
+(declare-const i12 Int)
+(declare-const i13 Int)
+(declare-const i14 Int)
+(declare-const v4 Bool)
+(assert (xor v1 (<= i13 i6) (= (or v1 v3 v2) v1) v0 (= (or v1 v3 v2) v1) v2 v0 v2 (or v1 v3 v2) (=> v4 (<= i13 i6))))
+(declare-const v5 Bool)
+(assert v1)
+(declare-const i15 Int)
+(declare-const v6 Bool)
+(assert (distinct v5 (<= i8 i15)))
+(declare-const i16 Int)
+(assert v0)
+(declare-const i17 Int)
+(assert (xor (or v1 v3 v2) (<= i13 i6) (xor (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (= (- i8) 36) v6) (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v1 (<= i13 i6) (= (or v1 v3 v2) v1) v0 (= (or v1 v3 v2) v1) v2 v0 v2 (or v1 v3 v2) (=> v4 (<= i13 i6))) (= (- i8) 36) v4 (= (<= i8 i15) v0 (distinct i6 i12) (= (or v1 v3 v2) v1) v6 v1 (= (- i8) 36) v6)))
+(declare-const i18 Int)
+(declare-const v7 Bool)
+(assert (xor (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (= (- i8) 36) v6))
+(declare-const v8 Bool)
+(declare-const v9 Bool)
+(assert (xor (or v1 v3 v2) (<= i13 i6) (xor (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (= (- i8) 36) v6) (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v1 (<= i13 i6) (= (or v1 v3 v2) v1) v0 (= (or v1 v3 v2) v1) v2 v0 v2 (or v1 v3 v2) (=> v4 (<= i13 i6))) (= (- i8) 36) v4 (= (<= i8 i15) v0 (distinct i6 i12) (= (or v1 v3 v2) v1) v6 v1 (= (- i8) 36) v6)))
+(assert (= (<= i8 i15) v0 (distinct i6 i12) (= (or v1 v3 v2) v1) v6 v1 (= (- i8) 36) v6))
+(assert (=> v4 (<= i13 i6)))
+(declare-const v10 Bool)
+(declare-const v11 Bool)
+(assert v9)
+(check-sat)
+(assert (> (abs i7) i4))
+(assert v2)
+(declare-const v12 Bool)
+(assert (distinct v5 (<= i8 i15)))
+(declare-const i19 Int)
+(assert (xor (not (< (div i4 i8) 79)) (> (- 888) i15) (distinct i6 i12) (distinct i6 i12) (= (or v1 v3 v2) v1) (and v3 (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) v3 v0 v2 v4 (= (or v1 v3 v2) v1) (= (or v1 v3 v2) v1)) v10))
+(check-sat)
+(declare-const v13 Bool)
+(push 1)
+(assert (< i9 i8))
+(assert (= v2 (xor v1 (<= i13 i6) (= (or v1 v3 v2) v1) v0 (= (or v1 v3 v2) v1) v2 v0 v2 (or v1 v3 v2) (=> v4 (<= i13 i6))) (<= i13 i6) v12 v11 v10 (distinct v5 (<= i8 i15)) v5 v8))
+(push 1)
+(push 1)
+(declare-const v14 Bool)
+(assert v7)
+(assert v10)
+(declare-const v15 Bool)
+(declare-const v16 Bool)
+(declare-const i20 Int)
+(assert (or v1 v3 v2))
+(declare-const i21 Int)
+(declare-const v17 Bool)
+(assert (=> (> i6 (abs 79)) (or (= (- i8) 36) v6 v1)))
+(declare-const v18 Bool)
+(assert (distinct i6 i12))
+(declare-const v19 Bool)
+(assert (< i9 i8))
+(declare-const v20 Bool)
+(assert (= v16 (>= i19 (abs i14)) (= (or (= (- i8) 36) v6 v1) (distinct i6 i12) (> 546 i8) (> 546 i8) (xor (or v1 v3 v2) (<= i13 i6) (xor (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (= (- i8) 36) v6) (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v1 (<= i13 i6) (= (or v1 v3 v2) v1) v0 (= (or v1 v3 v2) v1) v2 v0 v2 (or v1 v3 v2) (=> v4 (<= i13 i6))) (= (- i8) 36) v4 (= (<= i8 i15) v0 (distinct i6 i12) (= (or v1 v3 v2) v1) v6 v1 (= (- i8) 36) v6)) (> i6 (abs 79)) v11 (and v3 (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) v3 v0 v2 v4 (= (or v1 v3 v2) v1) (= (or v1 v3 v2) v1)) (xor (or v1 v3 v2) (<= i13 i6) (xor (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (= (- i8) 36) v6) (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v1 (<= i13 i6) (= (or v1 v3 v2) v1) v0 (= (or v1 v3 v2) v1) v2 v0 v2 (or v1 v3 v2) (=> v4 (<= i13 i6))) (= (- i8) 36) v4 (= (<= i8 i15) v0 (distinct i6 i12) (= (or v1 v3 v2) v1) v6 v1 (= (- i8) 36) v6))) (<= i13 i6)))
+(declare-const v21 Bool)
+(declare-const v22 Bool)
+(assert (> 79 34))
+(declare-const i22 Int)
+(assert v9)
+(declare-const i23 Int)
+(declare-const v23 Bool)
+(declare-const v24 Bool)
+(declare-const i24 Int)
+(pop 1)
+(declare-const i25 Int)
+(assert (xor v1 (<= i13 i6) (= (or v1 v3 v2) v1) v0 (= (or v1 v3 v2) v1) v2 v0 v2 (or v1 v3 v2) (=> v4 (<= i13 i6))))
+(declare-const v25 Bool)
+(pop 1)
+(declare-const v26 Bool)
+(declare-const i26 Int)
+(declare-const i27 Int)
+(assert (=> (= v3 v4 (<= i13 i6) v0 v10 v6) v1))
+(push 1)
+(assert (and (=> (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (=> v4 (<= i13 i6))) (xor (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (= (- i8) 36) v6) (= v2 (xor v1 (<= i13 i6) (= (or v1 v3 v2) v1) v0 (= (or v1 v3 v2) v1) v2 v0 v2 (or v1 v3 v2) (=> v4 (<= i13 i6))) (<= i13 i6) v12 v11 v10 (distinct v5 (<= i8 i15)) v5 v8) (>= i14 i19) (> (abs i7) i4)))
+(declare-const v27 Bool)
+(declare-const v28 Bool)
+(declare-const v29 Bool)
+(declare-const i28 Int)
+(assert (distinct v5 (<= i8 i15)))
+(assert (xor (> (- 888) i15) v3 (< i9 i8) (=> v4 (<= i13 i6)) (>= 162 43) (and (>= 162 43) (distinct 623 752) (= i15 960)) (and (=> (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (=> v4 (<= i13 i6))) (xor (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (= (- i8) 36) v6) (= v2 (xor v1 (<= i13 i6) (= (or v1 v3 v2) v1) v0 (= (or v1 v3 v2) v1) v2 v0 v2 (or v1 v3 v2) (=> v4 (<= i13 i6))) (<= i13 i6) v12 v11 v10 (distinct v5 (<= i8 i15)) v5 v8) (>= i14 i19) (> (abs i7) i4))))
+(assert (and v3 (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) v3 v0 v2 v4 (= (or v1 v3 v2) v1) (= (or v1 v3 v2) v1)))
+(declare-const v30 Bool)
+(assert (or (xor (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (= (- i8) 36) v6) v6 (= (or (or (= (- i8) 36) v6 v1) v10 v5 v10 (= (<= i8 i15) v0 (distinct i6 i12) (= (or v1 v3 v2) v1) v6 v1 (= (- i8) 36) v6) v8 (< i9 i8)) (xor (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (= (- i8) 36) v6) (= (<= i8 i15) v0 (distinct i6 i12) (= (or v1 v3 v2) v1) v6 v1 (= (- i8) 36) v6) v2 (=> (= v3 v4 (<= i13 i6) v0 v10 v6) v1) (>= 34 36) (and v3 (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) v3 v0 v2 v4 (= (or v1 v3 v2) v1) (= (or v1 v3 v2) v1))) (and v3 (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) v3 v0 v2 v4 (= (or v1 v3 v2) v1) (= (or v1 v3 v2) v1)) (>= 162 43) v30 (< (div i4 i8) 79) v2 (xor (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (= (- i8) 36) v6)))
+(assert (= (xor (or v1 v3 v2) (<= i13 i6) (xor (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (= (- i8) 36) v6) (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v1 (<= i13 i6) (= (or v1 v3 v2) v1) v0 (= (or v1 v3 v2) v1) v2 v0 v2 (or v1 v3 v2) (=> v4 (<= i13 i6))) (= (- i8) 36) v4 (= (<= i8 i15) v0 (distinct i6 i12) (= (or v1 v3 v2) v1) v6 v1 (= (- i8) 36) v6)) v28 v28))
+(declare-const v31 Bool)
+(assert (=> (= v3 v4 (<= i13 i6) v0 v10 v6) v1))
+(declare-const v32 Bool)
+(pop 1)
+(declare-const i29 Int)
+(assert (xor v2 v2 v3 v0 v0 v2 v3 v1 v2))
+(declare-const v33 Bool)
+(assert v9)
+(push 1)
+(declare-const v34 Bool)
+(assert (or (>= 162 43) (>= i14 i19) (or (or (= (- i8) 36) v6 v1) v10 v5 v10 (= (<= i8 i15) v0 (distinct i6 i12) (= (or v1 v3 v2) v1) v6 v1 (= (- i8) 36) v6) v8 (< i9 i8)) (< (div i4 i8) 79) (< i6 (div i4 i8)) (xor (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (= (- i8) 36) v6) (or (not (< (div i4 i8) 79)) (> (abs i7) i4) (= (or (= (- i8) 36) v6 v1) (distinct i6 i12) (> 546 i8) (> 546 i8) (xor (or v1 v3 v2) (<= i13 i6) (xor (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (= (- i8) 36) v6) (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v1 (<= i13 i6) (= (or v1 v3 v2) v1) v0 (= (or v1 v3 v2) v1) v2 v0 v2 (or v1 v3 v2) (=> v4 (<= i13 i6))) (= (- i8) 36) v4 (= (<= i8 i15) v0 (distinct i6 i12) (= (or v1 v3 v2) v1) v6 v1 (= (- i8) 36) v6)) (> i6 (abs 79)) v11 (and v3 (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) v3 v0 v2 v4 (= (or v1 v3 v2) v1) (= (or v1 v3 v2) v1)) (xor (or v1 v3 v2) (<= i13 i6) (xor (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (= (- i8) 36) v6) (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v1 (<= i13 i6) (= (or v1 v3 v2) v1) v0 (= (or v1 v3 v2) v1) v2 v0 v2 (or v1 v3 v2) (=> v4 (<= i13 i6))) (= (- i8) 36) v4 (= (<= i8 i15) v0 (distinct i6 i12) (= (or v1 v3 v2) v1) v6 v1 (= (- i8) 36) v6))) (and v3 (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) v3 v0 v2 v4 (= (or v1 v3 v2) v1) (= (or v1 v3 v2) v1))) (< i9 i8) (and v3 (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) v3 v0 v2 v4 (= (or v1 v3 v2) v1) (= (or v1 v3 v2) v1)) v5))
+(declare-const i30 Int)
+(declare-const v35 Bool)
+(push 1)
+(assert (and (>= 162 43) (distinct 623 752) (= i15 960)))
+(declare-const v36 Bool)
+(assert (=> (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (=> v4 (<= i13 i6))))
+(push 1)
+(declare-const v37 Bool)
+(declare-const v38 Bool)
+(assert (distinct (= v3 v4 (<= i13 i6) v0 v10 v6) (= (or (or (= (- i8) 36) v6 v1) v10 v5 v10 (= (<= i8 i15) v0 (distinct i6 i12) (= (or v1 v3 v2) v1) v6 v1 (= (- i8) 36) v6) v8 (< i9 i8)) (xor (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (= (- i8) 36) v6) (= (<= i8 i15) v0 (distinct i6 i12) (= (or v1 v3 v2) v1) v6 v1 (= (- i8) 36) v6) v2 (=> (= v3 v4 (<= i13 i6) v0 v10 v6) v1) (>= 34 36) (and v3 (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) v3 v0 v2 v4 (= (or v1 v3 v2) v1) (= (or v1 v3 v2) v1))) (> 546 i8) (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (= (or (or (= (- i8) 36) v6 v1) v10 v5 v10 (= (<= i8 i15) v0 (distinct i6 i12) (= (or v1 v3 v2) v1) v6 v1 (= (- i8) 36) v6) v8 (< i9 i8)) (xor (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (= (- i8) 36) v6) (= (<= i8 i15) v0 (distinct i6 i12) (= (or v1 v3 v2) v1) v6 v1 (= (- i8) 36) v6) v2 (=> (= v3 v4 (<= i13 i6) v0 v10 v6) v1) (>= 34 36) (and v3 (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) v3 v0 v2 v4 (= (or v1 v3 v2) v1) (= (or v1 v3 v2) v1))) (< i6 (div i4 i8)) (or (or (= (- i8) 36) v6 v1) v10 v5 v10 (= (<= i8 i15) v0 (distinct i6 i12) (= (or v1 v3 v2) v1) v6 v1 (= (- i8) 36) v6) v8 (< i9 i8)) (< (div i4 i8) 79)))
+(assert (and (= v3 v4 (<= i13 i6) v0 v10 v6) (>= (abs 969) (* i6 162 i4 i4))))
+(assert v0)
+(assert (<= 12 i4))
+(check-sat)
+(assert (distinct (>= (abs 969) (* i6 162 i4 i4)) (xor (=> (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (=> v4 (<= i13 i6))) (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (< (div i4 i8) 79) v11 (xor (xor (or v1 v3 v2) v3 (= (or v1 v3 v2) v1) (= (- i8) 36) (=> v4 (<= i13 i6)) v3 v2 (=> v4 (<= i13 i6)) v4 (or v1 v3 v2)) (xor v2 v2 v3 v0 v0 v2 v3 v1 v2) (= (- i8) 36) v6) v4 (> 546 i8) (> i6 (abs 79)))))
+(assert (=> (or (= (- i8) 36) v6 v1) (distinct v5 (<= i8 i15))))
+(declare-const v39 Bool)
+(push 1)
+(declare-const v40 Bool)
+(declare-const v41 Bool)
+(declare-const v42 Bool)
+(check-sat)
+(assert (or (= (- i8) 36) v6 v1))
+(assert (=> (=> v4 (<= i13 i6)) (< i6 (div i4 i8))))
+(pop 1)
+(declare-const v43 Bool)
+(pop 1)
+(assert (or v1 v3 v2))
+(push 1)
+(assert (not (> (abs i7) i4)))
+(check-sat)
+(exit)
--- /dev/null
+; COMMAND-LINE: --incremental --check-unsat-cores
+; EXPECT: sat
+; EXPECT: sat
+; EXPECT: unsat
+(set-logic QF_NIA)
+(declare-const i7 Int)
+(check-sat)
+(declare-const v18 Bool)
+(assert (and (= i7 93) (or (> 19 i7) v18) v18))
+(check-sat)
+(assert (> 19 i7))
+(assert (> (div i7 0) 0))
+(check-sat)