Exemplo n.º 1
0
    def cosine_law_crit_angle(self):
        """Use cosine law to find cos^2(theta) between three points
        node1---node2---node3 to assert that it is less than cos^2(thetaC)
        where thetaC is the critical crossing angle

        :param node1: Outside node
        :param node2: Middle connecting node
        :param node3: Outside node
        :returns: cos^2 as calculated using cosine law (a_dot_b^2/a^2*b^2)
        """
        node1 = self.get_input_nodes().values()[0]
        node2 = self.get_input_nodes().values()[1]
        node3 = self.get_output_node()

        # Lengths of channels
        aX = Minus(node1.get_x(), node2.get_x())
        aY = Minus(node1.get_y(), node2.get_y())
        bX = Minus(node3.get_x(), node2.get_x())
        bY = Minus(node3.get_y(), node2.get_y())
        # Dot products between each channel
        a_dot_b_squared = Pow(Plus(Times(aX, bX), Times(aY, bY)), Real(2))
        a_squared_b_squared = Times(
            Plus(Times(aX, aX), Times(aY, aY)),
            Plus(Times(bX, bX), Times(bY, bY)),
        )
        return Div(a_dot_b_squared, a_squared_b_squared)
Exemplo n.º 2
0
    def test_real(self):
        f = Plus([ Real(1),
                   Symbol("x", REAL),
                   Symbol("y", REAL)])

        self.assertEqual(f.to_smtlib(daggify=False), "(+ 1.0 x y)")
        self.assertEqual(f.to_smtlib(daggify=True), "(let ((.def_0 (+ 1.0 x y))) .def_0)")
Exemplo n.º 3
0
def process():
    varA = Symbol("A")
    varB = Symbol("B")
    f = And(varA, Not(varB))
    print(f)
    print(is_sat(f))

    hello = [Symbol(s, INT) for s in "hello"]
    world = [Symbol(s, INT) for s in "world"]

    letters = set(hello + world)

    domains = And(And(LE(Int(1), l),
                      GE(Int(10), l)) for l in letters)
    print(domains,'domain')
    sum_hello = Plus(hello)
    sum_world = Plus(world)

    problem = And(Equals(sum_hello, sum_world),
                  Equals(sum_hello, Int(36)))

    formula = And(domains, problem)

    print("Serialization of the formula:")
    print(formula)
    print(formula.serialize())
    print(is_sat(formula))
    print(get_model(formula))
Exemplo n.º 4
0
    def test_plus_negatives(self):
        r0 = Symbol("r0", REAL)
        r1 = Symbol("r1", REAL)
        p_1 = Real(1)
        m_1 = Real(-1)
        p_2 = Real(2)
        m_4 = Real(-4)

        # 4 * r0 + (-1) * r1 + 2 - 4
        neg_r1 = Times(m_1, r1)
        m_4_r0 = Times(Real(4), r0)
        expr = Plus(m_4_r0, neg_r1, p_2, m_4)
        res = expr.simplify()
        self.assertValid(Equals(expr, res))
        stack = [res]
        while stack:
            curr = stack.pop()
            if curr.is_plus():
                stack.extend(curr.args())
            elif curr.is_minus():
                stack.extend(curr.args())
            elif curr.is_times():
                stack.extend(curr.args())
            elif curr.is_constant():
                self.assertNotEqual(curr, m_1)
                self.assertNotEqual(curr, p_1)
            elif not curr.is_symbol():
                # unexpected expression type.
                self.assertTrue(False)
Exemplo n.º 5
0
def vertex_cover_solver(graph, k):
    vertexes, edges = graph

    # vertex in vertex cover 1 otherwise 0
    vertex_vars = [Symbol(v, INT) for v in vertexes]
    vertex_range = And(
        [And(GE(v, Int(0)), LE(v, Int(1))) for v in vertex_vars])

    # size of vertex cover <= k
    sum_vertex = Plus(vertex_vars)
    vertex_constraint = LE(sum_vertex, Int(k))

    # edge constraints
    # Plus(vi, vj) >= 1 for edge = (vi, vj)
    # cannot use Or(vi, vj), because variables are integers not boolean type
    edge_constraint = And([
        GE(Plus([vertex_vars[lv], vertex_vars[rv]]), Int(1))
        for (lv, rv) in edges
    ])

    # combined formula
    formula = And(vertex_range, vertex_constraint, edge_constraint)

    model = get_model(formula)
    size = get_formula_size(formula)
    cover = set()
    if model:
        for i, node in enumerate(vertexes):
            if model.get_py_value(vertex_vars[i]):
                cover.add(node)
        return cover, formula, size
    else:
        return None, formula, size
