Ejemplo n.º 1
0
def normalize(model, seed, sample_count, engine='pa'):
    
    if engine == 'pa':
        solver = PredicateAbstractionEngine(model.domain, model.support, model.weightfun)
    elif engine == 'rej':
        solver = RejectionEngine(model.domain, model.support, model.weightfun,
                                 sample_count=sample_count, seed=seed)
    else:
        raise NotImplementedError()

    Z = solver.compute_volume()

    assert(Z >= 0), "Z is negative"

    if not np.isclose(Z, 1.0):
        logger.debug("Normalizing w with Z: {}".format(Z))
        model.weightfun = Times(Real(1.0/Z), model.weightfun)

    return Z
def test_adaptive_unweighted_real():
    domain = Domain.make([], ["x", "y"], [(-5, 10), (-5, 10)])
    x, y = domain.get_symbols(domain.variables)
    support = (x >= -4) & (x <= y) & (y <= 9) & ((y <= -1) | (y >= 6))
    weight = Real(1.0)
    engine = AdaptiveRejection(domain, support, weight, SAMPLE_COUNT,
                               SAMPLE_COUNT / 10)
    computed_volume = engine.compute_volume()
    rejection_engine = RejectionEngine(domain, support, weight, SAMPLE_COUNT)
    correction_volume_rej = rejection_engine.compute_volume()
    print(computed_volume, correction_volume_rej,
          APPROX_ERROR * correction_volume_rej)
    assert computed_volume == pytest.approx(correction_volume_rej,
                                            rel=APPROX_ERROR)

    query = x <= y / 2
    prob_adaptive = engine.compute_probability(query)
    prob_rej = rejection_engine.compute_probability(query)
    assert prob_adaptive == pytest.approx(prob_rej, rel=APPROX_ERROR)
Ejemplo n.º 3
0
    def test_msat_back_simple(self):
        from pysmt.solvers.msat import MathSAT5Solver, MSatConverter

        env = get_env()
        msat = MathSAT5Solver(environment=env, logic=QF_UFLIRA)
        new_converter = MSatConverter(env, msat.msat_env)

        r, s = FreshSymbol(REAL), FreshSymbol(INT)
        f1 = GT(r, Real(1))
        f2 = LE(Plus(s, Int(2)), Int(3))
        f3 = LE(Int(2), Int(3))
        f = And(f1, f2, f3)

        term = new_converter.convert(f)
        res = new_converter.back(term)

        # Checking equality is not enough: MathSAT can change the
        # shape of the formula into a logically equivalent form.
        self.assertTrue(is_valid(Iff(f, res), logic=QF_UFLIRA))
Ejemplo n.º 4
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)]))
Ejemplo n.º 5
0
def SpinTimes(spin, bias):
    """Define our own multiplication for bias times spins. This allows for
    cleaner log code as well as value checking.

    Args:
        spin (int): -1 or 1
        bias (:class:`pysmt.shortcuts.Symbol`): The bias

    Returns:
        spins * bias

    """
    if not isinstance(spin, int):
        raise TypeError('spin must be an int')
    if spin == -1:
        return Times(Real((-1, 1)), bias)  # -1 / 1
    elif spin == 1:
        # identity
        return bias
    else:
        raise ValueError('expected spins to be -1., or 1.')
Ejemplo n.º 6
0
    def test_substitution_complex(self):
        x, y = Symbol("x", REAL), Symbol("y", REAL)
        # y = 0 /\ (Forall x. x > 3 /\ y < 2)
        f = And(Equals(y, Real(0)),
                ForAll([x], And(GT(x, Real(3)), LT(y, Real(2)))))

        subs = {
            y: Real(0),
            ForAll([x], And(GT(x, Real(3)), LT(y, Real(2)))): TRUE()
        }
        f_subs = substitute(f, subs).simplify()
        if self.env.SubstituterClass == MGSubstituter:
            self.assertEqual(f_subs, TRUE())
        else:
            # In the MSS the y=0 substitution is performed first,
            # therefore, the overall quantified expression does not
            # match the one defined in the substitution map.
            # See test_substitution_complex_mss for a positive example.
            self.assertEqual(f_subs, ForAll([x], GT(x, Real(3))))
Ejemplo n.º 7
0
def test_trivial_weight_function_partial():
    # Support:  (a | b) & (~a | ~b) & (x >= 0) & (x <= y) & (y <= 10)
    # Weight:   1

    domain = Domain.make(["a", "b"], ["x", "y"], [(0, 1), (0, 1)])
    a, b, x, y = domain.get_symbols(domain.variables)
    support = (a | b) & (~a | ~b) & (x >= 0) & (x <= y) & (y <= 1)
    weight = Real(1.0)
    computed_volume = XsddEngine(
        domain=domain,
        support=support,
        weight=weight,
        convex_backend=EngineConvexIntegrationBackend(PyXaddEngine()),
    ).compute_volume()
    correction_volume_rej = RejectionEngine(domain, support, weight,
                                            1000000).compute_volume()
    correction_volume_xadd = PyXaddEngine(domain, support,
                                          weight).compute_volume()
    # print(correction_volume_rej, correction_volume_xadd, computed_volume)
    assert computed_volume == pytest.approx(correction_volume_rej, rel=ERROR)
    assert computed_volume == pytest.approx(correction_volume_xadd, rel=ERROR)
Ejemplo n.º 8
0
def filter_intervals(bounds: List, var, domains, solver_name='msat'):
    min_bound, max_bound = min(bounds), max(bounds)
    extended_bounds = bounds + [min_bound - 1, max_bound + 1]  # replace inf
    extended_bounds.sort()

    intervals = list(zip(extended_bounds, extended_bounds[1:]))
    res_intervals = []
    for start, end in intervals:
        test_point = (start + end) * 0.5
        test = Equals(var, Real(test_point))
        problem = domains.And(test)
        with Solver(name=solver_name) as solver:
            solver.add_assertion(problem)
            if solver.solve():
                if start < min_bound:
                    res_intervals.append([float('-inf'), end])
                elif end > max_bound:
                    res_intervals.append([start, float('inf')])
                else:
                    res_intervals.append([start, end])
    return res_intervals
