Esempio n. 1
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
Esempio n. 2
0
def simple_checker_problem():
    theory = Or(
        And(LE(Symbol("x", REAL), Real(0.5)), LE(Symbol("y", REAL), Real(0.5))),
        And(GT(Symbol("x", REAL), Real(0.5)), GT(Symbol("y", REAL), Real(0.5)))
    )

    return xy_domain(), theory, "simple_checker"
Esempio n. 3
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
Esempio n. 4
0
def run_rcwmi(density,
              n_bins,
              complits,
              maxiters,
              rand_gen,
              log_path,
              cache=True,
              nproc=None):

    if nproc is None:
        nproc = 1

    #log_path = join(output_folder, "comp_log.json")

    if not isfile(log_path):

        print("Running RCWMI")
        print(f"N. compensating literals: {complits}")
        print(f"Max. iterations: {maxiters}")
        print(f"N. processes: {nproc}")

        # create bin queries
        debug_queries = []

        xvals = {}
        for xvar in density.domain.get_real_symbols():
            x = xvar.symbol_name()
            low, up = density.domain.var_domains[x]
            slices = [(i / n_bins) * (up - low) + low
                      for i in range(0, n_bins + 1)]
            xvals[x] = slices[:-1]
            for i in range(len(slices) - 1):
                l, u = slices[i], slices[i + 1]
                debug_queries.append(LE(Real(l), xvar))
                debug_queries.append(LE(xvar, Real(u)))

        t0 = time.perf_counter()
        rcwmi = RCWMI(density.support,
                      density.weight,
                      n_comp_lits=complits,
                      rand_gen=rand_gen,
                      max_compensate_iters=maxiters,
                      log_path=log_path,
                      debug_queries=debug_queries,
                      n_processes=nproc)
        t1 = time.perf_counter()

        # adding xvals and runtime to the log
        with open(log_path, 'r') as f:
            log = json.load(f)

        log['runtime'] = t1 - t0
        log['xvals'] = xvals

        with open(log_path, 'w') as f:
            json.dump(log, f)
    else:
        print(f"Found {log_path}")
Esempio n. 5
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)
Esempio n. 6
0
 def add_relu_maxOA_constraint(self):
     zero = Real(0)
     for relu_out, relu_in in self.relus:
         # MAX abstraction
         self.formulae.append(GE(relu_out, relu_in))
         self.formulae.append(GE(relu_out, zero))
         # MAX - case based upper bound
         self.formulae.append(
             Implies(GT(relu_in, zero), LE(relu_out, relu_in)))
         self.formulae.append(Implies(LE(relu_in, zero), LE(relu_out,
                                                            zero)))
Esempio n. 7
0
def main():
    x,y = [Symbol(n, REAL) for n in "xy"]
    f_sat = Implies(And(GT(y, Real(0)), LT(y, Real(10))),
                    LT(Minus(y, Times(x, Real(2))), Real(7)))

    f_incomplete = And(GT(x, Real(0)), LE(x, Real(10)),
                       Implies(And(GT(y, Real(0)), LE(y, Real(10)),
                                   Not(Equals(x, y))),
                               GT(y, x)))

    run_test([y], f_sat)
    run_test([y], f_incomplete)
def hist_to_piecewise_constant(var, breaks, ys):
    assert (len(breaks) == len(ys)), "dimensions mismatch"
    assert(all(breaks[i-1] < breaks[i] for i in range(1,len(breaks)))),\
        "bin bounds should be sorted"

    else_branch = Real(0)
    for i in range(1, len(breaks)):
        assert (breaks[i - 1] < breaks[i])
        interval = And(LE(Real(breaks[i - 1]), var), LE(var, Real(breaks[i])))
        else_branch = Ite(interval, Real(ys[i], else_branch))

    return else_branch
Esempio n. 9
0
    def bounds_to_SMT(self):
        formula = []
        for var in self.bounds:
            if var.symbol_type() == REAL:
                lower, upper = self.bounds[var]
                formula.append(And(LE(Real(lower), var), LE(var, Real(upper))))

            elif self.bounds[var] is not None:
                bool_bound = var if self.bounds[var] else Not(var)
                formula.append(bool_bound)

        return And(formula)
Esempio n. 10
0
def checker_problem():
    variables = ["x", "y", "a"]
    var_types = {"x": REAL, "y": REAL, "a": BOOL}
    var_domains = {"x": (0, 1), "y": (0, 1)}

    theory = Or(
        And(LE(Symbol("x", REAL), Real(0.5)), LE(Symbol("y", REAL), Real(0.5)), Symbol("a", BOOL)),
        And(GT(Symbol("x", REAL), Real(0.5)), GT(Symbol("y", REAL), Real(0.5)), Symbol("a", BOOL)),
        And(GT(Symbol("x", REAL), Real(0.5)), LE(Symbol("y", REAL), Real(0.5)), Not(Symbol("a", BOOL))),
        And(LE(Symbol("x", REAL), Real(0.5)), GT(Symbol("y", REAL), Real(0.5)), Not(Symbol("a", BOOL)))
    )

    return Domain(variables, var_types, var_domains), theory, "checker"