Exemplo n.º 6
0
def main():
    # Example Transition System (SMV-like syntax)
    #
    # VAR x: integer;
    #     y: integer;
    #
    # INIT: x = 1 & y = 2;
    #
    # TRANS: next(x) = x + 1;
    # TRANS: next(y) = y + 2;

    x, y = [Symbol(s, INT) for s in "xy"]
    nx, ny = [next_var(Symbol(s, INT)) for s in "xy"]

    example = TransitionSystem(variables=[x, y],
                               init=And(Equals(x, Int(1)), Equals(y, Int(2))),
                               trans=And(Equals(nx, Plus(x, Int(1))),
                                         Equals(ny, Plus(y, Int(2)))))

    # A true invariant property: y = x * 2
    true_prop = Equals(y, Times(x, Int(2)))

    # A false invariant property: x <= 10
    false_prop = LE(x, Int(10))

    for prop in [true_prop, false_prop]:
        check_property(example, prop)
        print("")
Exemplo n.º 7
0
def construct_spread_formula_from_graph(spread_graph, limit, target):
    initial_infection_ints = [
        Symbol('init_int_' + str(i), INT) for i in spread_graph.nodes
    ]
    final_infection_ints = [
        Symbol('final_int_' + str(i), INT) for i in spread_graph.nodes
    ]

    spreading_clauses = []
    origin_clauses = []
    all_bounds = []

    # Here, we ensure that, if node i is selected as an initial infector, all of its neighbors are also infected:
    for starting_node in spread_graph.nodes:
        initial_infection_bounds = And(
            LE(initial_infection_ints[int(starting_node)], Int(1)),
            GE(initial_infection_ints[int(starting_node)], Int(0)))

        infected_neighbors = And([
            Equals(final_infection_ints[int(i)], Int(1))
            for i in spread_graph.successors(starting_node)
        ])
        infected_nodes = And(
            infected_neighbors,
            Equals(final_infection_ints[int(starting_node)], Int(1)))
        spreading_forumla = Implies(
            Equals(initial_infection_ints[int(starting_node)], Int(1)),
            infected_nodes)

        spreading_clauses.append(spreading_forumla)
        all_bounds.append(initial_infection_bounds)

    # Here, we ensure that, if node i becomes infected, either it was infected by an initial infectors with an edge to node i
    # of node i itself was an initial infector.
    for infected_node in spread_graph.nodes:
        final_infection_bounds = And(
            LE(final_infection_ints[int(infected_node)], Int(1)),
            GE(final_infection_ints[int(infected_node)], Int(0)))

        origin_neighbors = Or([
            Equals(initial_infection_ints[int(i)], Int(1))
            for i in spread_graph.predecessors(infected_node)
        ])
        origin_nodes = Or(
            origin_neighbors,
            Equals(initial_infection_ints[int(infected_node)], Int(1)))
        origin_formula = Implies(
            Equals(final_infection_ints[int(infected_node)], Int(1)),
            origin_nodes)

        origin_clauses.append(origin_formula)
        all_bounds.append(final_infection_bounds)

    initial_infection_limit = LE(Plus(initial_infection_ints), Int(limit))
    final_infection_target = GE(Plus(final_infection_ints), Int(target))

    return And(
        And(spreading_clauses), And(origin_clauses), And(all_bounds),
        initial_infection_limit,
        final_infection_target), initial_infection_ints, final_infection_ints
Exemplo n.º 8
0
def create_smt_formula(data, labels, dim, n_weights):
    weights = []
    biases = []
    weight_symbols = [Symbol('weight_{}'.format(i), REAL) for i in range(n_weights[0])]
    weight_symbols2 = Symbol('weight_out', REAL)
    weights.append(weight_symbols)
    weights.append([weight_symbols2])

    bias_symbol1 = Symbol('bias_{}'.format(1), REAL)
    bias_symbol2 = Symbol('bias_{}'.format(2), REAL)
    biases.append([bias_symbol1])
    biases.append([bias_symbol2])

    layer_domains = []
    layer_input = data
    for i in range(len(layer_input)):  # loop over data
        # \sum <w_ji,  x_i> + b_i
        g = len(weight_symbols)//2
        # Layer 1
        weight_input1_i = Plus([Times(w_i, Real(int(x_j)))
            for w_i, x_j in zip(weight_symbols, layer_input[i])])
        prod_bias1_i = Plus(weight_input1_i, bias_symbol1)
        # Layer 2
        weight_input2_i = Plus(Times(prod_bias1_i, weight_symbols2))
        prod_bias2_i = Plus(weight_input2_i, bias_symbol2)
        # output
        weight_output = prod_bias2_i
        layer_domain = Equals(weight_output, Real(labels[i]))
        layer_domains.append(layer_domain)

    network_domain = And(x for x in layer_domains)
    dnn_problem = network_domain
    return dnn_problem, weights, biases
