Пример #1
0
def test_wmc1(verbose=False):
    vtree = Vtree(var_count=4, var_order=[2, 1, 4, 3], vtree_type="balanced")
    sdd = SddManager.from_vtree(vtree)
    a, b, c, d = [sdd.literal(i) for i in range(1, 5)]
    # formula = (a & b) | c
    formula = (a & b) | (b & c) | (c & d)
    if verbose:
        with open("sdd.dot", "w") as out:
            print(formula.dot(), file=out)

    #                     -d   -c   -b   -a   a    b    c    d
    weights = array('d', [0.8, 0.7, 0.6, 0.5, 0.5, 0.4, 0.3, 0.2])

    # Normal WMC
    wmc = WmcManager(formula, log_mode=False)
    print(f"MC = {wmc.propagate()}")
    wmc.set_literal_weights_from_array(weights)
    wmc_result = wmc.propagate()
    print(f"WMC-Normal = {wmc_result}")

    # Stochastic WMC
    wmcs = WmcStochastic(formula, log_mode=False)
    wmcs.set_literal_weights_from_array(weights)
    wmcs_result = wmcs.propagate(bitlength=1000)
    print(f"WMC-Stochastic = {wmcs_result}")
Пример #2
0
def test_it4():
    vtree = Vtree(var_count=4, var_order=[4, 3, 2, 1], vtree_type="right")
    sdd = SddManager.from_vtree(vtree)
    a, b, c, d = sdd.vars
    f1 = a | b
    f2 = f1 | c
    f3 = f2 | d
    f1.ref()
    f2.ref()
    f3.ref()

    if directory:
        litnamemap = {1: 'a', 2: 'b', 3: 'c', 4: 'd'}
        for key, val in list(litnamemap.items()):
            litnamemap[-key] = f"¬{val}"
        with (directory / "sdd.gv").open("w") as out:
            print(sdd_to_dot(f3, litnamemap=litnamemap, show_id=True),
                  file=out)
        with (directory / "vtree.gv").open("w") as out:
            print(vtree_to_dot(sdd.vtree(),
                               litnamemap=litnamemap,
                               show_id=True),
                  file=out)

    it = SddIterator(sdd, smooth=True)
    mc = it.depth_first(f1, SddIterator.func_modelcounting)
    assert mc == 3, "MC {} != 3".format(mc)

    it = SddIterator(sdd, smooth=True, smooth_to_root=True)
    mc = it.depth_first(f1, SddIterator.func_modelcounting)
    assert mc == 12, "MC {} != 3 * 2**2 = 12".format(mc)
Пример #3
0
def test_it3():
    """ Test case where formula = literal or -literal """
    vtree = Vtree(var_count=4, var_order=[1, 2, 3, 4], vtree_type="right")
    sdd = SddManager.from_vtree(vtree)
    a, b, c, d = sdd.vars[:5]
    f = a

    wmc = f.wmc(log_mode=False)
    mc = wmc.propagate()
    # print(f"mc = {mc}")
    assert mc == 8.0

    it = SddIterator(sdd, smooth=True, smooth_to_root=True)
    mc = it.depth_first(f, SddIterator.func_modelcounting)
    assert mc == 8, "MC {} != 8".format(mc)

    it = SddIterator(sdd, smooth=False, smooth_to_root=True)
    mc = it.depth_first(f, SddIterator.func_modelcounting)
    assert mc == 1, "MC (non-smooth) {} != 1".format(mc)

    f = -a

    wmc = f.wmc(log_mode=False)
    mc = wmc.propagate()
    # print(f"mc = {mc}")
    assert mc == 8.0

    it = SddIterator(sdd, smooth=True, smooth_to_root=True)
    mc = it.depth_first(f, SddIterator.func_modelcounting)
    assert mc == 8, "MC {} != 8".format(mc)

    it = SddIterator(sdd, smooth=False, smooth_to_root=True)
    mc = it.depth_first(f, SddIterator.func_modelcounting)
    assert mc == 1, "MC (non-smooth) {} != 1".format(mc)
Пример #4
0
def main():

    # set up vtree and manager
    vtree = Vtree.from_file("input/opt-swap.vtree".encode())
    manager = SddManager.from_vtree(vtree)

    print("reading sdd from file ...")
    alpha = manager.read_sdd_file("input/opt-swap.sdd".encode())
    print(f"  sdd size = {alpha.size()}")

    # ref, perform the minimization, and then de-ref
    alpha.ref()
    print("minimizing sdd size ... ", end="")
    manager.minimize()  # see also manager.minimize_limited()
    print("done!")
    print(f"  sdd size = {alpha.size()}")
    alpha.deref()

    # augment the SDD
    print("augmenting sdd ...")
    beta = alpha * (manager.l(4) + manager.l(5))
    print(f"  sdd size = {beta.size()}")

    # ref, perform the minimization again on new SDD, and then de-ref
    beta.ref()
    print("minimizing sdd ... ", end="")
    manager.minimize()
    print("done!")
    print(f"  sdd size = {beta.size()}")
    beta.deref()
