-
Notifications
You must be signed in to change notification settings - Fork 4
/
libminisat_stubs.c
158 lines (124 loc) · 3.32 KB
/
libminisat_stubs.c
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include <minisat2/Solver.h>
extern "C"
{
#include <caml/mlvalues.h>
#include <caml/memory.h>
#include <caml/alloc.h>
#include <caml/custom.h>
#include <caml/fail.h>
}
/* Declaring the functions which should be accessible on the C side. */
extern "C"
{
CAMLprim value minisat_new(value solver);
CAMLprim value minisat_del(value solver);
CAMLprim value minisat_new_var(value solver);
CAMLprim value minisat_pos_lit(value v);
CAMLprim value minisat_neg_lit(value v);
CAMLprim value minisat_add_clause(value solver, value c);
CAMLprim value minisat_simplify(value solver);
CAMLprim value minisat_solve(value solver);
CAMLprim value minisat_solve_with_assumption(value solver, value a);
CAMLprim value minisat_value_of(value solver, value v);
}
static void convert_literals(value l, vec<Lit> &r) {
while(Int_val(l) != 0) {
Lit lit = toLit(Int_val(Field(l, 0)));
r.push(lit);
l = Field(l, 1);
}
}
CAMLprim value minisat_new(value unit) {
CAMLparam0 ();
CAMLlocal1 (result);
Solver *solver = new Solver();
result = alloc_small(1, Abstract_tag);
Field(result, 0) = (value) solver;
CAMLreturn(result);
}
#define solver_val(v) ((Solver*)(Field((v), 0)))
CAMLprim value minisat_del(value solver) {
CAMLparam1 (solver);
Solver *_solver;
_solver = solver_val(solver);
delete _solver;
CAMLreturn(Val_unit);
}
CAMLprim value minisat_new_var(value solver) {
CAMLparam1 (solver);
Solver *_solver;
_solver = solver_val(solver);
Var var = _solver->newVar();
return Val_int(var);
}
CAMLprim value minisat_pos_lit(value v) {
Var var = Int_val(v);
Lit lit(var, false);
return Val_int(toInt(lit));
}
CAMLprim value minisat_neg_lit(value v) {
Var var = Int_val(v);
Lit lit(var, true);
return Val_int(toInt(lit));
}
CAMLprim value minisat_add_clause(value solver, value c) {
CAMLparam2 (solver, c);
CAMLlocal1 (result);
Solver* _solver = solver_val(solver);
vec<Lit> clause;
convert_literals(c, clause);
_solver->addClause(clause);
result = alloc_small(1, Abstract_tag);
Field(result, 0) = (value) _solver;
CAMLreturn(result);
}
CAMLprim value minisat_simplify(value solver) {
CAMLparam1 (solver);
CAMLlocal1 (result);
Solver* _solver = solver_val(solver);
_solver->simplify();
result = alloc_small(1, Abstract_tag);
Field(result, 0) = (value) _solver;
CAMLreturn(result);
}
CAMLprim value minisat_solve(value solver) {
CAMLparam1 (solver);
CAMLlocal1 (result);
Solver* _solver = solver_val(solver);
if(_solver->solve()) {
result = Val_int(0);
} else {
result = Val_int(1);
}
CAMLreturn(result);
}
CAMLprim value minisat_solve_with_assumption(value solver, value a) {
CAMLparam2 (solver, a);
CAMLlocal1 (result);
vec<Lit> assumption;
convert_literals(a, assumption);
Solver* _solver = solver_val(solver);
if(_solver->solve(assumption)) {
result = Val_int(0);
} else {
result = Val_int(1);
}
CAMLreturn(result);
}
CAMLprim value minisat_value_of(value solver, value v) {
CAMLparam2 (solver,v);
CAMLlocal1 (result);
Solver* _solver = solver_val(solver);
Var var = Int_val(v);
lbool val = _solver->model[var];
if(val == l_False) {
result = Val_int(0);
} else if(val == l_True) {
result = Val_int(1);
} else if (val == l_Undef) {
result = Val_int(2);
} else {
assert(0);
}
CAMLreturn(result);
}