Ejemplo n.º 9
0
    def test_propagate_toplevel(self):
        x = Symbol("x", REAL)
        y = Symbol("y", REAL)

        f = And(LT(Real(4), Times(x, x)), Equals(Real(1), x))
        fp = propagate_toplevel(f)
        self.assertTrue(fp.is_false())
        if self.env.factory.has_solvers(logic=QF_NRA):
            try:
                ok = is_valid(Iff(f, fp))
            except SolverReturnedUnknownResultError:
                ok = not logic.quantifier_free
            self.assertTrue(ok)

        f = And(LT(Real(4), Times(x, x)), Equals(y, x), Equals(y, Real(1)))
        fp = propagate_toplevel(f)
        self.assertTrue(fp.is_false())
        if self.env.factory.has_solvers(logic=QF_NRA):
            try:
                ok = is_valid(Iff(f, fp))
            except SolverReturnedUnknownResultError:
                ok = not logic.quantifier_free
            self.assertTrue(ok)

        f = And(Equals(Real(4), x), Equals(y, x), Equals(y, Real(0)))
        fp = propagate_toplevel(f)
        self.assertTrue(fp.is_false())
        fp = propagate_toplevel(f, preserve_equivalence=False)
        self.assertTrue(fp.is_false())
        fp = propagate_toplevel(f,
                                preserve_equivalence=False,
                                do_simplify=False)
        self.assertTrue(fp.is_false())

        f = Equals(Real(4), Real(5))
        fp = propagate_toplevel(f, do_simplify=False)
        self.assertTrue(fp.is_false())
Ejemplo n.º 10
0
    def test_solving_under_assumption_mixed(self):
        x = Symbol("x", REAL)
        v1 = GT(x, Real(10))
        v2 = Symbol("v2", BOOL)
        xor = Or(And(v1, Not(v2)), And(Not(v1), v2))

        for name in get_env().factory.all_solvers(logic=QF_UFLIRA):
            with Solver(name=name) as solver:
                solver.add_assertion(xor)
                res1 = solver.solve(assumptions=[v1, Not(v2)])
                model1 = solver.get_model()
                res2 = solver.solve(assumptions=[Not(v1), v2])
                model2 = solver.get_model()
                res3 = solver.solve(assumptions=[v1, v2])
                self.assertTrue(res1)
                self.assertTrue(res2)
                self.assertFalse(res3)

                self.assertEqual(model1.get_value(v1), TRUE())
                self.assertEqual(model1.get_value(v2), FALSE())
                self.assertEqual(model2.get_value(v1), FALSE())
                self.assertEqual(model2.get_value(v2), TRUE())
Ejemplo n.º 11
0
    def compensating_potentials(self, n_comp_lits):
        winit = lambda x: safeexp(self.rand_gen.random())
        comp_pots = {}
        init_w = 1
        for k in self.relaxations:
            if len(k) == 1:
                continue
            x, y = k
            xc = self.relaxations[(x,y)]['copy_name']
            var_x = self.primal.nodes()[x]['var']
            var_xc = self.primal.nodes()[xc]['var']
            
            if x not in comp_pots:
                # REM model for 'x'
                rem = MP2WMI(self.primal.get_univariate_formula(x), Real(1),
                             n_processes=self.n_processes)

                # sampling compensating potentials for 'x'
                # original = [[self.sample_comp_literal(var_x), winit(None)]
                #             for _ in range(n_comp_lits)]
                # try uniform weights
                original = [[self.sample_comp_literal(var_x), init_w]
                            for _ in range(n_comp_lits)]
                print(f"%%%%%%% var {x} compensating literals:")
                for lit, w in original:
                    print(f"%%%%%%% {lit}")
                comp_pots[x] = (rem, original, {})
            else:
                original = comp_pots[x][1]

            # using the same comp lits for the copies of 'x'
            # comp_pots[x][2][xc] = [
            #     [substitute(lit, {var_x: var_xc}), winit(None)]
            #     for lit, _ in original]
            comp_pots[x][2][xc] = [
                [substitute(lit, {var_x: var_xc}), init_w]
                for lit, _ in original]

        return comp_pots
Ejemplo n.º 12
0
def SMT_solver(rule, a, b, feature_num, con_num, data):
    letters = []
    letters1 = []
    for i in range(feature_num):
        letters.append(Symbol('x' + str(i), REAL))
        letters1.append(Symbol('x_' + str(i), INT))

    domains = And([
        And(GE(letters[i], Real(float(a[i]))),
            LE(letters[i], Real(float(b[i])))) for i in range(feature_num)
    ])
    problem_rule = []

    for node in rule:
        if node[1] == ">":
            problem_rule.append(GT(letters[node[0]], Real(float(node[2]))))
        else:
            problem_rule.append(LE(letters[node[0]], Real(float(node[2]))))

    problem = And(problem_rule)

    constraint = And([
        And(
            Implies(Equals(letters[i], Real(float(data[i]))),
                    Equals(letters1[i], Int(0))),
            Implies(NotEquals(letters[i], Real(float(data[i]))),
                    Equals(letters1[i], Int(1)))) for i in range(feature_num)
    ])
    sum_letters1 = Plus(letters1)
    problem1 = LE(sum_letters1, Int(con_num))
    formula = And([domains, problem, constraint, problem1])

    test_case = []
    with Solver(name='z3', random_seed=23) as solver:
        solver.add_assertion(formula)
        if solver.solve():
            for l in letters:
                ans = solver.get_py_value(l)
                test_case.append(float(ans))
            print("find a solution")
        # else:
        #     print("No solution found")

    return test_case
Ejemplo n.º 13
0
    def renormalize(self, support):
        assert (support is not None), "Can't renormalize with support = None"
        self.support = support

        # mark the tree
        queue = []
        for leaf in self.root.get_leaves():
            domA = [
                var.symbol_name() for var in leaf.bounds
                if var.symbol_type() == BOOL
            ]
            domX = []
            bs = []
            for var, b in leaf.bounds.items():
                if var.symbol_type() == REAL:
                    domX.append(var.symbol_name())
                    bs.append(tuple(b))

            domain = Domain.make(domA, domX, bs)
            intersection = And(support, leaf.bounds_to_SMT())
            engine = PredicateAbstractionEngine(domain, intersection, Real(1))
            intervol = engine.compute_volume()
            leaf.marked = intervol <= 0
            if leaf.marked:
                logger.debug("Marked a leaf")
                queue.append(leaf)

        while len(queue) > 0:
            n = queue.pop(0)
            if not n.parent.marked:
                if n.parent.pos.marked and n.parent.neg.marked:
                    n.parent.marked = True
                    queue.append(n.parent)

        self.root.merge_marked()
        self.root.renormalize_node(support)
