def sdd_to_dot(self, node, litnamemap=None, show_id=False, merge_leafs=False): """ SDD for the given node, formatted for use with Graphviz dot. This method provides more control over the used symbols than to_internal_dot (see litnamemap). Primes are given by a dotted line, subs by a full line. :param node: The node to get the dot from. :param litnamemap: A dictionary providing the symbols to use. The following options are available: 1. literals, e.g. {1:'A', -1:'-A', ...}, 2. True/False, e.g. {true':'1', 'false':'0'} 3. And/Or e.g. {'mult':'x', 'add':'+'} :type litnamemap: dict[(int | str), str] | None :param show_id: Whether to display the ids of each sdd node. :param merge_leafs: Whether to merge the same leaf nodes. True results in less nodes but makes it harder to render without having crossing lines. :return: The dot format of the given node. When node is None, the mgr is used (this behavior can be overriden). :rtype: str """ used_node = node if node is not None else self.get_manager() return sdd_to_dot(node=used_node, litnamemap=litnamemap, show_id=show_id, merge_leafs=merge_leafs)
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_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_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 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)