Example #1
0
def make_from_graph(graph):
    n = graph.vcount()
    domain = Domain.make([], [f"x{i}" for i in range(n)], real_bounds=(-1, 1))
    X = domain.get_symbols()
    support = smt.And(*((X[e.source] + 1 <= X[e.target]) | (X[e.target] <= X[e.source] - 1)
                        for e in graph.es))
    return Density(domain, support & domain.get_bounds(), smt.Real(1))
def test_projection():
    domain = Domain.make(["a", "b"], ["x", "y"], real_bounds=(0, 1))
    data = numpy.array([
        [1, 0, 0.5, 0.3],
        [0, 0, 0.2, 0.1],
    ])

    # Get boolean variables
    domain1, data1 = domain.project(["a", "b"], data)
    assert domain1.variables == ["a", "b"]
    assert (data1 == numpy.array([
        [1, 0],
        [0, 0],
    ])).all()

    # Get real variables
    domain2, data2 = domain.project(["x", "y"], data)
    assert domain2.variables == ["x", "y"]
    assert (data2 == numpy.array([
        [0.5, 0.3],
        [0.2, 0.1],
    ])).all()

    # Reorder variables
    domain3, data3 = domain.project(["x", "a"], data)
    assert domain3.variables == ["x", "a"]
    assert (data3 == numpy.array([
        [0.5, 1],
        [0.2, 0],
    ])).all()
Example #3
0
def background_knowledge_example():
    domain = Domain.make(["a", "b"], ["x", "y"], [(0, 1), (0, 1)])
    a, b, x, y = domain.get_symbols(domain.variables)
    formula = (a | b) & (~a | ~b) & (x >= 0) & (x <= y) & (y <= 1)
    thresholds = {v: 0.1 for v in domain.real_vars}
    data = uniform(domain, 10000)
    labels = evaluate(domain, formula, data)
    data = data[labels == 1]
    labels = labels[labels == 1]

    def learn_inc(_data, _labels, _i, _k, _h):
        strategy = OneClassStrategy(
            RandomViolationsStrategy(10),
            thresholds)  #, background_knowledge=(a | b) & (~a | ~b))
        learner = KCnfSmtLearner(_k, _h, strategy, "mvn")
        initial_indices = LearnOptions.initial_random(20)(list(
            range(len(_data))))
        # learner.add_observer(LoggingObserver(None, _k, _h, None, True))
        learner.add_observer(
            PlottingObserver(domain, "test_output/bg",
                             "run_{}_{}_{}".format(_i, _k,
                                                   _h), domain.real_vars[0],
                             domain.real_vars[1], None, False))
        return learner.learn(domain, _data, _labels, initial_indices)

    (new_data, new_labels,
     formula), k, h = learn_bottom_up(data, labels, learn_inc, 1, 1, 1, 1,
                                      None, None)
    print("Learned CNF(k={}, h={}) formula {}".format(k, h,
                                                      pretty_print(formula)))
    print("Data-set grew from {} to {} entries".format(len(labels),
                                                       len(new_labels)))
def ex1_b2_r2():
    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.0) & (x <= y) & (y <= 1.0)
    weight = Ite(a, Real(0.6), Real(0.4)) * Ite(b, Real(0.8), Real(0.2))\
        * (Ite(x >= Real(0.5), Real(0.5) * x + Real(0.1) * y, Real(0.1) * x + Real(0.7) * y))
    return Density(domain, support, weight, [x <= y / 2])
def test_minus():
    domain = Domain.make([], ["x"], [(0, 1)])
    (x, ) = domain.get_symbols()
    support = TRUE()
    weight = Real(1) - x
    engine = XaddEngine(domain, support, weight)
    assert engine.compute_volume() is not None
def sanity_b1_r0():
    domain = Domain.make(["a"])
    a, = domain.get_symbols()
    support = TRUE()
    weight = Ite(a, Real(0.3), Real(0.7))
    queries = [a, ~a]
    return Density(domain, support, weight, queries)