Ejemplo n.º 14
0
def sympy2pysmt(expression):
    """Converts a sympy formula representing a polynomial into a  pysmt formula.
    
    Keyword arguments:
    expression -- sympy formula.

    Raises:
    WMIParsingError -- If it fails to parse the formula.

    """
    if expression.is_Add:
        return Plus(map(sympy2pysmt, expression.args))
    elif expression.is_Mul:
        return Times(map(sympy2pysmt, expression.args))
    elif expression.is_Pow:
        base, exp = expression.args
        return Pow(sympy2pysmt(base), sympy2pysmt(exp))
    elif expression.is_Symbol:
        return Symbol(str(expression), REAL)
    elif expression.is_Number:
        return Real(float(expression))
    else:
        msg = "Couldn't parse the sympy formula: " + str(expression)
        raise WMIParsingError(msg, None)
Ejemplo n.º 15
0
def check_Z_normalize(model, seed, sample_count):
    """Tests whether the model is normalized. If not, updates the weight
    function accordingly."""

    logger.debug("Approximating Z")
    solver = RejectionEngine(model.domain, model.support, model.weightfun,
                             sample_count=sample_count, seed=seed)
    all_ohes = dict()
    for var in model.domain.bool_vars:
        print("VAR:", var)
        if "_OHE_" in var:
            prefix = var.partition("_OHE_")[0]
            if prefix not in all_ohes:
                all_ohes[prefix] = []

            all_ohes[prefix].append(var)
    ohe_variables = list(all_ohes.values()) if len(all_ohes) > 0 else None
    Z_approx = solver.compute_volume(ohe_variables=ohe_variables)
    logger.debug("Z_approx: {}".format(Z_approx))
    if Z_approx <= 0:
        raise ModelException("Partition function is <= 0")
    
    if not abs(Z_approx - 1.0) <= DEF_CLOSE_ENOUGH:
        model.weightfun = Times(Real(float(1.0/Z_approx)), model.weightfun)
Ejemplo n.º 16
0
    def test_div_pow(self):
        x = FreshSymbol(REAL)
        f = Equals(Times(Real(4), Pow(x, Real(-1))), Real(2))
        try:
            self.assertTrue(is_sat(f))
        except SolverReturnedUnknownResultError:
            pass

        f = Equals(Div(Real(4), x), Real(2))
        try:
            self.assertTrue(is_sat(f, solver_name="z3"))
        except SolverReturnedUnknownResultError:
            pass

        f = Equals(Times(x, x), Real(16))
        try:
            self.assertTrue(is_sat(f))
        except SolverReturnedUnknownResultError:
            pass
Ejemplo n.º 17
0
    def __init__(self,
                 symbol: FNode,
                 label: int,
                 domains: FNode = None,
                 cache: bool = True,
                 n_bbox: int = 2,
                 xrange: float = 1):
        """
        :param symbol:
        :param label:
        :param domains:
        :param cache:
        :param n_bbox: the number of disjuctive intervals in domain
        :param xrange:  the range of the whole bounding box,
        from -xrange to xrange
        """
        self.symbol = symbol
        self.label = label
        self.edges = defaultdict(list)  # key label to value TEdge
        self.children = []  # a list of TNode
        self.domains = domains or And(symbol >= Real(-1), symbol <= Real(1))
        if domains:
            self.domains = domains
        else:
            intervals = get_bounding_box(n_bbox, xrange)
            clauses = []
            pre_start, pre_end = intervals[0]
            clauses.append(LE(Real(pre_start), symbol))
            for start, end in intervals[1:]:
                clauses.append(
                    Or(LE(symbol, Real(pre_end)), LE(Real(start), symbol)))
                pre_end = end
            clauses.append(LE(symbol, Real(pre_end)))
            self.domains = And([c for c in clauses])

        self.initiations = []
        if cache:
            self.cache_index = []
            self.cache = dict()
            self.cache_ide = []  # cache intervals and degree
Ejemplo n.º 18
0
 def test_times_one(self):
     r = Symbol("r", REAL)
     f = Times(r, r, Real(1))
     f = f.simplify()
     self.assertNotIn(Real(1), f.args())
Ejemplo n.º 19
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
Ejemplo n.º 20
0
 def test_array_value_get(self):
     ax = Array(
         REAL, Real(0), {
             Real(1): Real(2),
             Real(2): Real(3),
             Real(3): Real(4),
             Real(4): Real(5),
         })
     self.assertEqual(ax.array_value_get(Real(1)), Real(2))
     self.assertEqual(ax.array_value_get(Real(2)), Real(3))
     self.assertEqual(ax.array_value_get(Real(3)), Real(4))
     self.assertEqual(ax.array_value_get(Real(4)), Real(5))
     self.assertEqual(ax.array_value_get(Real(-1)), Real(0))
     self.assertEqual(ax.array_value_get(Real(5)), Real(0))
Ejemplo n.º 21
0
    def test_times_distributivity(self):
        r = Symbol("r", REAL)
        s = Symbol("s", REAL)
        td = TimesDistributor()

        f = Times(Plus(r, Real(1)), Real(3))
        fp = td.walk(f)
        self.assertValid(Equals(f, fp), (f, fp))

        f = Times(Plus(r, Real(1)), s)
        fp = td.walk(f)
        self.assertValid(Equals(f, fp), (f, fp))

        f = Times(Plus(r, Real(1), s), Real(3))
        fp = td.walk(f)
        self.assertValid(Equals(f, fp), (f, fp))

        f = Times(Minus(r, Real(1)), Real(3))
        fp = td.walk(f)
        self.assertValid(Equals(f, fp), (f, fp))

        f = Times(Minus(r, Real(1)), s)
        fp = td.walk(f)
        self.assertValid(Equals(f, fp), (f, fp))

        f = Times(Minus(Real(1), s), Real(3))
        fp = td.walk(f)
        self.assertValid(Equals(f, fp), (f, fp))

        f = Times(Minus(r, Real(1)), Plus(r, s))
        fp = td.walk(f)
        self.assertValid(Equals(f, fp), (f, fp))

        # (r + 1) * (s-1) = r*s + (-r) + s - 1
        f = Times(Plus(r, Real(1)), Minus(s, Real(1)))
        fp = td.walk(f).simplify()
        target = Plus(Times(r, s), Times(r, Real(-1)), s, Real(-1))
        self.assertValid(Equals(fp, target), fp)
        self.assertTrue(fp.is_plus(), fp)
