Skip to content

Commit 72e8819

Browse files
committed
Minor fixes according to PR feedback.
1 parent ffce671 commit 72e8819

File tree

2 files changed

+26
-21
lines changed

2 files changed

+26
-21
lines changed

nnf/__init__.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def all_models(names: 't.Iterable[Name]') -> t.Iterator[Model]:
6060
T_NNF_co = t.TypeVar('T_NNF_co', bound='NNF', covariant=True)
6161
_Tristate = t.Optional[bool]
6262

63-
# Valid values: native, kissat, and pysat
63+
# Valid values: native and kissat
6464
SAT_BACKEND = 'native'
6565

6666
if t.TYPE_CHECKING:
@@ -599,13 +599,11 @@ def to_CNF(self) -> 'And[Or[Var]]':
599599

600600
def _cnf_satisfiable(self) -> bool:
601601
"""Call a SAT solver on the presumed CNF theory."""
602-
if 'native' == SAT_BACKEND:
602+
if SAT_BACKEND == 'native':
603603
return self._cnf_satisfiable_native()
604-
elif 'kissat' == SAT_BACKEND:
604+
elif SAT_BACKEND == 'kissat':
605605
from nnf import kissat
606606
return kissat.solve(t.cast(And[Or[Var]], self)) is not None
607-
elif 'pysat' == SAT_BACKEND:
608-
raise NotImplementedError('pysat backend not yet implemented')
609607
else:
610608
raise NotImplementedError('Unrecognized SAT backend: '+SAT_BACKEND)
611609

nnf/kissat.py

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
"""
55

66
import os
7+
import shutil
78
import subprocess
8-
import tempfile
99
import typing as t
1010

1111
from nnf import And, Or, Var, dimacs, Model
@@ -26,9 +26,12 @@ def solve(
2626
if not sentence.is_CNF():
2727
raise ValueError("Sentence must be in CNF")
2828

29-
SOLVER = os.path.join(
30-
os.path.dirname(os.path.abspath(__file__)), 'bin', 'kissat'
31-
)
29+
if shutil.which('kissat') is not None:
30+
SOLVER = 'kissat'
31+
else:
32+
SOLVER = os.path.join(
33+
os.path.dirname(os.path.abspath(__file__)), 'bin', 'kissat'
34+
)
3235
assert os.path.isfile(SOLVER), "Cannot seem to find kissat solver."
3336

3437
args = [SOLVER]
@@ -37,20 +40,24 @@ def solve(
3740
var_labels = dict(enumerate(sentence.vars(), start=1))
3841
var_labels_inverse = {v: k for k, v in var_labels.items()}
3942

40-
infd, infname = tempfile.mkstemp(text=True)
41-
try:
42-
with open(infd, 'w') as f:
43-
dimacs.dump(sentence, f, mode='cnf', var_labels=var_labels_inverse)
43+
cnf = dimacs.dumps(sentence, mode='cnf', var_labels=var_labels_inverse)
4444

45+
try:
4546
proc = subprocess.Popen(
46-
args + [infname],
47+
args,
4748
stdout=subprocess.PIPE,
49+
stdin=subprocess.PIPE,
4850
universal_newlines=True
4951
)
50-
log, _ = proc.communicate()
51-
52-
finally:
53-
os.remove(infname)
52+
log, _ = proc.communicate(cnf)
53+
except OSError as err:
54+
if err.errno == 8:
55+
print("Error: Attempting to run the kissat binary on an")
56+
print(" incompatible system. Consider compiling kissat")
57+
print(" natively so it is accessible via the command line.")
58+
raise RuntimeError("Unable to run kissat.")
59+
else:
60+
raise RuntimeError("Unrecognized OSError: %d" % err.errno)
5461

5562
# Two known exit codes for the solver
5663
if proc.returncode not in [10, 20]:
@@ -60,11 +67,11 @@ def solve(
6067
)
6168
)
6269

63-
if 's UNSATISFIABLE' in log:
70+
# Unsatisfiable
71+
if proc.returncode == 20:
6472
return None
6573

66-
if 's SATISFIABLE' not in log:
67-
raise RuntimeError("Something went wrong. Log:\n\n{}".format(log))
74+
assert proc.returncode == 10, "Bad error code. Log:\n\n{}".format(log)
6875

6976
variable_lines = [
7077
line[2:] for line in log.split("\n") if line.startswith("v ")

0 commit comments

Comments
 (0)