Skip to content

Commit 434cc99

Browse files
Merge pull request diffblue#1732 from peterschrammel/catch-sat-memout
Catch Minisat/Glucose OutOfMemoryException
2 parents 8ae53bb + ef45a1d commit 434cc99

File tree

2 files changed

+174
-91
lines changed

2 files changed

+174
-91
lines changed

src/solvers/sat/satcheck_glucose.cpp

Lines changed: 105 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ Author: Daniel Kroening, [email protected]
1212
#include <inttypes.h>
1313
#endif
1414

15-
#include <cassert>
1615
#include <stack>
1716

17+
#include <util/invariant.h>
1818
#include <util/threeval.h>
1919

2020
#include <core/Solver.h>
@@ -64,9 +64,19 @@ tvt satcheck_glucose_baset<T>::l_get(literalt a) const
6464
template<typename T>
6565
void satcheck_glucose_baset<T>::set_polarity(literalt a, bool value)
6666
{
67-
assert(!a.is_constant());
68-
add_variables();
69-
solver->setPolarity(a.var_no(), value);
67+
PRECONDITION(!a.is_constant());
68+
69+
try
70+
{
71+
add_variables();
72+
solver->setPolarity(a.var_no(), value);
73+
}
74+
catch(Glucose::OutOfMemoryException)
75+
{
76+
messaget::error() << "SAT checker ran out of memory" << eom;
77+
status = statust::ERROR;
78+
throw std::bad_alloc();
79+
}
7080
}
7181

7282
const std::string satcheck_glucose_no_simplifiert::solver_text()
@@ -89,32 +99,42 @@ void satcheck_glucose_baset<T>::add_variables()
8999
template<typename T>
90100
void satcheck_glucose_baset<T>::lcnf(const bvt &bv)
91101
{
92-
add_variables();
93-
94-
forall_literals(it, bv)
102+
try
95103
{
96-
if(it->is_true())
97-
return;
98-
else if(!it->is_false())
99-
assert(it->var_no()<(unsigned)solver->nVars());
100-
}
104+
add_variables();
101105

102-
Glucose::vec<Glucose::Lit> c;
106+
forall_literals(it, bv)
107+
{
108+
if(it->is_true())
109+
return;
110+
else if(!it->is_false())
111+
INVARIANT(
112+
it->var_no() < (unsigned)solver->nVars(), "variable not added yet");
113+
}
114+
115+
Glucose::vec<Glucose::Lit> c;
103116

104-
convert(bv, c);
117+
convert(bv, c);
105118

106-
// Note the underscore.
107-
// Add a clause to the solver without making superflous internal copy.
119+
// Note the underscore.
120+
// Add a clause to the solver without making superflous internal copy.
108121

109-
solver->addClause_(c);
122+
solver->addClause_(c);
110123

111-
clause_counter++;
124+
clause_counter++;
125+
}
126+
catch(Glucose::OutOfMemoryException)
127+
{
128+
messaget::error() << "SAT checker ran out of memory" << eom;
129+
status = statust::ERROR;
130+
throw std::bad_alloc();
131+
}
112132
}
113133