def sanity_b0_r1():
    domain = Domain.make(real_variables=["x"], real_bounds=(0, 1))
    x, = domain.get_symbols()
    support = (x >= 0.25) & (x <= 0.75)
    weight = x + 1
    queries = [x >= 0.5]
    return Density(domain, support, weight, queries)
def test_sampling():
    domain = Domain.make(["a", "b"], ["x", "y"], real_bounds=(0, 1))
    a, b, x, y = domain.get_symbols()
    support = (a | b) & (~a | ~b) & (x <= y)
    weight = smt.Ite(a, smt.Real(1), smt.Real(2))

    required_sample_count = 10000
    samples_weighted, pos_ratio = positive(required_sample_count, domain,
                                           support, weight)
    assert samples_weighted.shape[0] == required_sample_count
    assert sum(evaluate(domain, support,
                        samples_weighted)) == len(samples_weighted)
    samples_a = sum(evaluate(domain, a, samples_weighted))
    samples_b = sum(evaluate(domain, b, samples_weighted))
    assert samples_a == pytest.approx(samples_b / 2, rel=0.2)
    assert pos_ratio == pytest.approx(0.25, rel=0.1)

    samples_unweighted, pos_ratio = positive(required_sample_count, domain,
                                             support)
    assert samples_unweighted.shape[0] == required_sample_count
    assert sum(evaluate(domain, support,
                        samples_unweighted)) == len(samples_weighted)
    samples_a = sum(evaluate(domain, a, samples_unweighted))
    samples_b = sum(evaluate(domain, b, samples_unweighted))
    assert samples_a == pytest.approx(samples_b, rel=0.1)
    assert pos_ratio == pytest.approx(0.25, rel=0.1)
Example #9
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
Example #10
0
    def renormalize_node(self, support):
        if self.is_leaf():

            domA = [
                var.symbol_name() for var in self.bounds
                if var.symbol_type() == BOOL
            ]
            domX = []
            bs = []
            for var, b in self.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, self.bounds_to_SMT())
            engine = PredicateAbstractionEngine(domain, intersection, Real(1))
            intervol = engine.compute_volume()

            if not intervol > 0:
                raise ModelException("Non-positive leaf intersection volume")

            if self.volume != intervol:
                self.renorm_const = self.volume / intervol

        else:
            self.pos.renormalize_node(support)
            self.neg.renormalize_node(support)
Example #11
0
def univariate(n):
    domain = Domain.make([], ["x{}".format(i) for i in range(n)], real_bounds=(-2, 2))
    x_vars = domain.get_symbols()
    support = smt.And(*[x > 0.5 for x in x_vars])
    weight = smt.Times(*[smt.Ite((x > -1) & (x < 1), smt.Ite(x < 0, x + smt.Real(1), -x + smt.Real(1)), smt.Real(0))
                         for x in x_vars])
    return FileDensity(domain, support, weight)
def test_plot_boolean_or():
    nested_string = "(| (var bool a) (var bool b))"
    domain = Domain.make(["a", "b"], ["x", "y"], [(0, 1), (0, 1)])
    formula = nested_to_smt(nested_string)
    with TemporaryFile(suffix=".png") as filename:
        plot_formula(filename, domain, formula)
        image = Image.open(filename)
        assert image.getpixel((900, 900)) == image.getpixel((300, 900))
def test_real():
    domain = Domain.make([], ["x", "y"], [(-1, 1), (2, 10)])
    sample_count = 10
    data = sample.uniform(domain, sample_count)
    assert len(data) == sample_count
    for i in range(sample_count):
        assert -1 <= data[i, 0] <= 1
        assert 2 <= data[i, 1] <= 10
def test_boolean():
    domain = Domain.make(["a", "b", "c"])
    sample_count = 10
    data = sample.uniform(domain, sample_count)
    assert len(data) == sample_count
    for i in range(sample_count):
        for j in range(3):
            assert data[i, j] == 0 or data[i, j] == 1
def _test_plot_data():
    domain = Domain.make(["a"], ["x", "y"], [(0, 1), (0, 1)])
    a, x, y = domain.get_symbols(["a", "x", "y"])
    formula = a | (~a & (x <= y))
    data = uniform(domain, 100)
    labels = evaluate(domain, formula, data)
    mpl.use('Agg')
    plot_data(None, domain, (data, labels))
    assert True
