Skip to content

Commit 202efb7

Browse files
author
beckydvn
committed
make requested changes
1 parent ddcfe8a commit 202efb7

File tree

2 files changed

+110
-12
lines changed

2 files changed

+110
-12
lines changed

nnf/__init__.py

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
__version__ = '0.2.1'
1616

17+
from _typeshed import IdentityFunction
1718
import abc
1819
import functools
1920
import itertools
@@ -62,7 +63,6 @@
6263
"tseitin",
6364
"operators",
6465
"pysat",
65-
"flatten_one_level"
6666
)
6767

6868

@@ -86,28 +86,36 @@ def all_models(names: 't.Iterable[Name]') -> t.Iterator[Model]:
8686

8787
auto_simplify = False
8888

89+
8990
class NNF(metaclass=abc.ABCMeta):
9091
"""Base class for all NNF sentences."""
9192
__slots__ = ("__weakref__",)
92-
93-
93+
9494
def __and__(self: T_NNF, other: U_NNF) -> 'And[t.Union[T_NNF, U_NNF]]':
95-
"""And({self, other})"""
95+
"""And({self, other})"""
9696
# prevent unnecessary nesting
97-
if auto_simplify:
98-
if type(self) == And:
99-
return And({*self.children, *other.children}) if type(other) == And else And({*self.children, other})
97+
if config.auto_simplify:
98+
if not isinstance(self, And) and isinstance(other, And):
99+
return And({self, *other.children})
100+
elif isinstance(self, And) and not isinstance(other, And):
101+
return And({*self.children, other})
102+
elif isinstance(self, And) and isinstance(other, And):
103+
return And({*self.children, *other.children})
100104
return And({self, other})
101105

102106
def __or__(self: T_NNF, other: U_NNF) -> 'Or[t.Union[T_NNF, U_NNF]]':
103107
"""Or({self, other})"""
104108
# prevent unnecessary nesting
105-
if auto_simplify:
106-
if type(self) == Or:
107-
return Or({*self.children, *other.children}) if type(other) == Or else Or({*self.children, other})
109+
if config.auto_simplify:
110+
if not isinstance(self, Or) and isinstance(other, Or):
111+
return Or({self, *other.children})
112+
elif isinstance(self, Or) and not isinstance(other, Or):
113+
return Or({*self.children, other})
114+
elif isinstance(self, Or) and isinstance(other, Or):
115+
return Or({*self.children, *other.children})
108116
return Or({self, other})
109117

110-
def __rshift__(self: T_NNF, other: U_NNF)-> 'Or[t.Union[T_NNF.negate(), U_NNF]]':
118+
def __rshift__(self, other: 'NNF')-> 'Or[NNF]':
111119
"""Or({self.negate(), other})"""
112120
return Or({self.negate(), other})
113121

@@ -1802,6 +1810,7 @@ class _Config:
18021810
sat_backend = _Setting("auto", {"auto", "native", "kissat", "pysat"})
18031811
models_backend = _Setting("auto", {"auto", "native", "pysat"})
18041812
pysat_solver = _Setting("minisat22")
1813+
auto_simplify = _Setting(False, {True, False})
18051814

18061815
__slots__ = ()
18071816

@@ -1853,7 +1862,15 @@ def __call__(self, **settings: str) -> _ConfigContext:
18531862
#: `pysat.solvers.SolverNames
18541863
#: <https://pysathq.github.io/docs/html/api/solvers.html
18551864
#: #pysat.solvers.SolverNames>`_. Default: ``minisat22``.
1865+
#:
1866+
#: - ``auto_simplify``: An optional setting to prevent "extra" nesting when
1867+
#: NNF formulas are added onto with & or |.
1868+
#:
1869+
#: - ``True``: Remove nesting whenever & or | are used on an NNF formula.
1870+
#: - ``False``: Generate formulas as normal, with nesting reflecting exactly
1871+
#: how the formula was created.
1872+
18561873
config = _Config()
18571874

18581875