Ejemplo n.º 22
0
def test_normalization():
    def get_normalization_file(filename):
        return path.join(path.dirname(__file__), "res", "renorm_bug", filename)

    for i in range(5):
        domain = Domain.from_file(get_normalization_file("domain.json"))
        support = read_smtlib(get_normalization_file("vanilla.support"))
        weight = read_smtlib(get_normalization_file("vanilla.weight"))
        new_support = read_smtlib(
            get_normalization_file("renorm_chi_{}.support".format(i)))

        # print(smt_to_nested(support))

        clean_support = normalize_formula(support)
        clean_new_support = normalize_formula(new_support)
        clean_weight = normalize_formula(weight)

        print(smt_to_nested(clean_weight))

        assert (RejectionEngine(domain, ~Iff(support, clean_support),
                                Real(1.0), 1000000).compute_volume() == 0)
        assert (RejectionEngine(domain, ~Iff(new_support, clean_new_support),
                                Real(1.0), 1000000).compute_volume() == 0)

        # plot_formula("new_support", domain, new_support, ["r0", "r1"])
        # plot_formula("clean_new_support", domain, clean_new_support, ["r0", "r1"])

        support = clean_support
        new_support = clean_new_support
        weight = clean_weight

        # print(RejectionEngine(domain, Iff(weight, ~clean_weight), Real(1.0), 1000000).compute_volume())

        # print(smt_to_nested(support))

        print("Problem", i)
        engine = XaddEngine(domain, support, weight, "original")
        print("Volume before starting", engine.compute_volume())
        new_weight = engine.normalize(new_support, paths=False)

        Density(domain, new_support, new_weight).to_file("normalized.json")

        illegal_volume = XaddEngine(domain, ~new_support, new_weight,
                                    "mass").compute_volume()
        assert illegal_volume == pytest.approx(0, rel=EXACT_REL_ERROR)

        computed_volume = XaddEngine(domain, TRUE(), new_weight,
                                     "mass").compute_volume()
        computed_volume_within = XaddEngine(domain, new_support, new_weight,
                                            "mass").compute_volume()
        computed_volume_within2 = XaddEngine(domain, new_support,
                                             new_weight).compute_volume()
        computed_volume_within3 = RejectionEngine(domain, new_support,
                                                  new_weight,
                                                  1000000).compute_volume()
        print(
            "pa new_support new_weight",
            computed_volume_within,
            "xadd new_support new_weight:",
            computed_volume_within2,
            "rej new_support new_weight:",
            computed_volume_within3,
        )
        assert computed_volume_within == pytest.approx(computed_volume_within2,
                                                       EXACT_REL_ERROR)
        print(
            "pa true new_weight:",
            computed_volume,
            "pa new_support new_weight",
            computed_volume_within,
            "pa outside new_support new_weight",
            illegal_volume,
        )
        assert computed_volume == pytest.approx(1, rel=EXACT_REL_ERROR)
        assert computed_volume_within == pytest.approx(1, rel=EXACT_REL_ERROR)

        illegal_volume = engine.copy_with(support=~new_support,
                                          weight=new_weight).compute_volume()
        assert illegal_volume == pytest.approx(0, rel=EXACT_REL_ERROR)
Ejemplo n.º 23
0
    def test_sample(self, sample):
        """
            Check whether or not the encoding "predicts" the same class
            as the classifier given an input sample.
        """

        # first, compute the scores for all classes as would be
        # predicted by the classifier

        # score arrays computed for each class
        csum = [[] for c in range(self.nofcl)]

        if self.optns.verb:
            print('testing sample:', list(sample))

        sample_internal = list(self.xgb.transform(sample)[0])

        # traversing all trees
        for i, tree in enumerate(self.ensemble.trees):
            # getting class id
            clid = i % self.nofcl

            # a score computed by the current tree
            score = scores_tree(tree, sample_internal)

            # this tree contributes to class with clid
            csum[clid].append(score)

        # final scores for each class
        cscores = [sum(scores) for scores in csum]

        # second, get the scores computed with the use of the encoding

        # asserting the sample
        hypos = []

        if not self.intvs:
            for i, fval in enumerate(sample_internal):
                feat, vid = self.xgb.transform_inverse_by_index(i)
                fid = self.feats[feat]

                if vid == None:
                    fvar = Symbol('f{0}'.format(fid), typename=REAL)
                    hypos.append(Equals(fvar, Real(float(fval))))
                else:
                    fvar = Symbol('f{0}_{1}'.format(fid, vid), typename=BOOL)
                    if int(fval) == 1:
                        hypos.append(fvar)
                    else:
                        hypos.append(Not(fvar))
        else:
            for i, fval in enumerate(sample_internal):
                feat, _ = self.xgb.transform_inverse_by_index(i)
                feat = 'f{0}'.format(self.feats[feat])

                # determining the right interval and the corresponding variable
                for ub, fvar in zip(self.intvs[feat], self.ivars[feat]):
                    if ub == '+' or fval < ub:
                        hypos.append(fvar)
                        break
                else:
                    assert 0, 'No proper interval found for {0}'.format(feat)

        # now, getting the model
        escores = []
        model = get_model(And(self.enc, *hypos), solver_name=self.optns.solver)
        for c in range(self.nofcl):
            v = Symbol('class{0}_score'.format(c), typename=REAL)
            escores.append(float(model.get_py_value(v)))

        assert all(map(lambda c, e: abs(c - e) <= 0.001, cscores, escores)), \
                'wrong prediction: {0} vs {1}'.format(cscores, escores)

        if self.optns.verb:
            print('xgb scores:', cscores)
            print('enc scores:', escores)
