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}")
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)
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)
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()
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")
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)
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")
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
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)
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()
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()
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)
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)
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()
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())
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())
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
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)
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()
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')
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
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]))
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
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)