def _division(self, left, right): """Utility function that builds a division""" mgr = self.env.formula_manager if left.is_constant() and right.is_constant(): return mgr.Real(Fraction(left.constant_value()) / \ Fraction(right.constant_value())) return self.Div(left, right)
def test_conversion_of_fractions_in_z3(self): self.assertValid(Equals(Real(Fraction(1,9)), Div(Real(1), Real(9))), solver_name="msat") self.assertValid(Equals(Real(Fraction(1,9)), Div(Real(1), Real(9))), solver_name="z3")
def test_realtoint(self): b = Symbol('b', INT) check = Equals(RealToInt(Real(Fraction(3, 2))), Int(1)) check = And(check, Equals(RealToInt(Real(Fraction(-3, 2))), Int(-2))) check = And(check, Equals(RealToInt(Real(1)), Int(1))) check = And(check, Equals(RealToInt(ToReal(b)), b)) for sname in get_env().factory.all_solvers(logic=UFLIRA): self.assertValid(check, solver_name=sname)
def _division(self, left, right): """Utility function that builds a division""" mgr = self.env.formula_manager if left.is_constant() and right.is_constant(): return mgr.Real(Fraction(left.constant_value()) / \ Fraction(right.constant_value())) # for some reason pysmt does not like integer division if right.is_constant(types.INT): return mgr.create_node(node_type=op.DIV, args=(left, right)) return mgr.Div(left, right)
def test_real(self): """Create Real using different constant types.""" from fractions import Fraction as pyFraction from pysmt.constants import HAS_GMPY v1 = (1, 2) v2 = 0.5 v3 = pyFraction(1, 2) v4 = Fraction(1, 2) c1 = self.mgr.Real(v1) c2 = self.mgr.Real(v2) c3 = self.mgr.Real(v3) c4 = self.mgr.Real(v4) self.assertIs(c1, c2) self.assertIs(c2, c3) self.assertIs(c3, c4) if HAS_GMPY: from gmpy2 import mpq, mpz v5 = (mpz(1), mpz(2)) v6 = mpq(1, 2) c5 = self.mgr.Real(v5) c6 = self.mgr.Real(v6) self.assertIs(c4, c5) self.assertIs(c5, c6)
def test_is_methods(self): from fractions import Fraction as pyFraction self.assertFalse(is_pysmt_fraction(4)) self.assertTrue(is_pysmt_fraction(Fraction(4))) self.assertFalse(is_pysmt_integer(4.0)) self.assertTrue(is_pysmt_integer(Integer(4))) self.assertTrue(is_python_integer(int(2))) if PY2: self.assertTrue(is_python_integer(long(2))) if HAS_GMPY: from gmpy2 import mpz self.assertTrue(is_python_integer(mpz(1))) if HAS_GMPY: from gmpy2 import mpz, mpq self.assertTrue(is_python_rational(mpz(1))) self.assertTrue(is_python_rational(mpq(1))) if PY2: self.assertTrue(is_python_rational(long(1))) self.assertTrue(is_python_rational(pyFraction(5))) self.assertTrue(is_python_rational(3)) self.assertTrue(is_python_boolean(True)) self.assertTrue(is_python_boolean(False))
def test_pysmt_integer_from_integer(self): from fractions import Fraction as pyFraction self.assertEqual(Integer(4), pysmt_integer_from_integer(4)) self.assertEqual(Integer(4), pysmt_integer_from_integer(Integer(4))) self.assertEqual(Integer(4), pysmt_integer_from_integer(Fraction(4))) self.assertEqual(Integer(4), pysmt_integer_from_integer(pyFraction(4)))
def Real(self, value): """ Returns a Real-type constant of the given value. value can be: - A Fraction(n,d) - A tuple (n,d) - A long or int n - A float - (Optionally) a mpq or mpz object """ if value in self.real_constants: return self.real_constants[value] if is_pysmt_fraction(value): val = value elif type(value) == tuple: val = Fraction(value[0], value[1]) elif is_python_rational(value): val = pysmt_fraction_from_rational(value) else: raise PysmtTypeError("Invalid type in constant. The type was:" + \ str(type(value))) n = self.create_node(node_type=op.REAL_CONSTANT, args=tuple(), payload=val) self.real_constants[value] = n return n
def back(self, expr): res = None if expr.isConst(): if expr.getType().isBoolean(): v = expr.getConstBoolean() res = self.mgr.Bool(v) elif expr.getType().isInteger(): v = expr.getConstRational().toString() res = self.mgr.Int(int(v)) elif expr.getType().isReal(): v = expr.getConstRational().toString() res = self.mgr.Real(Fraction(v)) elif expr.getType().isBitVector(): bv = expr.getConstBitVector() v = bv.getValue().toString() width = bv.getSize() res = self.mgr.BV(int(v), width) elif expr.getType().isString(): v = expr.getConstString() res = self.mgr.String(v.toString()) elif expr.getType().isArray(): const_ = expr.getConstArrayStoreAll() array_type = self._cvc4_type_to_type(const_.getType()) base_value = self.back(const_.getExpr()) res = self.mgr.Array(array_type.index_type, base_value) else: raise PysmtTypeError("Unsupported constant type:", expr.getType().toString()) else: raise PysmtTypeError("Unsupported expression:", expr.toString()) return res
def test_constant(self): n1 = self.mgr.Real(Fraction(100, 10)) self.assertIsNotNone(n1) self.assertTrue(n1.is_constant()) self.assertTrue(n1.is_real_constant()) n2 = self.mgr.Real((100, 10)) self.assertEqual( n1, n2, "Generation of constant does not provide a consistent result.") n3 = self.mgr.Real(10) self.assertEqual( n1, n3, "Generation of constant does not provide a consistent result.") n4 = self.mgr.Real(10.0) self.assertEqual( n1, n4, "Generation of constant does not provide a consistent result.") nd = self.mgr.Real(Fraction(100, 1)) self.assertNotEqual(nd, n1) with self.assertRaises(PysmtTypeError): self.mgr.Real(True) nd = self.mgr.Int(10) self.assertIsNotNone(nd) self.assertTrue(nd.is_constant()) self.assertTrue(nd.is_int_constant()) # Memoization of constants a = self.mgr.Real(Fraction(1, 2)) b = self.mgr.Real((1, 2)) c = self.mgr.Real(1.0 / 2.0) self.assertEqual(a, b) self.assertEqual(b, c) # Constant's Type b = self.mgr.Bool(True) i = self.mgr.Int(1) r = self.mgr.Real(1) bv8 = self.mgr.BV(1, 8) self.assertEqual(i.constant_type(), INT) self.assertEqual(r.constant_type(), REAL) self.assertEqual(bv8.constant_type(), BV8) self.assertEqual(b.constant_type(), BOOL)
def get_value(self, item): self._assert_no_function_type(item) term = self.converter.convert(item) cvc4_res = self.cvc4.getValue(term) res = self.converter.back(cvc4_res) if self.environment.stc.get_type(item).is_real_type() and \ self.environment.stc.get_type(res).is_int_type(): res = self.environment.formula_manager.Real(Fraction(res.constant_value(), 1)) return res
def test_to_python_integer(self): res = long(4) if PY2 else int(4) self.assertEqual(res, to_python_integer(pysmt_integer_from_integer(4))) self.assertEqual( res, to_python_integer(pysmt_integer_from_integer(Integer(4)))) self.assertEqual( res, to_python_integer(pysmt_integer_from_integer(Fraction(4)))) self.assertEqual( res, to_python_integer(pysmt_integer_from_integer(pyFraction(4))))
def test_irrational(self): x = FreshSymbol(REAL) f = Equals(Times(x, x), Real(2)) with Solver(name="z3") as s: self.assertTrue(s.is_sat(f)) model = s.get_model() xval = model[x] self.assertTrue(xval.is_algebraic_constant()) approx = Fraction(-3109888511975, 2199023255552) self.assertEqual(xval.algebraic_approx_value(), approx)
def Div(self, left, right): """ Creates an expression of the form: left / right """ if right.is_constant(types.REAL): # If right is a constant we rewrite as left * 1/right inverse = Fraction(1) / right.constant_value() return self.Times(left, self.Real(inverse)) elif right.is_constant(types.INT): raise NotImplementedError # This is a non-linear expression return self.create_node(node_type=op.DIV, args=(left, right))
def algebraic_approx_value(self, precision=10): value = self.constant_value() approx = value.approx(precision) # MG: This is a workaround python 3 since Z3 mixes int and long. # The bug was fixed in master of Z3, but no official relase # has been done containing it. # In the most recent version of z3, this can be done with: # return approx.as_fraction() n = int(str(approx.numerator())) d = int(str(approx.denominator())) return Fraction(n, d)
def test_div_node(self): n = self.mgr.Div(self.real_expr, self.rconst) self.assertIsNotNone(n) n = self.mgr.Div(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.Div(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.Div(self.s, self.rconst) self.assertIsNotNone(n) inv = self.mgr.Real(Fraction(1) / self.rconst.constant_value()) self.assertEqual(n, self.mgr.Times(self.s, inv))
def test_pysmt_fraction_from_rational(self): self.assertEqual(Fraction(4, 5), pysmt_fraction_from_rational("4/5")) self.assertEqual(Fraction(4, 5), pysmt_fraction_from_rational(pyFraction(4, 5))) self.assertEqual(Fraction(4, 5), pysmt_fraction_from_rational(Fraction(4, 5))) self.assertEqual(Fraction(4), pysmt_fraction_from_rational(4)) self.assertEqual(Fraction(4), pysmt_fraction_from_rational(Integer(4)))
def Div(self, left, right): """ Creates an expression of the form: left / right """ if (right.is_constant(types.REAL, 0) or right.is_constant(types.INT, 0)) \ and self.env.enable_div_by_0: # Allow division by 0 byt warn the user # This can only happen in non-linear logics warnings.warn("Warning: Division by 0") elif right.is_constant(types.REAL): # If right is a constant we rewrite as left * 1/right inverse = Fraction(1) / right.constant_value() return self.Times(left, self.Real(inverse)) # This is a non-linear expression return self.create_node(node_type=op.DIV, args=(left, right))
def test_irrational(self): x = FreshSymbol(REAL) f = Equals(Times(x, x), Real(2)) with Solver(name="z3") as s: self.assertTrue(s.is_sat(f)) model = s.get_model() xval = model[x] self.assertTrue(xval.is_algebraic_constant()) # There are two solutions, that only differ by sign # we take the positive one x_approx_val = abs(xval.algebraic_approx_value()) approx = Fraction(3109888511975, 2199023255552) # We only get an approximation of the actual value. # We check that the error of the approximation is within # the precision (default is 10 digits) err = abs(x_approx_val - approx) self.assertTrue(err < 0.00000000001, err)
def back(self, expr): res = None if expr.isConst(): if expr.getType().isBoolean(): v = expr.getConstBoolean() res = self.mgr.Bool(v) elif expr.getType().isInteger(): v = expr.getConstRational().toString() res = self.mgr.Int(int(v)) elif expr.getType().isReal(): v = expr.getConstRational().toString() res = self.mgr.Real(Fraction(v)) elif expr.getType().isBitVector(): bv = expr.getConstBitVector() v = bv.getValue().toString() width = bv.getSize() res = self.mgr.BV(int(v), width) elif expr.getType().isString(): v = expr.getConstString() res = self.mgr.String(v.toString()) elif expr.getType().isArray(): # if no children, typical array declaration if not expr.getChildren(): const_ = expr.getConstArrayStoreAll() array_type = self._cvc4_type_to_type(const_.getType()) base_value = self.back(const_.getExpr()) res = self.mgr.Array(array_type.index_type, base_value) # if children, expecting index assignments of this form: # ARRAY(STRING OF STRING) : "" WITH ["a"] := "1", ["b"] := "2" # The children have been observed to be as follows for the above example: # child 0: ARRAY(STRING OF STRING) : "" WITH ["a"] := "1" # child 1: "b" # child 2: "2" else: assert len(expr.getChildren()) == 3 arr = self.back(expr.getChild(0)) ind = self.back(expr.getChild(1)) val = self.back(expr.getChild(2)) res = self.mgr.Store(arr, ind, val) else: raise PysmtTypeError("Unsupported constant type:", expr.getType().toString()) else: raise PysmtTypeError("Unsupported expression:", expr.toString()) return res
def atom(self, token, mgr): """ Given a token and a FormulaManager, returns the pysmt representation of the token """ res = self.cache.get(token) if res is None: if token.startswith("#"): # it is a BitVector value = None width = None if token[1] == "b": # binary width = len(token) - 2 value = int("0" + token[1:], 2) else: if token[1] != "x": raise PysmtSyntaxError("Invalid bit-vector constant " "'%s'" % token) width = (len(token) - 2) * 16 value = int("0" + token[1:], 16) res = mgr.BV(value, width) else: # it could be a number or a string try: frac = Fraction(token) if frac.denominator == 1: # We found an integer, depending on the logic this can be # an Int or a Real if self.logic is None or \ self.logic.theory.integer_arithmetic: if "." in token: res = mgr.Real(frac) else: res = mgr.Int(frac.numerator) else: res = mgr.Real(frac) else: res = mgr.Real(frac) except ValueError: # a string constant res = token self.cache.bind(token, res) return res
def get_value(self, item, model_completion=True): # self._assert_no_function_type(item) titem = self.get_term(item) ty = self.environment.stc.get_type(item) if ty.is_bool_type(): res = c_int32() status = yicespy.yices_get_bool_value(self.yices_model, titem, res) if (status != 0): res = yicespy.yices_formula_true_in_model(self.yices_model, titem) if res == -1: return self.mgr.Bool(bool(0)) self._check_error(status) return self.mgr.Bool(bool(res.value)) elif ty.is_int_type(): res = c_int32() status = yicespy.yices_get_int64_value(self.yices_model, titem, res) self._check_error(status) return self.mgr.Int(res.value) elif ty.is_real_type(): num = c_int32() den = c_int32() status = yicespy.yices_get_rational64_value(self.yices_model, titem, num, den) self._check_error(status) return self.mgr.Real(Fraction(num.value, den.value)) elif ty.is_bv_type(): res = yicespy.make_empty_int32_array(ty.width) status = yicespy.yices_get_bv_value(self.yices_model, titem, res) self._check_error(status) str_val = "".join(str(x.value) for x in reversed(res)) return self.mgr.BV("#b" + str_val) elif ty.is_enum_type(): res = c_int32() status = yicespy.yices_get_scalar_value(self.yices_model, titem, res) if (status != 0): return self.mgr.Enum(ty._domain[0], ty) self._check_error(status) assert(res.value >= 0) assert(res.value < len(ty._domain)) return self.mgr.Enum(ty._domain[res.value], ty) else: status, yices_res = yicespy.yices_get_value_as_term(self.yices_model, titem) self._check_error(status) return self.converter.back(yices_res, model=self.yices_model)
def get_value(self, item): self._assert_no_function_type(item) titem = self.converter.convert(item) ty = self.environment.stc.get_type(item) if ty.is_bool_type(): status, res = yicespy.yices_get_bool_value(self.model, titem) self._check_error(status) return self.mgr.Bool(bool(res)) elif ty.is_int_type(): res = yicespy.yices_get_integer_value(self.model, titem) return self.mgr.Int(res) elif ty.is_real_type(): status, val = yicespy.yices_get_rational_value(self.model, titem) self._check_error(status) return self.mgr.Real(Fraction(val)) elif ty.is_bv_type(): status, res = yicespy.yices_get_bv_value(self.model, titem, ty.width) self._check_error(status) str_val = "".join(str(x) for x in reversed(res)) return self.mgr.BV("#b" + str_val) else: raise NotImplementedError()
def test_pysmt_integer_from_integer(self): self.assertEqual(Integer(4), pysmt_integer_from_integer(4)) self.assertEqual(Integer(4), pysmt_integer_from_integer(Integer(4))) self.assertEqual(Integer(4), pysmt_integer_from_integer(Fraction(4))) self.assertEqual(Integer(4), pysmt_integer_from_integer(pyFraction(4)))
def real_constant(self, read): return Constant(self.mgr.Real(Fraction(read)))
def get_full_example_formulae(environment=None): """Return a list of Examples using the given environment.""" if environment is None: environment = get_env() with environment: x = Symbol("x", BOOL) y = Symbol("y", BOOL) p = Symbol("p", INT) q = Symbol("q", INT) r = Symbol("r", REAL) s = Symbol("s", REAL) aii = Symbol("aii", ARRAY_INT_INT) ari = Symbol("ari", ArrayType(REAL, INT)) arb = Symbol("arb", ArrayType(REAL, BV8)) abb = Symbol("abb", ArrayType(BV8, BV8)) nested_a = Symbol("a_arb_aii", ArrayType(ArrayType(REAL, BV8), ARRAY_INT_INT)) rf = Symbol("rf", FunctionType(REAL, [REAL, REAL])) rg = Symbol("rg", FunctionType(REAL, [REAL])) ih = Symbol("ih", FunctionType(INT, [REAL, INT])) ig = Symbol("ig", FunctionType(INT, [INT])) bf = Symbol("bf", FunctionType(BOOL, [BOOL])) bg = Symbol("bg", FunctionType(BOOL, [BOOL])) bv8 = Symbol("bv1", BV8) bv16 = Symbol("bv2", BV16) result = [ # Formula, is_valid, is_sat, is_qf Example(hr="(x & y)", expr=And(x, y), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BOOL), Example(hr="(x <-> y)", expr=Iff(x, y), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BOOL), Example(hr="((x | y) & (! (x | y)))", expr=And(Or(x, y), Not(Or(x, y))), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BOOL), Example(hr="(x & (! y))", expr=And(x, Not(y)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BOOL), Example(hr="(False -> True)", expr=Implies(FALSE(), TRUE()), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BOOL), # # LIA # Example(hr="((q < p) & (x -> y))", expr=And(GT(p, q), Implies(x, y)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_IDL), Example(hr="(((p + q) = 5) & (q < p))", expr=And(Equals(Plus(p, q), Int(5)), GT(p, q)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LIA), Example(hr="((q <= p) | (p <= q))", expr=Or(GE(p, q), LE(p, q)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_IDL), Example(hr="(! (p < (q * 2)))", expr=Not(LT(p, Times(q, Int(2)))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LIA), Example(hr="(p < (p - (5 - 2)))", expr=GT(Minus(p, Minus(Int(5), Int(2))), p), is_valid=False, is_sat=False, logic=pysmt.logics.QF_IDL), Example(hr="((x ? 7 : ((p + -1) * 3)) = q)", expr=Equals( Ite(x, Int(7), Times(Plus(p, Int(-1)), Int(3))), q), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LIA), Example(hr="(p < (q + 1))", expr=LT(p, Plus(q, Int(1))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LIA), # # LRA # Example(hr="((s < r) & (x -> y))", expr=And(GT(r, s), Implies(x, y)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_RDL), Example(hr="(((r + s) = 28/5) & (s < r))", expr=And(Equals(Plus(r, s), Real(Fraction("5.6"))), GT(r, s)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LRA), Example(hr="((s <= r) | (r <= s))", expr=Or(GE(r, s), LE(r, s)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_RDL), Example(hr="(! ((r * 2.0) < (s * 2.0)))", expr=Not(LT(Div(r, Real((1, 2))), Times(s, Real(2)))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LRA), Example(hr="(! (r < (r - (5.0 - 2.0))))", expr=Not(GT(Minus(r, Minus(Real(5), Real(2))), r)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_RDL), Example(hr="((x ? 7.0 : ((s + -1.0) * 3.0)) = r)", expr=Equals( Ite(x, Real(7), Times(Plus(s, Real(-1)), Real(3))), r), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LRA), # # EUF # Example(hr="(bf(x) <-> bg(x))", expr=Iff(Function(bf, (x, )), Function(bg, (x, ))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_UF), Example(hr="(rf(5.0, rg(r)) = 0.0)", expr=Equals(Function(rf, (Real(5), Function(rg, (r, )))), Real(0)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_UFLRA), Example(hr="((rg(r) = (5.0 + 2.0)) <-> (rg(r) = 7.0))", expr=Iff(Equals(Function(rg, [r]), Plus(Real(5), Real(2))), Equals(Function(rg, [r]), Real(7))), is_valid=True, is_sat=True, logic=pysmt.logics.QF_UFLRA), Example( hr="((r = (s + 1.0)) & (rg(s) = 5.0) & (rg((r - 1.0)) = 7.0))", expr=And([ Equals(r, Plus(s, Real(1))), Equals(Function(rg, [s]), Real(5)), Equals(Function(rg, [Minus(r, Real(1))]), Real(7)) ]), is_valid=False, is_sat=False, logic=pysmt.logics.QF_UFLRA), # # BV # Example(hr="((1_32 & 0_32) = 0_32)", expr=Equals(BVAnd(BVOne(32), BVZero(32)), BVZero(32)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((! 2_3) = 5_3)", expr=Equals(BVNot(BV("010")), BV("101")), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((7_3 xor 0_3) = 0_3)", expr=Equals(BVXor(BV("111"), BV("000")), BV("000")), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), Example(hr="((bv1::bv1) u< 0_16)", expr=BVULT(BVConcat(bv8, bv8), BVZero(16)), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), Example(hr="(1_32[0:7] = 1_8)", expr=Equals(BVExtract(BVOne(32), end=7), BVOne(8)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="(0_8 u< (((bv1 + 1_8) * 5_8) u/ 5_8))", expr=BVUGT( BVUDiv(BVMul(BVAdd(bv8, BVOne(8)), BV(5, width=8)), BV(5, width=8)), BVZero(8)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="(0_16 u<= bv2)", expr=BVUGE(bv16, BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="(0_16 s<= bv2)", expr=BVSGE(bv16, BVZero(16)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), Example( hr="((0_32 u< (5_32 u% 2_32)) & ((5_32 u% 2_32) u<= 1_32))", expr=And( BVUGT(BVURem(BV(5, width=32), BV(2, width=32)), BVZero(32)), BVULE(BVURem(BV(5, width=32), BV(2, width=32)), BVOne(32))), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((((1_32 + (- 1_32)) << 1_32) >> 1_32) = 1_32)", expr=Equals( BVLShr(BVLShl(BVAdd(BVOne(32), BVNeg(BVOne(32))), 1), 1), BVOne(32)), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), Example(hr="((1_32 - 1_32) = 0_32)", expr=Equals(BVSub(BVOne(32), BVOne(32)), BVZero(32)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # Rotations Example(hr="(((1_32 ROL 1) ROR 1) = 1_32)", expr=Equals(BVRor(BVRol(BVOne(32), 1), 1), BVOne(32)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # Extensions Example(hr="((0_5 ZEXT 11) = (0_1 SEXT 15))", expr=Equals(BVZExt(BVZero(5), 11), BVSExt(BVZero(1), 15)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((bv2 - bv2) = 0_16)", expr=Equals(BVSub(bv16, bv16), BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((bv2 - bv2)[0:7] = bv1)", expr=Equals(BVExtract(BVSub(bv16, bv16), 0, 7), bv8), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((bv2[0:7] bvcomp bv1) = 1_1)", expr=Equals(BVComp(BVExtract(bv16, 0, 7), bv8), BVOne(1)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((bv2 bvcomp bv2) = 0_1)", expr=Equals(BVComp(bv16, bv16), BVZero(1)), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), Example(hr="(bv2 s< bv2)", expr=BVSLT(bv16, bv16), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), Example(hr="(bv2 s< 0_16)", expr=BVSLT(bv16, BVZero(16)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((bv2 s< 0_16) | (0_16 s<= bv2))", expr=Or(BVSGT(BVZero(16), bv16), BVSGE(bv16, BVZero(16))), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="(bv2 u< bv2)", expr=BVULT(bv16, bv16), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), Example(hr="(bv2 u< 0_16)", expr=BVULT(bv16, BVZero(16)), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), Example(hr="((bv2 | 0_16) = bv2)", expr=Equals(BVOr(bv16, BVZero(16)), bv16), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((bv2 & 0_16) = 0_16)", expr=Equals(BVAnd(bv16, BVZero(16)), BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((0_16 s< bv2) & ((bv2 s/ 65535_16) s< 0_16))", expr=And(BVSLT(BVZero(16), bv16), BVSLT(BVSDiv(bv16, SBV(-1, 16)), BVZero(16))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((0_16 s< bv2) & ((bv2 s% 1_16) s< 0_16))", expr=And(BVSLT(BVZero(16), bv16), BVSLT(BVSRem(bv16, BVOne(16)), BVZero(16))), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), Example(hr="((bv2 u% 1_16) = 0_16)", expr=Equals(BVURem(bv16, BVOne(16)), BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((bv2 s% 1_16) = 0_16)", expr=Equals(BVSRem(bv16, BVOne(16)), BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((bv2 s% (- 1_16)) = 0_16)", expr=Equals(BVSRem(bv16, BVNeg(BVOne(16))), BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((bv2 a>> 0_16) = bv2)", expr=Equals(BVAShr(bv16, BVZero(16)), bv16), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((0_16 s<= bv2) & ((bv2 a>> 1_16) = (bv2 >> 1_16)))", expr=And( BVSLE(BVZero(16), bv16), Equals(BVAShr(bv16, BVOne(16)), BVLShr(bv16, BVOne(16)))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), # # Quantification # Example(hr="(forall y . (x -> y))", expr=ForAll([y], Implies(x, y)), is_valid=False, is_sat=True, logic=pysmt.logics.BOOL), Example(hr="(forall p, q . ((p + q) = 0))", expr=ForAll([p, q], Equals(Plus(p, q), Int(0))), is_valid=False, is_sat=False, logic=pysmt.logics.LIA), Example( hr="(forall r, s . (((0.0 < r) & (0.0 < s)) -> ((r - s) < r)))", expr=ForAll([r, s], Implies(And(GT(r, Real(0)), GT(s, Real(0))), (LT(Minus(r, s), r)))), is_valid=True, is_sat=True, logic=pysmt.logics.LRA), Example(hr="(exists x, y . (x -> y))", expr=Exists([x, y], Implies(x, y)), is_valid=True, is_sat=True, logic=pysmt.logics.BOOL), Example(hr="(exists p, q . ((p + q) = 0))", expr=Exists([p, q], Equals(Plus(p, q), Int(0))), is_valid=True, is_sat=True, logic=pysmt.logics.LIA), Example(hr="(exists r . (forall s . (r < (r - s))))", expr=Exists([r], ForAll([s], GT(Minus(r, s), r))), is_valid=False, is_sat=False, logic=pysmt.logics.LRA), Example(hr="(forall r . (exists s . (r < (r - s))))", expr=ForAll([r], Exists([s], GT(Minus(r, s), r))), is_valid=True, is_sat=True, logic=pysmt.logics.LRA), Example(hr="(x & (forall r . ((r + s) = 5.0)))", expr=And(x, ForAll([r], Equals(Plus(r, s), Real(5)))), is_valid=False, is_sat=False, logic=pysmt.logics.LRA), Example(hr="(exists x . ((x <-> (5.0 < s)) & (s < 3.0)))", expr=Exists([x], (And(Iff(x, GT(s, Real(5))), LT(s, Real(3))))), is_valid=False, is_sat=True, logic=pysmt.logics.LRA), # # UFLIRA # Example(hr="((p < ih(r, q)) & (x -> y))", expr=And(GT(Function(ih, (r, q)), p), Implies(x, y)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_UFLIRA), Example( hr= "(((p - 3) = q) -> ((p < ih(r, (q + 3))) | (ih(r, p) <= p)))", expr=Implies( Equals(Minus(p, Int(3)), q), Or(GT(Function(ih, (r, Plus(q, Int(3)))), p), LE(Function(ih, (r, p)), p))), is_valid=True, is_sat=True, logic=pysmt.logics.QF_UFLIRA), Example( hr= "(((ToReal((p - 3)) = r) & (ToReal(q) = r)) -> ((p < ih(ToReal((p - 3)), (q + 3))) | (ih(r, p) <= p)))", expr=Implies( And(Equals(ToReal(Minus(p, Int(3))), r), Equals(ToReal(q), r)), Or( GT( Function( ih, (ToReal(Minus(p, Int(3))), Plus(q, Int(3)))), p), LE(Function(ih, (r, p)), p))), is_valid=True, is_sat=True, logic=pysmt.logics.QF_UFLIRA), Example( hr= "(! (((ToReal((p - 3)) = r) & (ToReal(q) = r)) -> ((p < ih(ToReal((p - 3)), (q + 3))) | (ih(r, p) <= p))))", expr=Not( Implies( And(Equals(ToReal(Minus(p, Int(3))), r), Equals(ToReal(q), r)), Or( GT( Function(ih, (ToReal(Minus( p, Int(3))), Plus(q, Int(3)))), p), LE(Function(ih, (r, p)), p)))), is_valid=False, is_sat=False, logic=pysmt.logics.QF_UFLIRA), Example( hr= """("Did you know that any string works? #yolo" & "10" & "|#somesolverskeepthe||" & " ")""", expr=And(Symbol("Did you know that any string works? #yolo"), Symbol("10"), Symbol("|#somesolverskeepthe||"), Symbol(" ")), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BOOL), # # Arrays # Example(hr="((q = 0) -> (aii[0 := 0] = aii[0 := q]))", expr=Implies( Equals(q, Int(0)), Equals(Store(aii, Int(0), Int(0)), Store(aii, Int(0), q))), is_valid=True, is_sat=True, logic=pysmt.logics.QF_ALIA), Example(hr="(aii[0 := 0][0] = 0)", expr=Equals(Select(Store(aii, Int(0), Int(0)), Int(0)), Int(0)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_ALIA), Example(hr="((Array{Int, Int}(0)[1 := 1] = aii) & (aii[1] = 0))", expr=And(Equals(Array(INT, Int(0), {Int(1): Int(1)}), aii), Equals(Select(aii, Int(1)), Int(0))), is_valid=False, is_sat=False, logic=pysmt.logics.get_logic_by_name("QF_ALIA*")), Example(hr="((Array{Int, Int}(0)[1 := 3] = aii) & (aii[1] = 3))", expr=And(Equals(Array(INT, Int(0), {Int(1): Int(3)}), aii), Equals(Select(aii, Int(1)), Int(3))), is_valid=False, is_sat=True, logic=pysmt.logics.get_logic_by_name("QF_ALIA*")), Example(hr="((Array{Real, Int}(10) = ari) & (ari[6/5] = 0))", expr=And(Equals(Array(REAL, Int(10)), ari), Equals(Select(ari, Real((6, 5))), Int(0))), is_valid=False, is_sat=False, logic=pysmt.logics.get_logic_by_name("QF_AUFBVLIRA*")), Example( hr= "((Array{Real, Int}(0)[1.0 := 10][2.0 := 20][3.0 := 30][4.0 := 40] = ari) & (! ((ari[0.0] = 0) & (ari[1.0] = 10) & (ari[2.0] = 20) & (ari[3.0] = 30) & (ari[4.0] = 40))))", expr=And( Equals( Array( REAL, Int(0), { Real(1): Int(10), Real(2): Int(20), Real(3): Int(30), Real(4): Int(40) }), ari), Not( And(Equals(Select(ari, Real(0)), Int(0)), Equals(Select(ari, Real(1)), Int(10)), Equals(Select(ari, Real(2)), Int(20)), Equals(Select(ari, Real(3)), Int(30)), Equals(Select(ari, Real(4)), Int(40))))), is_valid=False, is_sat=False, logic=pysmt.logics.get_logic_by_name("QF_AUFBVLIRA*")), Example( hr= "((Array{Real, Int}(0)[1.0 := 10][2.0 := 20][3.0 := 30][4.0 := 40][5.0 := 50] = ari) & (! ((ari[0.0] = 0) & (ari[1.0] = 10) & (ari[2.0] = 20) & (ari[3.0] = 30) & (ari[4.0] = 40) & (ari[5.0] = 50))))", expr=And( Equals( Array( REAL, Int(0), { Real(1): Int(10), Real(2): Int(20), Real(3): Int(30), Real(4): Int(40), Real(5): Int(50) }), ari), Not( And(Equals(Select(ari, Real(0)), Int(0)), Equals(Select(ari, Real(1)), Int(10)), Equals(Select(ari, Real(2)), Int(20)), Equals(Select(ari, Real(3)), Int(30)), Equals(Select(ari, Real(4)), Int(40)), Equals(Select(ari, Real(5)), Int(50))))), is_valid=False, is_sat=False, logic=pysmt.logics.get_logic_by_name("QF_AUFBVLIRA*")), Example( hr= "((a_arb_aii = Array{Array{Real, BV{8}}, Array{Int, Int}}(Array{Int, Int}(7))) -> (a_arb_aii[arb][42] = 7))", expr=Implies( Equals(nested_a, Array(ArrayType(REAL, BV8), Array(INT, Int(7)))), Equals(Select(Select(nested_a, arb), Int(42)), Int(7))), is_valid=True, is_sat=True, logic=pysmt.logics.get_logic_by_name("QF_AUFBVLIRA*")), Example(hr="(abb[bv1 := y_][bv1 := z_] = abb[bv1 := z_])", expr=Equals( Store(Store(abb, bv8, Symbol("y_", BV8)), bv8, Symbol("z_", BV8)), Store(abb, bv8, Symbol("z_", BV8))), is_valid=True, is_sat=True, logic=pysmt.logics.QF_ABV), Example(hr="((r / s) = (r * s))", expr=Equals(Div(r, s), Times(r, s)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_NRA), Example(hr="(2.0 = (r * r))", expr=Equals(Real(2), Times(r, r)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_NRA), Example(hr="((p ^ 2) = 0)", expr=Equals(Pow(p, Int(2)), Int(0)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_NIA), Example(hr="((r ^ 2.0) = 0.0)", expr=Equals(Pow(r, Real(2)), Real(0)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_NRA), Example(hr="((r * r * r) = 25.0)", expr=Equals(Times(r, r, r), Real(25)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_NRA), Example(hr="((5.0 * r * 5.0) = 25.0)", expr=Equals(Times(Real(5), r, Real(5)), Real(25)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LRA), Example(hr="((p * p * p) = 25)", expr=Equals(Times(p, p, p), Int(25)), is_valid=False, is_sat=False, logic=pysmt.logics.QF_NIA), Example(hr="((5 * p * 5) = 25)", expr=Equals(Times(Int(5), p, Int(5)), Int(25)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LIA), Example(hr="(((1 - 1) * p * 1) = 0)", expr=Equals(Times(Minus(Int(1), Int(1)), p, Int(1)), Int(0)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_LIA), # Huge Fractions: Example( hr= "((r * 1606938044258990275541962092341162602522202993782792835301376/7) = -20480000000000000000000000.0)", expr=Equals(Times(r, Real(Fraction(2**200, 7))), Real(-200**11)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LRA), Example(hr="(((r + 5.0 + s) * (s + 2.0 + r)) = 0.0)", expr=Equals( Times(Plus(r, Real(5), s), Plus(s, Real(2), r)), Real(0)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_NRA), Example( hr= "(((p + 5 + q) * (p - (q - 5))) = ((p * p) + (10 * p) + 25 + (-1 * q * q)))", expr=Equals( Times(Plus(p, Int(5), q), Minus(p, Minus(q, Int(5)))), Plus(Times(p, p), Times(Int(10), p), Int(25), Times(Int(-1), q, q))), is_valid=True, is_sat=True, logic=pysmt.logics.QF_NIA), ] return result
def _back_single_term(self, expr, args, model=None): assert z3.is_expr(expr) if z3.is_quantifier(expr): raise NotImplementedError( "Quantified back conversion is currently not supported") assert not len(args) > 2 or \ (z3.is_and(expr) or z3.is_or(expr) or z3.is_add(expr) or z3.is_mul(expr) or (len(args) == 3 and (z3.is_ite(expr) or z3.is_array_store(expr)))),\ "Unexpected n-ary term: %s" % expr res = None try: decl = z3.Z3_get_app_decl(expr.ctx_ref(), expr.as_ast()) kind = z3.Z3_get_decl_kind(expr.ctx.ref(), decl) # Try to get the back-conversion function for the given Kind fun = self._back_fun[kind] return fun(args, expr) except KeyError as ex: pass if z3.is_const(expr): # Const or Symbol if z3.is_rational_value(expr): n = expr.numerator_as_long() d = expr.denominator_as_long() f = Fraction(n, d) return self.mgr.Real(f) elif z3.is_int_value(expr): n = expr.as_long() return self.mgr.Int(n) elif z3.is_bv_value(expr): n = expr.as_long() w = expr.size() return self.mgr.BV(n, w) elif z3.is_as_array(expr): if model is None: raise NotImplementedError("As-array expressions cannot be" \ " handled as they are not " \ "self-contained") else: interp_decl = z3.get_as_array_func(expr) interp = model[interp_decl] default = self.back(interp.else_value(), model=model) assign = {} for i in xrange(interp.num_entries()): e = interp.entry(i) assert e.num_args() == 1 idx = self.back(e.arg_value(0), model=model) val = self.back(e.value(), model=model) assign[idx] = val arr_type = self._z3_to_type(expr.sort()) return self.mgr.Array(arr_type.index_type, default, assign) elif z3.is_algebraic_value(expr): # Algebraic value return self.mgr._Algebraic(Numeral(expr)) else: # it must be a symbol try: return self.mgr.get_symbol(str(expr)) except UndefinedSymbolError: import warnings symb_type = self._z3_to_type(expr.sort()) warnings.warn("Defining new symbol: %s" % str(expr)) return self.mgr.FreshSymbol(symb_type, template="__z3_%d") elif z3.is_function(expr): # This needs to be after we try to convert regular Symbols fsymbol = self.mgr.get_symbol(expr.decl().name()) return self.mgr.Function(fsymbol, args) # If we reach this point, we did not manage to translate the expression raise ConvertExpressionError(message=("Unsupported expression: %s" % (str(expr))), expression=expr)
def test_truncate(self): check = Equals(Truncate(Real(Fraction(3, 2))), Int(1)) check = And(check, Equals(Truncate(Real(Fraction(-3, 2))), Int(-1))) check = And(check, Equals(Truncate(Real(1)), Int(1))) for sname in get_env().factory.all_solvers(logic=UFLIRA): self.assertValid(check, solver_name=sname)