Ejemplo n.º 24
0
def expr_to_pysmt(context: TranslationContext,
                  expr: Expr,
                  *,
                  is_expectation: bool = False,
                  allow_infinity: bool = False) -> FNode:
    """
    Translate a pGCL expression to a pySMT formula.

    Note that substitution expressions are not allowed here (they are not
    supported in pySMT).

    You can pass in the optional `is_expectation` parameter to have all integer
    values converted to real values.

    If `allow_infinity` is `True`, then infinity expressions will be mapped
    directly to the `infinity` variable of the given
    :py:class:`TranslationContext`. Take care to appropriately constrain the
    `infinity` variable! Note that arithmetic expressions may not contain
    infinity, to prevent expressions like `infinity - infinity`.

    .. doctest::

        >>> from probably.pgcl.parser import parse_expr
        >>> from pysmt.shortcuts import Symbol
        >>> from pysmt.typing import INT

        >>> expr = parse_expr("x + 4 * 13")
        >>> context = TranslationContext({"x": Symbol("x", INT)})
        >>> expr_to_pysmt(context, expr)
        (x + (4 * 13))
    """
    if isinstance(expr, BoolLitExpr):
        return TRUE() if expr.value else FALSE()
    elif isinstance(expr, NatLitExpr):
        if is_expectation:
            return ToReal(Int(expr.value))
        else:
            return Int(expr.value)
    elif isinstance(expr, FloatLitExpr):
        if expr.is_infinite():
            if not allow_infinity:
                raise Exception(
                    f"Infinity is not allowed in this expression: {expr}")
            return context.infinity
        else:
            return Real(Fraction(expr.value))
    elif isinstance(expr, VarExpr):
        var = context.variables[expr.var]
        if is_expectation and get_type(var) == INT:
            var = ToReal(var)
        return var
    elif isinstance(expr, UnopExpr):
        operand = expr_to_pysmt(context,
                                expr.expr,
                                is_expectation=False,
                                allow_infinity=allow_infinity)
        if expr.operator == Unop.NEG:
            return Not(operand)
        elif expr.operator == Unop.IVERSON:
            return Ite(operand, Real(1), Real(0))
    elif isinstance(expr, BinopExpr):
        # `is_expectation` is disabled if we enter a non-arithmetic expression
        # (we do not convert integers to reals within a boolean expression such
        # as `x == y`, for example).
        #
        # Similarly, `allow_infinity` is disabled if we enter an arithmetic
        # expression because calculations with infinity are hard to make sense of.
        is_arith_op = expr.operator in [Binop.PLUS, Binop.MINUS, Binop.TIMES]
        is_expectation = is_expectation  # TODO: and is_arith_op
        allow_infinity = allow_infinity  # TODO: and not is_arith_op?!??!
        lhs = expr_to_pysmt(context,
                            expr.lhs,
                            is_expectation=is_expectation,
                            allow_infinity=allow_infinity)
        rhs = expr_to_pysmt(context,
                            expr.rhs,
                            is_expectation=is_expectation,
                            allow_infinity=allow_infinity)
        if expr.operator == Binop.OR:
            return Or(lhs, rhs)
        elif expr.operator == Binop.AND:
            return And(lhs, rhs)
        elif expr.operator == Binop.LEQ:
            return LE(lhs, rhs)
        elif expr.operator == Binop.LE:
            return LT(lhs, rhs)
        elif expr.operator == Binop.EQ:
            return EqualsOrIff(lhs, rhs)
        elif expr.operator == Binop.PLUS:
            return Plus(lhs, rhs)
        elif expr.operator == Binop.MINUS:
            return Ite(LE(lhs, rhs),
                       (Int(0) if get_type(lhs) == INT else Real(0)),
                       Minus(lhs, rhs))
        elif expr.operator == Binop.TIMES:
            return Times(lhs, rhs)
    elif isinstance(expr, SubstExpr):
        raise Exception("Substitution expression is not allowed here.")

    raise Exception("unreachable")
Ejemplo n.º 25
0
    def prepare(self, sample, expl):
        """
            Prepare the oracle for validating an explanation given a sample.
        """

        if self.selv:
            # disable the previous assumption if any
            self.oracle.add_assertion(Not(self.selv))

        # creating a fresh selector for a new sample
        sname = ','.join([str(v).strip() for v in sample])

        # the samples should not repeat; otherwise, they will be
        # inconsistent with the previously introduced selectors
        assert sname not in self.idmgr.obj2id, 'this sample has been considered before (sample {0})'.format(
            self.idmgr.id(sname))
        self.selv = Symbol('sample{0}_selv'.format(self.idmgr.id(sname)),
                           typename=BOOL)

        self.rhypos = []  # relaxed hypotheses

        # transformed sample
        self.sample = list(self.xgb.transform(sample)[0])

        # preparing the selectors
        for i, (inp, val) in enumerate(zip(self.inps, self.sample), 1):
            feat = inp.symbol_name().split('_')[0]
            selv = Symbol('selv_{0}'.format(feat))
            val = float(val)

            self.rhypos.append(selv)

        # adding relaxed hypotheses to the oracle
        for inp, val, sel in zip(self.inps, self.sample, self.rhypos):
            if '_' not in inp.symbol_name():
                hypo = Implies(self.selv,
                               Implies(sel, Equals(inp, Real(float(val)))))
            else:
                hypo = Implies(self.selv, Implies(sel,
                                                  inp if val else Not(inp)))

            self.oracle.add_assertion(hypo)

        # propagating the true observation
        if self.oracle.solve([self.selv] + self.rhypos):
            model = self.oracle.get_model()
        else:
            assert 0, 'Formula is unsatisfiable under given assumptions'

        # choosing the maximum
        outvals = [float(model.get_py_value(o)) for o in self.outs]
        maxoval = max(zip(outvals, range(len(outvals))))

        # correct class id (corresponds to the maximum computed)
        true_output = maxoval[1]

        # forcing a misclassification, i.e. a wrong observation
        disj = []
        for i in range(len(self.outs)):
            if i != true_output:
                disj.append(GT(self.outs[i], self.outs[true_output]))
        self.oracle.add_assertion(Implies(self.selv, Or(disj)))

        # removing all hypotheses except for those in the explanation
        hypos = []
        for i, hypo in enumerate(self.rhypos):
            j = self.ftids[self.xgb.transform_inverse_by_index(i)[0]]
            if j in expl:
                hypos.append(hypo)
        self.rhypos = hypos

        if self.verbose:
            inpvals = self.xgb.readable_sample(sample)

            preamble = []
            for f, v in zip(self.xgb.feature_names, inpvals):
                if f not in v:
                    preamble.append('{0} = {1}'.format(f, v))
                else:
                    preamble.append(v)

            print('  explanation for:  "IF {0} THEN {1}"'.format(
                ' AND '.join(preamble), self.xgb.target_name[true_output]))