Exemplo n.º 9
0
    def message(self, tree, spins, subtheta, auxvars):
        """Determine the energy of the elimination tree.

        Args:
            tree (dict): The current elimination tree
            spins (dict): The current fixed spins
            subtheta (dict): Theta with spins fixed.
            auxvars (dict): The auxiliary variables for the given spins.

        Returns:
            The formula for the energy of the tree.

        """
        energy_sources = set()
        for v, children in iteritems(tree):
            aux = auxvars[v]

            assert all(u in spins for u in self._ancestors[v])

            # build an iterable over all of the energies contributions
            # that we can exactly determine given v and our known spins
            # in these contributions we assume that v is positive
            def energy_contributions():
                yield subtheta.linear[v]

                for u, bias in iteritems(subtheta.adj[v]):
                    if u in spins:
                        yield SpinTimes(spins[u], bias)

            plus_energy = Plus(energy_contributions())
            minus_energy = SpinTimes(-1, plus_energy)

            # if the variable has children, we need to recursively determine their energies
            if children:
                # set v to be positive
                spins[v] = 1
                plus_energy = Plus(plus_energy, self.message(children, spins, subtheta, auxvars))
                spins[v] = -1
                minus_energy = Plus(minus_energy, self.message(children, spins, subtheta, auxvars))
                del spins[v]

            # we now need a real-valued smt variable to be our message
            m = FreshSymbol(REAL)

            ancestor_aux = {auxvars[u] if spins[u] > 0 else Not(auxvars[u])
                            for u in self._ancestors[v]}
            plus_aux = And({aux}.union(ancestor_aux))
            minus_aux = And({Not(aux)}.union(ancestor_aux))

            self.assertions.update({LE(m, plus_energy),
                                    LE(m, minus_energy),
                                    Implies(plus_aux, GE(m, plus_energy)),
                                    Implies(minus_aux, GE(m, minus_energy))
                                    })

            energy_sources.add(m)

        return Plus(energy_sources)
Exemplo n.º 10
0
 def test_simplifying_int_plus_changes_type_of_expression(self):
     varA = Symbol("At", INT)
     varB = Symbol("Bt", INT)
     get_type = get_env().stc.get_type
     f = Plus(varB, Int(1))
     old_type = get_type(f)
     f = f.simplify()
     new_type = get_type(f)
     self.assertEqual(new_type, old_type)
Exemplo n.º 11
0
 def test_simplifying_int_plus_changes_type_of_expression(self):
     varA = Symbol("At", INT)
     varB = Symbol("Bt", INT)
     get_type = get_env().stc.get_type
     f = Plus(varB, Int(1))
     old_type = get_type(f)
     f = f.simplify()
     new_type = get_type(f)
     self.assertEqual(new_type, old_type)
Exemplo n.º 12
0
    def test_msat_back_not_identical(self):
        msat = Solver(name="msat", logic=QF_UFLIRA)

        r, s = FreshSymbol(REAL), FreshSymbol(REAL)
        # r + 1 > s + 1
        f = GT(Plus(r, Real(1)), Plus(s, Real(1)))

        term = msat.converter.convert(f)
        res = msat.converter.back(term)
        self.assertFalse(f == res)
Exemplo n.º 13
0
    def test_sum_all_negatives(self):
        r0 = Symbol("r0", REAL)
        r1 = Symbol("r1", REAL)
        m_1 = Real(-1)

        # -4 * r0 + (-1) * r1
        neg_r1 = Times(m_1, r1)
        m_4_r0 = Times(Real(-4), r0)
        expr = Plus(m_4_r0, neg_r1)
        res = expr.simplify()
        self.assertValid(Equals(expr, res))
Exemplo n.º 14
0
def k_sequence_WH_worst_case(m, K, K_seq_len=100, count=100):
    k_seq = [Symbol('x_%i' % i, INT) for i in range(K_seq_len)]
    domain = And([Or(Equals(x, Int(0)), Equals(x, Int(1))) for x in k_seq])
    K_window = And([
        LE(Plus(k_seq[t:min(K_seq_len, t + K)]), Int(m))
        for t in range(max(1, K_seq_len - K + 1))
    ])
    violate_up = And([
        GT(Plus(k_seq[t:min(K_seq_len, t + K)]), Int(m - 1))
        for t in range(max(1, K_seq_len - K + 1))
    ])

    def violate_right_generator(n):
        return And([
            GT(Plus(k_seq[t:min(K_seq_len, t + K + n)]), Int(m))
            for t in range(max(1, K_seq_len - (K + n) + 1))
        ])

    right_shift = 1
    formula = And(domain, K_window, violate_up,
                  violate_right_generator(right_shift))
    solver = Solver(name='z3', incremental=True, random_seed=randint(2 << 30))
    solver.add_assertion(formula)
    solver.z3.set('timeout', 5 * 60 * 1000)
    solutions = And()
    for _ in range(count):
        while right_shift + K < K_seq_len:
            try:
                result = solver.solve()
            except BaseException:
                result = None
            if not result:
                solver = Solver(name='z3',
                                incremental=True,
                                random_seed=randint(2 << 30))
                right_shift += 1
                solver.z3.set('timeout', 5 * 60 * 1000)
                solver.add_assertion(
                    And(solutions, domain, K_window, violate_up,
                        violate_right_generator(right_shift)))
            else:
                break
        try:
            model = solver.get_model()
        except BaseException:
            break
        model = array(list(map(lambda x: model.get_py_value(x), k_seq)),
                      dtype=bool)
        yield model
        solution = Or(
            [NotEquals(k_seq[i], Int(model[i])) for i in range(K_seq_len)])
        solutions = And(solutions, solution)
        solver.add_assertion(solution)