Пример #5
0
def main():
    # Start from a given CNF and VTREE file
    vtree = Vtree.from_file(bytes(here / "input" / "simple.vtree"))
    sdd = SddManager.from_vtree(vtree)
    print(f"Created an SDD with {sdd.var_count()} variables")
    root = sdd.read_cnf_file(bytes(here / "input" / "simple.cnf"))
    # For DNF functions use `read_dnf_file`
    # If the vtree is not given, you can also use 'from_cnf_file`

    # Model Counting
    wmc = root.wmc(log_mode=True)
    w = wmc.propagate()
    print(f"Model count: {int(math.exp(w))}")

    # Weighted Model Counting
    lits = [None] + [sdd.literal(i) for i in range(1, sdd.var_count() + 1)]
    # Positive literal weight
    wmc.set_literal_weight(lits[1], math.log(0.5))
    # Negative literal weight
    wmc.set_literal_weight(-lits[1], math.log(0.5))
    w = wmc.propagate()
    print(f"Weighted model count: {math.exp(w)}")

    # Visualize SDD and VTREE
    print("saving sdd and vtree ... ", end="")
    with open(here / "output" / "sdd.dot", "w") as out:
        print(sdd.dot(), file=out)
    with open(here / "output" / "vtree.dot", "w") as out:
        print(vtree.dot(), file=out)
    print("done")
Пример #6
0
def test_it1():
    vtree = Vtree(var_count=4, var_order=[1, 2, 3, 4], vtree_type="right")
    sdd = SddManager.from_vtree(vtree)
    a, b, c, d = sdd.vars[:5]
    f = ((a & b) | (c & d))
    if directory:
        litnamemap = {1: 'a', 2: 'b', 3: 'c', 4: 'd'}
        for key, val in list(litnamemap.items()):
            litnamemap[-key] = f"¬{val}"
        with (directory / "sdd1.gv").open("w") as out:
            print(f.dot(), file=out)
        with (directory / "sdd2.gv").open("w") as out:
            print(sdd_to_dot(f, litnamemap=litnamemap, show_id=True), file=out)
        with (directory / "vtree1.gv").open("w") as out:
            print(sdd.vtree().dot(), file=out)
        with (directory / "vtree2.gv").open("w") as out:
            print(vtree_to_dot(sdd.vtree(),
                               sdd,
                               litnamemap=litnamemap,
                               show_id=True),
                  file=out)
    wmc = f.wmc(log_mode=False)
    mc = wmc.propagate()
    # print(f"mc = {mc}")
    assert mc == 7.0

    it = SddIterator(sdd, smooth=True, smooth_to_root=True)
    mc = it.depth_first(f, SddIterator.func_modelcounting)
    assert mc == 7, "MC {} != 7".format(mc)

    it = SddIterator(sdd, smooth=False, smooth_to_root=True)
    mc = it.depth_first(f, SddIterator.func_modelcounting)
    assert mc == 3, "MC (non-smooth) {} != 3".format(mc)
Пример #7
0
def test_wmc2(verbose=False):
    vtree = Vtree(var_count=4, var_order=[2, 1, 4, 3], vtree_type="balanced")
    sdd = SddManager.from_vtree(vtree)
    a, b, c, d = [sdd.literal(i) for i in range(1, 5)]
    # formula = (a & b) | c
    formula = (a & b) | (b & c) | (c & d)

    #                     -d   -c   -b   -a   a    b    c    d
    weights = array('d', [0.8, 0.7, 0.6, 0.5, 0.5, 0.4, 0.3, 0.2])

    # Normal WMC
    wmc = WmcManager(formula, log_mode=False)
    wmc.set_literal_weights_from_array(weights)
    wmc_result = wmc.propagate()

    # Stochastic WMC
    wmcs = WmcStochastic(formula, log_mode=False)
    wmcs.set_literal_weights_from_array(weights)
    nb_pos, nb_neg, scaling = 0, 0, 1
    wmcs_results = []
    iterations = 1000
    for i in range(iterations):
        random.seed()
        nb_pos_i, nb_neg_i, scaling_i = wmcs.propagate_counts(bitlength=10)
        nb_pos += nb_pos_i
        nb_neg += nb_neg_i
        scaling = scaling_i
        wmcs_results.append((nb_pos / (nb_pos + nb_neg)) * scaling)
    print(wmcs_results[-1])
    if verbose:
        import matplotlib.pyplot as plt
        plt.plot([i * 10 for i in range(iterations)],
                 [wmc_result] * iterations)
        plt.plot([i * 10 for i in range(iterations)], wmcs_results)
        plt.savefig("stochastic_wmc.png")