Ejemplo n.º 26
0
def minReward(intents, queries, tuples, matches, minRewardValue):
	userStrategy = dict()
	dbmsStrategy = dict()
	rewardMatrix = constructRewardMatrix(intents, tuples, matches)
	letters = set()

	#User Strategy matrix, each cell holds a variable for the SMT
	for intent in intents:
		if intent not in userStrategy:
			userStrategy[intent] = dict()
		for query in queries:
			userStrategy[intent][query] = Symbol('User['+intent + '][' + query + ']', REAL)
			letters.add(userStrategy[intent][query])
			
	#DBMS Strategy matrix, each cell holds a variable for the SMT
	for query in queries:
		if query not in dbmsStrategy:
			dbmsStrategy[query] = dict()
		for tup in tuples:
			dbmsStrategy[query][tup] = Symbol('DBMS['+query + '][' + tup + ']', REAL)
			letters.add(dbmsStrategy[query][tup])

	#Tells the range of values, for now set to Pure strategy so [0,1]
	domains = And([Or(Equals(l, Real(0)), Equals(l, Real(1))) for l in letters])

	#Adds each row of the user strategy
	stochasticMatrixUser = list()
	for intent in intents:
		stochasticMatrixUser.append(Plus(userStrategy[intent].values()))
	
	#Adds each row of the DBMS strategy
	stochasticMatrixdbms = list()
	for query in queries:
		stochasticMatrixdbms.append(Plus(dbmsStrategy[query].values()))
	
	#Checks the rows to make sure that the strategies are row stochastic
	stochUserEquals = [Equals(x, Real(1)) for x in stochasticMatrixUser]
	stochdbmsEquals = [Equals(x, Real(1)) for x in stochasticMatrixdbms]
	allEquals = stochdbmsEquals + stochUserEquals

	#Stochastic problem
	stochasticProblem = And(allEquals)
	if DEBUG:
		print('\nStochastic Serialization: ')
		print(stochasticProblem)
	
	#Uses Formula 1 from my paper to calculate the payoff
	reward = list()
	for intent in intents:
		for query in queries:
			for tup in tuples:
				reward.append(Times(Real(1/len(intents)), userStrategy[intent][query], dbmsStrategy[query][tup], rewardMatrix[intent][tup]))

	#Reward problem, requires a minimum reward. May not always be possible to achieve this reward
	rewardProblem = GE(Plus(reward), Real(minRewardValue))
	if DEBUG:
		print('\nReward Serialization: ')
		print(rewardProblem)

	with Solver(name="z3") as solver:
		solver.add_assertion(domains)
		if not solver.solve():
			print('No solultion available')
			return
		print('Can satisfy domains')

		solver.add_assertion(stochasticProblem)
		if not solver.solve():
			print('No sulution available')
			return
		print('Can satisfy stochastic')
		
		solver.add_assertion(rewardProblem)
		if not solver.solve():
			print('No solution available')
			return
		print('Can satisfy minimum reward')

		for intent in intents:
			for query in queries:
				print("%s = %s" % (userStrategy[intent][query], solver.get_value(userStrategy[intent][query])))

		for query in queries:
			for tup in tuples:
				print("%s = %s" % (dbmsStrategy[query][tup], solver.get_value(dbmsStrategy[query][tup])))
Ejemplo n.º 27
0
            else:
                raise WMIParsingError("Unhandled formula format", formula)


if __name__ == "__main__":
    from pysmt.shortcuts import Symbol, Ite, And, LE, LT, Real, Times, serialize
    from pysmt.typing import REAL

    def compute_print(method, query, evidence):
        print("query: ", serialize(query))
        print("evidence: ", serialize(evidence) if evidence else "-")
        prob = method.compute_normalized_probability(query, evidence)
        print("normalized: ", prob)
        print("--------------------------------------------------")

    x = Symbol("x", REAL)
    A = Symbol("A")
    support = And(LE(Real(-1), x), LE(x, Real(1)))
    weights = Ite(LT(Real(0), x), Ite(A, Times(Real(2), x), x),
                  Ite(A, Times(Real(-2), x), Times(Real(-1), x)))

    praise = PRAiSEInference(support, weights)
    print("support: ", serialize(support))
    print("weights: ", serialize(weights))
    print("==================================================")

    suite = [(A, None), (And(A, LE(Real(0), x)), None), (LE(Real(0), x), A)]

    for query, evidence in suite:
        compute_print(praise, query, evidence)