Exemplo n.º 15
0
    def test_clear_pop_smtlibsolver(self):
        for n in self.all_solvers:
            with Solver(name=n, logic=QF_LRA) as s:
                x1, x2 = [Symbol(var, REAL) for var in ["x1", "x2"]]
                init = LT(Plus(x1, Real(-1), x2), Real(Fraction(1, 4)))
                invar = TRUE()
                safe = LT(Plus(x1, x2), Real(8))
                invar_init = And(invar, init)
                iv_imp = Implies(invar, safe)

                self.assertFalse(s.is_unsat(invar_init))
                self.assertFalse(s.is_valid(iv_imp))
Exemplo n.º 16
0
def get_x_coefficient(atom: FNode):
    """
    obtain coefficient of variable in univariate LRA
    :param atom: FNode atom
    :return: coeffcient of variable, type FNode
    """
    variable = list(get_real_variables(atom))
    assert len(variable) == 1
    var = variable[0]
    const = get_constants(atom)
    new_atom = Plus(atom, -const)
    new_atom = new_atom.substitute({var: Real(1)})
    return simplify(new_atom)
Exemplo n.º 17
0
    def message_upperbound(self, tree, spins, subtheta):
        """Determine an upper bound on the energy of the elimination tree.

        Args:
            tree (dict): The current elimination tree
            spins (dict): The current fixed spins
            subtheta (dict): Theta with spins fixed.

        Returns:
            The formula for the energy of the tree.

        """
        energy_sources = set()
        for v, subtree in tree.items():

            assert all(u in spins for u in self._ancestors[v])

            # build an iterable over all of the energies contributions
            # that we can exactly determine given v and our known spins
            # in these contributions we assume that v is positive
            def energy_contributions():
                yield subtheta.linear[v]

                for u, bias in subtheta.adj[v].items():
                    if u in spins:
                        yield Times(limitReal(spins[u]), bias)

            energy = Plus(energy_contributions())

            # if there are no more variables in the order, we can stop
            # otherwise we need the next message variable
            if subtree:
                spins[v] = 1.
                plus = self.message_upperbound(subtree, spins, subtheta)
                spins[v] = -1.
                minus = self.message_upperbound(subtree, spins, subtheta)
                del spins[v]
            else:
                plus = minus = limitReal(0.0)

            # we now need a real-valued smt variable to be our message
            m = FreshSymbol(REAL)

            self.assertions.update({
                LE(m, Plus(energy, plus)),
                LE(m, Plus(Times(energy, limitReal(-1.)), minus))
            })

            energy_sources.add(m)

        return Plus(energy_sources)
Exemplo n.º 18
0
 def feed_data(self, X, Y):
     formula = []
     for x, y in zip(X, Y):
         x_formula = []
         for i, (weight, bias) in self.net_formula.items():
             if i == 0:
                 x_hidden = []
                 for r, w_r in enumerate(weight):
                     tmp = Plus([Plus(Times(w, Real(float(x[c]))), bias[r]) for c, w in enumerate(w_r)])
                     if self.activation == 'relu':
                         x_hidden.append(Max(tmp, Real(0)))
                     else:
                         x_hidden.append(tmp)
                     """node_output = []
                     for c, w in enumerate(w_r):
                         var = Plus(Times(w, Real(float(x[c]))), bias[r])
                         exp_3 = Pow(var, Real(3))
                         #exp_5 = Pow(var, Real(5))
                         sen_2 = Times(Real(0.25), var)
                         sen_3 = Times(Real(0.02), exp_3)
                         #sen_4 = Times(Real(0.002), exp_5)
                         node_output.append(Plus(Real(0.5), sen_2, sen_3))#, sen_4))
                     matrix_addition = Plus(node_output[i] for i in range(len(node_output)))
                     x_hidden.append(matrix_addition)"""
                 x = x_hidden
             else:
                 x_hidden = []
                 for r, w_r in enumerate(weight):
                     tmp = Plus([Plus(Times(w, x[c]), bias[r]) for c, w in enumerate(w_r)])
                     if self.activation == 'relu' and i < len(self.net_formula) - 1:
                         x_hidden.append(Max(tmp, Real(0)))
                     else:
                         x_hidden.append(tmp)
                     """node_output = []
                     for c, w in enumerate(w_r):
                         var = Plus(Times(w, x[c]), bias[r])
                         exp_3 = Pow(var, Real(3))
                         #exp_5 = Pow(var, Real(5))
                         sen_2 = Times(Real(0.25), var)
                         sen_3 = Times(Real(0.02), exp_3)
                         #sen_4 = Times(Real(0.002), exp_5)
                         node_output.append(Plus(Real(0.5), sen_2, sen_3)) #, sen_4))
                     matrix_addition = Plus(node_output[i] for i in range(len(node_output)))
                     x_hidden.append(matrix_addition)"""
                 x = x_hidden
             ## Add activation function
         if np.argmax(y) == 0:
             x_formula.append(GE(x[0], x[1]))
         else:
             x_formula.append(GE(x[1], x[0]))
     return And(x_formula)
