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))
Example #2
0
 def run_internal(self):
     density = Density.from_file(self["filename"])
     solver = get_engine(self["solver"], density.domain, density.support, density.weight)
     if not density.queries or (len(density.queries) == 1 and density.queries[0] == smt.TRUE()):
         self["volumes"] = [solver.compute_volume()]
     else:
         self["volumes"] = [solver.compute_probabilities(density.queries)]
Example #3
0
def generate_xor(n):
    domain = make_domain(n)
    symbols = domain.get_symbols(domain.real_vars)
    x, symbols = symbols[0], symbols[1:]
    bounds = make_distinct_bounds(domain)
    terms = [x <= v for v in symbols]
    xor = smt.FALSE()
    for term in terms:
        xor = (xor | term) & ~(xor & term)

    return Density(flip_domain(domain), bounds & xor, smt.Real(1.0))
Example #4
0
def dual_paths(n):
    booleans = []  # ["A{}".format(i) for i in range(n)]
    domain = Domain.make(booleans, ["x{}".format(i) for i in range(n)], real_bounds=(0, 1))
    bool_vars = domain.get_bool_symbols()
    real_vars = domain.get_real_symbols()
    terms = []
    for i in range(n):
        v1, v2 = random.sample(real_vars, 2)
        terms.append(v1 * random.random() <= v2 * random.random())

    paths = []
    for i in range(n):
        paths.append(smt.And(*random.sample(bool_vars + terms, n)))

    return Density(domain, domain.get_bounds() & smt.Or(*paths), smt.Real(1))
Example #5
0
def generate_mutual_exclusive(n):
    domain = make_domain(n)

    symbols = domain.get_symbols(domain.real_vars)
    x, symbols = symbols[0], symbols[1:]

    bounds = make_distinct_bounds(domain)

    terms = [x <= v for v in symbols]
    disjunction = smt.Or(*terms)
    for i in range(n):
        for j in range(i + 1, n):
            disjunction &= ~terms[i] | ~terms[j]

    return Density(flip_domain(domain), bounds & disjunction, smt.Real(1.0))
Example #6
0
def generate_click_graph(n):
    def t(c):
        return smt.Ite(c, one, zero)

    sim_n, cl_n, b_n, sim_x_n, b_x_n = "sim", "cl", "b", "sim_x", "b_x"
    domain = Domain.make(
        # Boolean
        ["{}_{}".format(sim_n, i) for i in range(n)] +
        ["{}_{}_{}".format(cl_n, i, j) for i in range(n) for j in (0, 1)] +
        ["{}_{}_{}".format(b_n, i, j) for i in range(n) for j in (0, 1)],
        # Real
        ["{}".format(sim_x_n)] +
        ["{}_{}_{}".format(b_x_n, i, j) for i in range(n) for j in (0, 1)],
        real_bounds=(0, 1))
    sim = [domain.get_symbol("{}_{}".format(sim_n, i)) for i in range(n)]
    cl = [[domain.get_symbol("{}_{}_{}".format(cl_n, i, j)) for j in (0, 1)]
          for i in range(n)]
    b = [[domain.get_symbol("{}_{}_{}".format(b_n, i, j)) for j in (0, 1)]
         for i in range(n)]
    sim_x = domain.get_symbol("{}".format(sim_x_n))
    b_x = [[domain.get_symbol("{}_{}_{}".format(b_x_n, i, j)) for j in (0, 1)]
           for i in range(n)]

    support = smt.And([
        smt.Iff(cl[i][0], b[i][0])
        & smt.Iff(cl[i][1], (sim[i] & b[i][0]) | (~sim[i] & b[i][1]))
        for i in range(n)
    ])

    one = smt.Real(1)
    zero = smt.Real(0)
    w_sim_x = t(sim_x >= 0) * t(sim_x <= 1)
    w_sim = [smt.Ite(s_i, sim_x, 1 - sim_x) for s_i in sim]
    w_b_x = [
        t(b_x[i][j] >= 0) * t(b_x[i][j] <= 1) for i in range(n) for j in (0, 1)
    ]
    w_b = [
        smt.Ite(b[i][j], b_x[i][j], 1 - b_x[i][j]) for i in range(n)
        for j in (0, 1)
    ]

    weight = smt.Times(*([w_sim_x] + w_sim + w_b_x + w_b))
    return Density(domain, support, weight)
