cprover
Toggle main menu visibility
Loading...
Searching...
No Matches
satcheck_glucose.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_glucose.h
"
10
11
#include <stack>
12
13
#include <
util/invariant.h
>
14
#include <
util/threeval.h
>
15
16
#include <core/Solver.h>
17
#include <simp/SimpSolver.h>
18
19
#ifndef HAVE_GLUCOSE
20
#error "Expected HAVE_GLUCOSE"
21
#endif
22
23
void
convert
(
const
bvt
&bv, Glucose::vec<Glucose::Lit> &dest)
24
{
25
dest.capacity(bv.size());
26
27
for
(
const
auto
&literal : bv)
28
{
29
if
(!literal.is_false())
30
dest.push(Glucose::mkLit(literal.var_no(), literal.sign()));
31
}
32
}
33
34
void
convert_assumptions
(
const
bvt
&bv, Glucose::vec<Glucose::Lit> &dest)
35
{
36
dest.capacity(bv.size());
37
38
for
(
const
auto
&literal : bv)
39
{
40
if
(!literal.is_true())
41
dest.push(Glucose::mkLit(literal.var_no(), literal.sign()));
42
}
43
}
44
45
template
<
typename
T>
46
tvt
satcheck_glucose_baset<T>::l_get
(
literalt
a)
const
47
{
48
if
(a.
is_true
())
49
return
tvt
(
true
);
50
else
if
(a.
is_false
())
51
return
tvt
(
false
);
52
53
tvt
result;
54
55
if
(a.
var_no
()>=(
unsigned
)
solver
->model.size())
56
return
tvt
(
tvt::tv_enumt::TV_UNKNOWN
);
57
58
using
Glucose::lbool;
59
60
if
(
solver
->model[a.
var_no
()]==
l_True
)
61
result=
tvt
(
true
);
62
else
if
(
solver
->model[a.
var_no
()]==
l_False
)
63
result=
tvt
(
false
);
64
else
65
return
tvt
(
tvt::tv_enumt::TV_UNKNOWN
);
66
67
if
(a.
sign
())
68
result=!result;
69
70
return
result;
71
}
72
73
template
<
typename
T>
74
void
satcheck_glucose_baset<T>::set_polarity
(
literalt
a,
bool
value)
75
{
76
PRECONDITION
(!a.
is_constant
());
77
78
try
79
{
80
add_variables
();
81
solver
->setPolarity(a.
var_no
(), value);
82
}
83
catch
(Glucose::OutOfMemoryException)
84
{
85
log
.error() <<
"SAT checker ran out of memory"
<<
messaget::eom
;
86
status
=
statust::ERROR
;
87
throw
std::bad_alloc();
88
}
89
}
90
91
std::string
satcheck_glucose_no_simplifiert::solver_text
()
const
92
{
93
return
"Glucose Syrup without simplifier"
;
94
}
95
96
std::string
satcheck_glucose_simplifiert::solver_text
()
const
97
{
98
return
"Glucose Syrup with simplifier"
;
99
}
100
101
template
<
typename
T>
102
void
satcheck_glucose_baset<T>::add_variables
()
103
{
104
while
((
unsigned
)
solver
->nVars()<
no_variables
())
105
solver
->newVar();
106
}
107
108
template
<
typename
T>
109
void
satcheck_glucose_baset<T>::lcnf
(
const
bvt
&bv)
110
{
111
try
112
{
113
add_variables
();
114
115
for
(
const
auto
&literal : bv)
116
{
117
if
(literal.is_true())
118
return
;
119
else
if
(!literal.is_false())
120
{
121
INVARIANT
(
122
literal.var_no() < (
unsigned
)
solver
->nVars(),
123
"variable not added yet"
);
124
}
125
}
126
127
Glucose::vec<Glucose::Lit> c;
128
129
convert
(bv, c);
130
131
// Note the underscore.
132
// Add a clause to the solver without making superflous internal copy.
133
134
solver
->addClause_(c);
135
136
if
(
solver_hardness
)
137
{
138
// To map clauses to lines of program code, track clause indices in the
139
// dimacs cnf output. Dimacs output is generated after processing
140
// clauses to remove duplicates and clauses that are trivially true.
141
// Here, a clause is checked to see if it can be thus eliminated. If
142
// not, add the clause index to list of clauses in
143
// solver_hardnesst::register_clause().
144
static
size_t
cnf_clause_index = 0;
145
bvt
cnf;
146
bool
clause_removed =
process_clause
(bv, cnf);
147
148
if
(!clause_removed)
149
cnf_clause_index++;
150
151
solver_hardness
->register_clause(
152
bv, cnf, cnf_clause_index, !clause_removed);
153
}
154
155
clause_counter
++;
156
}
157
catch
(Glucose::OutOfMemoryException)
158
{
159
log
.error() <<
"SAT checker ran out of memory"
<<
messaget::eom
;
160
status
=
statust::ERROR
;
161
throw
std::bad_alloc();
162
}
163
}
164
165
template
<
typename
T>
166
propt::resultt
satcheck_glucose_baset<T>::do_prop_solve
(
const
bvt
&assumptions)
167
{
168
PRECONDITION
(
status
!=
statust::ERROR
);
169
170
// We start counting at 1, thus there is one variable fewer.
171
log
.statistics() << (
no_variables
() - 1) <<
" variables, "
172
<<
solver
->nClauses() <<
" clauses"
<<
messaget::eom
;
173
174
try
175
{
176
add_variables
();
177
178
if
(!
solver
->okay())
179
{
180
log
.status() <<
"SAT checker inconsistent: instance is UNSATISFIABLE"
181
<<
messaget::eom
;
182
}
183
else
184
{
185
// if assumptions contains false, we need this to be UNSAT
186
bool
has_false =
false
;
187
188
for
(
const
auto
&literal : assumptions)
189
{
190
if
(literal.is_false())
191
has_false =
true
;
192
}
193
194
if
(has_false)
195
{
196
log
.status() <<
"got FALSE as assumption: instance is UNSATISFIABLE"
197
<<
messaget::eom
;
198
}
199
else
200
{
201
Glucose::vec<Glucose::Lit> solver_assumptions;
202
convert_assumptions
(assumptions, solver_assumptions);
203
204
if
(
solver
->solve(solver_assumptions))
205
{
206
log
.status() <<
"SAT checker: instance is SATISFIABLE"
207
<<
messaget::eom
;
208
status
=
statust::SAT
;
209
return
resultt::P_SATISFIABLE
;
210
}
211
else
212
{
213
log
.status() <<
"SAT checker: instance is UNSATISFIABLE"
214
<<
messaget::eom
;
215
}
216
}
217
}
218
219
status
=
statust::UNSAT
;
220
return
resultt::P_UNSATISFIABLE
;
221
}
222
catch
(Glucose::OutOfMemoryException)
223
{
224
log
.error() <<
"SAT checker ran out of memory"
<<
messaget::eom
;
225
status
=
statust::ERROR
;
226
throw
std::bad_alloc();
227
}
228
}
229
230
template
<
typename
T>
231
void
satcheck_glucose_baset<T>::set_assignment
(
literalt
a,
bool
value)
232
{
233
PRECONDITION
(!a.
is_constant
());
234
235
try
236
{
237
unsigned
v = a.
var_no
();
238
bool
sign = a.
sign
();
239
240
// MiniSat2 kills the model in case of UNSAT
241
solver
->model.growTo(v + 1);
242
value ^= sign;
243
solver
->model[v] = Glucose::lbool(value);
244
}
245
catch
(Glucose::OutOfMemoryException)
246
{
247
log
.error() <<
"SAT checker ran out of memory"
<<
messaget::eom
;
248
status
=
statust::ERROR
;
249
throw
std::bad_alloc();
250
}
251
}
252
253
template
<
typename
T>
254
satcheck_glucose_baset<T>::satcheck_glucose_baset
(
255
message_handlert
&message_handler)
256
:
cnf_solvert
(message_handler),
solver
(
std
::make_unique<T>())
257
{
258
}
259
260
template
<
typename
T>
261
satcheck_glucose_baset<T>::~satcheck_glucose_baset
() =
default
;
262
263
template
<
typename
T>
264
bool
satcheck_glucose_baset<T>::is_in_conflict
(
literalt
a)
const
265
{
266
int
v=a.
var_no
();
267
268
for
(
int
i=0; i<
solver
->conflict.size(); i++)
269
if
(var(
solver
->conflict[i])==v)
270
return
true
;
271
272
return
false
;
273
}
274
275
template
class
satcheck_glucose_baset<Glucose::Solver>
;
276
template
class
satcheck_glucose_baset<Glucose::SimpSolver>
;
277
278
void
satcheck_glucose_simplifiert::set_frozen
(
literalt
a)
279
{
280
try
281
{
282
if
(!a.
is_constant
())
283
{
284
add_variables
();
285
solver
->setFrozen(a.
var_no
(),
true
);
286
}
287
}
288
catch
(Glucose::OutOfMemoryException)
289
{
290
log
.error() <<
"SAT checker ran out of memory"
<<
messaget::eom
;
291
status
=
statust::ERROR
;
292
throw
std::bad_alloc();
293
}
294
}
295
296
bool
satcheck_glucose_simplifiert::is_eliminated
(
literalt
a)
const
297
{
298
PRECONDITION
(!a.
is_constant
());
299
300
return
solver
->isEliminated(a.
var_no
());
301
}
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::log
messaget log
Definition
prop.h:134
satcheck_glucose_baset
Definition
satcheck_glucose.h:32
satcheck_glucose_baset::is_in_conflict
bool is_in_conflict(literalt a) const override
Returns true if an assumption is in the final conflict.
Definition
satcheck_glucose.cpp:264
satcheck_glucose_baset::~satcheck_glucose_baset
~satcheck_glucose_baset() override
A default destructor defined in the .cpp is used to ensure the unique_ptr to the solver is correctly ...
satcheck_glucose_baset::lcnf
void lcnf(const bvt &bv) override
Definition
satcheck_glucose.cpp:109
satcheck_glucose_baset< Glucose::Solver >::solver
std::unique_ptr< Glucose::Solver > solver
Definition
satcheck_glucose.h:60
satcheck_glucose_baset::set_polarity
void set_polarity(literalt a, bool value)
Definition
satcheck_glucose.cpp:74
satcheck_glucose_baset::satcheck_glucose_baset
satcheck_glucose_baset(message_handlert &message_handler)
Definition
satcheck_glucose.cpp:254
satcheck_glucose_baset::l_get
tvt l_get(literalt a) const override
Definition
satcheck_glucose.cpp:46
satcheck_glucose_baset::do_prop_solve
resultt do_prop_solve(const bvt &assumptions) override
Definition
satcheck_glucose.cpp:166
satcheck_glucose_baset::set_assignment
void set_assignment(literalt a, bool value) override
Definition
satcheck_glucose.cpp:231
satcheck_glucose_baset::add_variables
void add_variables()
Definition
satcheck_glucose.cpp:102
satcheck_glucose_no_simplifiert::solver_text
std::string solver_text() const override
Definition
satcheck_glucose.cpp:91
satcheck_glucose_simplifiert::set_frozen
void set_frozen(literalt a) override
Definition
satcheck_glucose.cpp:278
satcheck_glucose_simplifiert::solver_text
std::string solver_text() const override
Definition
satcheck_glucose.cpp:96
satcheck_glucose_simplifiert::is_eliminated
bool is_eliminated(literalt a) const
Definition
satcheck_glucose.cpp:296
tvt
Definition
threeval.h:20
tvt::tv_enumt::TV_UNKNOWN
@ TV_UNKNOWN
Definition
threeval.h:23
bvt
std::vector< literalt > bvt
Definition
literal.h:201
std
STL namespace.
convert
void convert(const bvt &bv, Glucose::vec< Glucose::Lit > &dest)
Definition
satcheck_glucose.cpp:23
convert_assumptions
void convert_assumptions(const bvt &bv, Glucose::vec< Glucose::Lit > &dest)
Definition
satcheck_glucose.cpp:34
satcheck_glucose.h
l_True
#define l_True
Definition
satcheck_minisat2.cpp:26
l_False
#define l_False
Definition
satcheck_minisat2.cpp:25
invariant.h
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_glucose.cpp
Generated by
1.17.0