Example #1
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("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()
Example #2
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")
Example #3
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()
Example #4
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 ...")
  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 ...")
  manager_vtree.save_as_dot("output/after-rotate-vtree.dot".encode())
  alpha.save_as_dot("output/after-rotate-sdd.dot".encode())
Example #5
0
def main(argv=None):
    options, args = getopt(argv)
    fnf = None
    weights = None

    if options.cnf_filename is not None:
        print("reading cnf...")
        fnf = Fnf.from_cnf_file(bytes(options.cnf_filename))
        weights = read_weights(options.cnf_filename)
    elif options.dnf_filename is not None:
        print("reading dnf...")
        fnf = Fnf.from_dnf_file(bytes(options.dnf_filename))
        weights = read_weights(options.cnf_filename)

    if options.vtree_filename is not None:
        print("reading initial vtree...")
        vtree = Vtree.from_file(bytes(options.vtree_filename))
    else:
        if fnf is None:
            raise argparse.ArgumentTypeError("CNF or DNF file required")
        print(f"creating initial vtree {options.initial_vtree_type.decode()}")
        vtree = Vtree(var_count=fnf.var_count,
                      vtree_type=options.initial_vtree_type)

    print("creating manager...")
    manager = SddManager.from_vtree(vtree)
    manager.set_options(options)

    if options.sdd_filename is None:
        print("compiling...")
        c1 = time.time()
        node = manager.fnf_to_sdd(fnf)
        c2 = time.time()
        secs = c2 - c1
        print("")
        print(f"compilation time         : {secs:.3f} sec")
    else:
        print("reading sdd from file...")
        c1 = time.time()
        node = manager.read_sdd_file(options.sdd_filename)
        c2 = time.time()
        secs = c2 - c1
        print(f"read time                : {secs:.3f} sec")
        weights = read_weights(options.sdd_filename)

    wmc = create_wmc(node, weights, args)

    print_node(node, wmc)
    if options.verbose:
        manager.print_stdout()

    if options.minimize_cardinality:
        print("\nminimizing cardinality...", end="")
        c1 = time.time()
        node = manager.global_minimize_cardinality(node)
        c2 = time.time()
        min_card = manager.minimum_cardinality(node)
        print("")
        wmc = create_wmc(node, weights, args)
        print_node(node, wmc)
        print(f" min cardinality        : {min_card}   {c2-c1:.3f} sec")

    manager_vtree = manager.vtree()

    if options.post_search:
        node.ref()
        print("dynamic vtree (post compilation)")
        print(f" sdd initial size       : {node.size()}")
        c1 = time.time()
        manager.minimize_limited()
        c2 = time.time()
        print(f" dynamic vtree time      : {c2-c1:.3f} sec")
        wmc = create_wmc(node, weights, args)
        print_node(node, wmc)
        node.deref()
        if options.verbose:
            manager.print_stdout()

    if options.output_sdd_filename is not None:
        print("saving compiled sdd ...", end="")
        node.save(options.output_sdd_filename)
        print("done")

    if options.output_sdd_dot_filename is not None:
        print("saving compiled sdd (dot) ...", end="")
        node.save_as_dot(options.output_sdd_dot_filename)
        print("done")

    if options.output_vtree_filename is not None:
        print("saving vtree ...", end="")
        manager_vtree.save(options.output_vtree_filename)
        print("done")

    if options.output_vtree_dot_filename is not None:
        print("saving vtree (dot) ...", end="")
        manager_vtree.save_as_dot(options.output_vtree_dot_filename)
        print("done")

    print("done")