Example #7
0
def prepare_ratios():
    sample_count = 1000
    bounds_pool = [(-1, 1), (-10, 10), (-100, 100), (-1000, 1000)]
    ratios = dict()
    for name, entry, density_filename in select_benchmark_files(
            lambda e: "bounds" not in e and benchmark_filter(e)):
        print("Finding ratios for {}".format(name))
        pysmt.environment.push_env()
        pysmt.environment.get_env().enable_infix_notation = True

        density = Density.import_from(density_filename)
        domain = density.domain

        result_bounds = []
        result_ratios = []
        for bounds in itertools.product(
                *[bounds_pool for _ in range(len(domain.real_vars))]):
            var_bounds = dict(zip(domain.real_vars, bounds))
            restricted_domain = Domain(domain.variables, domain.var_types,
                                       var_bounds)
            samples = uniform(restricted_domain, sample_count)
            labels = evaluate(restricted_domain, density.support, samples)
            positive_count = sum(labels)
            if 0 < positive_count < sample_count:
                ratio = positive_count / sample_count
                result_bounds.append(var_bounds)
                result_ratios.append(ratio)

        ratios[name] = list(zip(result_bounds, result_ratios))
        print(name, result_ratios)

        pysmt.environment.pop_env()

    with open(get_summary_file(), "rb") as summary_file_reference:
        summary = pickle.load(summary_file_reference)

    for name, bounds in ratios.items():
        summary[name]["bounds"] = bounds

    with open(get_summary_file(), "wb") as summary_file_reference:
        pickle.dump(summary, summary_file_reference)
Example #8
0
 def accuracy_approx(experiment):
     key = "accuracy_approx:{}".format(experiment.imported_from_file)
     if Properties.db.exists(key):
         return Properties.db.get(key)
     else:
         pysmt.environment.push_env()
         pysmt.environment.get_env().enable_infix_notation = True
         if os.path.basename(experiment.imported_from_file).startswith("synthetic"):
             db = Properties.get_db_synthetic(experiment)
             name = Properties.to_synthetic_name(experiment.imported_from_file)
             entry = db.get(name)
             domain = import_domain(json.loads(entry["domain"]))
             true_formula = nested_to_smt(entry["formula"])
         else:
             density = Density.import_from(experiment.parameters.original_values["domain"])
             domain = Domain(density.domain.variables, density.domain.var_types, Properties.get_bound(experiment))
             true_formula = density.support
         learned_formula = nested_to_smt(experiment.results.formula)
         engine = RejectionEngine(domain, smt.TRUE(), smt.Real(1.0), 100000)
         accuracy = engine.compute_probability(smt.Iff(true_formula, learned_formula))
         pysmt.environment.pop_env()
         print(accuracy)
         Properties.db.set(key, accuracy)
     return accuracy
Example #9
0
 def from_state(cls, state: dict):
     density = Density.from_state(state)
     return cls(density.domain, density.support)