def ex_jonathan_smaller():
    domain = Domain.make(["f0", "d0"], ["r0"], [(10, 45)])
    f0, d0 = domain.get_bool_symbols()
    r0, = domain.get_real_symbols()
    support = ((f0 & ~(r0 <= 35) & ~d0) |
               (f0 & (r0 <= 35) & ~d0)) & domain.get_bounds()

    weight_function = Real(0.00000001) * r0 * r0 * r0
    return Density(domain, support, weight_function, queries=[d0])
def test_sampling_stacking():
    domain = Domain.make([], ["x", "y"], real_bounds=(0, 1))
    x, y = domain.get_symbols()
    support = (x <= y)
    try:
        positive(20, domain, support, sample_count=10, max_samples=10000)
        assert True
    except ValueError:
        assert False
Example #18
0
def negative_samples_example(background_knowledge):
    domain = Domain.make(["a", "b"], ["x", "y"], [(0, 1), (0, 1)])
    a, b, x, y = domain.get_symbols(domain.variables)
    formula = (a | b) & (~a | ~b) & (x <= y) & domain.get_bounds()
    background_knowledge = (a | b) & (~a
                                      | ~b) if background_knowledge else None
    thresholds = {"x": 0.1, "y": 0.2}
    data = uniform(domain, 10000)
    labels = evaluate(domain, formula, data)
    data = data[labels == 1]
    labels = labels[labels == 1]
    original_sample_count = len(labels)

    start_time = time.time()

    data, labels = OneClassStrategy.add_negatives(domain, data, labels,
                                                  thresholds, 100,
                                                  background_knowledge)
    print("Created {} negative examples".format(
        len(labels) - original_sample_count))

    directory = "test_output{}bg_sampled{}{}".format(
        os.path.sep, os.path.sep, time.strftime("%Y-%m-%d %Hh%Mm%Ss"))

    def learn_inc(_data, _labels, _i, _k, _h):
        strategy = OneClassStrategy(RandomViolationsStrategy(10),
                                    thresholds,
                                    background_knowledge=background_knowledge)
        learner = KCnfSmtLearner(_k, _h, strategy, "mvn")
        initial_indices = LearnOptions.initial_random(20)(list(
            range(len(_data))))
        learner.add_observer(
            PlottingObserver(domain, directory,
                             "run_{}_{}_{}".format(_i, _k,
                                                   _h), domain.real_vars[0],
                             domain.real_vars[1], None, False))
        return learner.learn(domain, _data, _labels, initial_indices)

    (new_data, new_labels,
     learned_formula), k, h = learn_bottom_up(data, labels, learn_inc, 1, 1, 1,
                                              1, None, None)
    if background_knowledge:
        learned_formula = learned_formula & background_knowledge

    duration = time.time() - start_time

    print("{}".format(smt_to_nested(learned_formula)))
    print("Learned CNF(k={}, h={}) formula {}".format(
        k, h, pretty_print(learned_formula)))
    print("Data-set grew from {} to {} entries".format(len(labels),
                                                       len(new_labels)))
    print("Learning took {:.2f}s".format(duration))

    test_data, labels = OneClassStrategy.add_negatives(domain, data, labels,
                                                       thresholds, 1000,
                                                       background_knowledge)
    assert all(evaluate(domain, learned_formula, test_data) == labels)
def import_wmi_generate_100(filename):
    # type: (str) -> Density
    queries = [smt.read_smtlib(filename + ".query")]
    support = smt.read_smtlib(filename + ".support")
    weights = smt.read_smtlib(filename + ".weights")
    variables = queries[0].get_free_variables() | support.get_free_variables() | weights.get_free_variables()
    domain = Domain.make(real_bounds=(-100, 100),
                         boolean_variables=[v.symbol_name() for v in variables if v.symbol_type() == smt.BOOL])
    return Density(domain, support, weights, queries)
def test_sampling_max_samples():
    domain = Domain.make([], ["x", "y"], real_bounds=(0, 1))
    x, y = domain.get_symbols()
    support = smt.FALSE()
    try:
        positive(10, domain, support, max_samples=100000)
        assert False
    except SamplingError:
        assert True