Exemplo n.º 19
0
    def convert(self, abstract=False):

        for i in range(self.nnet.inputSize):
            x = Symbol("x%d" % i, REAL)
            self.input_vars.append(x)
        for i in range(self.nnet.outputSize):
            y = Symbol("y%d" % i, REAL)
            self.output_vars.append(y)
        # for i,v in enumerate(self.input_vars):
        #     # normalized
        #     m = self.nnet.mins[i]
        #     l = GE(self.input_vars[i],
        #            Real((m - self.nnet.means[i])/self.nnet.ranges[i]))
        #     self.formulae.append(l)
        #     # normalized
        #     m = self.nnet.maxes[i]
        #     l = LE(self.input_vars[i],
        #            Real((m - self.nnet.means[i])/self.nnet.ranges[i]))
        #     self.formulae.append(l)

        prev_layer_result = self.input_vars.copy()
        layer_result = []
        zero = Real(0)
        self.relus_level.append(set())
        for l in range(self.nnet.numLayers - 1):
            self.relus_level.append(set())
            for ls in range(self.nnet.layerSizes[l + 1]):
                r = self.dot(self.nnet.weights[l][ls], prev_layer_result)
                r = Plus(r, Real(float(self.nnet.biases[l][ls])))
                relu_in = FreshSymbol(REAL)
                self.formulae.append(Equals(relu_in, r))
                if abstract:
                    relu_out = FreshSymbol(REAL)
                    r = relu_out
                    self.relus.append((relu_out, relu_in))
                    self.relus_level[l + 1].add((relu_out, relu_in))
                else:
                    r = Max(relu_in, zero)
                layer_result.append(r)
            prev_layer_result = layer_result.copy()
            layer_result.clear()

        for i, y in enumerate(self.output_vars):
            o = self.dot(self.nnet.weights[-1][i], prev_layer_result)
            o = Plus(o, Real(float(self.nnet.biases[-1][i])))
            # # undo normalization
            # o = Times(o, Real(self.nnet.ranges[-1]))
            # o = Plus(o, Real(self.nnet.means[-1]))
            self.formulae.append(Equals(y, o))

        self.parse_violation(self.violation_path)