Example #10
0
def prepare_smt_lib_benchmark():
    benchmark_folder = get_res_root("smt_lib_benchmark")
    if not os.path.exists(benchmark_folder):
        os.makedirs(benchmark_folder)

    zip_file = os.path.join(benchmark_folder, "qf_lra.zip")
    zip_checksums = [
        'd0031a9e1799f78e72951aa4bacedaff7c0d027905e5de29b5980083b9c51138def165cc18fff205c1cdd0ef60d5d95cf179f0d82ec41ba489acf4383f3e783c'
    ]  # ,
    # '8aa31ada44bbb6705ce58f1f50870da4f3b2d2d27065f3c5c6a17bd484a4cb7eab0c1d55a8d78e48217e66c5b2d876c0708516fb8a383d1ea82a6d4f1278d476']
    qf_lra_folder = os.path.join(benchmark_folder, "QF_LRA")
    if not os.path.exists(qf_lra_folder) and not os.path.exists(zip_file):
        print("Downloading ZIP file to {}".format(zip_file))
        url = "http://smt-lib.loria.fr/zip/QF_LRA.zip"
        with urllib.request.urlopen(url) as response, open(zip_file,
                                                           'wb') as out_file:
            shutil.copyfileobj(response, out_file)
    if not os.path.exists(qf_lra_folder):
        print("Extracting ZIP file {}".format(zip_file))
        if checksum(zip_file) not in zip_checksums:
            fix_zip_file(zip_file)
            if checksum(zip_file) not in zip_checksums:
                raise RuntimeError("Corrupted file download")
        with zipfile.ZipFile(zip_file, 'r') as zip_ref:
            zip_ref.extractall(benchmark_folder)

    summary_file = os.path.join(benchmark_folder, "qf_lra_summary.pickle")

    if not os.path.exists(summary_file):
        with open(summary_file, "wb") as summary_file_ref:
            pickle.dump(dict(), summary_file_ref)
    with open(summary_file, "rb") as summary_file_ref:
        summary = pickle.load(summary_file_ref)

    cache_dir = os.path.join(benchmark_folder, "qf_lra_cache")
    if not os.path.exists(cache_dir):
        os.makedirs(cache_dir)

    for filename in glob.glob("{}/**/*.smt*".format(qf_lra_folder),
                              recursive=True):
        name = filename[filename.find("QF_LRA"):]
        if name not in summary:
            summary[name] = dict()

        cache_filename = "{}{}{}".format(cache_dir, os.path.sep, name)

        entry = summary[name]
        if "file_size" not in entry:
            entry["file_size"] = os.path.getsize(filename)

        if entry["file_size"] / 1024 > 100:
            continue

        density_filename = "{}.density".format(cache_filename)
        if not os.path.exists(os.path.dirname(density_filename)):
            os.makedirs(os.path.dirname(density_filename))

        domain, formula = None, None

        pysmt.environment.push_env()
        pysmt.environment.get_env().enable_infix_notation = True

        if not os.path.exists(density_filename):
            print("Importing {}".format(name))
            try:
                domain, formula = import_problem(filename)
                Density(domain, formula,
                        smt.Real(1.0)).export_to(density_filename)
            except RuntimeError:
                print("Error")
                continue

        keys = [
            "real_variables_count", "bool_variables_count", "operators",
            "half_spaces"
        ]
        if any(k not in entry
               for k in keys) and (domain is None or formula is None):
            print("Loading {}".format(name))
            density = Density.import_from(density_filename)
            domain = density.domain
            formula = density.support

        if "real_variables_count" not in entry:
            entry["real_variables_count"] = len(domain.real_vars)
        if "bool_variables_count" not in entry:
            entry["bool_variables_count"] = len(domain.bool_vars)
        if "operators" not in entry:
            entry["operators"] = OperatorWalker().find_operators(formula)
        if "half_spaces" not in entry:
            entry["half_spaces"] = HalfSpaceWalker().find_half_spaces(formula)

        pysmt.environment.pop_env()

    with open(summary_file, "wb") as summary_file_ref:
        pickle.dump(summary, summary_file_ref)
