cprover
Toggle main menu visibility
Loading...
Searching...
No Matches
satcheck_minisat2.cpp
Go to the documentation of this file.
1
/*******************************************************************\
2
3
Module:
4
5
Author: Daniel Kroening, kroening@kroening.com
6
7
\*******************************************************************/
8
9
#include "
satcheck_minisat2.h
"
10
11
#ifndef _WIN32
12
# include <signal.h>
13
# include <unistd.h>
14
#endif
15
16
#include <limits>
17
18
#include <
util/invariant.h
>
19
#include <
util/threeval.h
>
20
21
#include <minisat/core/Solver.h>
22
#include <minisat/simp/SimpSolver.h>
23
24
#ifndef l_False
25
# define l_False Minisat::l_False
26
# define l_True Minisat::l_True
27
#endif
28
29
#ifndef HAVE_MINISAT2
30
#error "Expected HAVE_MINISAT2"
31
#endif
32
33
void
convert
(
const
bvt
&bv, Minisat::vec<Minisat::Lit> &dest)
34
{
35
PRECONDITION
(
36
bv.size() <=
static_cast<
std::size_t
>
(std::numeric_limits<int>::max()));
37
dest.capacity(
static_cast<
int
>
(bv.size()));
38
39
for
(
const
auto
&literal : bv)
40
{
41
if
(!literal.is_false())
42
dest.push(Minisat::mkLit(literal.var_no(), literal.sign()));
43
}
44
}
45
46
void
convert_assumptions
(
const
bvt
&bv, Minisat::vec<Minisat::Lit> &dest)
47
{
48
PRECONDITION
(
49
bv.size() <=
static_cast<
std::size_t
>
(std::numeric_limits<int>::max()));
50
dest.capacity(
static_cast<
int
>
(bv.size()));
51
52
for
(
const
auto
&literal : bv)
53
{
54
// when converting assumptions, ignore 'true'
55
if
(!literal.is_true())
56
dest.push(Minisat::mkLit(literal.var_no(), literal.sign()));
57
}
58
}
59
60
template
<
typename
T>
61
tvt
satcheck_minisat2_baset<T>::l_get
(
literalt
a)
const
62
{
63
if
(a.
is_true
())
64
return
tvt
(
true
);
65
else
if
(a.
is_false
())
66
return
tvt
(
false
);
67
68
tvt
result;
69
70
if
(a.
var_no
()>=(
unsigned
)
solver
->model.size())
71
return
tvt::unknown
();
72
73
using
Minisat::lbool;
74
75
if
(
solver
->model[a.
var_no
()]==
l_True
)
76
result=
tvt
(
true
);
77
else
if
(
solver
->model[a.
var_no
()]==
l_False
)
78
result=
tvt
(
false
);
79
else
80
return
tvt::unknown
();
81
82
if
(a.
sign
())
83
result=!result;
84
85
return
result;
86
}
87
88
template
<
typename
T>
89
void
satcheck_minisat2_baset<T>::set_polarity
(
literalt
a,
bool
value)
90
{
91
PRECONDITION
(!a.
is_constant
());
92
93
using
Minisat::lbool;
94
95
try
96
{
97
add_variables
();
98
solver
->setPolarity(a.
var_no
(), value ?
l_True
:
l_False
);
99
}
100
catch
(Minisat::OutOfMemoryException)
101
{
102
log
.error() <<
"SAT checker ran out of memory"
<<
messaget::eom
;
103
status
=
statust::ERROR
;
104
throw
std::bad_alloc();
105
}
106
}
107
108
template
<
typename
T>
109
void
satcheck_minisat2_baset<T>::interrupt
()
110
{
111
solver
->interrupt();
112
}
113
114
template
<
typename
T>
115
void
satcheck_minisat2_baset<T>::clear_interrupt
()
116
{
117
solver
->clearInterrupt();
118
}
119
120
std::string
satcheck_minisat_no_simplifiert::solver_text
()
const
121
{
122
return
"MiniSAT 2.2.1 without simplifier"
;
123
}
124
125
std::string
satcheck_minisat_simplifiert::solver_text
()
const
126
{
127
return
"MiniSAT 2.2.1 with simplifier"
;
128
}
129
130
template
<
typename
T>
131
void
satcheck_minisat2_baset<T>::add_variables
()
132
{
133
while
((
unsigned
)
solver
->nVars()<
no_variables
())
134
solver
->newVar();
135
}
136
137
template
<
typename
T>
138
void
satcheck_minisat2_baset<T>::lcnf
(
const
bvt
&bv)
139
{
140
try
141
{
142
add_variables
();
143
144
for
(
const
auto
&literal : bv)
145
{
146
if
(literal.is_true())
147
return
;
148
else
if
(!literal.is_false())
149
{
150
INVARIANT
(
151
literal.var_no() < (
unsigned
)
solver
->nVars(),
152
"variable not added yet"
);
153
}
154
}
155
156
Minisat::vec<Minisat::Lit> c;
157
158
convert
(bv, c);
159
160
// Note the underscore.
161
// Add a clause to the solver without making superflous internal copy.
162
163
solver
->addClause_(c);
164
165
if
(
solver_hardness
)
166
{
167
// To map clauses to lines of program code, track clause indices in the
168
// dimacs cnf output. Dimacs output is generated after processing
169
// clauses to remove duplicates and clauses that are trivially true.
170
// Here, a clause is checked to see if it can be thus eliminated. If
171
// not, add the clause index to list of clauses in
172
// solver_hardnesst::register_clause().
173
static
size_t
cnf_clause_index = 0;
174
bvt
cnf;
175
bool
clause_removed =
process_clause
(bv, cnf);
176
177
if
(!clause_removed)
178
cnf_clause_index++;
179
180
solver_hardness
->register_clause(
181
bv, cnf, cnf_clause_index, !clause_removed);
182
}
183
184
clause_counter
++;
185
}
186
catch
(
const
Minisat::OutOfMemoryException &)
187
{
188
log
.error() <<
"SAT checker ran out of memory"
<<
messaget::eom
;
189
status
=
statust::ERROR
;
190
throw
std::bad_alloc();
191
}
192
}
193
194
#ifndef _WIN32
195
196
static
Minisat::Solver *
solver_to_interrupt
=
nullptr
;
197
198
static
void
interrupt_solver
(
int
signum)
199
{
200
(void)signum;
// unused parameter -- just removing the name trips up cpplint
201
solver_to_interrupt
->interrupt();
202
}
203
204
#endif
205
206
template
<
typename
T>
207
propt::resultt
satcheck_minisat2_baset<T>::do_prop_solve
(
const
bvt
&assumptions)
208
{
209
PRECONDITION
(
status
!=
statust::ERROR
);
210
211
log
.statistics() << (
no_variables
() - 1) <<
" variables, "
212
<<
solver
->nClauses() <<
" clauses"
<<
messaget::eom
;
213
214
try
215
{
216
add_variables
();
217
218
if
(!
solver
->okay())
219
{
220
log
.status() <<
"SAT checker inconsistent: instance is UNSATISFIABLE"
221
<<
messaget::eom
;
222
status
=
statust::UNSAT
;
223
return
resultt::P_UNSATISFIABLE
;
224
}
225
226
// if assumptions contains false, we need this to be UNSAT
227
for
(
const
auto
&assumption : assumptions)
228
{
229
if
(assumption.is_false())
230
{
231
log
.status() <<
"got FALSE as assumption: instance is UNSATISFIABLE"
232
<<
messaget::eom
;
233
status
=
statust::UNSAT
;
234
return
resultt::P_UNSATISFIABLE
;
235
}
236
}
237
238
Minisat::vec<Minisat::Lit> solver_assumptions;
239
convert_assumptions
(assumptions, solver_assumptions);
240
241
using
Minisat::lbool;
242
243
#ifndef _WIN32
244
245
void (*old_handler)(int) = SIG_ERR;
246
247
if
(
time_limit_seconds
!= 0)
248
{
249
solver_to_interrupt
=
solver
.get();
250
old_handler = signal(SIGALRM,
interrupt_solver
);
251
if
(old_handler == SIG_ERR)
252
log
.warning() <<
"Failed to set solver time limit"
<<
messaget::eom
;
253
else
254
alarm(
time_limit_seconds
);
255
}
256
257
lbool solver_result =
solver
->solveLimited(solver_assumptions);
258
259
if
(old_handler != SIG_ERR)
260
{
261
alarm(0);
262
signal(SIGALRM, old_handler);
263
solver_to_interrupt
=
solver
.get();
264
}
265
266
#else
// _WIN32
267
268
if
(
time_limit_seconds
!= 0)
269
{
270
log
.warning() <<
"Time limit ignored (not supported on Win32 yet)"
271
<<
messaget::eom
;
272
}
273
274
lbool solver_result =
solver
->solve(solver_assumptions) ?
l_True
:
l_False
;
275
276
#endif
277
278
if
(solver_result ==
l_True
)
279
{
280
log
.status() <<
"SAT checker: instance is SATISFIABLE"
<<
messaget::eom
;
281
CHECK_RETURN
(
solver
->model.size() > 0);
282
status
=
statust::SAT
;
283
return
resultt::P_SATISFIABLE
;
284
}
285
286
if
(solver_result ==
l_False
)
287
{
288
log
.status() <<
"SAT checker: instance is UNSATISFIABLE"
<<
messaget::eom
;
289
status
=
statust::UNSAT
;
290
return
resultt::P_UNSATISFIABLE
;
291
}
292
293
log
.status() <<
"SAT checker: timed out or other error"
<<
messaget::eom
;
294
status
=
statust::ERROR
;
295
return
resultt::P_ERROR
;
296
}
297
catch
(
const
Minisat::OutOfMemoryException &)
298
{
299
log
.error() <<
"SAT checker ran out of memory"
<<
messaget::eom
;
300
status
=
statust::ERROR
;
301
return
resultt::P_ERROR
;
302
}
303
}
304
305
template
<
typename
T>
306
void
satcheck_minisat2_baset<T>::set_assignment
(
literalt
a,
bool
value)
307
{
308
PRECONDITION
(!a.
is_constant
());
309
310
try
311
{
312
unsigned
v = a.
var_no
();
313
bool
sign = a.
sign
();
314
315
// MiniSat2 kills the model in case of UNSAT
316
solver
->model.growTo(v + 1);
317
value ^= sign;
318
solver
->model[v] = Minisat::lbool(value);
319
}
320
catch
(
const
Minisat::OutOfMemoryException &)
321
{
322
log
.error() <<
"SAT checker ran out of memory"
<<
messaget::eom
;
323
status
=
statust::ERROR
;
324
throw
std::bad_alloc();
325
}
326
}
327
328
template
<
typename
T>
329
satcheck_minisat2_baset<T>::satcheck_minisat2_baset
(
330
message_handlert
&message_handler)
331
:
cnf_solvert
(message_handler),
332
solver
(
std
::make_unique<T>()),
333
time_limit_seconds
(0)
334
{
335
}
336
337
template
<
typename
T>
338
satcheck_minisat2_baset<T>::~satcheck_minisat2_baset
() =
default
;
339
340
template
<
typename
T>
341
bool
satcheck_minisat2_baset<T>::is_in_conflict
(
literalt
a)
const
342
{
343
int
v=a.
var_no
();
344
345
for
(
int
i=0; i<
solver
->conflict.size(); i++)
346
if
(var(
solver
->conflict[i])==v)
347
return
true
;
348
349
return
false
;
350
}
351
352
template
class
satcheck_minisat2_baset<Minisat::Solver>
;
353
template
class
satcheck_minisat2_baset<Minisat::SimpSolver>
;
354
355
void
satcheck_minisat_simplifiert::set_frozen
(
literalt
a)
356
{
357
try
358
{
359
if
(!a.
is_constant
())
360
{
361
add_variables
();
362
solver
->setFrozen(a.
var_no
(),
true
);
363
}
364
}
365
catch
(
const
Minisat::OutOfMemoryException &)
366
{
367
log
.error() <<
"SAT checker ran out of memory"
<<
messaget::eom
;
368
status
=
statust::ERROR
;
369
throw
std::bad_alloc();
370
}
371
}
372
373
bool
satcheck_minisat_simplifiert::is_eliminated
(
literalt
a)
const
374
{
375
PRECONDITION
(!a.
is_constant
());
376
377
return
solver
->isEliminated(a.
var_no
());
378
}
cnf_solvert::status
statust status
Definition
cnf.h:87
cnf_solvert::cnf_solvert
cnf_solvert(message_handlert &message_handler)
Definition
cnf.h:75
cnf_solvert::statust::UNSAT
@ UNSAT
Definition
cnf.h:86
cnf_solvert::statust::SAT
@ SAT
Definition
cnf.h:86
cnf_solvert::statust::ERROR
@ ERROR
Definition
cnf.h:86
cnf_solvert::clause_counter
size_t clause_counter
Definition
cnf.h:88
cnft::process_clause
bool process_clause(const bvt &bv, bvt &dest) const
filter 'true' from clause, eliminate duplicates, recognise trivially satisfied clauses
Definition
cnf.cpp:424
cnft::no_variables
virtual size_t no_variables() const override
Definition
cnf.h:42
hardness_collectort::solver_hardness
std::unique_ptr< clause_hardness_collectort > solver_hardness
Definition
hardness_collector.h:47
literalt
Definition
literal.h:26
literalt::is_true
bool is_true() const
Definition
literal.h:156
literalt::sign
bool sign() const
Definition
literal.h:88
literalt::is_constant
bool is_constant() const
Definition
literal.h:166
literalt::var_no
var_not var_no() const
Definition
literal.h:83
literalt::is_false
bool is_false() const
Definition
literal.h:161
message_handlert
Definition
message.h:27
messaget::eom
static eomt eom
Definition
message.h:289
propt::resultt
resultt
Definition
prop.h:101
propt::resultt::P_UNSATISFIABLE
@ P_UNSATISFIABLE
Definition
prop.h:101
propt::resultt::P_SATISFIABLE
@ P_SATISFIABLE
Definition
prop.h:101
propt::resultt::P_ERROR
@ P_ERROR
Definition
prop.h:101
propt::log
messaget log
Definition
prop.h:134
satcheck_minisat2_baset
Definition
satcheck_minisat2.h:34
satcheck_minisat2_baset::is_in_conflict
bool is_in_conflict(literalt a) const override
Returns true if an assumption is in the final conflict.
Definition
satcheck_minisat2.cpp:341
satcheck_minisat2_baset::clear_interrupt
void clear_interrupt()
Definition
satcheck_minisat2.cpp:115
satcheck_minisat2_baset::solver
std::unique_ptr< T > solver
Definition
satcheck_minisat2.h:73
satcheck_minisat2_baset::~satcheck_minisat2_baset
~satcheck_minisat2_baset() override
A default destructor defined in the .cpp is used to ensure the unique_ptr to the solver is correctly ...
satcheck_minisat2_baset::do_prop_solve
resultt do_prop_solve(const bvt &) override
Definition
satcheck_minisat2.cpp:207
satcheck_minisat2_baset::interrupt
void interrupt()
Definition
satcheck_minisat2.cpp:109
satcheck_minisat2_baset::satcheck_minisat2_baset
satcheck_minisat2_baset(message_handlert &message_handler)
Definition
satcheck_minisat2.cpp:329
satcheck_minisat2_baset::add_variables
void add_variables()
Definition
satcheck_minisat2.cpp:131
satcheck_minisat2_baset::set_polarity
void set_polarity(literalt a, bool value)
Definition
satcheck_minisat2.cpp:89
satcheck_minisat2_baset::lcnf
void lcnf(const bvt &bv) override final
Definition
satcheck_minisat2.cpp:138
satcheck_minisat2_baset::l_get
tvt l_get(literalt a) const override final
Definition
satcheck_minisat2.cpp:61
satcheck_minisat2_baset::set_assignment
void set_assignment(literalt a, bool value) override
Definition
satcheck_minisat2.cpp:306
satcheck_minisat2_baset::time_limit_seconds
uint32_t time_limit_seconds
Definition
satcheck_minisat2.h:74
satcheck_minisat_no_simplifiert::solver_text
std::string solver_text() const override
Definition
satcheck_minisat2.cpp:120
satcheck_minisat_simplifiert::set_frozen
void set_frozen(literalt a) override final
Definition
satcheck_minisat2.cpp:355
satcheck_minisat_simplifiert::is_eliminated
bool is_eliminated(literalt a) const
Definition
satcheck_minisat2.cpp:373
satcheck_minisat_simplifiert::solver_text
std::string solver_text() const override final
Definition
satcheck_minisat2.cpp:125
tvt
Definition
threeval.h:20
tvt::unknown
static tvt unknown()
Definition
threeval.h:33
bvt
std::vector< literalt > bvt
Definition
literal.h:201
std
STL namespace.
solver_to_interrupt
static Minisat::Solver * solver_to_interrupt
Definition
satcheck_minisat2.cpp:196
interrupt_solver
static void interrupt_solver(int signum)
Definition
satcheck_minisat2.cpp:198
convert_assumptions
void convert_assumptions(const bvt &bv, Minisat::vec< Minisat::Lit > &dest)
Definition
satcheck_minisat2.cpp:46
convert
void convert(const bvt &bv, Minisat::vec< Minisat::Lit > &dest)
Definition
satcheck_minisat2.cpp:33
l_True
#define l_True
Definition
satcheck_minisat2.cpp:26
l_False
#define l_False
Definition
satcheck_minisat2.cpp:25
satcheck_minisat2.h
invariant.h
CHECK_RETURN
#define CHECK_RETURN(CONDITION)
Definition
invariant.h:495
PRECONDITION
#define PRECONDITION(CONDITION)
Definition
invariant.h:463
INVARIANT
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition
invariant.h:423
threeval.h
solvers
sat
satcheck_minisat2.cpp
Generated by
1.17.0