Ejemplo n.º 28
0
    def prepare(self, sample):
        """
            Prepare the oracle for computing an explanation.
        """

        if self.selv:
            # disable the previous assumption if any
            self.oracle.add_assertion(Not(self.selv))

        # creating a fresh selector for a new sample
        sname = ','.join([str(v).strip() for v in sample])

        # the samples should not repeat; otherwise, they will be
        # inconsistent with the previously introduced selectors
        assert sname not in self.idmgr.obj2id, 'this sample has been considered before (sample {0})'.format(
            self.idmgr.id(sname))
        self.selv = Symbol('sample{0}_selv'.format(self.idmgr.id(sname)),
                           typename=BOOL)

        self.rhypos = []  # relaxed hypotheses

        # transformed sample
        self.sample = list(self.xgb.transform(sample)[0])

        self.sel2fid = {}  # selectors to original feature ids
        self.sel2vid = {}  # selectors to categorical feature ids

        # preparing the selectors
        for i, (inp, val) in enumerate(zip(self.inps, self.sample), 1):
            feat = inp.symbol_name().split('_')[0]
            selv = Symbol('selv_{0}'.format(feat))
            val = float(val)

            self.rhypos.append(selv)
            if selv not in self.sel2fid:
                self.sel2fid[selv] = int(feat[1:])
                self.sel2vid[selv] = [i - 1]
            else:
                self.sel2vid[selv].append(i - 1)

        # adding relaxed hypotheses to the oracle
        if not self.intvs:
            for inp, val, sel in zip(self.inps, self.sample, self.rhypos):
                if '_' not in inp.symbol_name():
                    hypo = Implies(self.selv,
                                   Implies(sel, Equals(inp, Real(float(val)))))
                else:
                    hypo = Implies(self.selv,
                                   Implies(sel, inp if val else Not(inp)))

                self.oracle.add_assertion(hypo)
        else:
            for inp, val, sel in zip(self.inps, self.sample, self.rhypos):
                inp = inp.symbol_name()
                # determining the right interval and the corresponding variable
                for ub, fvar in zip(self.intvs[inp], self.ivars[inp]):
                    if ub == '+' or val < ub:
                        hypo = Implies(self.selv, Implies(sel, fvar))
                        break

                self.oracle.add_assertion(hypo)

        # in case of categorical data, there are selector duplicates
        # and we need to remove them
        self.rhypos = sorted(set(self.rhypos),
                             key=lambda x: int(x.symbol_name()[6:]))

        # propagating the true observation
        if self.oracle.solve([self.selv] + self.rhypos):
            model = self.oracle.get_model()
        else:
            assert 0, 'Formula is unsatisfiable under given assumptions'

        # choosing the maximum
        outvals = [float(model.get_py_value(o)) for o in self.outs]
        maxoval = max(zip(outvals, range(len(outvals))))

        # correct class id (corresponds to the maximum computed)
        self.out_id = maxoval[1]
        self.output = self.xgb.target_name[self.out_id]

        # forcing a misclassification, i.e. a wrong observation
        disj = []
        for i in range(len(self.outs)):
            if i != self.out_id:
                disj.append(GT(self.outs[i], self.outs[self.out_id]))
        self.oracle.add_assertion(Implies(self.selv, Or(disj)))

        if self.verbose:
            inpvals = self.xgb.readable_sample(sample)

            self.preamble = []
            for f, v in zip(self.xgb.feature_names, inpvals):
                if f not in v:
                    self.preamble.append('{0} = {1}'.format(f, v))
                else:
                    self.preamble.append(v)

            print('  explaining:  "IF {0} THEN {1}"'.format(
                ' AND '.join(self.preamble), self.output))