114134
template<typename T>
115135
propt::resultt satcheck_glucose_baset<T>::prop_solve()
116136
{
117-
assert(status!=statust::ERROR);
137+
PRECONDITION(status != statust::ERROR);
118138

119139
// We start counting at 1, thus there is one variable fewer.
120140
{
@@ -123,63 +143,79 @@ propt::resultt satcheck_glucose_baset<T>::prop_solve()
123143
solver->nClauses() << " clauses" << eom;
124144
}
125145

126-
add_variables();
127-
128-
if(!solver->okay())
146+
try
129147
{
130-
messaget::status() <<
131-
"SAT checker inconsistent: instance is UNSATISFIABLE" << eom;
132-
}
133-
else
134-
{
135-
// if assumptions contains false, we need this to be UNSAT
136-
bool has_false=false;
137-
138-
forall_literals(it, assumptions)
139-
if(it->is_false())
140-
has_false=true;
148+
add_variables();
141149

142-
if(has_false)
150+
if(!solver->okay())
143151
{
144-
messaget::status() <<
145-
"got FALSE as assumption: instance is UNSATISFIABLE" << eom;
152+
messaget::status()
153+
<< "SAT checker inconsistent: instance is UNSATISFIABLE" << eom;
146154
}
147155
else
148156
{
149-
Glucose::vec<Glucose::Lit> solver_assumptions;
150-
convert(assumptions, solver_assumptions);
157+
// if assumptions contains false, we need this to be UNSAT
158+
bool has_false = false;
159+
160+
forall_literals(it, assumptions)
161+
if(it->is_false())
162+
has_false = true;
151163

152-
if(solver->solve(solver_assumptions))
164+
if(has_false)
153165
{
154-
messaget::status() <<
155-
"SAT checker: instance is SATISFIABLE" << eom;
156-
status=statust::SAT;
157-
return resultt::P_SATISFIABLE;
166+
messaget::status()
167+
<< "got FALSE as assumption: instance is UNSATISFIABLE" << eom;
158168
}
159169
else
160170
{
161-
messaget::status() <<
162-
"SAT checker: instance is UNSATISFIABLE" << eom;
171+
Glucose::vec<Glucose::Lit> solver_assumptions;
172+
convert(assumptions, solver_assumptions);
173+
174+
if(solver->solve(solver_assumptions))
175+
{
176+
messaget::status() << "SAT checker: instance is SATISFIABLE" << eom;
177+
status = statust::SAT;
178+
return resultt::P_SATISFIABLE;
179+
}
180+
else
181+
{
182+
messaget::status() << "SAT checker: instance is UNSATISFIABLE" << eom;
183+
}
163184
}
164185
}
165-
}
166186

167-
status=statust::UNSAT;
168-
return resultt::P_UNSATISFIABLE;
187+
status = statust::UNSAT;
188+
return resultt::P_UNSATISFIABLE;
189+
}
190+
catch(Glucose::OutOfMemoryException)
191+
{
192+
messaget::error() << "SAT checker ran out of memory" << eom;
193+
status = statust::ERROR;
194+
throw std::bad_alloc();
195+
}
169196
}
170197

171198
template<typename T>
172199
void satcheck_glucose_baset<T>::set_assignment(literalt a, bool value)
173200
{
174-
assert(!a.is_constant());
201+
PRECONDITION(!a.is_constant());
175202

176-
unsigned v=a.var_no();
177-
bool sign=a.sign();
203+
try
204+
{
205+
unsigned v = a.var_no();
206+
bool sign = a.sign();
178207

179-
// MiniSat2 kills the model in case of UNSAT
180-
solver->model.growTo(v+1);
181-
value^=sign;
182-
solver->model[v]=Glucose::lbool(value);
208+
// MiniSat2 kills the model in case of UNSAT
209+
solver->model.growTo(v + 1);
210+
value ^= sign;
211+
solver->model[v] = Glucose::lbool(value);
212+
}
213+
catch(Glucose::OutOfMemoryException)
214+
{
215+
messaget::error() << "SAT checker ran out of memory" << eom;
216+
status = statust::ERROR;
217+
throw std::bad_alloc();
218+
}
183219
}
184220

185221
template<typename T>
@@ -218,7 +254,7 @@ void satcheck_glucose_baset<T>::set_assumptions(const bvt &bv)
218254
assumptions=bv;
219255

220256
forall_literals(it, assumptions)
221-
assert(!it->is_constant());
257+
INVARIANT(!it->is_constant(), "assumption literals must not be constant");
222258
}
223259

224260
satcheck_glucose_no_simplifiert::satcheck_glucose_no_simplifiert():
@@ -233,16 +269,25 @@ satcheck_glucose_simplifiert::satcheck_glucose_simplifiert():
233269

234270
void satcheck_glucose_simplifiert::set_frozen(literalt a)
235271
{
236-
if(!a.is_constant())
272+
try
237273
{
238-
add_variables();
239-
solver->setFrozen(a.var_no(), true);
274+
if(!a.is_constant())
275+
{
276+
add_variables();
277+
solver->setFrozen(a.var_no(), true);
278+
}
279+
}
280+
catch(Glucose::OutOfMemoryException)
281+
{
282+
messaget::error() << "SAT checker ran out of memory" << eom;
283+
status = statust::ERROR;
284+
throw std::bad_alloc();
240285
}
241286
}
242287

243288
bool satcheck_glucose_simplifiert::is_eliminated(literalt a) const
244289
{
245-
assert(!a.is_constant());
290+
PRECONDITION(!a.is_constant());
246291

247292
return solver->isEliminated(a.var_no());
248293
}

0 commit comments

Comments
 (0)