Пример #1
0
def xsdd():
    domain, formula, weight = get_problem()
    return XsddEngine(domain, formula, weight,
                      repeated=True).compute_probabilities([
                          domain.get_symbol("x") <= 0.5,
                          domain.get_symbol("x") <= 1.0
                      ])
Пример #2
0
def run_xsdd(density, n_bins, n_samples, log_path):

    #log_path = join(output_folder, f"{name}-xsdd.json")
    print(f"running XSDD(Sampling) with {n_bins} bins and {n_samples} samples")
    print(f"dumping the result in {log_path}")
    if not isfile(log_path):
        xsdd_log = {}
        # create queries
        qs = {}
        for xvar in density.domain.get_real_symbols():
            x = xvar.symbol_name()
            qs[x] = []
            low, up = density.domain.var_domains[x]
            slices = [(i / n_bins) * (up - low) + low
                      for i in range(0, n_bins + 1)]
            for i in range(len(slices) - 1):
                l, u = slices[i], slices[i + 1]
                qs[x].append((l, u, And(LE(Real(l), xvar), LE(xvar, Real(u)))))

        t0 = time.perf_counter()
        backend = RejectionIntegrator(n_samples, 0)
        xsdd_engine = XsddEngine(density.domain,
                                 density.support,
                                 density.weight,
                                 convex_backend=backend,
                                 factorized=True,
                                 ordered=False)
        xsdd_bin_probs = {}
        for x in qs:
            xsdd_bin_probs[x] = []
            for l, u, q in qs[x]:
                prob_q = xsdd_engine.compute_probability(q)
                xsdd_bin_probs[x].append((l, u, prob_q))
        t1 = time.perf_counter()
        xsdd_log['time'] = t1 - t0
        xsdd_log['query_marginals'] = xsdd_bin_probs

        with open(log_path, 'w') as f:
            json.dump(xsdd_log, f)

    else:
        print(f"Found {log_path}")
        with open(log_path, 'r') as f:
            xsdd_bin_probs = json.load(f)['query_marginals']

    return xsdd_bin_probs
Пример #3
0
def test_trivial_weight_function_partial():
    # Support:  (a | b) & (~a | ~b) & (x >= 0) & (x <= y) & (y <= 10)
    # Weight:   1

    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)
    computed_volume = XsddEngine(
        domain=domain,
        support=support,
        weight=weight,
        convex_backend=EngineConvexIntegrationBackend(PyXaddEngine()),
    ).compute_volume()
    correction_volume_rej = RejectionEngine(domain, support, weight,
                                            1000000).compute_volume()
    correction_volume_xadd = PyXaddEngine(domain, support,
                                          weight).compute_volume()
    # print(correction_volume_rej, correction_volume_xadd, computed_volume)
    assert computed_volume == pytest.approx(correction_volume_rej, rel=ERROR)
    assert computed_volume == pytest.approx(correction_volume_xadd, rel=ERROR)
Пример #4
0
def test_volume():
    # Support:  (a | b) & (~a | ~b) & (x >= 0) & (x <= y) & (y <= 10)
    # Weight:   {
    #                a  b  (x>=0.5): 0.6*0.8*(0.5x+0.1y)  0.5 <= x <= y, x <= y <= 10
    #                a  b !(x>=0.5): 0.6*0.8*(0.1x+0.7y)  0 <= x <= [y, 0.5], x <= y <= 10
    #                a !b  (x>=0.5): 0.6*0.2*(0.5x+0.1y)  0.5 <= x <= y, x <= y <= 10
    #                a !b !(x>=0.5): 0.6*0.2*(0.1x+0.7y)  0 <= x <= [y, 0.5], x <= y <= 10
    #               !a  b  (x>=0.5): 0.4*0.8*(0.5x+0.1y)  0.5 <= x <= y, x <= y <= 10
    #               !a  b !(x>=0.5): 0.4*0.8*(0.1x+0.7y)  0 <= x <= [y, 0.5], x <= y <= 10
    #               !a !b  (x>=0.5): 0.4*0.2*(0.5x+0.1y)  0.5 <= x <= y, x <= y <= 10
    #               !a !b !(x>=0.5): 0.4*0.2*(0.1x+0.7y)  0 <= x <= [y, 0.5], x <= y <= 10
    # }

    # TODO What if we don't expand the Weight Function, only compile the support?
    # TODO => Can we reuse the SDD? It doesn't seem so... => Need multiple SDDs to use caching

    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,
              )))
    computed_volume = XsddEngine(
        domain=domain,
        support=support,
        weight=weight,
        convex_backend=EngineConvexIntegrationBackend(PyXaddEngine()),
    ).compute_volume()
    correction_volume_rej = RejectionEngine(domain, support, weight,
                                            1000000).compute_volume()
    correction_volume_xadd = PyXaddEngine(domain, support,
                                          weight).compute_volume()
    # print(correction_volume_rej, correction_volume_xadd, computed_volume)
    assert computed_volume == pytest.approx(correction_volume_rej, rel=ERROR)
    assert computed_volume == pytest.approx(correction_volume_xadd, rel=ERROR)