Example #11
0
def prepare_synthetic(input_directory, output_directory, runs, sample_size):
    seeds = [random.randint(0, 2**32 - 1) for _ in range(runs)]

    db = get_synthetic_db(output_directory, True)
    os.makedirs(output_directory)
    for filename in glob.glob("{}/**/synthetics*.txt".format(input_directory),
                              recursive=True):
        pysmt.environment.push_env()
        pysmt.environment.get_env().enable_infix_notation = True
        with open(filename) as file_reference:
            flat = json.load(file_reference)

        name = flat["synthetic_problem"]["problem"]["name"]
        print(name)

        if not db.exists(name):
            domain = import_domain(
                flat["synthetic_problem"]["problem"]["domain"])
            formula = nested_to_smt(
                flat["synthetic_problem"]["problem"]["theory"])
            Density(domain, formula, smt.Real(1.0)).export_to(
                os.path.join(output_directory, "{}.density".format(name)))
            entry = {
                "domain": export_domain(domain),
                "generation": {
                    "h": flat["synthetic_problem"]["half_space_count"],
                    "k": flat["synthetic_problem"]["formula_count"],
                    "l": flat["synthetic_problem"]["terms_per_formula"],
                    "structure": flat["synthetic_problem"]["cnf_or_dnf"],
                },
                "formula": smt_to_nested(formula),
                "samples": []
            }
        else:
            entry = dict(db.get(name))
            domain = import_domain(entry["domain"])
            formula = import_domain(entry["domain"])

        samples = entry.get("samples", [])
        matching_samples = []
        for sample in samples:
            if sample["sample_size"] == sample_size:
                matching_samples.append(sample)

        for i in range(runs - len(matching_samples)):
            seed = seeds[len(matching_samples) + i]
            samples_file = "{}.{}.{}.samples.npy".format(
                name, sample_size, seed)
            labels_file = "{}.{}.{}.labels.npy".format(name, sample_size, seed)
            np.random.seed(seed)
            data = uniform(domain, sample_size)
            np.save(os.path.join(output_directory, samples_file), data)
            labels = evaluate(domain, formula, data)
            np.save(os.path.join(output_directory, labels_file), labels)
            samples.append({
                "sample_size": sample_size,
                "seed": seed,
                "samples_file": samples_file,
                "labels_file": labels_file
            })

        entry["samples"] = samples
        db.set(name, entry)

        pysmt.environment.pop_env()
Example #12
0
def prepare_samples(n, sample_size, reset):
    samples_dir = get_benchmark_samples_dir()

    seeds = [random.randint(0, 2**32 - 1) for _ in range(n)]
    samples_dict = dict()

    def sample_filter(_entry):
        if "bounds" in _entry and benchmark_filter(_entry):
            if "samples" not in _entry["samples"]:
                return True
            else:
                return reset or any(
                    len([
                        s for s in _entry["samples"] if s["sample_size"] ==
                        sample_size and s["bounds"] == _bounds[0]
                    ]) < n for _bounds in _entry["bounds"]
                    if 0.2 <= _bounds[1] <= 0.8)
        return False

    for name, entry, filename in select_benchmark_files(sample_filter):
        print("Creating samples for {}".format(name))
        pysmt.environment.push_env()
        pysmt.environment.get_env().enable_infix_notation = True

        density = Density.import_from(filename)
        samples_dict[name] = [] if reset else entry.get("samples", [])

        for i, (bounds, ratio) in enumerate(entry["bounds"]):
            if not (0.2 <= ratio <= 0.8):
                continue

            print(i, bounds, ratio)
            previous_samples = [] if reset else ([
                s for s in entry.get("samples", [])
                if s["sample_size"] == sample_size and s["bounds"] == bounds
            ])
            bounded_domain = Domain(density.domain.variables,
                                    density.domain.var_types, bounds)

            for j in range(n - len(previous_samples)):
                seed = seeds[j]
                samples_filename = "{}{}{}.{}.{}.{}.sample.npy".format(
                    samples_dir, os.path.sep, name, sample_size, seed, i)
                labels_filename = "{}{}{}.{}.{}.{}.labels.npy".format(
                    samples_dir, os.path.sep, name, sample_size, seed, i)

                if not os.path.exists(os.path.dirname(samples_filename)):
                    os.makedirs(os.path.dirname(samples_filename))

                random.seed(seed)
                np.random.seed(seed)
                samples = uniform(bounded_domain, sample_size)
                labels = evaluate(bounded_domain, density.support, samples)
                np.save(samples_filename, samples)
                np.save(labels_filename, labels)

                samples_dict[name].append({
                    "bounds": bounds,
                    "seed": seed,
                    "samples_filename": samples_filename,
                    "labels_filename": labels_filename,
                    "sample_size": sample_size
                })

        pysmt.environment.pop_env()

    def edit(summary):
        for _n, _s in samples_dict.items():
            summary[_n]["samples"] = _s

    edit_summary(edit)