Exemplo n.º 20
0
    def test_msat_back_not_identical(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(REAL)
        # r + 1 > s + 1
        f = GT(Plus(r, Real(1)), Plus(s, Real(1)))

        term = new_converter.convert(f)
        res = new_converter.back(term)
        self.assertFalse(f == res)
Exemplo n.º 21
0
    def test_plus_algebraic(self):
        from pysmt.constants import Numeral
        env = get_env()
        mgr = env.formula_manager
        r0 = Symbol("r0", REAL)
        p_2 = Real(2)
        m_5 = mgr._Algebraic(Numeral(-5))
        m_3 = mgr._Algebraic(Numeral(-3))

        # r0 + 2 - 5
        expr = Plus(r0, p_2, m_5)
        res = expr.simplify()
        self.assertValid(Equals(expr, res))
        self.assertIn(m_3, res.args())
Exemplo n.º 22
0
def triangle(nvars, rand_gen):
    # alpha = rand_gen.uniform(0.05, 0.25)
    alpha = rand_gen.uniform(0.2, 0.25)
    remain = nvars % 3
    n_tris = int(nvars / 3)

    variables = [Symbol(f"x{i}", REAL) for i in range(1, nvars + 1)]

    lbounds = [LE(Real(0), x) for x in variables]
    ubounds = [LE(x, Real(1)) for x in variables]

    clauses = []
    potentials = []

    for i in range(n_tris):
        x, y, z = variables[3 * i], variables[3 * i + 1], variables[3 * i + 2]
        xc = None if 3 * i + 3 >= nvars else variables[3 * i + 3]
        # x_i
        clauses.append(Or(LE(x, Real(alpha)), LE(Real(1 - alpha), x)))
        # x_i -- y_i
        clauses.append(
            Or(LE(y, Plus(x, Real(-alpha))), LE(Plus(x, Real(alpha)), y)))
        # x_i -- z_i
        clauses.append(Or(LE(Real(1 - alpha), x), LE(Real(1 - alpha), z)))
        clauses.append(Or(LE(x, Real(alpha)), LE(z, Real(alpha))))
        # z_i -- y_i
        clauses.append(LE(z, y))
        # x_i -- x_i+1
        if xc:
            clauses.append(Or(LE(x, Real(alpha)), LE(Real(1 - alpha), xc)))
            clauses.append(Or(LE(Real(1 - alpha), x), LE(xc, Real(alpha))))

        pot_yz = Ite(LE(z, y), Times([z, y, Real(100)]), Real(1))
        pot_xy = Ite(LE(y, Plus(x, Real(-alpha))),
                     Times(Real(100), Plus(x, y)), Real(1))
        potentials.append(pot_xy)
        potentials.append(pot_yz)

    if remain == 1:
        x = variables[3 * n_tris]
        clauses.append(Or(LE(x, Real(alpha)), LE(Real(1 - alpha), x)))
    if remain == 2:
        x, y = variables[3 * n_tris], variables[nvars - 1]
        # x_n
        clauses.append(Or(LE(x, Real(alpha)), LE(Real(1 - alpha), x)))
        # x -- y
        clauses.append(
            Or(LE(y, Plus(x, Real(-alpha))), LE(Plus(x, Real(alpha)), y)))
        potentials.append(
            Ite(LE(y, Plus(x, Real(-alpha))), Times(Real(100), Plus(x, y)),
                Real(1)))

    domain = Domain.make(
        [],  # no booleans
        [x.symbol_name() for x in variables],
        [(0, 1) for _ in range(len(variables))])
    support = And(lbounds + ubounds + clauses)
    weight = Times(potentials) if len(potentials) > 1 else potentials[0]

    return Density(domain, support, weight, []), alpha
Exemplo n.º 23
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)]))
Exemplo n.º 24
0
def link_constraints(constraints, frameSetSortedByLink):
    '''
    已验证
    '''
    # print ('###### 测试link constraints生成 ######')
    for link in frameSetSortedByLink:
        subFrameDict = frameSetSortedByLink[link]
        frameSameLink = []
        for vlid in subFrameDict:
            frameList = subFrameDict[vlid]
            for frame in frameList:
                frameSameLink.append(frame)
        # 对于同一个物理链路的任意两个帧成立:
        for i in range(len(frameSameLink)):
            for j in range(i + 1, len(frameSameLink)):
                frame_i = frameSameLink[i]
                frame_j = frameSameLink[j]
                # 挑选不同虚链路的Frame
                if frame_i.vlid == frame_j.vlid:
                    continue
                # print('frame_i: {}_{}_{}, T={}, L={}, frame_j: {}_{}_{}, T={}, L={}'.format(
                #    frame_i.vlid, frame_i.lname, frame_i.fid, frame_i.T, frame_i.L,
                #    frame_j.vlid, frame_j.lname, frame_j.fid, frame_j.T, frame_j.L))
                hp = lcm(frame_i.T, frame_j.T)
                # 对于任意的阿尔法和贝塔属于....都满足:
                for alpha in range(int(hp / frame_i.T)):
                    for beta in range(int(hp / frame_j.T)):
                        # single_link_constraint = Or(
                        #    (frame_i.offset + alpha * frame_i.T >=
                        #     frame_j.offset + beta * frame_j.T + frame_j.L),
                        #    (frame_j.offset + beta * frame_j.T >= frame_i.offset + alpha * frame_i.T + frame_i.L))
                        single_link_constraint = Or(
                            GE(
                                Plus(frame_i.offset, Int(alpha * frame_i.T)),
                                Plus(frame_j.offset,
                                     Int(beta * frame_j.T + frame_j.L))),
                            GE(
                                Plus(frame_j.offset, Int(beta * frame_j.T)),
                                Plus(frame_i.offset,
                                     Int(alpha * frame_i.T + frame_i.L))))
                        #print('alpha={},beta={}:\nconstraint={}'.format(
                        #      alpha, beta, single_link_constraint))
                        constraints.append(single_link_constraint)
                # print(solver)
    # print(solver.check())
    # print(solver.model())
    # pdb.set_trace()
    # FIXME:提高效率?
    return True