Ejemplo n.º 29
0
def findNashEquilibria(intents, queries, tuples, matches, strict, minReward, minRewardValue):
	userStrategy = dict()
	dbmsStrategy = dict()
	nashUserStrategy = dict()
	nashdbmsStrategy = dict()
	rewardMatrix = constructRewardMatrix(intents, tuples, matches)
	letters = set()
	nashRestrictions = list()

	#User Strategy matrix, each cell holds a variable for the SMT
	for intent in intents:
		if intent not in userStrategy:
			userStrategy[intent] = dict()
		for query in queries:
			userStrategy[intent][query] = Symbol('User['+intent + '][' + query + ']', REAL)
			letters.add(userStrategy[intent][query])
			
	#DBMS Strategy matrix, each cell holds a variable for the SMT
	for query in queries:
		if query not in dbmsStrategy:
			dbmsStrategy[query] = dict()
		for tup in tuples:
			dbmsStrategy[query][tup] = Symbol('DBMS['+query + '][' + tup + ']', REAL)
			letters.add(dbmsStrategy[query][tup])
	
	#We create a strategy for each move that can be made from the current position
	#This means that only a single row changes, the rest of the rows are the same as the strategies above
	#There also needs to be a strategy for each cell and a restriction only on the cell that this strategy belongs to
	for intent in intents:
		nashUserStrategy[intent] = dict()
		for query in queries:
			nashUserStrategy[intent][query] = copy.deepcopy(userStrategy)
			for query2 in copy.deepcopy(queries):
				nashUserStrategy[intent][query][intent][query2] = Symbol('Nash'+str(len(nashUserStrategy))+str(len(nashUserStrategy[intent]))+'User['+intent + '][' + query2 + ']', REAL)
				letters.add(nashUserStrategy[intent][query][intent][query2])
				if query == query2:
					nashRestrictions.append(NotEquals(nashUserStrategy[intent][query][intent][query2], userStrategy[intent][query2]))

	#Same here except for DBMS
	for query in queries:
		nashdbmsStrategy[query] = dict()
		for tup in tuples:
			nashdbmsStrategy[query][tup] = copy.deepcopy(dbmsStrategy)
			for tup2 in tuples:
				nashdbmsStrategy[query][tup][query][tup2] = Symbol('Nash'+str(len(nashdbmsStrategy))+str(len(nashdbmsStrategy[query]))+'DBMS['+query + '][' + tup2 + ']', REAL)
				letters.add(nashdbmsStrategy[query][tup][query][tup2])
				if tup == tup2:
					nashRestrictions.append(NotEquals(nashdbmsStrategy[query][tup][query][tup2], dbmsStrategy[query][tup2]))

	#Tells the range of values, for now set to Pure strategy so [0,1]
	domains = And([Or(Equals(l, Real(0)), Equals(l, Real(1))) for l in letters])
	if DEBUG:
		print('\nDomain Serialization: ')	
		print(domains)

	#Adds restriction that no value from the nashStrategies can be the same as the corresponding cell they are testing. This ensures a 'move'
	nashProblem = And(nashRestrictions)
	if DEBUG:
		print('\nNash Domain Serialization: ')
		print(nashProblem)

	#This is doing all the row stochastic stuff
	allEquals = []
	#Adds each row of the user strategy
	stochasticMatrixUser = list()
	stochasticMatrixNashUser = list()
	for intent in intents:
		stochasticMatrixUser.append(Plus(userStrategy[intent].values()))
		for query in queries:
			allEquals.append(Equals(Plus(nashUserStrategy[intent][query][intent].values()), Real(1)))
			
	#Adds each row of the DBMS strategy
	stochasticMatrixdbms = list()
	stochasticMatrixNashdbms = list()
	for query in queries:
		stochasticMatrixdbms.append(Plus(dbmsStrategy[query].values()))
		for tup in tuples:
			allEquals.append(Equals(Plus(nashdbmsStrategy[query][tup][query].values()), Real(1)))
	
	#Checks the rows to make sure that the strategies are row stochastic
	stochUserEquals = [Equals(x, Real(1)) for x in stochasticMatrixUser]
	stochdbmsEquals = [Equals(x, Real(1)) for x in stochasticMatrixdbms]
	allEquals += stochUserEquals + stochdbmsEquals

	#Stochastic problem
	stochasticProblem = And(set(allEquals))
	if DEBUG:
		print('\nStochastic Serialization: ')
		print(stochasticProblem.serialize())
	
	
	
	#Uses Formula 1 from my paper to calculate the payoff, assuming uniform prior.
	reward = list()
	for intent in intents:
		for query in queries:
			for tup in tuples:
				reward.append(Times(Real(1/len(intents)), userStrategy[intent][query], dbmsStrategy[query][tup], rewardMatrix[intent][tup]))

	#Reward problem, requires a minimum reward. May not always be possible to achieve this reward
	rewardProblem = GE(Plus(reward), Real(minRewardValue))
	if DEBUG:
		print('\nReward Serialization: ')	
		print(rewardProblem)

	nashRewardUser = dict()
	nashRewardDbms = dict()

	#Again using Formula 1, but now we are creating one for each move to make sure that it is less than (Strict Nash) or less than or equal (Nash)
	for strat in nashUserStrategy:
		if strat not in nashRewardUser:
			nashRewardUser[strat] = dict()
		for strat2 in nashUserStrategy[strat]:
			if strat2 not in nashRewardUser[strat]:
				nashRewardUser[strat][strat2] = list()
			for intent in intents:
				for query in queries:
					for tup in tuples:
						nashRewardUser[strat][strat2].append(Times(Real(1/len(intents)), nashUserStrategy[strat][strat2][intent][query], dbmsStrategy[query][tup], rewardMatrix[intent][tup]))

	#Same, but for DBMS side. Just separated them to make it cleaner
	for strat in nashdbmsStrategy:
		if strat not in nashRewardDbms:
			nashRewardDbms[strat] = dict()
		for strat2 in nashdbmsStrategy[strat]:
			if strat2 not in nashRewardDbms[strat]:
				nashRewardDbms[strat][strat2] = list()
			for intent in intents:
				for query in queries:
					for tup in tuples:
						nashRewardDbms[strat][strat2].append(Times(Real(1/len(intents)), userStrategy[intent][query], nashdbmsStrategy[strat][strat2][query][tup], rewardMatrix[intent][tup]))

	if DEBUG:
		print('\nReward Serialization Nash: ')
	
	#Check user nash
	#This is where we actually perform the checking to see if it is less than or equal (or prep to be added to the solver)
	userNash = list()
	for intent in intents:
		for query in queries:
			if strict:
				userNash.append(Implies(NotEquals(nashUserStrategy[intent][query][intent][query], userStrategy[intent][query]), LT(Plus(nashRewardUser[intent][query]), Plus(reward))))
			else:
				userNash.append(Implies(NotEquals(nashUserStrategy[intent][query][intent][query], userStrategy[intent][query]), LE(Plus(nashRewardUser[intent][query]), Plus(reward))))
						
	userNashProblem = And(userNash)

	if DEBUG:
		print(userNashProblem.serialize())

	#Check dbms nash
	dbmsNash = list()
	for query in queries:
		for tup in tuples:
			if strict:
				dbmsNash.append(Implies(NotEquals(dbmsStrategy[query][tup], nashdbmsStrategy[query][tup][query][tup]), LE(Plus(nashRewardDbms[query][tup]), Plus(reward))))
			else:
				dbmsNash.append(Implies(NotEquals(dbmsStrategy[query][tup], nashdbmsStrategy[query][tup][query][tup]), LE(Plus(nashRewardDbms[query][tup]), Plus(reward))))

	dbmsNashProblem = And(dbmsNash)

	if DEBUG:
		print(dbmsNashProblem.serialize())

	#Add each component to the solver and test as we go
	#PySMT has another method where you just AND everything together, but they suggest
	#this method as it looks cleaner and you can see which one fails, if any
	with Solver(name="z3") as solver:
		solver.add_assertion(domains)
		if not solver.solve():
			print('No solultion available (domains)')
			return
		print('Can satisfy domains')

		solver.add_assertion(nashProblem)
		if not solver.solve():
			print('No solultion available (nash restrictions)')
			return
		print('Can satisfy nash domains')
		
		solver.add_assertion(stochasticProblem)
		if not solver.solve():
			print('No sulution available (stochastic)')
			return
		print('Can satisfy stochastic')
		
		if minReward:
			solver.add_assertion(rewardProblem)
			if not solver.solve():
				print('No solution available')
				return
			print('Can satisfy minimum reward')
		
		solver.add_assertion(userNashProblem)
		if not solver.solve():
			print('No solution available (user nash)')
			return

		print('Can satisfy user nash')

		solver.add_assertion(dbmsNashProblem)
		if not solver.solve():
			print('No solution available (dbms nash)')
			return
		print('Can satisfy dbms nash')

		#Print out the final assignments if it made it this far, as a solution exists
		for intent in intents:
			for query in queries:
				print("%s = %s" % (userStrategy[intent][query], solver.get_value(userStrategy[intent][query])))

		for query in queries:
			for tup in tuples:
				print("%s = %s" % (dbmsStrategy[query][tup], solver.get_value(dbmsStrategy[query][tup])))
Ejemplo n.º 30
0
 def test_oracle(self):
     x = FreshSymbol(REAL)
     f = Equals(Times(x, x), Real(2))
     logic = get_logic(f)
     self.assertFalse(logic.theory.linear)