Skip to content

Commit 273ffbd

Browse files
author
beckydvn
committed
update children recursively, simplify algorithm
1 parent 1009a3b commit 273ffbd

File tree

1 file changed

+72
-16
lines changed

1 file changed

+72
-16
lines changed

nnf/__init__.py

Lines changed: 72 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1733,26 +1733,27 @@ def decision(
17331733
return (var & if_true) | (~var & if_false)
17341734

17351735
def flatten(nnf: NNF):
1736-
set_and_children = set()
1737-
set_other = set()
1738-
operator_type = type(nnf)
1736+
"""Flattens a formula by removing unnecessary extra nestings.
17391737
1738+
param var: The formula to be flattened.
1739+
"""
1740+
new_children = set()
1741+
outer_operator = type(nnf)
1742+
# iterate through all children
17401743
for c in nnf.children:
17411744
if type(c) == Var:
1742-
set_and_children.add(c)
1745+
new_children.add(c)
1746+
# atoms don't need to be nested
17431747
elif len(c.children) == 1:
1744-
set_and_children.update(c.children)
1745-
elif type(c) == operator_type:
1746-
set_and_children.update(c.children)
1748+
new_children.update(c.children)
1749+
# if the operator type is the same as the outer operator, flatten the formula
1750+
# and remove the nested operator by only taking the children (i.e. And(And()) or Or(Or()))
1751+
elif type(c) == outer_operator:
1752+
new_children.update(flatten(c).children)
17471753
else:
1748-
set_other.add(c)
1749-
nnf = operator_type(set_and_children | set_other)
1750-
1751-
for c in nnf.children:
1752-
if type(c) == operator_type:
1753-
return flatten(nnf)
1754-
return nnf
1755-
1754+
# otherwise, continue to flatten the children but keep the operator (i.e. And(Or) or Or(And))
1755+
new_children.add(flatten(c))
1756+
return outer_operator(new_children)
17561757

17571758
#: A node that's always true. Technically an And node without children.
17581759
true = And() # type: And[Bottom]
@@ -1881,4 +1882,59 @@ def __call__(self, **settings: str) -> _ConfigContext:
18811882
config = _Config()
18821883

18831884

1884-
from nnf import amc, dsharp, kissat, operators, pysat, tseitin # noqa: E402
1885+
from nnf import amc, dsharp, kissat, operators, pysat, tseitin # noqa: E402
1886+
1887+
if __name__ == "__main__":
1888+
# test nnf nesting - and
1889+
nnf_formula = Var(1)
1890+
for i in range(10):
1891+
nnf_formula = nnf_formula & Var(i)
1892+
nnf_formula_2 = Var(10)
1893+
for i in range(11, 20):
1894+
nnf_formula_2 = nnf_formula_2 & Var(i)
1895+
nnf_formula_3 = nnf_formula & nnf_formula_2
1896+
print()
1897+
print(nnf_formula)
1898+
print(nnf_formula_2)
1899+
print(nnf_formula_3)
1900+
print(flatten(nnf_formula_3))
1901+
1902+
# test nnf nesting - or
1903+
nnf_formula = Var(1)
1904+
for i in range(10):
1905+
nnf_formula = nnf_formula | Var(i)
1906+
nnf_formula_2 = Var(10)
1907+
for i in range(11, 20):
1908+
nnf_formula_2 = nnf_formula_2 | Var(i)
1909+
nnf_formula_3 = nnf_formula | nnf_formula_2
1910+
print()
1911+
print(nnf_formula)
1912+
print(nnf_formula_2)
1913+
print(nnf_formula_3)
1914+
print(flatten(nnf_formula_3))
1915+
1916+
#test nnf nesting - both and's and or's
1917+
print()
1918+
nnf_formula = Var(1)
1919+
for i in range(10):
1920+
nnf_formula = nnf_formula & (Var(i) | Var(i + 1))
1921+
print(nnf_formula)
1922+
print(flatten(nnf_formula))
1923+
1924+
print()
1925+
nnf_formula = Var(1)
1926+
for i in range(10):
1927+
nnf_formula = nnf_formula | (Var(i) & Var(i + 1))
1928+
print(nnf_formula)
1929+
print(flatten(nnf_formula))
1930+
1931+
x, a, y, z, b, c = Var("x"), Var("a"), Var("y"), Var("z"), Var("b"), Var("c")
1932+
nnf_formula = x | ((a & y) & z & (b | c))
1933+
print()
1934+
print(nnf_formula)
1935+
print(flatten(nnf_formula))
1936+
1937+
nnf_formula = x | (((a & ((y | ((x | z) & b)) & c))))
1938+
print()
1939+
print(nnf_formula)
1940+
print(flatten(nnf_formula))

0 commit comments

Comments
 (0)