Пример #5
0
            logging.info("using pa")

            # pa
            t1 = time.perf_counter()
            wmipa = WMI(density.support, density.weight)
            Z, _ = wmipa.computeWMI(Bool(True), mode=WMI.MODE_PA)
            t2 = time.perf_counter()

        elif args.solver == "xsdd":
            logging.info("using xsdd")

            # xsdd
            t1 = time.perf_counter()
            xsdd = XsddEngine(density.domain,
                              density.support,
                              density.weight,
                              factorized=False,
                              algebra=PyXaddAlgebra(),
                              ordered=False)
            Z = xsdd.compute_volume(add_bounds=False)
            t2 = time.perf_counter()

        else:
            logging.info(f"Unrecognized solver: {args.solver}")

        logging.info(f"done in {t2-t1} secs")
        logging.info(f"Z: {Z}")

        z_path = os.path.join(res_path, 'Z')
        with open(z_path, 'w') as f:
            f.write(f"{Z}\n")
            logging.info(f"Z saved to {z_path}")
Пример #6
0
def main(path, file_name, domain_real):
    domain, queries, support, weight = load(path, file_name, domain_real)
    return XsddEngine(domain, support,
                      weight).compute_probability(queries[0], collapse=True)
Пример #7
0
def test_xsdd_manual():
    inspect_manual(
        lambda d, s, w: XsddEngine(d, s, w, convex_backend=LatteIntegrator()),
        REL_ERROR)
Пример #8
0
def get_engine(description, domain, support, weight):
    # type: (str, Domain, FNode, FNode) -> Engine
    parts = description.split(":")

    if parts[0].lower() == "pa":
        options = parse_options(parts[1:], "timeout")
        return PredicateAbstractionEngine(domain, support, weight, **options)
    if parts[0].lower() == "mpwmi":
        options = parse_options(parts[1:], "cache")
        return MPWMIEngine(domain, support, weight, **options)
    if parts[0].lower() == "rej":
        options = parse_options(parts[1:], "sample_count", "seed")
        return RejectionEngine(domain, support, weight, **options)
    if parts[0].lower() == "adapt":
        options = parse_options(parts[1:], "sample_count", "seed")
        return AdaptiveRejection(domain, support, weight, **options)
    if parts[0].lower() == "xadd":
        options = parse_options(parts[1:], "mode", "timeout")
        return XaddEngine(domain, support, weight, **options)
    if parts[0].lower() == "pyxadd":
        options = parse_options(parts[1:], "reduce")
        return PyXaddEngine(domain, support, weight, **options)
    if parts[0].lower() == "praise":
        # options = parse_options(parts[1:])
        return PraiseEngine(domain, support, weight)
    if parts[0].lower() == "xsdd":
        options = parse_options(
            parts[1:],
            "backend",
            "factorized",
            "find_conflicts",
            "ordered",
            "balance",
            "minimize",
        )
        backend_string = options.get("backend", None)
        if backend_string is None:
            backend = None
        else:
            parts = backend_string.split(".")
            if parts[0] == "rej":
                from .engines.rejection import RejectionIntegrator

                bb = int(parts[2]) if len(parts) > 2 else 0
                seed = int(parts[3]) if len(parts) > 3 else None
                backend = RejectionIntegrator(int(parts[1]), bb, seed=seed)
            elif parts[0] == "xadd":
                from .engines.xadd import XaddIntegrator

                backend = XaddIntegrator(parts[1] if len(parts) > 1 else None)
            elif parts[0] == "latte":
                from .engines.latte_backend import LatteIntegrator

                backend = LatteIntegrator()
            else:
                raise ValueError(
                    "Please specify a valid backend instead of {}".format(parts[0])
                )

        if "backend" in options:
            del options["backend"]

        # TODO figure out this
        # return XsddEngine(domain, support, weight, factorized=True,algebra=PyXaddAlgebra(), ordered=True)
        return XsddEngine(domain, support, weight, convex_backend=backend, **options)