Exemplo n.º 25
0
    def test_lira(self):
        varA = Symbol("A", REAL)
        varB = Symbol("B", INT)

        with self.assertRaises(PysmtTypeError):
            f = And(LT(varA, Plus(varA, Real(1))), GT(varA,
                                                      Minus(varB, Int(1))))

        f = And(LT(varA, Plus(varA, Real(1))),
                GT(varA, ToReal(Minus(varB, Int(1)))))
        g = Equals(varA, ToReal(varB))

        self.assertUnsat(And(f, g, Equals(varA, Real(1.2))),
                         "Formula was expected to be unsat",
                         logic=QF_UFLIRA)
Exemplo n.º 26
0
    def _random_polynomial(self, nonnegative=False):
        if nonnegative:
            # the sum of squared rational functions is a non-negative polynomial
            sq_sum = []
            for _ in range(randint(1, self.MAX_SRF)):
                poly = self._random_polynomial()
                sq_sum.append(Times(poly, poly))

            return Plus(sq_sum)

        else:
            monomials = []
            for i in range(randint(1, self.MAX_MONOMIALS)):
                monomials.append(self._random_monomial())
            return Plus(monomials)
Exemplo n.º 27
0
 def learn(self, domain, data, border_indices):
     positive_indices = [i for i in range(len(data)) if data[i][1]]
     real_vars = [
         v for v in domain.variables if domain.var_types[v] == REAL
     ]
     bool_vars = [
         v for v in domain.variables if domain.var_types[v] == BOOL
     ]
     d = len(real_vars)
     hyperplanes = []
     for indices in itertools.combinations(positive_indices, d):
         print(indices)
         hyperplanes.append(
             Learner.fit_hyperplane(domain, [data[i][0] for i in indices]))
     boolean_data = []
     for i in range(len(data)):
         row = []
         for v in bool_vars:
             row.append(data[i][0][v].constant_value())
         boolean_data.append(row)
     hyperplanes_smt = []
     for a, c in hyperplanes:
         lhs_smt = Plus(
             Times(Real(float(a[j])), domain.get_symbol(real_vars[j]))
             for j in range(d))
         hyperplanes_smt.append(LE(lhs_smt, Real(c)))
         lhs_smt = Plus(
             Times(Real(-float(a[j])), domain.get_symbol(real_vars[j]))
             for j in range(d))
         hyperplanes_smt.append(LE(lhs_smt, Real(-c)))
         for i in range(len(data)):
             lhs = 0
             for j in range(d):
                 lhs += float(a[j]) * float(
                     data[i][0][real_vars[j]].constant_value())
             boolean_data[i].append(lhs <= c)
             boolean_data[i].append(lhs >= c)
     print(boolean_data)
     # logical_dnf_indices = [[i] for i in range(len(boolean_data[0]))]
     logical_dnf_indices = self.learn_logical(boolean_data,
                                              [row[1] for row in data])
     logical_dnf = [[
         domain.get_symbol(bool_vars[i])
         if i < len(bool_vars) else hyperplanes_smt[i - len(bool_vars)]
         for i in conj_indices
     ] for conj_indices in logical_dnf_indices]
     print(logical_dnf)
     return logical_dnf
Exemplo n.º 28
0
    def calculate_droplet_volume(self, h, w, wIn, epsilon, qD, qC):
        """From paper DOI:10.1039/c002625e.
        Calculating the droplet volume created in a T-junction
        Unit is volume in m^3

        :param Symbol h: Height of channel
        :param Symbol w: Width of continuous/output channel
        :param Symbol wIn: Width of dispersed_channel
        :param Symbol epsilon: Equals 0.414*radius of rounded edge where
                               channels join
        :param Symbol qD: Flow rate in dispersed_channel
        :param Symbol qC: Flow rate in continuous_channel
        """
        q_gutter = Real(0.1)
        # normalizedVFill = 3pi/8 - (pi/2)(1 - pi/4)(h/w)
        v_fill_simple = Minus(
            Times(Real((3, 8)), Real(math.pi)),
            Times(
                Times(Div(Real(math.pi), Real(2)),
                      Minus(Real(1), Div(Real(math.pi), Real(4)))), Div(h, w)))

        hw_parallel = Div(Times(h, w), Plus(h, w))

        # r_pinch = w+((wIn-(hw_parallel - eps))+sqrt(2*((wIn-hw_parallel)*(w-hw_parallel))))
        r_pinch = Plus(
            w,
            Plus(
                Minus(wIn, Minus(hw_parallel, epsilon)),
                Pow(
                    Times(
                        Real(2),
                        Times(Minus(wIn, hw_parallel), Minus(w, hw_parallel))),
                    Real(0.5))))
        r_fill = w
        alpha = Times(
            Minus(Real(1), Div(Real(math.pi), Real(4))),
            Times(
                Pow(Minus(Real(1), q_gutter), Real(-1)),
                Plus(
                    Minus(Pow(Div(r_pinch, w), Real(2)),
                          Pow(Div(r_fill, w), Real(2))),
                    Times(
                        Div(Real(math.pi), Real(4)),
                        Times(Minus(Div(r_pinch, w), Div(r_fill, w)),
                              Div(h, w))))))

        return Times(Times(h, Times(w, w)),
                     Plus(v_fill_simple, Times(alpha, Div(qD, qC))))
