-
Notifications
You must be signed in to change notification settings - Fork 4
/
picosat_cffi.py
65 lines (56 loc) · 1.79 KB
/
picosat_cffi.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import os
import platform
from cffi import FFI
__all__ = ['ffi', 'picosat']
PICOSAT_MINIMAL_H = """
#define PICOSAT_UNKNOWN 0
#define PICOSAT_SATISFIABLE 10
#define PICOSAT_UNSATISFIABLE 20
typedef struct PicoSAT PicoSAT;
const char *picosat_version (void);
PicoSAT * picosat_init (void); /* constructor */
void picosat_reset (PicoSAT *); /* destructor */
int picosat_inc_max_var (PicoSAT *);
int picosat_push (PicoSAT *);
int picosat_pop (PicoSAT *);
int picosat_add (PicoSAT *, int lit);
void picosat_assume (PicoSAT *, int lit);
int picosat_sat (PicoSAT *, int decision_limit);
int picosat_deref (PicoSAT *, int lit);
"""
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
NAMES = ["libpicosat.so",
os.path.join(BASE_DIR, "libpicosat.so"),
# TODO: Ideally, supporting multiple OS should boild down to trying to
# open the right shared library, e.g.:
# "libpicosat.dylib",
# os.path.join(BASE_DIR, "libpicosat.dylib"),
# "picosat.dll",
# os.path.join(BASE_DIR, "libpicosat.dylib"),
]
ffi = FFI()
ffi.cdef(PICOSAT_MINIMAL_H)
picosat = None
for libname in NAMES:
try:
picosat = ffi.dlopen(libname)
except OSError:
picosat = None
if picosat: break
if not picosat:
raise ImportError("Cannot find %s." % libname)
if __name__ == "__main__":
# Demo
v_cdata = picosat.picosat_version()
# Picosat Version
print(ffi.string(v_cdata))
# Defines work as expected
print(picosat.PICOSAT_SATISFIABLE)
pico = picosat.picosat_init()
picosat.picosat_add(pico, 1)
picosat.picosat_add(pico, -1)
picosat.picosat_add(pico, 0)
res = picosat.picosat_sat(pico, -1)
assert res == picosat.PICOSAT_SATISFIABLE
print("SAT")
picosat.picosat_reset(pico)