Skip to content

Commit 034112a

Browse files
authored
Merge pull request #29 from QuMuLab/simplify-tautologies
Simplify tautologies
2 parents c2e81fd + a025fdd commit 034112a

File tree

3 files changed

+34
-6
lines changed

3 files changed

+34
-6
lines changed

nnf/__init__.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -574,9 +574,12 @@ def neg(node: NNF) -> NNF:
574574

575575
return neg(self)
576576

577-
def to_CNF(self) -> 'And[Or[Var]]':
578-
"""Compile theory to a semantically equivalent CNF formula."""
579-
return tseitin.to_CNF(self)
577+
def to_CNF(self, simplify: bool = True) -> 'And[Or[Var]]':
578+
"""Compile theory to a semantically equivalent CNF formula.
579+
580+
:param simplify: If True, simplify clauses even if that means
581+
eliminating variables."""
582+
return tseitin.to_CNF(self, simplify)
580583

581584
def _cnf_satisfiable(self) -> bool:
582585
"""Call a SAT solver on the presumed CNF theory."""

nnf/tseitin.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010
from nnf.util import memoize
1111

1212

13-
def to_CNF(theory: NNF) -> And[Or[Var]]:
13+
def to_CNF(theory: NNF, simplify: bool = True) -> And[Or[Var]]:
1414
"""Convert an NNF into CNF using the Tseitin Encoding.
1515
1616
:param theory: Theory to convert.
17+
:param simplify: If True, simplify clauses even if that means eliminating
18+
variables.
1719
"""
1820

1921
clauses = []
@@ -34,7 +36,7 @@ def process_node(node: NNF) -> Var:
3436

3537
aux = Var.aux()
3638

37-
if any(~var in children for var in children):
39+
if simplify and any(~var in children for var in children):
3840
if isinstance(node, And):
3941
clauses.append(Or({~aux}))
4042
else:
@@ -73,7 +75,7 @@ def process_required(node: NNF) -> None:
7375

7476
elif isinstance(node, Or):
7577
children = {process_node(c) for c in node.children}
76-
if any(~var in children for var in children):
78+
if simplify and any(~v in children for v in children):
7779
return
7880
clauses.append(Or(children))
7981

test_nnf.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,6 +1107,29 @@ def test_models(sentence: nnf.NNF):
11071107
assert model_set(real_models) == model_set(models)
11081108

11091109

1110+
@given(NNF())
1111+
def test_toCNF_simplification_names(sentence: nnf.NNF):
1112+
names1 = set(sentence.vars())
1113+
T = sentence.to_CNF(simplify=False)
1114+
names2 = set({v for v in T.vars() if not isinstance(v, nnf.Aux)})
1115+
assert names1 == names2
1116+
1117+
1118+
def test_toCNF_simplification():
1119+
x = Var("x")
1120+
T = x | ~x
1121+
1122+
T1 = T.to_CNF()
1123+
T2 = T.to_CNF(simplify=False)
1124+
1125+
assert T1 == nnf.true
1126+
assert T1.is_CNF()
1127+
1128+
assert T2 != nnf.true
1129+
assert T2 == And({Or({~x, x})})
1130+
assert T2.is_CNF()
1131+
1132+
11101133
@config(auto_simplify=False)
11111134
def test_nesting():
11121135
a, b, c, d, e, f = Var("a"), Var("b"), Var("c"), Var("d"), \

0 commit comments

Comments
 (0)