1859-
from nnf import amc, dsharp, kissat, operators, pysat, tseitin # noqa: E402
1876+
from nnf import amc, dsharp, kissat, operators, pysat, tseitin # noqa: E402

test_nnf.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,3 +1105,84 @@ def test_models(sentence: nnf.NNF):
11051105
models = list(sentence.models())
11061106
assert len(real_models) == len(models)
11071107
assert model_set(real_models) == model_set(models)
1108+
1109+
1110+
def test_nesting():
1111+
a, b, c, d, e, f = Var("a"), Var("b"), Var("c"), Var("d"), \
1112+
Var("e"), Var("f")
1113+
1114+
# test left nestings on And
1115+
config.auto_simplify = False
1116+
formula = a & (b & c)
1117+
formula = formula & (d | e)
1118+
assert formula == And({And({And({b, c}), a}), Or({d, e})})
1119+
config.auto_simplify = True
1120+
formula = a & (b & c)
1121+
formula = formula & (d | e)
1122+
assert formula == And({a, b, c, Or({d, e})})
1123+
1124+
# test right nestings on And
1125+
config.auto_simplify = False
1126+
formula = a & (b & c)
1127+
formula = (d | e) & formula
1128+
assert formula == And({And({And({b, c}), a}), Or({d, e})})
1129+
config.auto_simplify = True
1130+
formula = a & (b & c)
1131+
formula = (d | e) & formula
1132+
assert formula == And({a, b, c, Or({d, e})})
1133+
1134+
# test nestings on both sides with And
1135+
config.auto_simplify = False
1136+
formula = a & (b & c)
1137+
formula2 = d & (e & f)
1138+
formula = formula & formula2
1139+
assert formula == And({(And({a, And({b, c})})), And({d, And({e, f})})})
1140+
config.auto_simplify = True
1141+
formula = a & (b & c)
1142+
formula2 = d & (e & f)
1143+
formula = formula & formula2
1144+
assert formula == And({a, b, c, d, e, f})
1145+
1146+
# test left nestings on Or
1147+
config.auto_simplify = False
1148+
formula = a | (b | c)
1149+
formula = formula | (d & e)
1150+
assert formula == Or({Or({Or({b, c}), a}), And({d, e})})
1151+
config.auto_simplify = True
1152+
formula = a | (b | c)
1153+
formula = formula | (d & e)
1154+
assert formula == Or({a, b, c, And({d, e})})
1155+
1156+
# test right nestings on Or
1157+
config.auto_simplify = False
1158+
formula = a | (b | c)
1159+
formula = (d & e) | formula
1160+
assert formula == Or({Or({Or({b, c}), a}), And({d, e})})
1161+
config.auto_simplify = True
1162+
formula = a | (b | c)
1163+
formula = (d & e) | formula
1164+
assert formula == Or({a, b, c, And({d, e})})
1165+
1166+
# test nestings on both sides with Or
1167+
config.auto_simplify = False
1168+
formula = a | (b | c)
1169+
formula2 = d | (e | f)
1170+
formula = formula | formula2
1171+
assert formula == Or({(Or({a, Or({b, c})})), Or({d, Or({e, f})})})
1172+
config.auto_simplify = True
1173+
formula = a | (b | c)
1174+
formula2 = d | (e | f)
1175+
formula = formula | formula2
1176+
assert formula == Or({a, b, c, d, e, f})
1177+
1178+
# test nestings with both And and Or
1179+
config.auto_simplify = False
1180+
formula = a & (b | c)
1181+
formula2 = d & (e & f)
1182+
formula = formula | formula2
1183+
assert formula == Or({(And({a, Or({b, c})})), And({d, And({e, f})})})
1184+
config.auto_simplify = True
1185+
formula = a & (b | c)
1186+
formula2 = d & (e & f)
1187+
formula = formula | formula2
1188+
assert formula == Or({(And({a, Or({b, c})})), And({d, e, f})})

0 commit comments

Comments
 (0)