Пример #8
0
def test_convert_weight2():
    domain = Domain.make(["a", "b"], ["x", "y"], [(0, 1), (0, 1)])
    a, b, x, y = domain.get_symbols(domain.variables)
    ite_a = smt.Ite(a, smt.Real(0.6), smt.Real(0.4))
    ite_b = smt.Ite(b, smt.Real(0.8), smt.Real(0.2))
    ite_x = smt.Ite(
        x >= smt.Real(0.5),
        smt.Real(0.5) * x + smt.Real(0.1) * y,
        smt.Real(0.1) * x + smt.Real(0.7) * y,
    )
    weight = ite_a * ite_b * ite_x

    algebra = PolynomialAlgebra()
    abstractions_c, var_to_lit_c = dict(), dict()
    converted_c = convert_function(smt.Real(0.6), SddManager(), algebra,
                                   abstractions_c, var_to_lit_c)
    for p, s in converted_c.sdd_dict.items():
        print("{}: {}".format(p,
                              recover_formula(s, abstractions_c,
                                              var_to_lit_c)))
    assert len(converted_c.sdd_dict) == 1

    abstractions_a, var_to_lit_a = dict(), dict()
    converted_a = convert_function(ite_a, SddManager(), algebra,
                                   abstractions_a, var_to_lit_a)
    for p, s in converted_a.sdd_dict.items():
        print("{}: {}".format(p,
                              recover_formula(s, abstractions_a,
                                              var_to_lit_a)))
    assert len(converted_a.sdd_dict) == 2

    converted_b = convert_function(ite_b, SddManager(), algebra)
    assert len(converted_b.sdd_dict) == 2

    print("X")
    abstractions_x, var_to_lit_x = dict(), dict()
    converted_x = convert_function(ite_x, SddManager(), algebra,
                                   abstractions_x, var_to_lit_x)
    for p, s in converted_x.sdd_dict.items():
        print("{}: {}".format(p,
                              recover_formula(s, abstractions_x,
                                              var_to_lit_x)))
    assert len(converted_x.sdd_dict) == 2

    converted = convert_function(weight, SddManager(), algebra)
    assert len(converted.sdd_dict) == 2 * 2 * 2
Пример #9
0
def test_dnf1():
    dnf_filename = str(here / "rsrc" / "test.cnf.nnf")
    fnf = Fnf.from_dnf_file(bytes(dnf_filename, encoding='utf8'))
    # weights = read_weights(dnf_filename)
    vtree = Vtree(var_count=fnf.var_count)
    manager = SddManager.from_vtree(vtree)
    node = manager.fnf_to_sdd(fnf)
    print(node)
Пример #10
0
def main():

    # set up vtree and manager
    vtree = Vtree.from_file(bytes(here / "input" / "big-swap.vtree"))
    manager = SddManager.from_vtree(vtree)

    print("reading sdd from file ...")
    alpha = manager.read_sdd_file("input/big-swap.sdd".encode())
    print(f"  sdd size = {alpha.size()}")

    # to perform a swap, we need the manager's vtree
    manager_vtree = manager.vtree()

    # ref alpha (no dead nodes when swapping)
    alpha.ref()

    # using size of sdd normalized for manager_vtree as baseline for limit
    manager.init_vtree_size_limit(manager_vtree)

    limit = 2.0
    manager.set_vtree_operation_size_limit(limit)

    print(f"modifying vtree (swap node 7) (limit growth by {limit:.1f}x) ... ",
          end="")
    succeeded = manager_vtree.swap(manager, 1)  # limited
    print("succeeded!" if succeeded == 1 else "did not succeed!")
    print(f"  sdd size = {alpha.size()}")

    print("modifying vtree (swap node 7) (no limit) ... ", end="")
    succeeded = manager_vtree.swap(manager, 0)  # not limited
    print("succeeded!" if succeeded == 1 else "did not succeed!")
    print(f"  sdd size = {alpha.size()}")

    print("updating baseline of size limit ...")
    manager.update_vtree_size_limit()

    left_vtree = manager_vtree.left()
    limit = 1.2
    manager.set_vtree_operation_size_limit(limit)
    print(f"modifying vtree (swap node 5) (limit growth by {limit}x) ... ",
          end="")
    succeeded = left_vtree.swap(manager, 1)  # limited
    print("succeeded!" if succeeded == 1 else "did not succeed!")
    print(f"  sdd size = {alpha.size()}")

    limit = 1.3
    manager.set_vtree_operation_size_limit(limit)
    print(f"modifying vtree (swap node 5) (limit growth by {limit}x) ... ",
          end="")
    succeeded = left_vtree.swap(manager, 1)  # limited
    print("succeeded!" if succeeded == 1 else "did not succeed!")
    print(f"  sdd size = {alpha.size()}")

    # deref alpha, since ref's are no longer needed
    alpha.deref()