Esempio n. 11
0
 def setUp(self) -> None:
     parent_symbol = Symbol("x", REAL)
     child_symbol = Symbol("y", REAL)
     # y < 2x+1 or y > x - 1 or x > 2 or y > 0.1
     atom0 = LE(child_symbol, Real(2) * parent_symbol + Real(1))
     atom1 = LE(parent_symbol - 1, child_symbol)
     atom2 = LE(Real(2), parent_symbol)
     atom3 = LE(Real(0.1), child_symbol)
     atom4 = LE(child_symbol, Real(0.4))
     self.parent_symbol = parent_symbol
     self.child_symbol = child_symbol
     self.atoms = [atom0, atom1, atom2, atom3, atom4]
     self.formula = Or(self.atoms[:4])
Esempio n. 12
0
 def add_relu_simplex_friendly_OA(self):
     zero = Real(0)
     for relu_out, relu_in in self.relus:
         #Introduce f = relu_out - relu_in
         f = FreshSymbol(REAL)
         self.formulae.append(Equals(f, Minus(relu_out, relu_in)))
         # MAX abstraction
         self.formulae.append(GE(f, zero))
         self.formulae.append(GE(relu_out, zero))
         # MAX - case based upper bound
         self.formulae.append(Implies(GT(relu_in, zero), LE(f, zero)))
         self.formulae.append(Implies(LE(relu_in, zero), LE(relu_out,
                                                            zero)))
Esempio n. 13
0
 def refine_zero_ub(self):
     lemmas = []
     zero = Real(0)
     for s in self.relus_level:
         for r1, r2 in s:
             l = Implies(LE(r2, zero), LE(r1, zero))
             tval = self.solver.get_value(l)
             if tval.is_false():
                 lemmas.append(l)
                 self.logger.debug('Adding %s' % l )
         if lemmas:
             break
     return lemmas
Esempio n. 14
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)
Esempio n. 15
0
def task_constraints(constraints, frameSet, vlinkSet):
    '''
    虚帧顺序执行(由其他约束规定),所有虚帧都处于调度窗口内(offset ---- deadline)
    参数:
        solver:
        frameSet:
    疑问:这里的task.offset是什么?0?还是设置值?
    '''
    # 首先选择一个条虚链路
    for vlid_t in frameSet:
        frameSameVLink = frameSet[vlid_t]
        vl = vlinkSet[vlid_t].vl
        firstSelfLink = vl[0]
        task = vlinkSet[vlid_t].task_p
        frameList = frameSameVLink[firstSelfLink]
        # 生成生成者约束
        # for frame in frameList:
        #    aCon = (frame.offset >= task.offset)
        #    print(aCon)
        #    solver.add(aCon)
        lastFrame = frameList[len(frameList) - 1]
        # FIXME: 这里lastFrame.L与论文理解不同
        # aCon = (lastFrame.offset <= task.D /
        #        firstSelfLink.macrotick - lastFrame.L)
        aCon = LE(lastFrame.offset,
                  Int(task.D / firstSelfLink.macrotick - lastFrame.L))
        #print(aCon)
        constraints.append(aCon)
        # 如何虚链路不是SelfLink,有消费者
        if len(vl) > 2:
            lastSelfLink = vl[len(vl) - 1]
            task = vlinkSet[vlid_t].task_c
            frameList = frameSameVLink[lastSelfLink]
            # for frame in frameList:
            #    aCon = (frame.offset >= task.offset)
            #    solver.add(aCon)
            lastFrame = frameList[len(frameList) - 1]
            # FIXME: 这里lastFrame.L与论文理解不同
            # aCon = (lastFrame.offset <= task.D /
            #        lastSelfLink.macrotick - lastFrame.L)
            aCon = LE(lastFrame.offset,
                      Int(task.D / firstSelfLink.macrotick - lastFrame.L))
            #print(aCon)
            constraints.append(aCon)
    # print(solver)
    # print(solver.check())
    # print(solver.model())
    # pdb.set_trace()

    return True
Esempio n. 16
0
    def test_msat_back_simple(self):
        msat = Solver(name="msat", logic=QF_UFLIRA)

        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 = msat.converter.convert(f)
        res = msat.converter.back(term)

        # Checking equality is not enough: MathSAT can change the
        # shape of the formula into a logically equivalent form.
        self.assertValid(Iff(f, res), logic=QF_UFLIRA)
