Example #1
0
    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))
Example #2
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)]))
Example #3
0
    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)
Example #4
0
 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)
Example #5
0
    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")
Example #6
0
 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)
Example #7
0
    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)
Example #8
0
    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)
Example #9
0
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())
Example #10
0
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
Example #11
0
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())
Example #12
0
 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)')
Example #13
0
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
Example #14
0
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())
Example #15
0
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)
Example #16
0
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