Пример #11
0
 def sddConstructorFromFile(self,sddFName):
     self.sddfName = sddFName
     if os.path.isfile(self.sddfName+".sdd") and os.path.isfile(self.sddfName+".vtree") and os.path.isfile(self.sddfName+".map") :
         with open(self.sddfName + ".map", "r") as f:
             self.nameMappingDic = json.load(f)
         vtree = Vtree.from_file((self.sddfName+".vtree").encode())
         self.sdd = SddManager.from_vtree(vtree)
         self.formula = self.sdd.read_sdd_file((self.sddfName+".sdd").encode())
     else:
         print("Please provide correct files")
         sys.exit()
Пример #12
0
 def obdd_to_sdd(self,root,offset=0):
     from pysdd.sdd import Vtree, SddManager
     var_count = self.var_count + offset
     vtree = Vtree(var_count=var_count,vtree_type="right")
     mgr = SddManager.from_vtree(vtree)
     for node in root.__iter__(clear_data=True):
         if node.is_terminal():
             alpha = mgr.true() if node.is_true() else mgr.false()
         else:
             dvar = node.dvar + offset
             plit,nlit = mgr.literal(dvar),mgr.literal(-dvar)
             alpha = (plit & node.hi.data) | (nlit & node.lo.data)
         node.data = alpha
     return (mgr,alpha)
Пример #13
0
def test_min2():
    sdd = SddManager(var_count=3)
    a, b, c = sdd.vars
    fa = b | c
    fa.ref()
    fb = b
    fb.ref()
    fc = c
    fc.ref()
    if directory:
        names = {1: 'a', -1: '-a', 2: 'b', -2: '-b', 3: 'c', -3: '-c'}
        with (directory / "vtree2_before_a.gv").open("w") as out:
            print(sdd.vtree().dot(), file=out)
        with (directory / "vtree2_before_b.gv").open("w") as out:
            print(vtree_to_dot(sdd.vtree(),
                               sdd,
                               litnamemap=names,
                               show_id=True),
                  file=out)
        # with (directory / "sdd2_before_a.gv").open("w") as out:
        #     print(sdd.dot(), file=out)
        with (directory / "sdd2_before_b.gv").open("w") as out:
            print(sdd_to_dot(sdd), file=out)