Example #13
0
 def domain_extraction(filename):
     return Density.import_from(filename).domain
def diabetes_example1():
    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()
    # support_smaller = ((f0 & ((~(r0 <= 35)) | ~d0)) |
    #                    (~f0 & d0 & (r0 <= 35))) & \
    #                   domain.get_bounds()

    # support_smaller = ((f0 & ((~(r0 <= 35)) | ~d0))) & \
    #                   domain.get_bounds()

    support_smaller = ((f0 & ~(r0 <= 35) & ~d0) |
                       (f0 & (r0 <= 35) & ~d0)) & domain.get_bounds()

    weight_function = smt.Ite(f0, smt.Real(0.0001), smt.Real(0.00001)) * \
                      smt.Ite(d0, (r0/10)-1, 8-(r0/10)) * \
                      smt.Ite(r0 <= 35, -0.001*(r0-27)*(r0-27)+0.3, -0.001*(r0-27)*(r0-27)+0.3)
    #
    # weight_function_smaller = smt.Ite(f0, smt.Real(0.0001), smt.Real(0.00001)) * \
    #                           r0 *\
    #                           smt.Ite(r0 <= 35, -0.001*(r0)*(r0)+0.3, -0.001*(r0)*(r0)+0.3)
    weight_function_smaller = (
        smt.Real(0.00000001) * r0 * r0 * r0
    )  # * smt.Real(1000)  #<--- add this changes the result from 0.0 to 102
    density = Density(domain, support & domain.get_bounds(),
                      weight_function)  # weight_function)
    query = d0

    startTime = time.time()
    rejection_engine = RejectionEngine(density.domain,
                                       density.support,
                                       density.weight,
                                       sample_count=1000000)

    vol1 = rejection_engine.compute_volume()
    result1 = rejection_engine.compute_probability(query)
    endTime = time.time()
    time1 = endTime - startTime

    startTime = time.time()
    xadd_engine = PyXaddEngine(density.domain, density.support, density.weight)
    vol2 = xadd_engine.compute_volume(add_bounds=False)
    result2 = xadd_engine.compute_probability(query)
    endTime = time.time()
    time2 = endTime - startTime
    # XsddEngine
    algebra = PyXaddAlgebra(reduce_strategy=PyXaddAlgebra.FULL_REDUCE)
    mfxsdd = FXSDD(
        density.domain,
        density.support,
        density.weight,
        vtree_strategy=balanced,
        algebra=algebra,
        ordered=False,
    )
    startTime = time.time()
    vol3 = mfxsdd.compute_volume(add_bounds=False)
    result3 = mfxsdd.compute_probability(query=query, add_bounds=False)
    endTime = time.time()
    time3 = endTime - startTime

    print(f"R1 {result1}, time1: {time1}")
    print(f"R2 {result2}, time2: {time2}")
    print(f"R3 {result3}, time3: {time3}")
    print("")
    print(f"Vol1 {vol1}, time1: {time1}")
    print(f"Vol2 {vol2}, time2: {time2}")
    print(f"Vol3 {vol3}, time3: {time3}")
    return result1, result2, time1, time2