Exemplo n.º 29
0
    def test_misc(self):
        bool_list = [
            And(self.x, self.y),
            Or(self.x, self.y),
            Not(self.x),
            self.x,
            Equals(self.p, self.q),
            GE(self.p, self.q),
            LE(self.p, self.q),
            GT(self.p, self.q),
            LT(self.p, self.q),
            Bool(True),
            Ite(self.x, self.y, self.x)
        ]

        # TODO: FORALL EXISTS
        real_list = [
            self.r,
            Real(4),
            Plus(self.r, self.s),
            Plus(self.r, Real(2)),
            Minus(self.s, self.r),
            Times(self.r, Real(1)),
            Div(self.r, Real(1)),
            Ite(self.x, self.r, self.s),
        ]

        int_list = [
            self.p,
            Int(4),
            Plus(self.p, self.q),
            Plus(self.p, Int(2)),
            Minus(self.p, self.q),
            Times(self.p, Int(1)),
            Ite(self.x, self.p, self.q),
        ]

        for f in bool_list:
            t = self.tc.walk(f)
            self.assertEqual(t, BOOL, f)

        for f in real_list:
            t = self.tc.walk(f)
            self.assertEqual(t, REAL, f)

        for f in int_list:
            t = self.tc.walk(f)
            self.assertEqual(t, INT, f)
Exemplo n.º 30
0
    def test_msat_converter_on_msat_error(self):
        import mathsat
        import _mathsat
        from pysmt.solvers.msat import MathSAT5Solver, MSatConverter

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

        def walk_plus(formula, args):
            res = mathsat.MSAT_MAKE_ERROR_TERM()
            return res

        # Replace the function used to compute the Plus()
        # with one that returns a msat_error
        new_converter.set_function(walk_plus, op.PLUS)

        r, s = FreshSymbol(REAL), FreshSymbol(REAL)
        f1 = GT(r, s)
        f2 = Plus(r, s)

        t1 = new_converter.convert(f1)
        self.assertFalse(mathsat.MSAT_ERROR_TERM(t1))

        with self.assertRaises(InternalSolverError):
            new_converter.convert(f2)
Exemplo n.º 31
0
    def energy(self, spins, break_aux_symmetry=True):
        """A formula for the exact energy of Theta with spins fixed.

        Args:
            spins (dict): Spin values for a subset of the variables in Theta.
            break_aux_symmetry (bool, optional): Default True. If True, break
                the aux variable symmetry by setting all aux variable to 1
                for one of the feasible configurations. If the energy ranges
                are not symmetric then this can make finding models impossible.

        Returns:
            Formula for the exact energy of Theta with spins fixed.

        """
        subtheta = self.theta.fix_variables(spins)

        # we need aux variables
        av = next(self._auxvar_counter)
        auxvars = {v: Symbol('aux{}_{}'.format(av, v), BOOL) for v in subtheta.linear}
        if break_aux_symmetry and av == 0:
            # without loss of generality, we can assume that the aux variables are all
            # spin-up for one configuration
            self.assertions.update(set(itervalues(auxvars)))

        trees = self._trees

        if not trees:
            # if there are no variables to eliminate, then the offset of
            # subtheta is the exact value and we can just return it
            assert not subtheta.linear and not subtheta.quadratic
            return subtheta.offset

        energy = Plus(self.message(trees, {}, subtheta, auxvars), subtheta.offset)

        return energy
Exemplo n.º 32
0
def get_coefficients(atom: FNode):
    """
    obtain coefficient of variable x in atom of form a * x + b * y + const
    note that when there is a * x + b * x, simplify() doesn't do multiplication
    but still here we return (a + b)
    :param atom:  FNode, formula
    :param x:  FNode, symbol of variable
    :return: dict with keys as variable symbol and values as coefficient in atom
    """
    variables = list(get_real_variables(atom))
    coefficients = defaultdict(int)

    if len(variables) == 0:
        return coefficients

    const = get_constants(atom)
    atom = simplify(Plus(atom, -const))

    sub_dict = dict().fromkeys(variables, Real(0))
    for i in range(len(variables)):
        sub_dict[variables[i]] = Real(1)
        coefficient = simplify(atom.substitute(sub_dict))
        coefficients[variables[i]] = coefficient
        sub_dict[variables[i]] = Real(0)
    return coefficients