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()
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)
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
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)
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
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)
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
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())