Esempio n. 17
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
Esempio n. 18
0
 def _op_raw_le(self, *args):
     # We emulate the integer through a bitvector but
     # since a constraint with the form (assert (= (str.len Symb_str) bit_vect))
     # is not valid we need to tranform the concrete vqalue of the bitvector in an integer
     #
     # TODO: implement logic for integer
     return LE(*_normalize_arguments(*args))
Esempio n. 19
0
    def test_get_critical_points(self):
        var_x = Symbol("x", REAL)

        bounds = [Plus(var_x, Real(1)), Real(2), Real(3)]
        domains = And(LE(var_x, Real(1.5)))
        points = get_critical_points(bounds, domains)
        self.assertListEqual(points, [Real(1)])
Esempio n. 20
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))
Esempio n. 21
0
def k_sequence_WH(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))
    ])
    formula = And(domain, K_window)
    solver = Solver(name='yices',
                    incremental=True,
                    random_seed=randint(2 << 30))
    solver.add_assertion(formula)
    for _ in range(count):
        result = solver.solve()
        if not result:
            solver = Solver(name='z3',
                            incremental=True,
                            random_seed=randint(2 << 30))
            solver.add_assertion(formula)
            solver.solve()
        model = solver.get_model()
        model = array(list(map(lambda x: model.get_py_value(x), k_seq)),
                      dtype=bool)
        yield model
        solver.add_assertion(
            Or([NotEquals(k_seq[i], Int(model[i])) for i in range(K_seq_len)]))
Esempio n. 22
0
    def test_int(self):
        p, q = Symbol("p", INT), Symbol("q", INT)
        f = Or(Equals(Times(p, Int(5)), Minus(p, q)), LT(p, q),
               LE(Int(6), Int(1)))

        f_string = self.print_to_string(f)
        self.assertEqual(f_string, "(or (= (* p 5) (- p q)) (< p q) (<= 6 1))")
Esempio n. 23
0
 def test_yices_quantifier(self):
     x = Symbol('x', REAL)
     f = ForAll([x], LE(x, Real(0)))
     with self.assertRaises(InternalSolverError):
         with Solver(name='yices') as s:
             s.add_assertion(f)
             self.assertFalse(s.solve())
Esempio n. 24
0
    def test_solving_under_assumption_theory(self):
        x = Symbol("x", REAL)
        y = Symbol("y", REAL)

        v1 = GT(x, Real(10))
        v2 = LE(y, Real(2))

        xor = Or(And(v1, Not(v2)), And(Not(v1), v2))

        for name in get_env().factory.all_solvers(logic=QF_LRA):
            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())
Esempio n. 25
0
 def test_equality_typing(self):
     x = Symbol('x', BOOL)
     y = Symbol('y', BOOL)
     with self.assertRaises(PysmtTypeError):
         Equals(x, y)
     with self.assertRaises(PysmtTypeError):
         LE(x, y)
Esempio n. 26
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("")
 def test_reals(self):
     f = And(LT(Symbol("x", REAL), Real(2)), LE(Symbol("x", REAL), Real(3)))
     for n in self.all_solvers:
         with Solver(name=n, logic=QF_UFLRA) as s:
             s.add_assertion(f)
             res = s.solve()
             self.assertTrue(res)
Esempio n. 28
0
 def add_relu_eager_constraint(self):
     # Eager lemma encoding for relus
     zero = Real(0)
     for r, relu_in in self.relus:
         self.formulae.append(Implies(GT(relu_in, zero), Equals(r,
                                                                relu_in)))
         self.formulae.append(Implies(LE(relu_in, zero), Equals(r, zero)))
Esempio n. 29
0
    def generate_support_tree(self, depth, domains=None):
        subformulas = []
        if domains != None:
            assert (len(domains) == len(self.reals))
            for i, dom in enumerate(domains):
                lower, upper = dom
                var = self.reals[i]
                dom_formula = And(LE(Real(lower), var), LE(var, Real(upper)))
                subformulas.append(dom_formula)
        else:
            # generate the domains of the real variables
            for rvar in self.reals:
                subformulas.append(ModelGenerator._random_domain(rvar))

        # generate the support
        subformulas.append(self._random_formula(depth))
        return And(subformulas)
Esempio n. 30
0
def simple_univariate_problem():
    variables = ["x"]
    var_types = {"x": REAL}
    var_domains = {"x": (0, 1)}

    theory = LE(Symbol("x", REAL), Real(0.6))

    return Domain(variables, var_types, var_domains), theory, "one_test"