def test_get_value_of_function(self): """get_value on a function should raise an exception.""" h = Symbol("h", FunctionType(REAL, [REAL, REAL])) h_0_0 = Function(h, (Real(0), Real(1))) f = GT(h_0_0, Real(0)) for sname in get_env().factory.all_solvers(logic=QF_UFLIRA): with Solver(name=sname) as solver: solver.add_assertion(f) res = solver.solve() self.assertTrue(res) with self.assertRaises(PysmtTypeError): solver.get_value(h) self.assertIsNotNone(solver.get_value(h_0_0))
def test_substitution_on_functions(self): i, r = FreshSymbol(INT), FreshSymbol(REAL) f = Symbol("f", FunctionType(BOOL, [INT, REAL])) phi = Function(f, [Plus(i, Int(1)), Minus(r, Real(2))]) phi_sub = substitute(phi, {i: Int(0)}).simplify() self.assertEqual(phi_sub, Function(f, [Int(1), Minus(r, Real(2))])) phi_sub = substitute(phi, {r: Real(0)}).simplify() self.assertEqual(phi_sub, Function(f, [Plus(i, Int(1)), Real(-2)])) phi_sub = substitute(phi, {r: Real(0), i: Int(0)}).simplify() self.assertEqual(phi_sub, Function(f, [Int(1), Real(-2)]))
def test_basic_types(self): self.assertTrue(BOOL.is_bool_type()) self.assertFalse(BOOL.is_function_type()) self.assertTrue(REAL.is_real_type()) self.assertFalse(REAL.is_bool_type()) self.assertTrue(INT.is_int_type()) self.assertFalse(INT.is_real_type()) ftype = FunctionType(REAL, [REAL, REAL]) self.assertTrue(ftype.is_function_type()) self.assertFalse(ftype.is_int_type()) self.assertNotEqual(BOOL, INT) self.assertEqual(REAL, REAL) AAIBR = ArrayType(ArrayType(INT, BOOL), REAL) self.assertEqual(str(AAIBR), "Array{Array{Int, Bool}, Real}") bt1 = BVType(4) bt2 = BVType(4) self.assertEqual(bt1, bt2) self.assertEqual(bt1.width, 4)
def _get_basic_type(self, type_name, params): """ Returns the pysmt type representation for the given type name. If params is specified, the type is interpreted as a function type. """ if len(params) == 0: if type_name == "Bool": return BOOL if type_name == "Int": return INT elif type_name == "Real": return REAL else: rt = self._get_basic_type(type_name, []) pt = [self._get_basic_type(par, []) for par in params] return FunctionType(rt, pt)
def test_quantified_euf(self): ftype1 = FunctionType(REAL, [REAL, REAL]) plus = Symbol("plus", ftype1) x = Symbol('x', REAL) y = Symbol('y', REAL) z = Symbol('z', REAL) axiom = ForAll([x, y], Equals(Function(plus, (x, y)), Plus(x, y))) test1 = Equals(Plus(z, Real(4)), Function(plus, (Real(4), z))) test2 = Equals(Function(plus, (Real(5), Real(4))), Real(9)) check = Implies(axiom, And(test1, test2)) self.assertValid(check, logic=UFLRA, msg="Formula was expected to be valid")
def _get_basic_type(self, type_name, params=None): """ Returns the pysmt type representation for the given type name. If params is specified, the type is interpreted as a function type. """ if params is None or len(params) == 0: if type_name == "Bool": return BOOL elif type_name == "Int": return INT elif type_name == "Real": return REAL elif type_name.startswith("BV"): size = int(type_name[2:]) return BVType(size) else: rt = self._get_basic_type(type_name) pt = [self._get_basic_type(par) for par in params] return FunctionType(rt, pt)
def setUp(self): super(TestFormulaManager, self).setUp() self.env = get_env() self.mgr = self.env.formula_manager self.x = self.mgr.Symbol("x") self.y = self.mgr.Symbol("y") self.p = self.mgr.Symbol("p", INT) self.q = self.mgr.Symbol("q", INT) self.r = self.mgr.Symbol("r", REAL) self.s = self.mgr.Symbol("s", REAL) self.rconst = self.mgr.Real(10) self.iconst = self.mgr.Int(10) self.ftype = FunctionType(REAL, [REAL, REAL]) self.f = self.mgr.Symbol("f", self.ftype) self.real_expr = self.mgr.Plus(self.s, self.r)
class TestFormulaManager(TestCase): def setUp(self): super(TestFormulaManager, self).setUp() self.env = get_env() self.mgr = self.env.formula_manager self.x = self.mgr.Symbol("x") self.y = self.mgr.Symbol("y") self.p = self.mgr.Symbol("p", INT) self.q = self.mgr.Symbol("q", INT) self.r = self.mgr.Symbol("r", REAL) self.s = self.mgr.Symbol("s", REAL) self.rconst = self.mgr.Real(10) self.iconst = self.mgr.Int(10) self.ftype = FunctionType(REAL, [REAL, REAL]) self.f = self.mgr.Symbol("f", self.ftype) self.real_expr = self.mgr.Plus(self.s, self.r) def test_new_fresh_symbol(self): fv1 = self.mgr.new_fresh_symbol(BOOL) self.assertIsNotNone(fv1, "New symbol was not created.") fv2 = self.mgr.new_fresh_symbol(BOOL) self.assertNotEqual(fv1, fv2, "Fresh symbol is not new.") fv3 = self.mgr.new_fresh_symbol(BOOL, "abc_%d") self.assertEqual(fv3.symbol_name()[:3], "abc", "Fresh variable doesn't have the desired prefix") def test_get_symbol(self): a = self.mgr.get_symbol("a") self.assertIsNone(a, "Symbol returned from an empty symboltable") self.mgr.get_or_create_symbol("a", BOOL) a = self.mgr.get_symbol("a") self.assertIsNotNone(a, "Symbol was not found in symbol table") def test_get_or_create_symbol(self): a = self.mgr.get_or_create_symbol("a", REAL) self.assertIsNotNone(a, "Symbol was not created") a2 = self.mgr.get_or_create_symbol("a", REAL) self.assertEqual(a, a2, "Symbol was not memoized") with self.assertRaises(TypeError): self.mgr.get_or_create_symbol("a", BOOL) def test_symbol(self): a1 = self.mgr.Symbol("a", BOOL) self.assertIsNotNone(a1, "Symbol was not created.") a2 = self.mgr.Symbol("a", BOOL) self.assertEqual(a1, a2, "Symbol is not memoized") c = self.mgr.Symbol("c") self.assertEqual(c.symbol_type(), BOOL, "Default Symbol Type is not BOOL") def test_and_node(self): n = self.mgr.And(self.x, self.y) self.assertIsNotNone(n) self.assertTrue(n.is_and()) self.assertEqual(n.get_free_variables(), set([self.x, self.y])) m = self.mgr.And([self.x, self.y]) self.assertEqual(m, n, "And(1,2) != And([1,2]") args = m.args() self.assertTrue(self.x in args and self.y in args) self.assertTrue(len(args) == 2) zero = self.mgr.And() self.assertEqual(zero, self.mgr.TRUE()) one = self.mgr.And(self.x) self.assertEqual(one, self.x) def test_or_node(self): n = self.mgr.Or(self.x, self.y) self.assertIsNotNone(n) self.assertTrue(n.is_or()) self.assertEqual(n.get_free_variables(), set([self.x, self.y])) m = self.mgr.Or([self.x, self.y]) self.assertEqual(m, n, "Or(1,2) != Or([1,2]") args = m.args() self.assertIn(self.x, args) self.assertIn(self.y, args) self.assertEqual(len(args), 2) zero = self.mgr.Or() self.assertEqual(zero, self.mgr.FALSE()) one = self.mgr.Or(self.x) self.assertEqual(one, self.x) def test_not_node(self): n = self.mgr.Not(self.x) self.assertIsNotNone(n) self.assertTrue(n.is_not()) self.assertEqual(n.get_free_variables(), set([self.x])) args = n.args() self.assertIn(self.x, args) self.assertEqual(len(args), 1) self.assertEqual(self.mgr.Not(n), self.x) def test_implies_node(self): n = self.mgr.Implies(self.x, self.y) self.assertIsNotNone(n) self.assertTrue(n.is_implies()) self.assertEqual(n.get_free_variables(), set([self.x, self.y])) args = n.args() self.assertEqual(self.x, args[0]) self.assertEqual(self.y, args[1]) self.assertEqual(len(args), 2) def test_iff_node(self): n = self.mgr.Iff(self.x, self.y) self.assertIsNotNone(n) self.assertTrue(n.is_iff()) self.assertEqual(n.get_free_variables(), set([self.x, self.y])) args = n.args() self.assertIn(self.x, args) self.assertIn(self.y, args) self.assertEqual(len(args), 2) def test_ge_node_type(self): with self.assertRaises(TypeError): self.mgr.GE(self.x, self.r) with self.assertRaises(TypeError): self.mgr.GE(self.r, self.x) with self.assertRaises(TypeError): self.mgr.GE(self.p, self.r) def test_ge_node(self): n = self.mgr.GE(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.GE(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.GE(self.rconst, self.s) self.assertIsNotNone(n) n = self.mgr.GE(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.GE(self.r, self.s) self.assertIsNotNone(n) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) n = self.mgr.GE(self.p, self.q) self.assertIsNotNone(n) def test_minus_node(self): n = self.mgr.Minus(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.Minus(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.Minus(self.rconst, self.s) self.assertIsNotNone(n) n = self.mgr.Minus(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.Minus(self.r, self.s) self.assertIsNotNone(n) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) n = self.mgr.Minus(self.p, self.q) self.assertIsNotNone(n) self.assertTrue(n.is_minus()) self.assertEqual(n.get_free_variables(), set([self.p, self.q])) with self.assertRaises(TypeError): n = self.mgr.Minus(self.r, self.q) def test_times_node(self): n = self.mgr.Times(self.real_expr, self.rconst) self.assertIsNotNone(n) n = self.mgr.Times(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.Times(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.Times(self.rconst, self.s) self.assertIsNotNone(n) args = n.args() self.assertIn(self.rconst, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) n = self.mgr.Times(self.r, self.s) self.assertIsNotNone(n) self.assertTrue(n.is_times()) self.assertEqual(n.get_free_variables(), set([self.r, self.s])) n = self.mgr.Times(self.iconst, self.q) self.assertIsNotNone(n) def test_div_non_linear(self): with self.assertRaises(NonLinearError): self.mgr.Div(self.r, self.s) with self.assertRaises(NonLinearError): self.mgr.Div(self.rconst, self.s) 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((1, self.rconst.constant_value())) self.assertEqual(n, self.mgr.Times(self.s, inv)) def test_equals(self): n = self.mgr.Equals(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.Equals(self.r, self.s) self.assertIsNotNone(n) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) n = self.mgr.Equals(self.p, self.q) self.assertIsNotNone(n) self.assertTrue(n.is_equals()) self.assertEqual(n.get_free_variables(), set([self.p, self.q])) with self.assertRaises(TypeError): n = self.mgr.Equals(self.p, self.r) def test_gt_node_type(self): with self.assertRaises(TypeError): self.mgr.GT(self.x, self.r) with self.assertRaises(TypeError): self.mgr.GT(self.r, self.x) with self.assertRaises(TypeError): self.mgr.GT(self.r, self.p) def test_gt_node(self): n = self.mgr.GT(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.GT(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.GT(self.rconst, self.s) self.assertIsNotNone(n) n = self.mgr.GT(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.GT(self.r, self.s) self.assertIsNotNone(n) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) n = self.mgr.GT(self.p, self.q) self.assertIsNotNone(n) def test_le_node_type(self): with self.assertRaises(TypeError): self.mgr.LE(self.x, self.r) with self.assertRaises(TypeError): self.mgr.LE(self.r, self.x) def test_le_node(self): n = self.mgr.LE(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.LE(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.LE(self.rconst, self.s) self.assertIsNotNone(n) n = self.mgr.LE(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.LE(self.r, self.s) self.assertIsNotNone(n) self.assertTrue(n.is_le()) self.assertEqual(n.get_free_variables(), set([self.r, self.s])) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) def test_lt_node_type(self): with self.assertRaises(TypeError): self.mgr.LT(self.x, self.r) with self.assertRaises(TypeError): self.mgr.LT(self.r, self.x) def test_lt_node(self): n = self.mgr.LT(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.LT(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.LT(self.rconst, self.s) self.assertIsNotNone(n) n = self.mgr.LT(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.LT(self.r, self.s) self.assertIsNotNone(n) self.assertTrue(n.is_lt()) self.assertEqual(n.get_free_variables(), set([self.r, self.s])) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) def test_ite(self): n = self.mgr.Ite(self.x, self.y, self.x) self.assertIsNotNone(n) args = n.args() self.assertIn(self.x, args) self.assertIn(self.y, args) self.assertEqual(len(args), 3) n = self.mgr.Ite(self.x, self.s, self.r) self.assertIsNotNone(n) n = self.mgr.Ite(self.x, self.p, self.q) self.assertIsNotNone(n) self.assertTrue(n.is_ite()) self.assertEqual(n.get_free_variables(), set([self.x, self.p, self.q])) with self.assertRaises(TypeError): self.mgr.Ite(self.x, self.p, self.r) def test_function(self): n = self.mgr.Function(self.f, [self.r, self.s]) self.assertIsNotNone(n) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) self.assertTrue(n.is_function_application()) self.assertEqual(n.get_free_variables(), set([self.f, self.r, self.s])) 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(TypeError): self.mgr.Real(True) nd = self.mgr.Int(10) self.assertIsNotNone(nd) self.assertTrue(nd.is_constant()) self.assertTrue(nd.is_int_constant()) def test_bconstant(self): n = self.mgr.Bool(True) m = self.mgr.Bool(False) self.assertIsNotNone(n) self.assertIsNotNone(m) self.assertNotEqual(n, m) self.assertTrue(n.is_constant()) self.assertTrue(n.is_bool_constant()) with self.assertRaises(TypeError): self.mgr.Bool(42) def test_plus_node(self): with self.assertRaises(TypeError): self.mgr.Plus([self.x, self.r]) with self.assertRaises(TypeError): self.mgr.Plus([self.p, self.r]) with self.assertRaises(TypeError): self.mgr.Plus() n1 = self.mgr.Plus([self.r, self.s]) n2 = self.mgr.Plus(self.r, self.s) self.assertIsNotNone(n1) self.assertIsNotNone(n2) self.assertEqual(n1, n2, "Constructed Plus expression do not match") self.assertTrue(n1.is_plus()) self.assertEqual(set([self.r, self.s]), n1.get_free_variables()) one = self.mgr.Plus([self.p]) self.assertEqual(one, self.p) def test_exactly_one(self): symbols = [ self.mgr.Symbol("s%d"%i, BOOL) for i in range(5) ] c = self.mgr.ExactlyOne(symbols) self.assertTrue(len(c.args()) > 1) t = self.mgr.Bool(True) c = c.substitute({symbols[0]: t, symbols[1]: t}).simplify() self.assertEqual(c, self.mgr.Bool(False), "ExactlyOne should not allow 2 symbols to be True") @skipIfNoSolverForLogic(QF_BOOL) def test_exactly_one_is_sat(self): symbols = [ self.mgr.Symbol("s%d"%i, BOOL) for i in range(5) ] c = self.mgr.ExactlyOne(symbols) all_zero = self.mgr.And([self.mgr.Iff(s, self.mgr.Bool(False)) for s in symbols]) test_zero = self.mgr.And(c, all_zero) self.assertFalse(is_sat(test_zero, logic=QF_BOOL), "ExactlyOne should not allow all symbols to be False") def test_at_most_one(self): symbols = [ self.mgr.Symbol("s%d"%i, BOOL) for i in range(5) ] c = self.mgr.AtMostOne(symbols) self.assertTrue(len(c.args()) > 1) t = self.mgr.Bool(True) c = c.substitute({symbols[0]: t, symbols[1]: t}).simplify() self.assertEqual(c, self.mgr.Bool(False), "AtMostOne should not allow two symbols to be True") def test_xor(self): xor1 = self.mgr.Xor(self.x, self.y) self.assertIsNotNone(xor1) with self.assertRaises(TypeError): self.mgr.Xor(self.p, self.q) xor_false = self.mgr.Xor(self.mgr.TRUE(), self.mgr.TRUE()).simplify() self.assertEqual(xor_false, self.mgr.FALSE(), "Xor should be False if both arguments are True") xor_true = self.mgr.Xor(self.mgr.TRUE(), self.mgr.FALSE()).simplify() self.assertEqual(xor_true, self.mgr.TRUE(), "Xor should be True if both arguments are False") def test_all_different(self): many = 5 symbols = [self.mgr.Symbol("s%d"%i, INT) for i in range(many) ] f = self.mgr.AllDifferent(symbols) one = self.mgr.Int(1) for i in xrange(many): for j in xrange(many): if i != j: c = f.substitute({symbols[i]: one, symbols[j]: one}).simplify() self.assertEqual(c, self.mgr.Bool(False), "AllDifferent should not allow 2 symbols "\ "to be 1") c = f.substitute({symbols[i]: self.mgr.Int(i) for i in xrange(many)}) self.assertEqual(c.simplify(), self.mgr.Bool(True), "AllDifferent should be tautological for a set " \ "of different values") def test_min(self): min1 = self.mgr.Min(self.p, Plus(self.q, self.mgr.Int(1))) self.assertIsNotNone(min1) with self.assertRaises(TypeError): self.mgr.Min(self.p, self.r) min_int = self.mgr.Min(self.mgr.Int(1), self.mgr.Int(2), self.mgr.Int(3)) self.assertEqual(min_int.simplify(), self.mgr.Int(1), "The minimum of 1, 2 and 3 should be 1") min_real = self.mgr.Min(self.mgr.Real(1), self.mgr.Real(2), self.mgr.Real(3)) self.assertEqual(min_real.simplify(), self.mgr.Real(1), "The minimum of 1.0, 2.0 and 3.0 should be 1.0") def test_max(self): max1 = self.mgr.Max(self.p, Plus(self.q, self.mgr.Int(1))) self.assertIsNotNone(max1) with self.assertRaises(TypeError): self.mgr.Max(self.p, self.r) max_int = self.mgr.Max(self.mgr.Int(1), self.mgr.Int(2), self.mgr.Int(3)) self.assertEqual(max_int.simplify(), self.mgr.Int(3), "The maximum of 1, 2 and 3 should be 3") max_real = self.mgr.Max(self.mgr.Real(1), self.mgr.Real(2), self.mgr.Real(3)) self.assertEqual(max_real.simplify(), self.mgr.Real(3), "The maximum of 1.0, 2.0 and 3.0 should be 3.0") def test_pickling(self): import pickle src_env = Environment() dst_env = Environment() src_mgr = src_env.formula_manager dst_mgr = dst_env.formula_manager a = src_mgr.Symbol("A") b = src_mgr.Symbol("B") f = src_mgr.And(a, src_mgr.Not(b)) self.assertEqual(str(f), "(A & (! B))", str(f)) serialized = pickle.dumps(f) f_new = pickle.loads(serialized) f_new = dst_mgr.normalize(f) args = f_new.args() self.assertEqual(str(args[0]), "A", "Expecting symbol A, " + "symbol %s found instead" % str(args[0])) a = dst_mgr.Symbol("A") b = dst_mgr.Symbol("B") g = dst_mgr.And(a, dst_mgr.Not(b)) # Contextualized formula is memoized self.assertEqual(f_new, g, "%s != %s" % (id(f_new), id(g))) # But it differs from the one in the other formula manager self.assertNotEqual(f_new, f) # Normalizing a formula in the same manager should not # be a problem f_new = src_mgr.normalize(f) self.assertEqual(f_new, f, "%s != %s" %(id(a),id(b))) def test_infix(self): x, y, p = self.x, self.y, self.p with self.assertRaises(Exception): x.Implies(y) get_env().enable_infix_notation = True self.assertEqual(Implies(x,y), x.Implies(y)) self.assertEqual(p + p, Plus(p,p)) self.assertEqual(p > p, GT(p,p)) get_env().enable_infix_notation = False def test_infix_extended(self): p, r, x, y = self.p, self.r, self.x, self.y get_env().enable_infix_notation = True self.assertEqual(Plus(p, Int(1)), p + 1) self.assertEqual(Plus(r, Real(1)), r + 1) self.assertEqual(Times(r, Real(1)), r * 1) self.assertEqual(Minus(p, Int(1)), p - 1) self.assertEqual(Minus(r, Real(1)), r - 1) self.assertEqual(Times(r, Real(1)), r * 1) self.assertEqual(Plus(r, Real(1.5)), r + 1.5) self.assertEqual(Minus(r, Real(1.5)), r - 1.5) self.assertEqual(Times(r, Real(1.5)), r * 1.5) self.assertEqual(Plus(r, Real(1.5)), 1.5 + r) self.assertEqual(Times(r, Real(1.5)), 1.5 * r) with self.assertRaises(TypeError): foo = p + 1.5 self.assertEqual(Not(x), ~x) self.assertEqual(Times(r, Real(-1)), -r) self.assertEqual(Times(p, Int(-1)), -p) self.assertEqual(Xor(x, y), x ^ y) self.assertEqual(And(x, y), x & y) self.assertEqual(Or(x, y), x | y) self.assertEqual(Or(x, TRUE()), x | True) self.assertEqual(Or(x, TRUE()), True | x) self.assertEqual(And(x, TRUE()), x & True) self.assertEqual(And(x, TRUE()), True & x) get_env().enable_infix_notation = False def test_toReal(self): f = self.mgr.Equals(self.rconst, self.mgr.ToReal(self.p)) self.assertIsNotNone(f) with self.assertRaises(TypeError): self.mgr.ToReal(self.x) f1 = self.mgr.ToReal(self.p) f2 = self.mgr.ToReal(f1) self.assertEqual(f1, f2) self.assertTrue(f1.is_toreal()) self.assertEqual(set([self.p]), f1.get_free_variables()) f3 = self.mgr.Equals(self.iconst, self.p) with self.assertRaises(TypeError): self.mgr.ToReal(f3) f4 = self.mgr.Plus(self.rconst, self.r) f5 = self.mgr.ToReal(f4) self.assertEqual(f5, f4) def test_equals_or_iff(self): eq_1 = self.mgr.EqualsOrIff(self.p, self.q) eq_2 = self.mgr.Equals(self.p, self.q) self.assertEqual(eq_1, eq_2) iff_1 = self.mgr.EqualsOrIff(self.x, self.y) iff_2 = self.mgr.Iff(self.x, self.y) self.assertEqual(iff_1, iff_2) def test_is_term(self): and_x_x = self.mgr.And(self.x, self.x) apply_f = self.mgr.Function(self.f, [self.r, self.s]) self.assertTrue(self.x.is_term()) self.assertTrue(and_x_x.is_term()) self.assertFalse(self.f.is_term()) self.assertTrue(apply_f.is_term()) def test_formula_in_formula_manager(self): x = self.mgr.FreshSymbol() and_x_x = self.mgr.And(x, x) new_mgr = FormulaManager(get_env()) y = new_mgr.FreshSymbol() and_y_y = new_mgr.And(y, y) self.assertTrue(x in self.mgr) self.assertFalse(y in self.mgr) self.assertTrue(and_x_x in self.mgr) self.assertFalse(and_y_y in self.mgr) def test_typing(self): self.assertTrue(BOOL.is_bool_type()) self.assertFalse(BOOL.is_function_type()) self.assertTrue(REAL.is_real_type()) self.assertFalse(REAL.is_bool_type()) self.assertTrue(INT.is_int_type()) self.assertFalse(INT.is_real_type()) self.assertTrue(self.ftype.is_function_type()) self.assertFalse(self.ftype.is_int_type())
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
class TestFormulaManager(TestCase): def setUp(self): super(TestFormulaManager, self).setUp() self.env = get_env() self.mgr = self.env.formula_manager self.x = self.mgr.Symbol("x") self.y = self.mgr.Symbol("y") self.p = self.mgr.Symbol("p", INT) self.q = self.mgr.Symbol("q", INT) self.r = self.mgr.Symbol("r", REAL) self.s = self.mgr.Symbol("s", REAL) self.rconst = self.mgr.Real(10) self.iconst = self.mgr.Int(10) self.ftype = FunctionType(REAL, [REAL, REAL]) self.f = self.mgr.Symbol("f", self.ftype) self.real_expr = self.mgr.Plus(self.s, self.r) def test_new_fresh_symbol(self): fv1 = self.mgr.new_fresh_symbol(BOOL) self.assertIsNotNone(fv1, "New symbol was not created.") fv2 = self.mgr.new_fresh_symbol(BOOL) self.assertNotEqual(fv1, fv2, "Fresh symbol is not new.") fv3 = self.mgr.new_fresh_symbol(BOOL, "abc_%d") self.assertEqual(fv3.symbol_name()[:3], "abc", "Fresh variable doesn't have the desired prefix") def test_get_symbol(self): a = self.mgr.get_symbol("a") self.assertIsNone(a, "Symbol returned from an empty symboltable") self.mgr.get_or_create_symbol("a", BOOL) a = self.mgr.get_symbol("a") self.assertIsNotNone(a, "Symbol was not found in symbol table") def test_get_or_create_symbol(self): a = self.mgr.get_or_create_symbol("a", REAL) self.assertIsNotNone(a, "Symbol was not created") a2 = self.mgr.get_or_create_symbol("a", REAL) self.assertEqual(a, a2, "Symbol was not memoized") with self.assertRaises(TypeError): self.mgr.get_or_create_symbol("a", BOOL) def test_symbol(self): a1 = self.mgr.Symbol("a", BOOL) self.assertIsNotNone(a1, "Symbol was not created.") a2 = self.mgr.Symbol("a", BOOL) self.assertEqual(a1, a2, "Symbol is not memoized") c = self.mgr.Symbol("c") self.assertEqual(c.symbol_type(), BOOL, "Default Symbol Type is not BOOL") def test_and_node(self): n = self.mgr.And(self.x, self.y) self.assertIsNotNone(n) self.assertTrue(n.is_and()) self.assertEqual(n.get_free_variables(), set([self.x, self.y])) m = self.mgr.And([self.x, self.y]) self.assertEqual(m, n, "And(1,2) != And([1,2]") args = m.args() self.assertTrue(self.x in args and self.y in args) self.assertTrue(len(args) == 2) zero = self.mgr.And() self.assertEqual(zero, self.mgr.TRUE()) one = self.mgr.And(self.x) self.assertEqual(one, self.x) def test_or_node(self): n = self.mgr.Or(self.x, self.y) self.assertIsNotNone(n) self.assertTrue(n.is_or()) self.assertEqual(n.get_free_variables(), set([self.x, self.y])) m = self.mgr.Or([self.x, self.y]) self.assertEqual(m, n, "Or(1,2) != Or([1,2]") args = m.args() self.assertIn(self.x, args) self.assertIn(self.y, args) self.assertEqual(len(args), 2) zero = self.mgr.Or() self.assertEqual(zero, self.mgr.FALSE()) one = self.mgr.Or(self.x) self.assertEqual(one, self.x) def test_not_node(self): n = self.mgr.Not(self.x) self.assertIsNotNone(n) self.assertTrue(n.is_not()) self.assertEqual(n.get_free_variables(), set([self.x])) args = n.args() self.assertIn(self.x, args) self.assertEqual(len(args), 1) self.assertEqual(self.mgr.Not(n), self.x) def test_implies_node(self): n = self.mgr.Implies(self.x, self.y) self.assertIsNotNone(n) self.assertTrue(n.is_implies()) self.assertEqual(n.get_free_variables(), set([self.x, self.y])) args = n.args() self.assertEqual(self.x, args[0]) self.assertEqual(self.y, args[1]) self.assertEqual(len(args), 2) def test_iff_node(self): n = self.mgr.Iff(self.x, self.y) self.assertIsNotNone(n) self.assertTrue(n.is_iff()) self.assertEqual(n.get_free_variables(), set([self.x, self.y])) args = n.args() self.assertIn(self.x, args) self.assertIn(self.y, args) self.assertEqual(len(args), 2) def test_ge_node_type(self): with self.assertRaises(TypeError): self.mgr.GE(self.x, self.r) with self.assertRaises(TypeError): self.mgr.GE(self.r, self.x) with self.assertRaises(TypeError): self.mgr.GE(self.p, self.r) def test_ge_node(self): n = self.mgr.GE(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.GE(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.GE(self.rconst, self.s) self.assertIsNotNone(n) n = self.mgr.GE(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.GE(self.r, self.s) self.assertIsNotNone(n) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) n = self.mgr.GE(self.p, self.q) self.assertIsNotNone(n) def test_minus_node(self): n = self.mgr.Minus(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.Minus(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.Minus(self.rconst, self.s) self.assertIsNotNone(n) n = self.mgr.Minus(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.Minus(self.r, self.s) self.assertIsNotNone(n) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) n = self.mgr.Minus(self.p, self.q) self.assertIsNotNone(n) self.assertTrue(n.is_minus()) self.assertEqual(n.get_free_variables(), set([self.p, self.q])) with self.assertRaises(TypeError): n = self.mgr.Minus(self.r, self.q) def test_times_node(self): n = self.mgr.Times(self.real_expr, self.rconst) self.assertIsNotNone(n) n = self.mgr.Times(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.Times(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.Times(self.rconst, self.s) self.assertIsNotNone(n) args = n.args() self.assertIn(self.rconst, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) n = self.mgr.Times(self.r, self.s) self.assertIsNotNone(n) self.assertTrue(n.is_times()) self.assertEqual(n.get_free_variables(), set([self.r, self.s])) n = self.mgr.Times(self.iconst, self.q) self.assertIsNotNone(n) def test_div_non_linear(self): with self.assertRaises(NonLinearError): self.mgr.Div(self.r, self.s) with self.assertRaises(NonLinearError): self.mgr.Div(self.rconst, self.s) 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((1, self.rconst.constant_value())) self.assertEqual(n, self.mgr.Times(self.s, inv)) def test_equals(self): n = self.mgr.Equals(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.Equals(self.r, self.s) self.assertIsNotNone(n) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) n = self.mgr.Equals(self.p, self.q) self.assertIsNotNone(n) self.assertTrue(n.is_equals()) self.assertEqual(n.get_free_variables(), set([self.p, self.q])) with self.assertRaises(TypeError): n = self.mgr.Equals(self.p, self.r) def test_gt_node_type(self): with self.assertRaises(TypeError): self.mgr.GT(self.x, self.r) with self.assertRaises(TypeError): self.mgr.GT(self.r, self.x) with self.assertRaises(TypeError): self.mgr.GT(self.r, self.p) def test_gt_node(self): n = self.mgr.GT(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.GT(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.GT(self.rconst, self.s) self.assertIsNotNone(n) n = self.mgr.GT(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.GT(self.r, self.s) self.assertIsNotNone(n) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) n = self.mgr.GT(self.p, self.q) self.assertIsNotNone(n) def test_le_node_type(self): with self.assertRaises(TypeError): self.mgr.LE(self.x, self.r) with self.assertRaises(TypeError): self.mgr.LE(self.r, self.x) def test_le_node(self): n = self.mgr.LE(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.LE(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.LE(self.rconst, self.s) self.assertIsNotNone(n) n = self.mgr.LE(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.LE(self.r, self.s) self.assertIsNotNone(n) self.assertTrue(n.is_le()) self.assertEqual(n.get_free_variables(), set([self.r, self.s])) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) def test_lt_node_type(self): with self.assertRaises(TypeError): self.mgr.LT(self.x, self.r) with self.assertRaises(TypeError): self.mgr.LT(self.r, self.x) def test_lt_node(self): n = self.mgr.LT(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.LT(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.LT(self.rconst, self.s) self.assertIsNotNone(n) n = self.mgr.LT(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.LT(self.r, self.s) self.assertIsNotNone(n) self.assertTrue(n.is_lt()) self.assertEqual(n.get_free_variables(), set([self.r, self.s])) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) def test_ite(self): n = self.mgr.Ite(self.x, self.y, self.x) self.assertIsNotNone(n) args = n.args() self.assertIn(self.x, args) self.assertIn(self.y, args) self.assertEqual(len(args), 3) n = self.mgr.Ite(self.x, self.s, self.r) self.assertIsNotNone(n) n = self.mgr.Ite(self.x, self.p, self.q) self.assertIsNotNone(n) self.assertTrue(n.is_ite()) self.assertEqual(n.get_free_variables(), set([self.x, self.p, self.q])) with self.assertRaises(TypeError): self.mgr.Ite(self.x, self.p, self.r) def test_function(self): n = self.mgr.Function(self.f, [self.r, self.s]) self.assertIsNotNone(n) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) self.assertTrue(n.is_function_application()) self.assertEqual(n.get_free_variables(), set([self.f, self.r, self.s])) 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(TypeError): self.mgr.Real(True) nd = self.mgr.Int(10) self.assertIsNotNone(nd) self.assertTrue(nd.is_constant()) self.assertTrue(nd.is_int_constant()) def test_bconstant(self): n = self.mgr.Bool(True) m = self.mgr.Bool(False) self.assertIsNotNone(n) self.assertIsNotNone(m) self.assertNotEqual(n, m) self.assertTrue(n.is_constant()) self.assertTrue(n.is_bool_constant()) with self.assertRaises(TypeError): self.mgr.Bool(42) def test_plus_node(self): with self.assertRaises(TypeError): self.mgr.Plus([self.x, self.r]) with self.assertRaises(TypeError): self.mgr.Plus([self.p, self.r]) with self.assertRaises(TypeError): self.mgr.Plus() n1 = self.mgr.Plus([self.r, self.s]) n2 = self.mgr.Plus(self.r, self.s) self.assertIsNotNone(n1) self.assertIsNotNone(n2) self.assertEqual(n1, n2, "Constructed Plus expression do not match") self.assertTrue(n1.is_plus()) self.assertEqual(set([self.r, self.s]), n1.get_free_variables()) one = self.mgr.Plus([self.p]) self.assertEqual(one, self.p) def test_exactly_one(self): symbols = [self.mgr.Symbol("s%d" % i, BOOL) for i in range(5)] c = self.mgr.ExactlyOne(symbols) self.assertTrue(len(c.args()) > 1) t = self.mgr.Bool(True) c = c.substitute({symbols[0]: t, symbols[1]: t}).simplify() self.assertEqual(c, self.mgr.Bool(False), "ExactlyOne should not allow 2 symbols to be True") @skipIfNoSolverForLogic(QF_BOOL) def test_exactly_one_is_sat(self): symbols = [self.mgr.Symbol("s%d" % i, BOOL) for i in range(5)] c = self.mgr.ExactlyOne(symbols) all_zero = self.mgr.And( [self.mgr.Iff(s, self.mgr.Bool(False)) for s in symbols]) test_zero = self.mgr.And(c, all_zero) self.assertFalse( is_sat(test_zero, logic=QF_BOOL), "ExactlyOne should not allow all symbols to be False") def test_at_most_one(self): symbols = [self.mgr.Symbol("s%d" % i, BOOL) for i in range(5)] c = self.mgr.AtMostOne(symbols) self.assertTrue(len(c.args()) > 1) t = self.mgr.Bool(True) c = c.substitute({symbols[0]: t, symbols[1]: t}).simplify() self.assertEqual(c, self.mgr.Bool(False), "AtMostOne should not allow two symbols to be True") def test_xor(self): xor1 = self.mgr.Xor(self.x, self.y) self.assertIsNotNone(xor1) with self.assertRaises(TypeError): self.mgr.Xor(self.p, self.q) xor_false = self.mgr.Xor(self.mgr.TRUE(), self.mgr.TRUE()).simplify() self.assertEqual(xor_false, self.mgr.FALSE(), "Xor should be False if both arguments are True") xor_true = self.mgr.Xor(self.mgr.TRUE(), self.mgr.FALSE()).simplify() self.assertEqual(xor_true, self.mgr.TRUE(), "Xor should be True if both arguments are False") def test_all_different(self): many = 5 symbols = [self.mgr.Symbol("s%d" % i, INT) for i in range(many)] f = self.mgr.AllDifferent(symbols) one = self.mgr.Int(1) for i in xrange(many): for j in xrange(many): if i != j: c = f.substitute({ symbols[i]: one, symbols[j]: one }).simplify() self.assertEqual(c, self.mgr.Bool(False), "AllDifferent should not allow 2 symbols "\ "to be 1") c = f.substitute({symbols[i]: self.mgr.Int(i) for i in xrange(many)}) self.assertEqual(c.simplify(), self.mgr.Bool(True), "AllDifferent should be tautological for a set " \ "of different values") def test_min(self): min1 = self.mgr.Min(self.p, Plus(self.q, self.mgr.Int(1))) self.assertIsNotNone(min1) with self.assertRaises(TypeError): self.mgr.Min(self.p, self.r) min_int = self.mgr.Min(self.mgr.Int(1), self.mgr.Int(2), self.mgr.Int(3)) self.assertEqual(min_int.simplify(), self.mgr.Int(1), "The minimum of 1, 2 and 3 should be 1") min_real = self.mgr.Min(self.mgr.Real(1), self.mgr.Real(2), self.mgr.Real(3)) self.assertEqual(min_real.simplify(), self.mgr.Real(1), "The minimum of 1.0, 2.0 and 3.0 should be 1.0") def test_max(self): max1 = self.mgr.Max(self.p, Plus(self.q, self.mgr.Int(1))) self.assertIsNotNone(max1) with self.assertRaises(TypeError): self.mgr.Max(self.p, self.r) max_int = self.mgr.Max(self.mgr.Int(1), self.mgr.Int(2), self.mgr.Int(3)) self.assertEqual(max_int.simplify(), self.mgr.Int(3), "The maximum of 1, 2 and 3 should be 3") max_real = self.mgr.Max(self.mgr.Real(1), self.mgr.Real(2), self.mgr.Real(3)) self.assertEqual(max_real.simplify(), self.mgr.Real(3), "The maximum of 1.0, 2.0 and 3.0 should be 3.0") def test_pickling(self): import pickle src_env = Environment() dst_env = Environment() src_mgr = src_env.formula_manager dst_mgr = dst_env.formula_manager a = src_mgr.Symbol("A") b = src_mgr.Symbol("B") f = src_mgr.And(a, src_mgr.Not(b)) self.assertEqual(str(f), "(A & (! B))", str(f)) serialized = pickle.dumps(f) f_new = pickle.loads(serialized) f_new = dst_mgr.normalize(f) args = f_new.args() self.assertEqual( str(args[0]), "A", "Expecting symbol A, " + "symbol %s found instead" % str(args[0])) a = dst_mgr.Symbol("A") b = dst_mgr.Symbol("B") g = dst_mgr.And(a, dst_mgr.Not(b)) # Contextualized formula is memoized self.assertEqual(f_new, g, "%s != %s" % (id(f_new), id(g))) # But it differs from the one in the other formula manager self.assertNotEqual(f_new, f) # Normalizing a formula in the same manager should not # be a problem f_new = src_mgr.normalize(f) self.assertEqual(f_new, f, "%s != %s" % (id(a), id(b))) def test_infix(self): x, y, p = self.x, self.y, self.p with self.assertRaises(Exception): x.Implies(y) get_env().enable_infix_notation = True self.assertEqual(Implies(x, y), x.Implies(y)) self.assertEqual(p + p, Plus(p, p)) self.assertEqual(p > p, GT(p, p)) get_env().enable_infix_notation = False def test_infix_extended(self): p, r, x, y = self.p, self.r, self.x, self.y get_env().enable_infix_notation = True self.assertEqual(Plus(p, Int(1)), p + 1) self.assertEqual(Plus(r, Real(1)), r + 1) self.assertEqual(Times(r, Real(1)), r * 1) self.assertEqual(Minus(p, Int(1)), p - 1) self.assertEqual(Minus(r, Real(1)), r - 1) self.assertEqual(Times(r, Real(1)), r * 1) self.assertEqual(Plus(r, Real(1.5)), r + 1.5) self.assertEqual(Minus(r, Real(1.5)), r - 1.5) self.assertEqual(Times(r, Real(1.5)), r * 1.5) self.assertEqual(Plus(r, Real(1.5)), 1.5 + r) self.assertEqual(Times(r, Real(1.5)), 1.5 * r) with self.assertRaises(TypeError): foo = p + 1.5 self.assertEqual(Not(x), ~x) self.assertEqual(Times(r, Real(-1)), -r) self.assertEqual(Times(p, Int(-1)), -p) self.assertEqual(Xor(x, y), x ^ y) self.assertEqual(And(x, y), x & y) self.assertEqual(Or(x, y), x | y) self.assertEqual(Or(x, TRUE()), x | True) self.assertEqual(Or(x, TRUE()), True | x) self.assertEqual(And(x, TRUE()), x & True) self.assertEqual(And(x, TRUE()), True & x) get_env().enable_infix_notation = False def test_toReal(self): f = self.mgr.Equals(self.rconst, self.mgr.ToReal(self.p)) self.assertIsNotNone(f) with self.assertRaises(TypeError): self.mgr.ToReal(self.x) f1 = self.mgr.ToReal(self.p) f2 = self.mgr.ToReal(f1) self.assertEqual(f1, f2) self.assertTrue(f1.is_toreal()) self.assertEqual(set([self.p]), f1.get_free_variables()) f3 = self.mgr.Equals(self.iconst, self.p) with self.assertRaises(TypeError): self.mgr.ToReal(f3) f4 = self.mgr.Plus(self.rconst, self.r) f5 = self.mgr.ToReal(f4) self.assertEqual(f5, f4) def test_equals_or_iff(self): eq_1 = self.mgr.EqualsOrIff(self.p, self.q) eq_2 = self.mgr.Equals(self.p, self.q) self.assertEqual(eq_1, eq_2) iff_1 = self.mgr.EqualsOrIff(self.x, self.y) iff_2 = self.mgr.Iff(self.x, self.y) self.assertEqual(iff_1, iff_2) def test_is_term(self): and_x_x = self.mgr.And(self.x, self.x) apply_f = self.mgr.Function(self.f, [self.r, self.s]) self.assertTrue(self.x.is_term()) self.assertTrue(and_x_x.is_term()) self.assertFalse(self.f.is_term()) self.assertTrue(apply_f.is_term()) def test_formula_in_formula_manager(self): x = self.mgr.FreshSymbol() and_x_x = self.mgr.And(x, x) new_mgr = FormulaManager(get_env()) y = new_mgr.FreshSymbol() and_y_y = new_mgr.And(y, y) self.assertTrue(x in self.mgr) self.assertFalse(y in self.mgr) self.assertTrue(and_x_x in self.mgr) self.assertFalse(and_y_y in self.mgr) def test_typing(self): self.assertTrue(BOOL.is_bool_type()) self.assertFalse(BOOL.is_function_type()) self.assertTrue(REAL.is_real_type()) self.assertFalse(REAL.is_bool_type()) self.assertTrue(INT.is_int_type()) self.assertFalse(INT.is_real_type()) self.assertTrue(self.ftype.is_function_type()) self.assertFalse(self.ftype.is_int_type())
def test_function_smtlib_print(self): f_t = FunctionType(BOOL, [BOOL]) f0 = Symbol('f 0', f_t) f0_of_false = Function(f0, [Bool(False)]) s = to_smtlib(f0_of_false, False) self.assertEqual(s, '(|f 0| false)')
def get_example_formulae(environment=None): 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) 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])) bv8 = Symbol("bv1", BV8) bv16 = Symbol("bv2", BV16) result = [ # Formula, is_valid, is_sat, is_qf # x /\ y Example(expr=And(x, y), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BOOL), # x <-> y Example(expr=Iff(x, y), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BOOL), # (x \/ y ) /\ ! ( x \/ y ) Example(expr=And(Or(x, y), Not(Or(x, y))), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BOOL), # (x /\ !y) Example(expr=And(x, Not(y)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BOOL), # False -> True Example(expr=Implies(FALSE(), TRUE()), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BOOL), # # LIA # # (p > q) /\ x -> y Example(expr=And(GT(p, q), Implies(x, y)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_IDL), # (p + q) = 5 /\ (p > q) Example(expr=And(Equals(Plus(p, q), Int(5)), GT(p, q)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LIA), # (p >= q) \/ ( p <= q) Example(expr=Or(GE(p, q), LE(p, q)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_IDL), # !( p < q * 2 ) Example(expr=Not(LT(p, Times(q, Int(2)))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LIA), # p - (5 - 2) > p Example(expr=GT(Minus(p, Minus(Int(5), Int(2))), p), is_valid=False, is_sat=False, logic=pysmt.logics.QF_IDL), # x ? 7: (p + -1) * 3 = q Example(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(expr=LT(p, Plus(q, Int(1))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LIA), # # LRA # # (r > s) /\ x -> y Example(expr=And(GT(r, s), Implies(x, y)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_RDL), # (r + s) = 5.6 /\ (r > s) Example(expr=And(Equals(Plus(r, s), Real(Fraction("5.6"))), GT(r, s)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LRA), # (r >= s) \/ ( r <= s) Example(expr=Or(GE(r, s), LE(r, s)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_RDL), # !( (r / (1/2)) < s * 2 ) Example(expr=Not(LT(Div(r, Real((1, 2))), Times(s, Real(2)))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LRA), # ! ( r - (5 - 2) > r ) Example(expr=Not(GT(Minus(r, Minus(Real(5), Real(2))), r)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_RDL), # x ? 7: (s + -1) * 3 = r Example(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 # # rf(5, rg(2)) = 0 Example(expr=Equals(Function(rf, (Real(5), Function(rg, (r, )))), Real(0)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_UFLRA), # (rg(r) = 5 + 2) <-> (rg(r) = 7) Example(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), # (r = s + 1) & (rg(s) = 5) & (rg(r - 1) = 7) Example(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 # # bv_one & bv_zero == bv_zero Example(expr=Equals(BVAnd(BVOne(32), BVZero(32)), BVZero(32)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # ~(010) == 101 Example(expr=Equals(BVNot(BV("010")), BV("101")), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # "111" xor "000" == "000" Example(expr=Equals(BVXor(BV("111"), BV("000")), BV("000")), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), # bv8 :: bv8 < bv_zero Example(expr=BVULT(BVConcat(bv8, bv8), BVZero(16)), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), # bv_one[:7] == bv_one Example(expr=Equals(BVExtract(BVOne(32), end=7), BVOne(8)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # (((bv8 + bv_one) * bv(5)) / bv(5)) > bv(0) Example(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), # bv16 >=u bv(0) Example(expr=BVUGE(bv16, BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # bv16 >=s bv(0) Example(expr=BVSGE(bv16, BVZero(16)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), # (BV(5) rem BV(2) > bv_zero) /\ (BV(5) rem BV(2) < bv_one) Example(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), # ((bv_one + (- bv_one)) << 1) >> 1 == bv_one Example(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), # bv_one - bv_one == bv_zero Example(expr=Equals(BVSub(BVOne(32), BVOne(32)), BVZero(32)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # Rotations Example(expr=Equals(BVRor(BVRol(BVOne(32), 1), 1), BVOne(32)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # Extensions Example(expr=Equals(BVZExt(BVZero(5), 11), BVSExt(BVZero(1), 15)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # bv16 - bv16 = 0_16 Example(expr=Equals(BVSub(bv16, bv16), BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # (bv16 - bv16)[0:7] = bv8 Example(expr=Equals(BVExtract(BVSub(bv16, bv16), 0, 7), bv8), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), # (bv16[0,7] comp bv8) = bv1 Example(expr=Equals(BVComp(BVExtract(bv16, 0, 7), bv8), BVOne(1)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), # (bv16 comp bv16) = bv0 Example(expr=Equals(BVComp(bv16, bv16), BVZero(1)), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), # (bv16 s< bv16) Example(expr=BVSLT(bv16, bv16), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), # (bv16 s< 0_16) Example(expr=BVSLT(bv16, BVZero(16)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), # (bv16 u< bv16) Example(expr=BVULT(bv16, bv16), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), # (bv16 s< 0_16) Example(expr=BVULT(bv16, BVZero(16)), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), # (bv16 | 0_16) = bv16 Example(expr=Equals(BVOr(bv16, BVZero(16)), bv16), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # (bv16 & 0_16) = 0_16 Example(expr=Equals(BVAnd(bv16, BVZero(16)), BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # 0_16 s< bv16 & ((bv16 s/ -1) s< 0) Example(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), # 0_16 s< bv16 & ((bv16 s% -1) s< 0) Example(expr=And(BVSLT(BVZero(16), bv16), BVSLT(BVSRem(bv16, BVOne(16)), BVZero(16))), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), # bv16 u% 1 = 0_16 Example(expr=Equals(BVURem(bv16, BVOne(16)), BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # bv16 s% 1 = 0_16 Example(expr=Equals(BVSRem(bv16, BVOne(16)), BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # bv16 s% -1 = 0_16 Example(expr=Equals(BVSRem(bv16, BVNeg(BVOne(16))), BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # bv16 a>> 0 = bv16 Example(expr=Equals(BVAShr(bv16, BVZero(16)), bv16), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # 0 s<= bv16 & bv16 a>> 1 = bv16 >> 1 Example(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 # # forall y . x -> y Example(expr=ForAll([y], Implies(x, y)), is_valid=False, is_sat=True, logic=pysmt.logics.BOOL), # forall p,q . p + q = 0 Example(expr=ForAll([p, q], Equals(Plus(p, q), Int(0))), is_valid=False, is_sat=False, logic=pysmt.logics.LIA), # forall r,s . ((r > 0) & (s > 0)) -> (r - s < r) Example(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), # exists x,y . x -> y Example(expr=Exists([x, y], Implies(x, y)), is_valid=True, is_sat=True, logic=pysmt.logics.BOOL), # exists p,q . p + q = 0 Example(expr=Exists([p, q], Equals(Plus(p, q), Int(0))), is_valid=True, is_sat=True, logic=pysmt.logics.LIA), # exists r . forall s . (r - s > r) Example(expr=Exists([r], ForAll([s], GT(Minus(r, s), r))), is_valid=False, is_sat=False, logic=pysmt.logics.LRA), # forall r . exists s . (r - s > r) Example(expr=ForAll([r], Exists([s], GT(Minus(r, s), r))), is_valid=True, is_sat=True, logic=pysmt.logics.LRA), # x /\ forall r. (r + s = 5) Example(expr=And(x, ForAll([r], Equals(Plus(r, s), Real(5)))), is_valid=False, is_sat=False, logic=pysmt.logics.LRA), # # UFLIRA # # ih(r,q) > p /\ (x -> y) Example(expr=And(GT(Function(ih, (r, q)), p), Implies(x, y)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_UFLIRA), # ( (p - 3) = q ) -> ( ih(r, q + 3) > p \/ ih(r, p) <= p ) Example(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), # ( (ToReal(p - 3) = r) /\ (ToReal(q) = r) ) -> # ( ( ih(ToReal(p - 3), q + 3) > p ) \/ (ih(r, p) <= p) ) Example(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), # ! ( (ToReal(p - 3) = r /\ ToReal(q) = r) -> # ( ih(ToReal(p - 3), q + 3) > p \/ # ih(r,p) <= p ) ) Example(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), # Test complex names Example(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), ] return result
class TestFormulaManager(TestCase): def setUp(self): super(TestFormulaManager, self).setUp() self.env = get_env() self.mgr = self.env.formula_manager self.x = self.mgr.Symbol("x") self.y = self.mgr.Symbol("y") self.p = self.mgr.Symbol("p", INT) self.q = self.mgr.Symbol("q", INT) self.r = self.mgr.Symbol("r", REAL) self.s = self.mgr.Symbol("s", REAL) self.rconst = self.mgr.Real(10) self.iconst = self.mgr.Int(10) self.ftype = FunctionType(REAL, [REAL, REAL]) self.f = self.mgr.Symbol("f", self.ftype) self.real_expr = self.mgr.Plus(self.s, self.r) def test_new_fresh_symbol(self): fv1 = self.mgr.new_fresh_symbol(BOOL) self.assertIsNotNone(fv1, "New symbol was not created.") fv2 = self.mgr.new_fresh_symbol(BOOL) self.assertNotEqual(fv1, fv2, "Fresh symbol is not new.") fv3 = self.mgr.new_fresh_symbol(BOOL, "abc_%d") self.assertEqual(fv3.symbol_name()[:3], "abc", "Fresh variable doesn't have the desired prefix") def test_get_symbol(self): with self.assertRaises(UndefinedSymbolError): a = self.mgr.get_symbol("a") self.mgr.get_or_create_symbol("a", BOOL) a = self.mgr.get_symbol("a") self.assertIsNotNone(a, "Symbol was not found in symbol table") def test_get_or_create_symbol(self): a = self.mgr.get_or_create_symbol("a", REAL) self.assertIsNotNone(a, "Symbol was not created") a2 = self.mgr.get_or_create_symbol("a", REAL) self.assertEqual(a, a2, "Symbol was not memoized") with self.assertRaises(PysmtTypeError): self.mgr.get_or_create_symbol("a", BOOL) def test_symbol(self): a1 = self.mgr.Symbol("a", BOOL) self.assertIsNotNone(a1, "Symbol was not created.") a2 = self.mgr.Symbol("a", BOOL) self.assertEqual(a1, a2, "Symbol is not memoized") c = self.mgr.Symbol("c") self.assertEqual(c.symbol_type(), BOOL, "Default Symbol Type is not BOOL") def test_payload_assertions(self): s = self.mgr.Symbol("x") c = self.mgr.Int(0) with self.assertRaises(AssertionError): c.symbol_name() with self.assertRaises(AssertionError): c.symbol_type() with self.assertRaises(AssertionError): s.bv_width() with self.assertRaises(AssertionError): s.bv_extract_start() with self.assertRaises(AssertionError): s.bv_extract_end() with self.assertRaises(AssertionError): s.bv_rotation_step() with self.assertRaises(AssertionError): s.bv_extend_step() with self.assertRaises(AssertionError): s.bv_extract_end() with self.assertRaises(AssertionError): s.constant_value() with self.assertRaises(AssertionError): s.array_value_index_type() with self.assertRaises(AssertionError): s.function_name() def test_and_node(self): n = self.mgr.And(self.x, self.y) self.assertIsNotNone(n) self.assertTrue(n.is_and()) self.assertEqual(n.get_free_variables(), set([self.x, self.y])) m = self.mgr.And([self.x, self.y]) self.assertEqual(m, n, "And(1,2) != And([1,2]") args = m.args() self.assertTrue(self.x in args and self.y in args) self.assertTrue(len(args) == 2) zero = self.mgr.And() self.assertEqual(zero, self.mgr.TRUE()) one = self.mgr.And(self.x) self.assertEqual(one, self.x) self.assertTrue(n.is_bool_op()) def test_or_node(self): n = self.mgr.Or(self.x, self.y) self.assertIsNotNone(n) self.assertTrue(n.is_or()) self.assertEqual(n.get_free_variables(), set([self.x, self.y])) m = self.mgr.Or([self.x, self.y]) self.assertEqual(m, n, "Or(1,2) != Or([1,2]") args = m.args() self.assertIn(self.x, args) self.assertIn(self.y, args) self.assertEqual(len(args), 2) zero = self.mgr.Or() self.assertEqual(zero, self.mgr.FALSE()) one = self.mgr.Or(self.x) self.assertEqual(one, self.x) self.assertTrue(n.is_bool_op()) def test_not_node(self): n = self.mgr.Not(self.x) self.assertIsNotNone(n) self.assertTrue(n.is_not()) self.assertEqual(n.get_free_variables(), set([self.x])) args = n.args() self.assertIn(self.x, args) self.assertEqual(len(args), 1) self.assertEqual(self.mgr.Not(n), self.x) self.assertTrue(n.is_bool_op()) def test_implies_node(self): n = self.mgr.Implies(self.x, self.y) self.assertIsNotNone(n) self.assertTrue(n.is_implies()) self.assertEqual(n.get_free_variables(), set([self.x, self.y])) args = n.args() self.assertEqual(self.x, args[0]) self.assertEqual(self.y, args[1]) self.assertEqual(len(args), 2) self.assertTrue(n.is_bool_op()) def test_iff_node(self): n = self.mgr.Iff(self.x, self.y) self.assertIsNotNone(n) self.assertTrue(n.is_iff()) self.assertEqual(n.get_free_variables(), set([self.x, self.y])) args = n.args() self.assertIn(self.x, args) self.assertIn(self.y, args) self.assertEqual(len(args), 2) self.assertTrue(n.is_bool_op()) def test_ge_node_type(self): with self.assertRaises(PysmtTypeError): self.mgr.GE(self.x, self.r) with self.assertRaises(PysmtTypeError): self.mgr.GE(self.r, self.x) with self.assertRaises(PysmtTypeError): self.mgr.GE(self.p, self.r) def test_ge_node(self): n = self.mgr.GE(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.GE(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.GE(self.rconst, self.s) self.assertIsNotNone(n) n = self.mgr.GE(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.GE(self.r, self.s) self.assertIsNotNone(n) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) n = self.mgr.GE(self.p, self.q) self.assertIsNotNone(n) self.assertFalse(n.is_bool_op()) self.assertTrue(n.is_theory_relation()) def test_minus_node(self): n = self.mgr.Minus(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.Minus(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.Minus(self.rconst, self.s) self.assertIsNotNone(n) n = self.mgr.Minus(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.Minus(self.r, self.s) self.assertIsNotNone(n) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) n = self.mgr.Minus(self.p, self.q) self.assertIsNotNone(n) self.assertTrue(n.is_minus()) self.assertEqual(n.get_free_variables(), set([self.p, self.q])) self.assertTrue(n.is_theory_op()) with self.assertRaises(PysmtTypeError): n = self.mgr.Minus(self.r, self.q) def test_times_node(self): n = self.mgr.Times(self.real_expr, self.rconst) self.assertIsNotNone(n) n = self.mgr.Times(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.Times(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.Times(self.r, self.s, self.rconst) self.assertIsNotNone(n) n = self.mgr.Times([self.r, self.s, self.rconst]) self.assertIsNotNone(n) n = self.mgr.Times(x for x in [self.r, self.s, self.rconst]) self.assertIsNotNone(n) n = self.mgr.Times(self.rconst, self.s) self.assertIsNotNone(n) args = n.args() self.assertIn(self.rconst, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) n = self.mgr.Times(self.r, self.s) self.assertIsNotNone(n) self.assertTrue(n.is_times()) self.assertEqual(n.get_free_variables(), set([self.r, self.s])) n = self.mgr.Times(self.iconst, self.q) self.assertIsNotNone(n) self.assertTrue(n.is_ira_op()) 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_equals(self): n = self.mgr.Equals(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.Equals(self.r, self.s) self.assertIsNotNone(n) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) n = self.mgr.Equals(self.p, self.q) self.assertIsNotNone(n) self.assertTrue(n.is_equals()) self.assertEqual(n.get_free_variables(), set([self.p, self.q])) self.assertTrue(n.is_theory_relation()) with self.assertRaises(PysmtTypeError): n = self.mgr.Equals(self.p, self.r) def test_gt_node_type(self): with self.assertRaises(PysmtTypeError): self.mgr.GT(self.x, self.r) with self.assertRaises(PysmtTypeError): self.mgr.GT(self.r, self.x) with self.assertRaises(PysmtTypeError): self.mgr.GT(self.r, self.p) def test_gt_node(self): n = self.mgr.GT(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.GT(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.GT(self.rconst, self.s) self.assertIsNotNone(n) n = self.mgr.GT(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.GT(self.r, self.s) self.assertIsNotNone(n) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) n = self.mgr.GT(self.p, self.q) self.assertIsNotNone(n) self.assertTrue(n.is_theory_relation()) def test_le_node_type(self): with self.assertRaises(PysmtTypeError): self.mgr.LE(self.x, self.r) with self.assertRaises(PysmtTypeError): self.mgr.LE(self.r, self.x) def test_le_node(self): n = self.mgr.LE(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.LE(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.LE(self.rconst, self.s) self.assertIsNotNone(n) n = self.mgr.LE(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.LE(self.r, self.s) self.assertIsNotNone(n) self.assertTrue(n.is_le()) self.assertEqual(n.get_free_variables(), set([self.r, self.s])) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) self.assertTrue(n.is_theory_relation()) def test_lt_node_type(self): with self.assertRaises(PysmtTypeError): self.mgr.LT(self.x, self.r) with self.assertRaises(PysmtTypeError): self.mgr.LT(self.r, self.x) def test_lt_node(self): n = self.mgr.LT(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.LT(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.LT(self.rconst, self.s) self.assertIsNotNone(n) n = self.mgr.LT(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.LT(self.r, self.s) self.assertIsNotNone(n) self.assertTrue(n.is_lt()) self.assertEqual(n.get_free_variables(), set([self.r, self.s])) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) self.assertTrue(n.is_theory_relation()) def test_ite(self): n = self.mgr.Ite(self.x, self.y, self.x) self.assertIsNotNone(n) args = n.args() self.assertIn(self.x, args) self.assertIn(self.y, args) self.assertEqual(len(args), 3) n = self.mgr.Ite(self.x, self.s, self.r) self.assertIsNotNone(n) n = self.mgr.Ite(self.x, self.p, self.q) self.assertIsNotNone(n) self.assertTrue(n.is_ite()) self.assertEqual(n.get_free_variables(), set([self.x, self.p, self.q])) with self.assertRaises(PysmtTypeError): self.mgr.Ite(self.x, self.p, self.r) def test_function(self): n = self.mgr.Function(self.f, [self.r, self.s]) self.assertIsNotNone(n) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) self.assertTrue(n.is_function_application()) self.assertEqual(n.get_free_variables(), set([self.f, self.r, self.s])) def test_0arity_function(self): # Calling FunctionType on a 0-arity list of parameters returns # the type itself. t = FunctionType(REAL, []) # After this call: t = REAL # s1 is a symbol of type real s1 = self.mgr.Symbol("s1", t) s1b = self.mgr.Function(s1, []) self.assertEqual(s1, s1b) 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 test_bconstant(self): n = self.mgr.Bool(True) m = self.mgr.Bool(False) self.assertIsNotNone(n) self.assertIsNotNone(m) self.assertNotEqual(n, m) self.assertTrue(n.is_constant()) self.assertTrue(n.is_bool_constant()) with self.assertRaises(PysmtTypeError): self.mgr.Bool(42) def test_plus_node(self): with self.assertRaises(PysmtTypeError): self.mgr.Plus([self.x, self.r]) with self.assertRaises(PysmtTypeError): self.mgr.Plus([self.p, self.r]) with self.assertRaises(PysmtTypeError): self.mgr.Plus() n1 = self.mgr.Plus([self.r, self.s]) n2 = self.mgr.Plus(self.r, self.s) self.assertIsNotNone(n1) self.assertIsNotNone(n2) self.assertEqual(n1, n2, "Constructed Plus expression do not match") self.assertTrue(n1.is_plus()) self.assertEqual(set([self.r, self.s]), n1.get_free_variables()) one = self.mgr.Plus([self.p]) self.assertEqual(one, self.p) def test_exactly_one(self): symbols = [self.mgr.Symbol("s%d" % i, BOOL) for i in range(5)] c = self.mgr.ExactlyOne(symbols) self.assertTrue(len(c.args()) > 1) t = self.mgr.Bool(True) c = c.substitute({symbols[0]: t, symbols[1]: t}).simplify() self.assertEqual(c, self.mgr.Bool(False), "ExactlyOne should not allow 2 symbols to be True") s1 = self.mgr.Symbol("x") s2 = self.mgr.Symbol("x") f1 = self.mgr.ExactlyOne((s for s in [s1, s2])) f2 = self.mgr.ExactlyOne([s1, s2]) f3 = self.mgr.ExactlyOne(s1, s2) self.assertEqual(f1, f2) self.assertEqual(f2, f3) @skipIfNoSolverForLogic(QF_BOOL) def test_exactly_one_is_sat(self): symbols = [self.mgr.Symbol("s%d" % i, BOOL) for i in range(5)] c = self.mgr.ExactlyOne(symbols) all_zero = self.mgr.And( [self.mgr.Iff(s, self.mgr.Bool(False)) for s in symbols]) test_zero = self.mgr.And(c, all_zero) self.assertFalse( is_sat(test_zero, logic=QF_BOOL), "ExactlyOne should not allow all symbols to be False") def test_at_most_one(self): symbols = [self.mgr.Symbol("s%d" % i, BOOL) for i in range(5)] c = self.mgr.AtMostOne(symbols) self.assertTrue(len(c.args()) > 1) t = self.mgr.Bool(True) c = c.substitute({symbols[0]: t, symbols[1]: t}).simplify() self.assertEqual(c, self.mgr.Bool(False), "AtMostOne should not allow two symbols to be True") def test_xor(self): xor1 = self.mgr.Xor(self.x, self.y) self.assertIsNotNone(xor1) with self.assertRaises(PysmtTypeError): self.mgr.Xor(self.p, self.q) xor_false = self.mgr.Xor(self.mgr.TRUE(), self.mgr.TRUE()).simplify() self.assertEqual(xor_false, self.mgr.FALSE(), "Xor should be False if both arguments are True") xor_true = self.mgr.Xor(self.mgr.TRUE(), self.mgr.FALSE()).simplify() self.assertEqual(xor_true, self.mgr.TRUE(), "Xor should be True if both arguments are False") def test_all_different(self): many = 5 symbols = [self.mgr.Symbol("s%d" % i, INT) for i in range(many)] f = self.mgr.AllDifferent(symbols) one = self.mgr.Int(1) for i in xrange(many): for j in xrange(many): if i != j: c = f.substitute({ symbols[i]: one, symbols[j]: one }).simplify() self.assertEqual(c, self.mgr.Bool(False), "AllDifferent should not allow 2 symbols "\ "to be 1") c = f.substitute( dict((symbols[i], self.mgr.Int(i)) for i in xrange(many))) self.assertEqual(c.simplify(), self.mgr.Bool(True), "AllDifferent should be tautological for a set " \ "of different values") def test_min(self): min1 = self.mgr.Min(self.p, Plus(self.q, self.mgr.Int(1))) self.assertIsNotNone(min1) with self.assertRaises(PysmtTypeError): self.mgr.Min(self.p, self.r) min_int = self.mgr.Min(self.mgr.Int(1), self.mgr.Int(2), self.mgr.Int(3)) self.assertEqual(min_int.simplify(), self.mgr.Int(1), "The minimum of 1, 2 and 3 should be 1") min_real = self.mgr.Min(self.mgr.Real(1), self.mgr.Real(2), self.mgr.Real(3)) self.assertEqual(min_real.simplify(), self.mgr.Real(1), "The minimum of 1.0, 2.0 and 3.0 should be 1.0") def test_max(self): max1 = self.mgr.Max(self.p, Plus(self.q, self.mgr.Int(1))) self.assertIsNotNone(max1) with self.assertRaises(PysmtTypeError): self.mgr.Max(self.p, self.r) max_int = self.mgr.Max(self.mgr.Int(1), self.mgr.Int(2), self.mgr.Int(3)) self.assertEqual(max_int.simplify(), self.mgr.Int(3), "The maximum of 1, 2 and 3 should be 3") max_real = self.mgr.Max(self.mgr.Real(1), self.mgr.Real(2), self.mgr.Real(3)) self.assertEqual(max_real.simplify(), self.mgr.Real(3), "The maximum of 1.0, 2.0 and 3.0 should be 3.0") def test_pickling(self): import pickle src_env = Environment() dst_env = Environment() src_mgr = src_env.formula_manager dst_mgr = dst_env.formula_manager a = src_mgr.Symbol("A") b = src_mgr.Symbol("B") f = src_mgr.And(a, src_mgr.Not(b)) self.assertEqual(str(f), "(A & (! B))", str(f)) # NOTE: We cannot use the textual format for pickle, because # we are using slots. We can, however, use more advanced # versions of pickle. Therefore, we specify here to use the # latest protocol. serialized = pickle.dumps(f, pickle.HIGHEST_PROTOCOL) f_new = pickle.loads(serialized) f_new = dst_mgr.normalize(f) args = f_new.args() self.assertEqual( str(args[0]), "A", "Expecting symbol A, " + "symbol %s found instead" % str(args[0])) a = dst_mgr.Symbol("A") b = dst_mgr.Symbol("B") g = dst_mgr.And(a, dst_mgr.Not(b)) # Contextualized formula is memoized self.assertEqual(f_new, g, "%s != %s" % (id(f_new), id(g))) # But it differs from the one in the other formula manager self.assertNotEqual(f_new, f) # Normalizing a formula in the same manager should not # be a problem f_new = src_mgr.normalize(f) self.assertEqual(f_new, f, "%s != %s" % (id(a), id(b))) def test_infix(self): x, y, p = self.x, self.y, self.p with self.assertRaises(PysmtModeError): x.Implies(y) with self.assertRaises(PysmtModeError): ~x with self.assertRaises(PysmtModeError): x[1] with self.assertRaises(PysmtModeError): x.Ite(x, y) get_env().enable_infix_notation = True self.assertEqual(Implies(x, y), x.Implies(y)) self.assertEqual(p + p, Plus(p, p)) self.assertEqual(p > p, GT(p, p)) with self.assertRaises(NotImplementedError): x[1] def test_infix_extended(self): p, r, x, y = self.p, self.r, self.x, self.y get_env().enable_infix_notation = True self.assertEqual(Plus(p, Int(1)), p + 1) self.assertEqual(Plus(r, Real(1)), r + 1) self.assertEqual(Times(r, Real(1)), r * 1) self.assertEqual(Minus(p, Int(1)), p - 1) self.assertEqual(Minus(r, Real(1)), r - 1) self.assertEqual(Times(r, Real(1)), r * 1) self.assertEqual(Plus(r, Real(1.5)), r + 1.5) self.assertEqual(Minus(r, Real(1.5)), r - 1.5) self.assertEqual(Times(r, Real(1.5)), r * 1.5) self.assertEqual(Plus(r, Real(1.5)), 1.5 + r) self.assertEqual(Times(r, Real(1.5)), 1.5 * r) with self.assertRaises(PysmtTypeError): foo = p + 1.5 self.assertEqual(Not(x), ~x) self.assertEqual(Times(r, Real(-1)), -r) self.assertEqual(Times(p, Int(-1)), -p) self.assertEqual(Xor(x, y), x ^ y) self.assertEqual(And(x, y), x & y) self.assertEqual(Or(x, y), x | y) self.assertEqual(Or(x, TRUE()), x | True) self.assertEqual(Or(x, TRUE()), True | x) self.assertEqual(And(x, TRUE()), x & True) self.assertEqual(And(x, TRUE()), True & x) self.assertEqual(Iff(x, y), x.Iff(y)) self.assertEqual(And(x, y), x.And(y)) self.assertEqual(Or(x, y), x.Or(y)) self.assertEqual(Ite(x, TRUE(), FALSE()), x.Ite(TRUE(), FALSE())) with self.assertRaises(Exception): x.Ite(1, 2) self.assertEqual(6 - r, Plus(Times(r, Real(-1)), Real(6))) # BVs # BV_CONSTANT: We use directly python numbers # # Note: In this case, the width is implicit (yikes!) The # width of the constant is inferred by the use of a # symbol or operator that enforces a bit_width. # # This works in very simple cases. For complex # expressions it is advisable to create a shortcut for # the given BVType. const1 = 3 const2 = 0b011 const3 = 0x3 # Since these are python numbers, the following holds self.assertEqual(const1, const2) self.assertEqual(const1, const3) # However, we cannot use infix pySMT Equals, since const1 is a # python int!!! with self.assertRaises(AttributeError): const1.Equals(const2) # We use the usual syntax to build a constant with a fixed width const1_8 = self.mgr.BV(3, width=8) # In actual code, one can simply create a macro for this: _8bv = lambda v: self.mgr.BV(v, width=8) const1_8b = _8bv(3) self.assertEqual(const1_8, const1_8b) # Equals forces constants to have the width of the operand self.assertEqual(const1_8.Equals(const1), self.mgr.Equals(const1_8, const1_8b)) # Symbols bv8 = self.mgr.FreshSymbol(BV8) bv7 = self.mgr.FreshSymbol(BVType(7)) self.assertEqual(bv8.Equals(const1), bv8.Equals(const1_8)) # BV_AND, self.assertEqual(bv8 & const1, self.mgr.BVAnd(bv8, const1_8)) self.assertEqual(const1 & bv8, self.mgr.BVAnd(bv8, const1_8)) self.assertEqual(const1 & bv8, self.mgr.BVAnd(bv8, const1_8)) # BV_XOR, self.assertEqual(bv8 ^ const1, self.mgr.BVXor(bv8, const1_8)) self.assertEqual(const1 ^ bv8, self.mgr.BVXor(bv8, const1_8)) # BV_OR, self.assertEqual(bv8 | const1, self.mgr.BVOr(bv8, const1_8)) self.assertEqual(const1 | bv8, self.mgr.BVOr(bv8, const1_8)) # BV_ADD, self.assertEqual(bv8 + const1, self.mgr.BVAdd(bv8, const1_8)) self.assertEqual(const1 + bv8, self.mgr.BVAdd(bv8, const1_8)) # BV_SUB, self.assertEqual(bv8 - const1, self.mgr.BVSub(bv8, const1_8)) self.assertEqual(const1 - bv8, self.mgr.BVSub(const1_8, bv8)) # BV_MUL, self.assertEqual(bv8 * const1, self.mgr.BVMul(bv8, const1_8)) self.assertEqual(const1 * bv8, self.mgr.BVMul(bv8, const1_8)) # BV_NOT: # !!!WARNING!!! Cannot be applied to python constants!! # This results in a negative number with self.assertRaises(PysmtValueError): _8bv(~const1) # For symbols and expressions this works as expected self.assertEqual(~bv8, self.mgr.BVNot(bv8)) # BV_NEG -- Cannot be applied to 'infix' constants self.assertEqual(-bv8, self.mgr.BVNeg(bv8)) # BV_EXTRACT -- Cannot be applied to 'infix' constants self.assertEqual(bv8[0:7], self.mgr.BVExtract(bv8, 0, 7)) self.assertEqual(bv8[:7], self.mgr.BVExtract(bv8, end=7)) self.assertEqual(bv8[0:], self.mgr.BVExtract(bv8, start=0)) self.assertEqual(bv8[7], self.mgr.BVExtract(bv8, start=7, end=7)) # BV_ULT, self.assertEqual(bv8 < const1, self.mgr.BVULT(bv8, const1_8)) # BV_ULE, self.assertEqual(bv8 <= const1, self.mgr.BVULE(bv8, const1_8)) # BV_UGT self.assertEqual(bv8 > const1, self.mgr.BVUGT(bv8, const1_8)) # BV_UGE self.assertEqual(bv8 >= const1, self.mgr.BVUGE(bv8, const1_8)) # BV_LSHL, self.assertEqual(bv8 << const1, self.mgr.BVLShl(bv8, const1_8)) # BV_LSHR, self.assertEqual(bv8 >> const1, self.mgr.BVLShr(bv8, const1_8)) # BV_UDIV, self.assertEqual(bv8 / const1, self.mgr.BVUDiv(bv8, const1_8)) # BV_UREM, self.assertEqual(bv8 % const1, self.mgr.BVURem(bv8, const1_8)) # The following operators use the infix syntax left.Operator.right # These includes all signed operators # BVSLT, self.assertEqual(self.mgr.BVSLT(bv8, const1_8), bv8.BVSLT(const1_8)) #BVSLE, self.assertEqual(self.mgr.BVSLE(bv8, const1_8), bv8.BVSLE(const1_8)) #BVComp self.assertEqual(self.mgr.BVComp(bv8, const1_8), bv8.BVComp(const1_8)) #BVSDiv self.assertEqual(self.mgr.BVSDiv(bv8, const1_8), bv8.BVSDiv(const1_8)) #BVSRem self.assertEqual(self.mgr.BVSRem(bv8, const1_8), bv8.BVSRem(const1_8)) #BVAShr self.assertEqual(self.mgr.BVAShr(bv8, const1_8), bv8.BVAShr(const1_8)) #BVNand self.assertEqual(self.mgr.BVNand(bv8, const1_8), bv8.BVNand(const1_8)) #BVNor self.assertEqual(self.mgr.BVNor(bv8, const1_8), bv8.BVNor(const1_8)) #BVXnor self.assertEqual(self.mgr.BVXnor(bv8, const1_8), bv8.BVXnor(const1_8)) #BVSGT self.assertEqual(self.mgr.BVSGT(bv8, const1_8), bv8.BVSGT(const1_8)) #BVSGE self.assertEqual(self.mgr.BVSGE(bv8, const1_8), bv8.BVSGE(const1_8)) #BVSMod self.assertEqual(self.mgr.BVSMod(bv8, const1_8), bv8.BVSMod(const1_8)) #BVRol, self.assertEqual(self.mgr.BVRol(bv8, steps=5), bv8.BVRol(5)) #BVRor, self.assertEqual(self.mgr.BVRor(bv8, steps=5), bv8.BVRor(5)) #BVZExt, self.assertEqual(self.mgr.BVZExt(bv8, increase=4), bv8.BVZExt(4)) #BVSExt, self.assertEqual(self.mgr.BVSExt(bv8, increase=4), bv8.BVSExt(4)) #BVRepeat, self.assertEqual(self.mgr.BVRepeat(bv8, count=5), bv8.BVRepeat(5)) def test_toReal(self): f = self.mgr.Equals(self.rconst, self.mgr.ToReal(self.p)) self.assertIsNotNone(f) with self.assertRaises(PysmtTypeError): self.mgr.ToReal(self.x) f1 = self.mgr.ToReal(self.p) f2 = self.mgr.ToReal(f1) self.assertEqual(f1, f2) self.assertTrue(f1.is_toreal()) self.assertEqual(set([self.p]), f1.get_free_variables()) f3 = self.mgr.Equals(self.iconst, self.p) with self.assertRaises(PysmtTypeError): self.mgr.ToReal(f3) f4 = self.mgr.Plus(self.rconst, self.r) f5 = self.mgr.ToReal(f4) self.assertEqual(f5, f4) def test_equals_or_iff(self): eq_1 = self.mgr.EqualsOrIff(self.p, self.q) eq_2 = self.mgr.Equals(self.p, self.q) self.assertEqual(eq_1, eq_2) iff_1 = self.mgr.EqualsOrIff(self.x, self.y) iff_2 = self.mgr.Iff(self.x, self.y) self.assertEqual(iff_1, iff_2) def test_is_term(self): and_x_x = self.mgr.And(self.x, self.x) apply_f = self.mgr.Function(self.f, [self.r, self.s]) self.assertTrue(self.x.is_term()) self.assertTrue(and_x_x.is_term()) self.assertFalse(self.f.is_term()) self.assertTrue(apply_f.is_term()) def test_formula_in_formula_manager(self): x = self.mgr.FreshSymbol() and_x_x = self.mgr.And(x, x) new_mgr = FormulaManager(get_env()) y = new_mgr.FreshSymbol() and_y_y = new_mgr.And(y, y) self.assertTrue(x in self.mgr) self.assertFalse(y in self.mgr) self.assertTrue(and_x_x in self.mgr) self.assertFalse(and_y_y in self.mgr) def test_typing(self): self.assertTrue(BOOL.is_bool_type()) self.assertFalse(BOOL.is_function_type()) self.assertTrue(REAL.is_real_type()) self.assertFalse(REAL.is_bool_type()) self.assertTrue(INT.is_int_type()) self.assertFalse(INT.is_real_type()) self.assertTrue(self.ftype.is_function_type()) self.assertFalse(self.ftype.is_int_type()) def test_array_value(self): a1 = self.mgr.Array(INT, self.mgr.Int(0)) a2 = self.mgr.Array(INT, self.mgr.Int(0), {self.mgr.Int(12): self.mgr.Int(0)}) self.assertEqual(a1, a2) 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_integer(self): """Create Int using different constant types.""" from pysmt.constants import HAS_GMPY from six import PY2 v_base = Integer(1) c_base = self.mgr.Int(v_base) v_int = int(1) c_int = self.mgr.Int(v_int) self.assertIs(c_base, c_int) if PY2: v_long = long(1) c_long = self.mgr.Int(v_long) self.assertIs(c_base, c_long) if HAS_GMPY: from gmpy2 import mpz v_mpz = mpz(1) c_mpz = self.mgr.Int(v_mpz) self.assertIs(c_base, c_mpz) def test_node_id(self): x = Symbol("x") y = Symbol("y") xx = Symbol("x") self.assertEqual(x.node_id(), xx.node_id()) self.assertNotEqual(x.node_id(), y.node_id())
class TestFormulaManager(TestCase): def setUp(self): super(TestFormulaManager, self).setUp() self.env = get_env() self.mgr = self.env.formula_manager self.x = self.mgr.Symbol("x") self.y = self.mgr.Symbol("y") self.p = self.mgr.Symbol("p", INT) self.q = self.mgr.Symbol("q", INT) self.r = self.mgr.Symbol("r", REAL) self.s = self.mgr.Symbol("s", REAL) self.rconst = self.mgr.Real(10) self.iconst = self.mgr.Int(10) self.ftype = FunctionType(REAL, [REAL, REAL]) self.f = self.mgr.Symbol("f", self.ftype) self.real_expr = self.mgr.Plus(self.s, self.r) def test_new_fresh_symbol(self): fv1 = self.mgr.new_fresh_symbol(BOOL) self.assertIsNotNone(fv1, "New symbol was not created.") fv2 = self.mgr.new_fresh_symbol(BOOL) self.assertNotEqual(fv1, fv2, "Fresh symbol is not new.") fv3 = self.mgr.new_fresh_symbol(BOOL, "abc_%d") self.assertEqual(fv3.symbol_name()[:3], "abc", "Fresh variable doesn't have the desired prefix") def test_get_symbol(self): with self.assertRaises(UndefinedSymbolError): a = self.mgr.get_symbol("a") self.mgr.get_or_create_symbol("a", BOOL) a = self.mgr.get_symbol("a") self.assertIsNotNone(a, "Symbol was not found in symbol table") def test_get_or_create_symbol(self): a = self.mgr.get_or_create_symbol("a", REAL) self.assertIsNotNone(a, "Symbol was not created") a2 = self.mgr.get_or_create_symbol("a", REAL) self.assertEqual(a, a2, "Symbol was not memoized") with self.assertRaises(TypeError): self.mgr.get_or_create_symbol("a", BOOL) def test_symbol(self): a1 = self.mgr.Symbol("a", BOOL) self.assertIsNotNone(a1, "Symbol was not created.") a2 = self.mgr.Symbol("a", BOOL) self.assertEqual(a1, a2, "Symbol is not memoized") c = self.mgr.Symbol("c") self.assertEqual(c.symbol_type(), BOOL, "Default Symbol Type is not BOOL") def test_and_node(self): n = self.mgr.And(self.x, self.y) self.assertIsNotNone(n) self.assertTrue(n.is_and()) self.assertEqual(n.get_free_variables(), set([self.x, self.y])) m = self.mgr.And([self.x, self.y]) self.assertEqual(m, n, "And(1,2) != And([1,2]") args = m.args() self.assertTrue(self.x in args and self.y in args) self.assertTrue(len(args) == 2) zero = self.mgr.And() self.assertEqual(zero, self.mgr.TRUE()) one = self.mgr.And(self.x) self.assertEqual(one, self.x) def test_or_node(self): n = self.mgr.Or(self.x, self.y) self.assertIsNotNone(n) self.assertTrue(n.is_or()) self.assertEqual(n.get_free_variables(), set([self.x, self.y])) m = self.mgr.Or([self.x, self.y]) self.assertEqual(m, n, "Or(1,2) != Or([1,2]") args = m.args() self.assertIn(self.x, args) self.assertIn(self.y, args) self.assertEqual(len(args), 2) zero = self.mgr.Or() self.assertEqual(zero, self.mgr.FALSE()) one = self.mgr.Or(self.x) self.assertEqual(one, self.x) def test_not_node(self): n = self.mgr.Not(self.x) self.assertIsNotNone(n) self.assertTrue(n.is_not()) self.assertEqual(n.get_free_variables(), set([self.x])) args = n.args() self.assertIn(self.x, args) self.assertEqual(len(args), 1) self.assertEqual(self.mgr.Not(n), self.x) def test_implies_node(self): n = self.mgr.Implies(self.x, self.y) self.assertIsNotNone(n) self.assertTrue(n.is_implies()) self.assertEqual(n.get_free_variables(), set([self.x, self.y])) args = n.args() self.assertEqual(self.x, args[0]) self.assertEqual(self.y, args[1]) self.assertEqual(len(args), 2) def test_iff_node(self): n = self.mgr.Iff(self.x, self.y) self.assertIsNotNone(n) self.assertTrue(n.is_iff()) self.assertEqual(n.get_free_variables(), set([self.x, self.y])) args = n.args() self.assertIn(self.x, args) self.assertIn(self.y, args) self.assertEqual(len(args), 2) def test_ge_node_type(self): with self.assertRaises(TypeError): self.mgr.GE(self.x, self.r) with self.assertRaises(TypeError): self.mgr.GE(self.r, self.x) with self.assertRaises(TypeError): self.mgr.GE(self.p, self.r) def test_ge_node(self): n = self.mgr.GE(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.GE(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.GE(self.rconst, self.s) self.assertIsNotNone(n) n = self.mgr.GE(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.GE(self.r, self.s) self.assertIsNotNone(n) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) n = self.mgr.GE(self.p, self.q) self.assertIsNotNone(n) def test_minus_node(self): n = self.mgr.Minus(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.Minus(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.Minus(self.rconst, self.s) self.assertIsNotNone(n) n = self.mgr.Minus(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.Minus(self.r, self.s) self.assertIsNotNone(n) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) n = self.mgr.Minus(self.p, self.q) self.assertIsNotNone(n) self.assertTrue(n.is_minus()) self.assertEqual(n.get_free_variables(), set([self.p, self.q])) with self.assertRaises(TypeError): n = self.mgr.Minus(self.r, self.q) def test_times_node(self): n = self.mgr.Times(self.real_expr, self.rconst) self.assertIsNotNone(n) n = self.mgr.Times(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.Times(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.Times(self.rconst, self.s) self.assertIsNotNone(n) args = n.args() self.assertIn(self.rconst, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) n = self.mgr.Times(self.r, self.s) self.assertIsNotNone(n) self.assertTrue(n.is_times()) self.assertEqual(n.get_free_variables(), set([self.r, self.s])) n = self.mgr.Times(self.iconst, self.q) self.assertIsNotNone(n) 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_equals(self): n = self.mgr.Equals(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.Equals(self.r, self.s) self.assertIsNotNone(n) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) n = self.mgr.Equals(self.p, self.q) self.assertIsNotNone(n) self.assertTrue(n.is_equals()) self.assertEqual(n.get_free_variables(), set([self.p, self.q])) with self.assertRaises(TypeError): n = self.mgr.Equals(self.p, self.r) def test_gt_node_type(self): with self.assertRaises(TypeError): self.mgr.GT(self.x, self.r) with self.assertRaises(TypeError): self.mgr.GT(self.r, self.x) with self.assertRaises(TypeError): self.mgr.GT(self.r, self.p) def test_gt_node(self): n = self.mgr.GT(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.GT(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.GT(self.rconst, self.s) self.assertIsNotNone(n) n = self.mgr.GT(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.GT(self.r, self.s) self.assertIsNotNone(n) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) n = self.mgr.GT(self.p, self.q) self.assertIsNotNone(n) def test_le_node_type(self): with self.assertRaises(TypeError): self.mgr.LE(self.x, self.r) with self.assertRaises(TypeError): self.mgr.LE(self.r, self.x) def test_le_node(self): n = self.mgr.LE(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.LE(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.LE(self.rconst, self.s) self.assertIsNotNone(n) n = self.mgr.LE(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.LE(self.r, self.s) self.assertIsNotNone(n) self.assertTrue(n.is_le()) self.assertEqual(n.get_free_variables(), set([self.r, self.s])) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) def test_lt_node_type(self): with self.assertRaises(TypeError): self.mgr.LT(self.x, self.r) with self.assertRaises(TypeError): self.mgr.LT(self.r, self.x) def test_lt_node(self): n = self.mgr.LT(self.real_expr, self.real_expr) self.assertIsNotNone(n) n = self.mgr.LT(self.r, self.rconst) self.assertIsNotNone(n) n = self.mgr.LT(self.rconst, self.s) self.assertIsNotNone(n) n = self.mgr.LT(self.rconst, self.rconst) self.assertIsNotNone(n) n = self.mgr.LT(self.r, self.s) self.assertIsNotNone(n) self.assertTrue(n.is_lt()) self.assertEqual(n.get_free_variables(), set([self.r, self.s])) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) def test_ite(self): n = self.mgr.Ite(self.x, self.y, self.x) self.assertIsNotNone(n) args = n.args() self.assertIn(self.x, args) self.assertIn(self.y, args) self.assertEqual(len(args), 3) n = self.mgr.Ite(self.x, self.s, self.r) self.assertIsNotNone(n) n = self.mgr.Ite(self.x, self.p, self.q) self.assertIsNotNone(n) self.assertTrue(n.is_ite()) self.assertEqual(n.get_free_variables(), set([self.x, self.p, self.q])) with self.assertRaises(TypeError): self.mgr.Ite(self.x, self.p, self.r) def test_function(self): n = self.mgr.Function(self.f, [self.r, self.s]) self.assertIsNotNone(n) args = n.args() self.assertIn(self.r, args) self.assertIn(self.s, args) self.assertEqual(len(args), 2) self.assertTrue(n.is_function_application()) self.assertEqual(n.get_free_variables(), set([self.f, self.r, self.s])) def test_0arity_function(self): # Calling FunctionType on a 0-arity list of parameters returns # the type itself. t = FunctionType(REAL, []) # After this call: t = REAL # s1 is a symbol of type real s1 = self.mgr.Symbol("s1", t) s1b = self.mgr.Function(s1, []) self.assertEqual(s1, s1b) 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(TypeError): self.mgr.Real(True) nd = self.mgr.Int(10) self.assertIsNotNone(nd) self.assertTrue(nd.is_constant()) self.assertTrue(nd.is_int_constant()) def test_bconstant(self): n = self.mgr.Bool(True) m = self.mgr.Bool(False) self.assertIsNotNone(n) self.assertIsNotNone(m) self.assertNotEqual(n, m) self.assertTrue(n.is_constant()) self.assertTrue(n.is_bool_constant()) with self.assertRaises(TypeError): self.mgr.Bool(42) def test_plus_node(self): with self.assertRaises(TypeError): self.mgr.Plus([self.x, self.r]) with self.assertRaises(TypeError): self.mgr.Plus([self.p, self.r]) with self.assertRaises(TypeError): self.mgr.Plus() n1 = self.mgr.Plus([self.r, self.s]) n2 = self.mgr.Plus(self.r, self.s) self.assertIsNotNone(n1) self.assertIsNotNone(n2) self.assertEqual(n1, n2, "Constructed Plus expression do not match") self.assertTrue(n1.is_plus()) self.assertEqual(set([self.r, self.s]), n1.get_free_variables()) one = self.mgr.Plus([self.p]) self.assertEqual(one, self.p) def test_exactly_one(self): symbols = [ self.mgr.Symbol("s%d"%i, BOOL) for i in range(5) ] c = self.mgr.ExactlyOne(symbols) self.assertTrue(len(c.args()) > 1) t = self.mgr.Bool(True) c = c.substitute({symbols[0]: t, symbols[1]: t}).simplify() self.assertEqual(c, self.mgr.Bool(False), "ExactlyOne should not allow 2 symbols to be True") s1 = self.mgr.Symbol("x") s2 = self.mgr.Symbol("x") f1 = self.mgr.ExactlyOne((s for s in [s1,s2])) f2 = self.mgr.ExactlyOne([s1,s2]) f3 = self.mgr.ExactlyOne(s1,s2) self.assertEqual(f1,f2) self.assertEqual(f2,f3) @skipIfNoSolverForLogic(QF_BOOL) def test_exactly_one_is_sat(self): symbols = [ self.mgr.Symbol("s%d"%i, BOOL) for i in range(5) ] c = self.mgr.ExactlyOne(symbols) all_zero = self.mgr.And([self.mgr.Iff(s, self.mgr.Bool(False)) for s in symbols]) test_zero = self.mgr.And(c, all_zero) self.assertFalse(is_sat(test_zero, logic=QF_BOOL), "ExactlyOne should not allow all symbols to be False") def test_at_most_one(self): symbols = [ self.mgr.Symbol("s%d"%i, BOOL) for i in range(5) ] c = self.mgr.AtMostOne(symbols) self.assertTrue(len(c.args()) > 1) t = self.mgr.Bool(True) c = c.substitute({symbols[0]: t, symbols[1]: t}).simplify() self.assertEqual(c, self.mgr.Bool(False), "AtMostOne should not allow two symbols to be True") def test_xor(self): xor1 = self.mgr.Xor(self.x, self.y) self.assertIsNotNone(xor1) with self.assertRaises(TypeError): self.mgr.Xor(self.p, self.q) xor_false = self.mgr.Xor(self.mgr.TRUE(), self.mgr.TRUE()).simplify() self.assertEqual(xor_false, self.mgr.FALSE(), "Xor should be False if both arguments are True") xor_true = self.mgr.Xor(self.mgr.TRUE(), self.mgr.FALSE()).simplify() self.assertEqual(xor_true, self.mgr.TRUE(), "Xor should be True if both arguments are False") def test_all_different(self): many = 5 symbols = [self.mgr.Symbol("s%d"%i, INT) for i in range(many) ] f = self.mgr.AllDifferent(symbols) one = self.mgr.Int(1) for i in xrange(many): for j in xrange(many): if i != j: c = f.substitute({symbols[i]: one, symbols[j]: one}).simplify() self.assertEqual(c, self.mgr.Bool(False), "AllDifferent should not allow 2 symbols "\ "to be 1") c = f.substitute(dict((symbols[i],self.mgr.Int(i)) for i in xrange(many))) self.assertEqual(c.simplify(), self.mgr.Bool(True), "AllDifferent should be tautological for a set " \ "of different values") def test_min(self): min1 = self.mgr.Min(self.p, Plus(self.q, self.mgr.Int(1))) self.assertIsNotNone(min1) with self.assertRaises(TypeError): self.mgr.Min(self.p, self.r) min_int = self.mgr.Min(self.mgr.Int(1), self.mgr.Int(2), self.mgr.Int(3)) self.assertEqual(min_int.simplify(), self.mgr.Int(1), "The minimum of 1, 2 and 3 should be 1") min_real = self.mgr.Min(self.mgr.Real(1), self.mgr.Real(2), self.mgr.Real(3)) self.assertEqual(min_real.simplify(), self.mgr.Real(1), "The minimum of 1.0, 2.0 and 3.0 should be 1.0") def test_max(self): max1 = self.mgr.Max(self.p, Plus(self.q, self.mgr.Int(1))) self.assertIsNotNone(max1) with self.assertRaises(TypeError): self.mgr.Max(self.p, self.r) max_int = self.mgr.Max(self.mgr.Int(1), self.mgr.Int(2), self.mgr.Int(3)) self.assertEqual(max_int.simplify(), self.mgr.Int(3), "The maximum of 1, 2 and 3 should be 3") max_real = self.mgr.Max(self.mgr.Real(1), self.mgr.Real(2), self.mgr.Real(3)) self.assertEqual(max_real.simplify(), self.mgr.Real(3), "The maximum of 1.0, 2.0 and 3.0 should be 3.0") def test_pickling(self): import pickle src_env = Environment() dst_env = Environment() src_mgr = src_env.formula_manager dst_mgr = dst_env.formula_manager a = src_mgr.Symbol("A") b = src_mgr.Symbol("B") f = src_mgr.And(a, src_mgr.Not(b)) self.assertEqual(str(f), "(A & (! B))", str(f)) # NOTE: We cannot use the textual format for pickle, because # we are using slots. We can, however, use more advanced # versions of pickle. Therefore, we specify here to use the # latest protocol. serialized = pickle.dumps(f, pickle.HIGHEST_PROTOCOL) f_new = pickle.loads(serialized) f_new = dst_mgr.normalize(f) args = f_new.args() self.assertEqual(str(args[0]), "A", "Expecting symbol A, " + "symbol %s found instead" % str(args[0])) a = dst_mgr.Symbol("A") b = dst_mgr.Symbol("B") g = dst_mgr.And(a, dst_mgr.Not(b)) # Contextualized formula is memoized self.assertEqual(f_new, g, "%s != %s" % (id(f_new), id(g))) # But it differs from the one in the other formula manager self.assertNotEqual(f_new, f) # Normalizing a formula in the same manager should not # be a problem f_new = src_mgr.normalize(f) self.assertEqual(f_new, f, "%s != %s" %(id(a),id(b))) def test_infix(self): x, y, p = self.x, self.y, self.p with self.assertRaises(Exception): x.Implies(y) get_env().enable_infix_notation = True self.assertEqual(Implies(x,y), x.Implies(y)) self.assertEqual(p + p, Plus(p,p)) self.assertEqual(p > p, GT(p,p)) get_env().enable_infix_notation = False def test_infix_extended(self): p, r, x, y = self.p, self.r, self.x, self.y get_env().enable_infix_notation = True self.assertEqual(Plus(p, Int(1)), p + 1) self.assertEqual(Plus(r, Real(1)), r + 1) self.assertEqual(Times(r, Real(1)), r * 1) self.assertEqual(Minus(p, Int(1)), p - 1) self.assertEqual(Minus(r, Real(1)), r - 1) self.assertEqual(Times(r, Real(1)), r * 1) self.assertEqual(Plus(r, Real(1.5)), r + 1.5) self.assertEqual(Minus(r, Real(1.5)), r - 1.5) self.assertEqual(Times(r, Real(1.5)), r * 1.5) self.assertEqual(Plus(r, Real(1.5)), 1.5 + r) self.assertEqual(Times(r, Real(1.5)), 1.5 * r) with self.assertRaises(TypeError): foo = p + 1.5 self.assertEqual(Not(x), ~x) self.assertEqual(Times(r, Real(-1)), -r) self.assertEqual(Times(p, Int(-1)), -p) self.assertEqual(Xor(x, y), x ^ y) self.assertEqual(And(x, y), x & y) self.assertEqual(Or(x, y), x | y) self.assertEqual(Or(x, TRUE()), x | True) self.assertEqual(Or(x, TRUE()), True | x) self.assertEqual(And(x, TRUE()), x & True) self.assertEqual(And(x, TRUE()), True & x) # BVs # BV_CONSTANT: We use directly python numbers # # Note: In this case, the width is implicit (yikes!) The # width of the constant is inferred by the use of a # symbol or operator that enforces a bit_width. # # This works in very simple cases. For complex # expressions it is advisable to create a shortcut for # the given BVType. const1 = 3 const2 = 0b011 const3 = 0x3 # Since these are python numbers, the following holds self.assertEqual(const1, const2) self.assertEqual(const1, const3) # However, we cannot use infix pySMT Equals, since const1 is a # python int!!! with self.assertRaises(AttributeError): const1.Equals(const2) # We use the usual syntax to build a constant with a fixed width const1_8 = self.mgr.BV(3, width=8) # In actual code, one can simply create a macro for this: _8bv = lambda v : self.mgr.BV(v, width=8) const1_8b = _8bv(3) self.assertEqual(const1_8, const1_8b) # Equals forces constants to have the width of the operand self.assertEqual(const1_8.Equals(const1), self.mgr.Equals(const1_8, const1_8b)) # Symbols bv8 = self.mgr.FreshSymbol(BV8) bv7 = self.mgr.FreshSymbol(BVType(7)) self.assertEqual(bv8.Equals(const1), bv8.Equals(const1_8)) # BV_AND, self.assertEqual(bv8 & const1, self.mgr.BVAnd(bv8, const1_8)) self.assertEqual(const1 & bv8, self.mgr.BVAnd(bv8, const1_8)) self.assertEqual(const1 & bv8, self.mgr.BVAnd(bv8, const1_8)) # BV_XOR, self.assertEqual(bv8 ^ const1, self.mgr.BVXor(bv8, const1_8)) self.assertEqual(const1 ^ bv8, self.mgr.BVXor(bv8, const1_8)) # BV_OR, self.assertEqual(bv8 | const1, self.mgr.BVOr(bv8, const1_8)) self.assertEqual(const1 | bv8, self.mgr.BVOr(bv8, const1_8)) # BV_ADD, self.assertEqual(bv8 + const1, self.mgr.BVAdd(bv8, const1_8)) self.assertEqual(const1 + bv8, self.mgr.BVAdd(bv8, const1_8)) # BV_SUB, self.assertEqual(bv8 - const1, self.mgr.BVSub(bv8, const1_8)) self.assertEqual(const1 - bv8, self.mgr.BVSub(const1_8, bv8)) # BV_MUL, self.assertEqual(bv8 * const1, self.mgr.BVMul(bv8, const1_8)) self.assertEqual(const1 * bv8, self.mgr.BVMul(bv8, const1_8)) # BV_NOT: # !!!WARNING!!! Cannot be applied to python constants!! # This results in a negative number with self.assertRaises(ValueError): _8bv(~const1) # For symbols and expressions this works as expected self.assertEqual(~bv8, self.mgr.BVNot(bv8)) # BV_NEG -- Cannot be applied to 'infix' constants self.assertEqual(-bv8, self.mgr.BVNeg(bv8)) # BV_EXTRACT -- Cannot be applied to 'infix' constants self.assertEqual(bv8[0:7], self.mgr.BVExtract(bv8, 0, 7)) self.assertEqual(bv8[:7], self.mgr.BVExtract(bv8, end=7)) self.assertEqual(bv8[0:], self.mgr.BVExtract(bv8, start=0)) self.assertEqual(bv8[7], self.mgr.BVExtract(bv8, start=7, end=7)) # BV_ULT, self.assertEqual(bv8 < const1, self.mgr.BVULT(bv8, const1_8)) # BV_ULE, self.assertEqual(bv8 <= const1, self.mgr.BVULE(bv8, const1_8)) # BV_UGT self.assertEqual(bv8 > const1, self.mgr.BVUGT(bv8, const1_8)) # BV_UGE self.assertEqual(bv8 >= const1, self.mgr.BVUGE(bv8, const1_8)) # BV_LSHL, self.assertEqual(bv8 << const1, self.mgr.BVLShl(bv8, const1_8)) # BV_LSHR, self.assertEqual(bv8 >> const1, self.mgr.BVLShr(bv8, const1_8)) # BV_UDIV, self.assertEqual(bv8 / const1, self.mgr.BVUDiv(bv8, const1_8)) # BV_UREM, self.assertEqual(bv8 % const1, self.mgr.BVURem(bv8, const1_8)) # The following operators use the infix syntax left.Operator.right # These includes all signed operators # BVSLT, self.assertEqual(self.mgr.BVSLT(bv8, const1_8), bv8.BVSLT(const1_8)) #BVSLE, self.assertEqual(self.mgr.BVSLE(bv8, const1_8), bv8.BVSLE(const1_8)) #BVComp self.assertEqual(self.mgr.BVComp(bv8, const1_8), bv8.BVComp(const1_8)) #BVSDiv self.assertEqual(self.mgr.BVSDiv(bv8, const1_8), bv8.BVSDiv(const1_8)) #BVSRem self.assertEqual(self.mgr.BVSRem(bv8, const1_8), bv8.BVSRem(const1_8)) #BVAShr self.assertEqual(self.mgr.BVAShr(bv8, const1_8), bv8.BVAShr(const1_8)) #BVNand self.assertEqual(self.mgr.BVNand(bv8, const1_8), bv8.BVNand(const1_8)) #BVNor self.assertEqual(self.mgr.BVNor(bv8, const1_8), bv8.BVNor(const1_8)) #BVXnor self.assertEqual(self.mgr.BVXnor(bv8, const1_8), bv8.BVXnor(const1_8)) #BVSGT self.assertEqual(self.mgr.BVSGT(bv8, const1_8), bv8.BVSGT(const1_8)) #BVSGE self.assertEqual(self.mgr.BVSGE(bv8, const1_8), bv8.BVSGE(const1_8)) #BVSMod self.assertEqual(self.mgr.BVSMod(bv8, const1_8), bv8.BVSMod(const1_8)) #BVRol, self.assertEqual(self.mgr.BVRol(bv8, steps=5), bv8.BVRol(5)) #BVRor, self.assertEqual(self.mgr.BVRor(bv8, steps=5), bv8.BVRor(5)) #BVZExt, self.assertEqual(self.mgr.BVZExt(bv8, increase=4), bv8.BVZExt(4)) #BVSExt, self.assertEqual(self.mgr.BVSExt(bv8, increase=4), bv8.BVSExt(4)) #BVRepeat, self.assertEqual(self.mgr.BVRepeat(bv8, count=5), bv8.BVRepeat(5)) # Reset Env get_env().enable_infix_notation = False def test_toReal(self): f = self.mgr.Equals(self.rconst, self.mgr.ToReal(self.p)) self.assertIsNotNone(f) with self.assertRaises(TypeError): self.mgr.ToReal(self.x) f1 = self.mgr.ToReal(self.p) f2 = self.mgr.ToReal(f1) self.assertEqual(f1, f2) self.assertTrue(f1.is_toreal()) self.assertEqual(set([self.p]), f1.get_free_variables()) f3 = self.mgr.Equals(self.iconst, self.p) with self.assertRaises(TypeError): self.mgr.ToReal(f3) f4 = self.mgr.Plus(self.rconst, self.r) f5 = self.mgr.ToReal(f4) self.assertEqual(f5, f4) def test_equals_or_iff(self): eq_1 = self.mgr.EqualsOrIff(self.p, self.q) eq_2 = self.mgr.Equals(self.p, self.q) self.assertEqual(eq_1, eq_2) iff_1 = self.mgr.EqualsOrIff(self.x, self.y) iff_2 = self.mgr.Iff(self.x, self.y) self.assertEqual(iff_1, iff_2) def test_is_term(self): and_x_x = self.mgr.And(self.x, self.x) apply_f = self.mgr.Function(self.f, [self.r, self.s]) self.assertTrue(self.x.is_term()) self.assertTrue(and_x_x.is_term()) self.assertFalse(self.f.is_term()) self.assertTrue(apply_f.is_term()) def test_formula_in_formula_manager(self): x = self.mgr.FreshSymbol() and_x_x = self.mgr.And(x, x) new_mgr = FormulaManager(get_env()) y = new_mgr.FreshSymbol() and_y_y = new_mgr.And(y, y) self.assertTrue(x in self.mgr) self.assertFalse(y in self.mgr) self.assertTrue(and_x_x in self.mgr) self.assertFalse(and_y_y in self.mgr) def test_typing(self): self.assertTrue(BOOL.is_bool_type()) self.assertFalse(BOOL.is_function_type()) self.assertTrue(REAL.is_real_type()) self.assertFalse(REAL.is_bool_type()) self.assertTrue(INT.is_int_type()) self.assertFalse(INT.is_real_type()) self.assertTrue(self.ftype.is_function_type()) self.assertFalse(self.ftype.is_int_type()) def test_array_value(self): a1 = self.mgr.Array(INT, self.mgr.Int(0)) a2 = self.mgr.Array(INT, self.mgr.Int(0), {self.mgr.Int(12) : self.mgr.Int(0)}) self.assertEquals(a1, a2)
def get_example_formulae(environment=None): 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) 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])) result = [ # Formula, is_valid, is_sat, is_qf # x /\ y Example(expr=And(x, y), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BOOL ), # x <-> y Example(expr=Iff(x, y), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BOOL ), # (x \/ y ) /\ ! ( x \/ y ) Example(expr=And(Or(x, y), Not(Or(x, y))), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BOOL ), # (x /\ !y) Example(expr=And(x, Not(y)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BOOL), # False -> True Example(expr=Implies(FALSE(),TRUE()), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BOOL ), # # LIA # # (p > q) /\ x -> y Example(expr=And(GT(p, q), Implies(x, y)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_IDL ), # (p + q) = 5 /\ (p > q) Example(expr=And(Equals(Plus(p,q),Int(5)) , GT(p, q)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LIA ), # (p >= q) \/ ( p <= q) Example(expr=Or(GE(p, q), LE(p, q)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_IDL ), # !( p < q * 2 ) Example(expr=Not(LT(p, Times(q, Int(2)))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LIA ), # p - (5 - 2) > p Example(expr=GT(Minus(p, Minus(Int(5), Int(2))), p), is_valid=False, is_sat=False, logic=pysmt.logics.QF_IDL ), # x ? 7: (p + -1) * 3 = q Example(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(expr=LT(p, Plus(q, Int(1))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LIA ), # # LRA # # (r > s) /\ x -> y Example(expr=And(GT(r, s), Implies(x, y)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_RDL ), # (r + s) = 5.6 /\ (r > s) Example(expr=And(Equals(Plus(r,s), Real(Fraction("5.6"))) , GT(r, s)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LRA ), # (r >= s) \/ ( r <= s) Example(expr=Or(GE(r, s), LE(r, s)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_RDL ), # !( (r / (1/2)) < s * 2 ) Example(expr=Not(LT(Div(r, Real((1,2))), Times(s, Real(2)))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LRA ), # ! ( r - (5 - 2) > r ) Example(expr=Not(GT(Minus(r, Minus(Real(5), Real(2))), r)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_RDL ), # x ? 7: (s + -1) * 3 = r Example(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 # # rf(5, rg(2)) = 0 Example(expr=Equals(Function(rf, (Real(5), Function(rg, (r,)))), Real(0)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_UFLRA ), # (rg(r) = 5 + 2) <-> (rg(r) = 7) Example(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 ), # (r = s + 1) & (rg(s) = 5) & (rg(r - 1) = 7) Example(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), # # Quantification # # forall y . x -> y Example(expr=ForAll([y], Implies(x,y)), is_valid=False, is_sat=True, logic=pysmt.logics.BOOL ), # forall p,q . p + q = 0 Example(expr=ForAll([p,q], Equals(Plus(p,q), Int(0))), is_valid=False, is_sat=False, logic=pysmt.logics.LIA ), # forall r,s . ((r > 0) & (s > 0)) -> (r - s < r) Example(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 ), # exists x,y . x -> y Example(expr=Exists([x,y], Implies(x,y)), is_valid=True, is_sat=True, logic=pysmt.logics.BOOL ), # exists p,q . p + q = 0 Example(expr=Exists([p,q], Equals(Plus(p,q), Int(0))), is_valid=True, is_sat=True, logic=pysmt.logics.LIA ), # exists r . forall s . (r - s > r) Example(expr=Exists([r], ForAll([s], GT(Minus(r,s), r))), is_valid=False, is_sat=False, logic=pysmt.logics.LRA ), # forall r . exists s . (r - s > r) Example(expr=ForAll([r], Exists([s], GT(Minus(r,s), r))), is_valid=True, is_sat=True, logic=pysmt.logics.LRA ), # # UFLIRA # # ih(r,q) > p /\ (x -> y) Example(expr=And(GT(Function(ih, (r, q)), p), Implies(x, y)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_UFLIRA ), # ( (p - 3) = q ) -> ( ih(r, q + 3) > p \/ ih(r, p) <= p ) Example(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 ), # ( (ToReal(p - 3) = r) /\ (ToReal(q) = r) ) -> # ( ( ih(ToReal(p - 3), q + 3) > p ) \/ (ih(r, p) <= p) ) Example(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 ), # ! ( (ToReal(p - 3) = r /\ ToReal(q) = r) -> # ( ih(ToReal(p - 3), q + 3) > p \/ # ih(r,p) <= p ) ) Example(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 ), ] return result