def test_latte_backend():
    print(xadd_installed)
    x, y = [Symbol(n, REAL) for n in "xy"]
    inequalities = [LinearInequality.from_smt(f) for f in [(x >= 0), (x <= y), (y <= 1)]]
    polynomial = Polynomial.from_smt((x*2/3 + 13/15) * (y*1/8 + x))
    domain = Domain.make([], ["x", "y"], [(0, 1), (0, 1)])
    result = LatteIntegrator().integrate(domain, inequalities, polynomial)
    xadd_result = EngineConvexIntegrationBackend(PyXaddEngine()).integrate(domain, inequalities, polynomial)
    print(result, xadd_result)
    assert result == pytest.approx(xadd_result, rel=0.001)
Example #22
0
def dual(n):
    n = 2*n
    domain = Domain.make([], ["x{}".format(i) for i in range(n)], real_bounds=(0, 1))
    x_vars = domain.get_symbols()
    terms = [x_vars[2 * i] <= x_vars[2 * i + 1] for i in range(int(n / 2))]
    disjunction = smt.Or(*terms)
    for i in range(len(terms)):
        for j in range(i + 1, len(terms)):
            disjunction &= ~terms[i] | ~terms[j]
    return FileDensity(domain, disjunction & domain.get_bounds(), smt.Real(1))
def test_plot_xor():
    domain = Domain.make(["a", "b"], ["x", "y"], [(0, 1), (0, 1)])
    a, b, x, y = domain.get_symbols()
    formula = ((x * -2.539851974031258e-15 + y * 3.539312736703863e-15 <= Real(0.0)) | ~a | ~b) \
        & (a | b) \
        & (Real(0.0) < x * -2.539851974031258e-15 + y * 3.539312736703863e-15)

    with TemporaryFile(suffix=".png") as filename:
        plot_formula(filename, domain, formula)
        image = Image.open(filename)
        assert image.getpixel((900, 900)) == image.getpixel((300, 300))
def ex_jonathan():
    domain = Domain.make(["f0", "d0"], ["r0"], [(10, 45)])
    f0, d0 = domain.get_bool_symbols()
    r0, = domain.get_real_symbols()
    support = ((f0 & (((d0 | ~d0) & ~(r0 <= 35)) | ((r0 <= 35) & (~d0))))
               | (~f0 & (d0 & (r0 <= 35)))) & domain.get_bounds()

    weight_function = Ite(f0, Real(0.0001), Real(0.00001)) * \
                      Ite(d0, (r0/10)-1, 8-(r0/10)) * \
                      Ite(r0 <= 35, -0.001*(r0-27)*(r0-27)+0.3, -0.001*(r0-27)*(r0-27)+0.3)
    return Density(domain, support, weight_function, queries=[d0])
def test_trivial_weight_function_partial_0b_1r_disjoint():
    domain = Domain.make([], ["x"], real_bounds=(0, 1))
    (x, ) = domain.get_symbols(domain.variables)
    support = (x >= 0.1) & (x <= 0.9) & ~((x >= 0.3) & (x <= 0.7))
    weight = Real(2.0)

    engine = FactorizedXsddEngine(domain, support, weight)
    computed_volume = engine.compute_volume()

    should_be = PyXaddEngine(domain, support, weight).compute_volume()
    # print(computed_volume, should_be)
    assert computed_volume == pytest.approx(should_be, rel=ERROR)
def test_partial_0b_2r_branch_weight():
    domain = Domain.make([], ["x", "y"], real_bounds=(0, 1))
    x, y = domain.get_symbols(domain.variables)
    support = (x >= 0.1) & (x <= 0.9) & (y >= 0.3) & (y <= 0.7)
    weight = Ite(x <= y, x, y * 3.17)

    engine = FactorizedXsddEngine(domain, support, weight)
    computed_volume = engine.compute_volume()

    should_be = PyXaddEngine(domain, support, weight).compute_volume()
    # print(computed_volume, should_be)
    assert computed_volume == pytest.approx(should_be, rel=ERROR)