Пример #14
0
    def sddConstructorFromLPMLN(self,content,saveSDD = False, savedSDDName=None):
        self.content = content
        self.bytesContent = str.encode(self.content)
        self.saveSDD = saveSDD
        self.saveSDDName = savedSDDName
        fn_gringo = os.path.join(os.path.dirname(__file__), '../binSupport/gringo')
        p = subprocess.Popen([fn_gringo], shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
        p.stdin.write(self.bytesContent)
        gringo_out = p.communicate()[0]
        p.stdin.close()
        p.stdout.close()
        if self.args.verbosity > 4:
            print("Grounding Done! ")
        fn_cmodels = os.path.join(os.path.dirname(__file__), '../binSupport/cmodels')
        p = subprocess.Popen([fn_cmodels+' -cdimacs'], shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
        p.stdin.write(gringo_out)
        cmodels_out_Name = p.communicate()[0]
        p.stdin.close()
        p.stdout.close()
        #print("Completion_1 Done! ")



        p = subprocess.Popen([fn_cmodels+' -dimacs'], shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
        p.stdin.write(gringo_out)
        cmodels_out_no_name = p.communicate()[0]
        p.stdin.close()
        p.stdout.close()

        if self.args.verbosity > 4:
            print("Completion Done! ")

        gp = groundComp.groundComp(cmodels_out_Name.decode(), cmodels_out_no_name.decode())
        self.nameMappingDic = gp.atom2idx_gen()
        if self.args.verbosity > 4:
            print("Name Mapping Done!")

        start = time.time()
        self.sdd, self.formula = SddManager.from_cnf_string(cmodels_out_no_name.decode())

        if self.args.verbosity > 4:
            print("SDD Done! Time For Construct SDD: ", str(time.time() - start))

        if self.saveSDD:
            return self.save()
Пример #15
0
def main():

  # set up vtree and manager
  vtree = Vtree.from_file(bytes(here / "input" / "rotate-left.vtree"))
  manager = SddManager.from_vtree(vtree)

  # construct the term X_1 ^ X_2 ^ X_3 ^ X_4
  x = [None] + [manager.literal(i) for i in range(1, 5)]
  alpha = x[1]*x[2]*x[3]*x[4]

  # to perform a rotate, we need the manager's vtree
  manager_vtree = manager.vtree()
  manager_vtree_right = manager_vtree.right()

  print("saving vtree & sdd ...")
  if not Path("output").is_dir():
      raise Exception(f"Directory 'output' does not exist")
  manager_vtree.save_as_dot("output/before-rotate-vtree.dot".encode())
  alpha.save_as_dot("output/before-rotate-sdd.dot".encode())

  # ref alpha (so it is not gc'd)
  alpha.ref()

  # garbage collect (no dead nodes when performing vtree operations)
  print(f"dead sdd nodes = {manager.dead_count()}")
  print("garbage collection ...")
  manager.garbage_collect()
  print(f"dead sdd nodes = {manager.dead_count()}")

  print("left rotating ... ", end="")
  succeeded = manager_vtree_right.rotate_left(manager, 0)
  print("succeeded!" if succeeded == 1 else "did not succeed!")

  # deref alpha, since ref's are no longer needed
  alpha.deref()

  # the root changed after rotation, so get the manager's vtree again
  # this time using root_location
  manager_vtree = manager.vtree()

  print("saving vtree & sdd ...")
  if not Path("output").is_dir():
      raise Exception(f"Directory 'output' does not exist")
  manager_vtree.save_as_dot("output/after-rotate-vtree.dot".encode())
  alpha.save_as_dot("output/after-rotate-sdd.dot".encode())
Пример #16
0
def main():

    # set up vtree and manager
    var_count = 4
    vtree_type = "right".encode()
    vtree = Vtree(var_count=var_count, vtree_type=vtree_type)
    manager = SddManager(vtree=vtree)

    x = [None] + [manager.literal(i) for i in range(1, 5)]

    # construct the term X_1 ^ X_2 ^ X_3 ^ X_4
    alpha = x[1] & x[2] & x[3] & x[4]

    # construct the term ~X_1 ^ X_2 ^ X_3 ^ X_4
    beta = ~x[1] & x[2] & x[3] & x[4]

    # construct the term ~X_1 ^ ~X_2 ^ X_3 ^ X_4
    gamma = ~x[1] & ~x[2] & x[3] & x[4]

    print("== before referencing:")
    print(f"  live sdd size = {manager.live_size()}")
    print(f"  dead sdd size = {manager.dead_size()}")

    # ref SDDs so that they are not garbage collected
    alpha.ref()
    beta.ref()
    gamma.ref()
    print("== after referencing:")
    print(f"  live sdd size = {manager.live_size()}")
    print(f"  dead sdd size = {manager.dead_size()}")

    # garbage collect
    manager.garbage_collect()
    print("== after garbage collection:")
    print(f"  live sdd size = {manager.live_size()}")
    print(f"  dead sdd size = {manager.dead_size()}")

    alpha.deref()
    beta.deref()
    gamma.deref()

    print("saving vtree & shared sdd ...")
    if not Path("output").is_dir():
        raise Exception(f"Directory 'output' does not exist")
    vtree.save_as_dot("output/shared-vtree.dot".encode())
    manager.shared_save_as_dot("output/shared.dot".encode())
Пример #17
0
def test_min1():
    vtree = Vtree(var_count=4, var_order=[1, 4, 2, 3], vtree_type="right")
    sdd = SddManager.from_vtree(vtree)
    sdd.auto_gc_and_minimize_off()
    a, b, c, d = sdd.vars
    f = ((a & b) | (c & d))
    f.ref()
    if directory:
        names = {
            1: 'a',
            -1: '-a',
            2: 'b',
            -2: '-b',
            3: 'c',
            -3: '-c',
            4: 'd',
            -4: '-d'
        }
        with (directory / "vtree1_before_a.gv").open("w") as out:
            print(sdd.vtree().dot(), file=out)
        with (directory / "vtree1_before_b.gv").open("w") as out:
            print(vtree_to_dot(sdd.vtree(),
                               sdd,
                               litnamemap=names,
                               show_id=True),
                  file=out)
        with (directory / "sdd1_before_a.gv").open("w") as out:
            print(sdd.dot(), file=out)
        with (directory / "sdd1_before_b.gv").open("w") as out:
            print(sdd_to_dot(sdd), file=out)
    sdd.minimize()
    if directory:
        with (directory / "vtree2_after.gv").open("w") as out:
            print(sdd.vtree().dot(), file=out)
        with (directory / "sdd1_after.gv").open("w") as out:
            print(sdd.dot(), file=out)
    f.deref()

    wmc = f.wmc(log_mode=False)
    mc = wmc.propagate()
    # print(f"mc = {mc}")
    assert mc == 7.0
Пример #18
0
def compile_to_sdd(formula: FNode, literals: LiteralInfo,
                   vtree: Optional[Vtree]) -> SddNode:
    """
    Compile a formula into an SDD.
    :param formula: The formula to represent as sdd. This formula must be a purely (abstracted) boolean formula
    (cf. extract_and_replace_literals(...) in literals.py)
    :param literals: The information of the literals in the formula
    :param vtree: The vtree to use. If None, a default vtree heuristic is used.
    :return: An SDD representing the given formula
    """
    if SddManager is None:
        raise InstallError(
            "The pysdd package is required for this function but is not currently installed."
        )
    if vtree is None:
        vtree = bami(literals)
    varnums = literals.numbered
    pysdd_vtree = vtree.to_pysdd(varnums)
    manager = SddManager.from_vtree(pysdd_vtree)
    converter = SddConversionWalker(manager, varnums)
    return converter.walk_smt(formula)
Пример #19
0
def main():
    # set up vtree and manager
    var_count = 4
    var_order = [2,1,4,3]
    vtree_type = "balanced"

    vtree = Vtree(var_count, var_order, vtree_type)
    manager = SddManager.from_vtree(vtree)

    # construct a formula (A^B)v(B^C)v(C^D)
    print("constructing SDD ... ")
    a, b, c, d = [manager.literal(i) for i in range(1, 5)]
    alpha = (a & b) | (b & c) | (c & d)
    print("done")

    print("saving sdd and vtree ... ")
    with open("output/sdd.dot", "w") as out:
        print(alpha.dot(), file=out)
    with open("output/vtree.dot", "w") as out:
        print(vtree.dot(), file=out)
    print("done")
    def do_model_count(self, filename):
        # create vtree
        vtree_path = CounterFactory.create("minic2d").create_vtree(filename)
        vtree = Vtree.from_file(bytes(vtree_path.encode()))

        sdd = SddManager.from_vtree(vtree)

        # read CNF
        root = sdd.read_cnf_file(bytes(filename.encode()))

        # do model counting
        wmc = root.wmc(log_mode=False)

        # add weights
        weights = get_weights_from_cnf_file(filename)
        lits = [sdd.literal(i) for i in range(1, sdd.var_count() + 1)]
        assert len(weights) == 2 * len(lits), \
            "Unexpected len {} for weights, got {}. Weights:\n{}".format(len(weights), 2 * len(lits), weights)

        for i in range(len(lits)):
            wmc.set_literal_weight(lits[i], weights[2 * i])
            wmc.set_literal_weight(-lits[i], weights[2 * i + 1])

        # write visualisation of SDD and Vtree to files
        sdd_file = os.path.abspath(
            os.path.join(os.path.dirname(filename), "sdd."))
        vtree_file = os.path.abspath(
            os.path.join(os.path.dirname(filename), "vtree-sdd."))

        with open(sdd_file + "dot", "w") as out:
            out.write(sdd.dot())
        with open(vtree_file + "dot", "w") as out:
            out.write(vtree.dot())

        # (graph,) = pydot.graph_from_dot_file(sdd_file + "dot")
        # graph.write_png(sdd_file + "png")
        # (graph,) = pydot.graph_from_dot_file(vtree_file + "dot")
        # graph.write_png(vtree_file + "png")

        return wmc.propagate()
Пример #21
0
    def set_cnf(self, cnf, n_inputs, n_targets):
        self.n_inputs, self.n_targets = n_inputs, n_targets

        BASENAME = 'distillation-loss'

        # TODO avoid dumping stuff on disk
        with open(BASENAME + '.sympy', 'wt') as fp:
            fp.write(f'shape [{2 * n_inputs + n_targets}, {2}]\n')
            for clause in cnf.args:
                fp.write(f'{str(clause)}\n')

        ConstraintsToCnf.expression_to_cnf(BASENAME + '.sympy',
                                           BASENAME + '.dimacs', 1)

        fnf = Fnf.from_cnf_file(bytes(Path(BASENAME + '.dimacs')))
        vtree = Vtree(var_count=fnf.var_count, vtree_type='balanced')
        manager = SddManager.from_vtree(vtree)
        sdd = manager.fnf_to_sdd(fnf)
        sdd.save(bytes(Path(BASENAME + '.sdd')))
        manager.vtree().save(bytes(Path(BASENAME + '.vtree')))

        self.sl = SemanticLoss(BASENAME + '.sdd', BASENAME + '.vtree')
Пример #22
0
    def __init__(self, abducibles: List, mutuallyExclusive):
        self.abduciblesToSddLiterals = dict()
        self.SddLiteralsToOutputNeurons = dict()
        self.outputneuronsToAbducibles = dict()
        self.mutuallyExclusiveDict = dict()

        vtree = Vtree(var_count=len(abducibles), var_order=list(range(1, len(abducibles) + 1)), vtree_type="balanced")
        self.sddmanager = SddManager.from_vtree(vtree)

        index = 0
        for abducible in abducibles:
            literal = self.sddmanager.literal(index + 1)
            self.abduciblesToSddLiterals[abducible] = literal
            self.SddLiteralsToOutputNeurons[literal] = index
            self.outputneuronsToAbducibles[index] = abducible
            index += 1

        for i in range(len(mutuallyExclusive)):
            me = mutuallyExclusive[i]
            for abducible in me:
                fresh = me.copy()
                fresh.remove(abducible)
                self.mutuallyExclusiveDict[abducible] = fresh
Пример #23
0
    for node in nnf.root.__iter__(clear_data=True):
        del node._depth
    #mgr.auto_gc_and_minimize_off()
    return alpha


############################################################
# experimental
############################################################

if __name__ == '__main__':
    from timer import Timer

    basename = 'c432.isc'
    nnf_filename = 'examples/%s.cnf.nnf' % basename
    vtree_filename = 'examples/%s.cnf.vtree' % basename

    with Timer("reading"):
        nnf_manager, nnf = Nnf.read(nnf_filename)

    vtree = Vtree(filename=vtree_filename)
    mgr = SddManager(vtree=vtree)
    with Timer("compiling"):
        node = compile_nnf_automatic(nnf, mgr)
    print("model count:", node.global_model_count())
    print(" node size: %d" % node.size())
    print("node count: %d" % node.count())

    print("live size: %d" % mgr.live_size())
    print("dead size: %d" % mgr.dead_size())
add_rule1("smokes(b)", "stress(b)", "friends(b,a)", "aux(b,a)", "friends(b,c)", "aux(b,c)")
add_rule1("smokes(c)", "stress(c)", "friends(c,a)", "aux(c,a)", "friends(c,b)", "aux(c,b)")
add_rule2("aux(a,b)", "stress(b)", "friends(b,c)", "stress(c)")
add_rule2("aux(a,c)", "stress(c)", "friends(c,b)", "stress(b)")
add_rule2("aux(b,a)", "stress(a)", "friends(a,c)", "stress(c)")
add_rule2("aux(b,c)", "stress(c)", "friends(c,a)", "stress(a)")
add_rule2("aux(c,a)", "stress(a)", "friends(a,b)", "stress(b)")
add_rule2("aux(c,b)", "stress(b)", "friends(b,a)", "stress(a)")
# clauses.append([7]) # This adds stress(c) as evidence
cnf = "p cnf " + str(len(vars)) + " " + str(len(clauses)) + "\n" \
    + "c weights " + " ".join([str(weight) for weight in weights]) + "\n" \
    + "\n".join(list(map(tostr, clauses)))
# print(cnf)

# Test : generate SDD and do weighted model counting
(manager, sdd) = SddManager.from_cnf_string(cnf)
# manager.auto_gc_and_minimize_off()
wmc = sdd.wmc(log_mode=False)
wmc.set_literal_weights_from_array(weights_array)
w = wmc.propagate()
# print("Weighted model count: " + str(w))

# Get interpretations
interpretations = list(examples(DATA_FILE, cap=NB_EXAMPLES))

# Generate SDD for each example
counters = []
header_cnf = "p cnf " + str(len(vars)) + " " + str(len(clauses) + 6) + "\n" \
    + "\n".join(list(map(tostr, clauses)))
for interpretation in interpretations:
    (_, sdd) = SddManager.from_cnf_string(header_cnf + "\n" + "\n".join([str(p) + " 0" for p in interpretation]))
Пример #25
0
def computeTensorWMC(node: SddNode, manager: SddManager, literal2OutputNeuron: dict,
                     weights: torch.tensor) -> torch.tensor:
    stack = list()
    nodesToTensors = dict()

    stack.append(node)

    while len(stack) > 0:

        top = stack[len(stack) - 1]
        if top not in nodesToTensors:

            if top.is_decision():

                noTensor = False
                for element in top.elements():
                    if element[0] not in nodesToTensors:
                        stack.append(element[0])
                        noTensor = True
                    if element[1] not in nodesToTensors:
                        stack.append(element[1])
                        noTensor = True

                if noTensor == False:
                    if useGPU:
                        result = torch.tensor([0.0], requires_grad=True).cuda()
                    else:
                        result = torch.tensor([0.0], requires_grad=True)
                    for element in top.elements():
                        result = result + nodesToTensors[element[0]] * nodesToTensors[element[1]]

                    nodesToTensors[top] = result
                    stack.pop()

            elif top.is_literal():
                literal = top.literal
                if literal < 0:
                    positive = manager.literal(-literal)
                    neuronIndex = literal2OutputNeuron[positive]
                    nodesToTensors[top] = 1 - weights[neuronIndex]
                else:
                    neuronIndex = literal2OutputNeuron[top]
                    nodesToTensors[top] = weights[neuronIndex]
                stack.pop()

            elif top.is_false():
                if useGPU:
                    nodesToTensors[top] = torch.tensor([0.0], requires_grad=True).cuda()
                else:
                    nodesToTensors[top] = torch.tensor([0.0], requires_grad=True)
                stack.pop()

            elif top.is_true():
                if useGPU:
                    nodesToTensors[top] = torch.tensor([1.0], requires_grad=True).cuda()
                else:
                    nodesToTensors[top] = torch.tensor([1.0], requires_grad=True)
                stack.pop()
        else:
            stack.pop()

    return nodesToTensors[node]
def main():
    arg_parser = argparse.ArgumentParser(description="problog pipeline")
    arg_parser.add_argument("--bif-file",
                            "-b",
                            help="The input bayesian network")
    arg_parser.add_argument("--pl-file", "-p", help="The input problog file")

    arg_parser.add_argument("cnf_file", help="The output cnf file")

    arg_parser.add_argument("--enc",
                            "-e",
                            default=1,
                            help="The enc type 1 or 2",
                            type=int)
    arg_parser.add_argument(
        "--cnf-type",
        "-c",
        default="c2d",
        help="The type of cnf file to output (c2d for minic2d or cachet)")

    arg_parser.add_argument("--verbose",
                            "-v",
                            default=False,
                            help="Verbose output",
                            type=bool,
                            nargs='?',
                            const=True)

    args = arg_parser.parse_args()

    if (args.bif_file is None and args.pl_file is None) or \
        (args.bif_file is not None and args.pl_file is not None):
        print("one input file required")
        return -1

    c2d = True
    if args.cnf_type == "c2d":
        c2d = True
    elif args.cnf_type == "cachet":
        c2d = False
    else:
        print("unknwon cnf type")
        return -1

    is_bif = args.bif_file is not None
    file_name = args.bif_file if is_bif else args.pl_file

    enc1 = args.enc == 1
    verbose = args.verbose

    contents = None
    with open(file_name, 'r') as f:
        contents = f.read()

    variables = None
    cnf = None
    weights = None
    evidence = None
    queries = None

    start_time = time.time()

    if is_bif:
        variables, cnf, weights, queries = parse_bif(contents, enc1, verbose)
    else:
        variables, cnf, weights, evidence, queries = parse_srl(
            contents, verbose)

    cnf_time = time.time()

    #    if verbose:
    #        print("cnf latex:")
    #        print(len(cnf.args))
    #        clauses = cnf.args
    #        for clause in clauses:
    #            print("$", latex_print(clause), "$")
    #            print()

    ints = cnf_to_ints(cnf, variables)

    if evidence is not None:
        for ev_name, ev_val in evidence:
            idx = variables.index(ev_name) + 1
            if not ev_val:
                idx = -idx
            ints.append([idx])

    save_cnf(args.cnf_file, ints, variables, weights, c2d)

    vtree_time = None

    if c2d:
        vtree_name = args.cnf_file + ".vtree"
        print("miniC2D:")
        minic2d = subprocess.run(
            [MINIC2D_PATH, '-c', args.cnf_file, '-o', vtree_name])

        if minic2d.returncode != 0:
            print("error creating vtree")
            return -1

        vtree_time = time.time()

        print("calculating sdd")
        vtree = Vtree.from_file(vtree_name.encode())
        sdd = SddManager.from_vtree(vtree)
        root = sdd.read_cnf_file(args.cnf_file.encode())

        print("sdd node count:", sdd.count())
        print("sdd size:", sdd.size())
        if verbose:
            sdd.print_stdout()

        print()

        wmc = root.wmc(log_mode=False)
        w = wmc.propagate()
        print("model count:", w)

        nlits = sdd.var_count()
        assert nlits == len(variables)

        for idx in range(nlits):
            i = idx + 1
            w_pos = weights[variables[idx]][0]
            w_neg = weights[variables[idx]][1]
            wmc.set_literal_weight(sdd.literal(i), w_pos)
            wmc.set_literal_weight(sdd.literal(-i), w_neg)
        w = wmc.propagate()
        print("weighted count:", w)
        print()
        print("queries:")
        if queries is not None:
            for query in queries:
                idx = variables.index(query) + 1
                pr = wmc.literal_pr(sdd.literal(idx))
                print("P(", query, ") =\t", pr)

    end_time = time.time()

    print()
    print("cnf variables:", len(variables), "clauses: ", len(ints))
    print()
    print("total time:\t", end_time - start_time)
    print("cnf time:\t", cnf_time - start_time)
    if vtree_time is not None:
        print("vtree time:\t", vtree_time - cnf_time)
        print("count time:\t", end_time - vtree_time)

    return 0
Пример #27
0
from pysdd.sdd import SddManager, Vtree

var_count = 3
var_order = [1, 2, 3]
vtree_type = 'balanced'

vtree = Vtree(var_count, var_order, vtree_type)
manager = SddManager.from_vtree(vtree)

a, b, c = [manager.literal(i) for i in range(1, 4)]
alpha = c & (a | -b)

with open('sdd.dot', 'w') as out:
    print(alpha.dot(), file=out)
with open('vtree.dot', 'w') as out:
    print(vtree.dot(), file=out)