syntax for sequences used by Z3.
* Arrays: Added support for an `eqrange` predicate. `(eqrange a b i j)` is true
if arrays `a` and `b` are equal on all indices within indices `i` and `j`.
+* Support for an integer operator `(_ iand n)` that returns the bitwise `and`
+ of two integers, seen as integers modulo n.
Improvements:
* New API: Added functions to retrieve the heap/nil term when using separation
/* Arithmetic ---------------------------------------------------------- */
{PLUS, CVC4::Kind::PLUS},
{MULT, CVC4::Kind::MULT},
+ {IAND, CVC4::Kind::IAND},
{MINUS, CVC4::Kind::MINUS},
{UMINUS, CVC4::Kind::UMINUS},
{DIVISION, CVC4::Kind::DIVISION},
/* Arithmetic ------------------------------------------------------ */
{CVC4::Kind::PLUS, PLUS},
{CVC4::Kind::MULT, MULT},
+ {CVC4::Kind::IAND, IAND},
{CVC4::Kind::MINUS, MINUS},
{CVC4::Kind::UMINUS, UMINUS},
{CVC4::Kind::DIVISION, DIVISION},
const static std::unordered_set<Kind, KindHashFunction> s_indexed_kinds(
{RECORD_UPDATE,
DIVISIBLE,
+ IAND,
BITVECTOR_REPEAT,
BITVECTOR_ZERO_EXTEND,
BITVECTOR_SIGN_EXTEND,
i = d_expr->getConst<BitVectorRotateRight>().d_rotateRightAmount;
break;
case INT_TO_BITVECTOR: i = d_expr->getConst<IntToBitVector>().d_size; break;
+ case IAND: i = d_expr->getConst<IntAnd>().d_size; break;
case FLOATINGPOINT_TO_UBV:
i = d_expr->getConst<FloatingPointToUBV>().bvs.d_size;
break;
*mkValHelper<CVC4::IntToBitVector>(CVC4::IntToBitVector(arg))
.d_expr.get());
break;
+ case IAND:
+ res = Op(this,
+ kind,
+ *mkValHelper<CVC4::IntAnd>(CVC4::IntAnd(arg)).d_expr.get());
+ break;
case FLOATINGPOINT_TO_UBV:
res = Op(
this,
* mkTerm(Kind kind, const std::vector<Term>& children)
*/
MULT,
+ /**
+ * Operator for Integer AND
+ * Parameter: 1
+ * -[1]: Size of the bit-vector that determines the semantics of the IAND
+ * Create with:
+ * mkOp(Kind kind, uint32_t param).
+ *
+ * Apply integer conversion to bit-vector.
+ * Parameters: 2
+ * -[1]: Op of kind IAND
+ * -[2]: Integer term
+ * -[3]: Integer term
+ * Create with:
+ * mkTerm(Op op, Term child1, Term child2)
+ * mkTerm(Op op, const std::vector<Term>& children)
+ */
+ IAND,
#if 0
/* Synonym for MULT. */
NONLINEAR_MULT,
defineVar("real.pi", d_solver->mkTerm(api::PI));
addTranscendentalOperators();
}
+ if (!strictModeEnabled())
+ {
+ // integer version of AND
+ addIndexedOperator(api::IAND, api::IAND, "iand");
+ }
}
if(d_logic.isTheoryEnabled(theory::THEORY_ARRAYS)) {
parametricTypeChildren = true;
out << smtKindString(k, d_variant) << " ";
break;
+ case kind::IAND:
+ out << "(_ iand " << n.getOperator().getConst<IntAnd>().d_size << ") ";
+ stillNeedToPrintParams = false;
+ break;
case kind::DIVISIBLE:
out << "(_ divisible " << n.getOperator().getConst<Divisible>().k << ")";
case kind::PLUS: return "+";
case kind::MULT:
case kind::NONLINEAR_MULT: return "*";
+ case kind::IAND: return "iand";
case kind::EXPONENTIAL: return "exp";
case kind::SINE: return "sin";
case kind::COSINE: return "cos";
regress1/nl/exp1-lb.smt2
regress1/nl/exp_monotone.smt2
regress1/nl/factor_agg_s.smt2
+ regress1/nl/iand-native-1.smt2
regress1/nl/issue3300-approx-sqrt-witness.smt2
regress1/nl/issue3441.smt2
regress1/nl/issue3617.smt2
--- /dev/null
+; COMMAND-LINE: --iand-mode=value
+; EXPECT: sat
+(set-logic QF_NIA)
+(set-info :status sat)
+(declare-fun x () Int)
+(declare-fun y () Int)
+
+(assert (and (<= 0 x) (< x 16)))
+(assert (and (<= 0 y) (< y 16)))
+(assert (> ((_ iand 4) x y) 0))
+
+(check-sat)