def test_adaptive_unweighted():
    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)
    engine = AdaptiveRejection(domain, support, weight, SAMPLE_COUNT,
                               SAMPLE_COUNT / 10)
    computed_volume = engine.compute_volume()
    correction_volume_rej = RejectionEngine(domain, support, weight,
                                            SAMPLE_COUNT).compute_volume()
    assert computed_volume == pytest.approx(correction_volume_rej,
                                            rel=APPROX_ERROR)
def test_volume():
    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.0) & (x <= y) & (y <= 1.0)
    weight = Ite(a, Real(0.6), Real(0.4)) * Ite(b, Real(0.8), Real(0.2))\
             * (Ite(x >= Real(0.5), Real(0.5) * x + Real(0.1) * y, Real(0.1) * x + Real(0.7) * y))
    engine = AdaptiveRejection(domain, support, weight, SAMPLE_COUNT)
    computed_volume = engine.compute_volume()
    correction_volume_rej = RejectionEngine(domain, support, weight,
                                            SAMPLE_COUNT).compute_volume()
    assert computed_volume == pytest.approx(correction_volume_rej,
                                            rel=APPROX_ERROR)
def merged_domain(model1, model2):
    assert(model1.get_vars() == model2.get_vars())
    bounds = deepcopy(model1.bounds)
    for v, b in model2.bounds.items():
        if v not in bounds:
            bounds[v] = b
        else:
            bounds[v][0] = min(b[0], bounds[v][0])
            bounds[v][-1] = max(b[-1], bounds[v][-1])

    domain = Domain.make(map(lambda v : v.symbol_name(),
                             model1.boolean_vars), bounds)
    return domain, bounds
Example #30
0
def test_adaptive_threshold():
    random.seed(888)
    np.random.seed(888)

    domain = Domain.make([], ["x", "y"], [(0, 1), (0, 1)])
    x, y = domain.get_symbols(domain.variables)
    formula = (x <= y) & (x <= 0.5) & (y <= 0.5) & domain.get_bounds()
    thresholds = {"x": 0.1, "y": 0.1}
    data, _ = RejectionEngine(domain, formula, x * x, 100000).get_samples(50)
    k = 4
    nearest_neighbors = []
    for i in range(len(data)):
        nearest_neighbors.append([])
        for j in range(len(data)):
            if i != j:
                distance = 1 if any(data[i, b] != data[j, b] for b, v in enumerate(domain.variables)
                                    if domain.is_bool(v))\
                    else max(abs(data[i, r] - data[j, r]) / (domain.var_domains[v][1] - domain.var_domains[v][0]) for r, v in enumerate(domain.variables) if domain.is_real(v))
                if len(nearest_neighbors[i]) < k:
                    nearest_neighbors[i].append((j, distance))
                else:
                    index_of_furthest = None
                    for fi, f in enumerate(nearest_neighbors[i]):
                        if index_of_furthest is None or f[
                                1] > nearest_neighbors[i][index_of_furthest][1]:
                            index_of_furthest = fi
                    if distance < nearest_neighbors[i][index_of_furthest][1]:
                        nearest_neighbors[i][index_of_furthest] = (j, distance)
    print(nearest_neighbors)
    t = [[
        sum(n[1] for n in nearest_neighbors[i]) / len(nearest_neighbors[i]) *
        (domain.var_domains[v][1] - domain.var_domains[v][0])
        for v in domain.real_vars
    ] for i in range(len(nearest_neighbors))]
    t = np.array(t)
    print(t)
    print(data)
    # data = uniform(domain, 400)
    labels = evaluate(domain, formula, data)
    data = data[labels == 1]
    labels = labels[labels == 1]
    data, labels = OneClassStrategy.add_negatives(domain, data, labels, t,
                                                  1000)

    directory = "test_output{}adaptive{}{}".format(
        os.path.sep, os.path.sep, time.strftime("%Y-%m-%d %Hh%Mm%Ss"))
    os.makedirs(directory)

    name = os.path.join(directory, "combined.png")
    plot.plot_combined("x", "y", domain, formula, (data, labels), None, name,
                       set(), set())