@@ -26,9 +26,14 @@ def process_node(node: NNF) -> Var:
2626
2727 assert isinstance (node , Internal )
2828
29- aux = Var .aux ()
3029 children = {process_node (c ) for c in node .children }
3130
31+ if len (children ) == 1 :
32+ [child ] = children
33+ return child
34+
35+ aux = Var .aux ()
36+
3237 if any (~ var in children for var in children ):
3338 if isinstance (node , And ):
3439 clauses .append (Or ({~ aux }))
@@ -50,8 +55,36 @@ def process_node(node: NNF) -> Var:
5055
5156 return aux
5257
53- root = process_node (theory )
54- clauses .append (Or ({root }))
58+ @memoize
59+ def process_required (node : NNF ) -> None :
60+ """For nodes that have to be satisfied.
61+
62+ This lets us perform some optimizations.
63+ """
64+ if isinstance (node , Var ):
65+ clauses .append (Or ({node }))
66+ return
67+
68+ assert isinstance (node , Internal )
69+
70+ if len (node .children ) == 1 :
71+ [child ] = node .children
72+ process_required (child )
73+
74+ elif isinstance (node , Or ):
75+ children = {process_node (c ) for c in node .children }
76+ if any (~ var in children for var in children ):
77+ return
78+ clauses .append (Or (children ))
79+
80+ elif isinstance (node , And ):
81+ for child in node .children :
82+ process_required (child )
83+
84+ else :
85+ raise TypeError (node )
86+
87+ process_required (theory )
5588 ret = And (clauses )
5689 NNF ._is_CNF_loose .set (ret , True )
5790 NNF ._is_CNF_strict .set (ret , True )
0 commit comments