CBMC
satcheck_minisat.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_minisat.h"
10 
11 #include <algorithm>
12 #include <stack>
13 
14 #include <util/invariant.h>
15 #include <util/threeval.h>
16 
17 #include <Solver.h>
18 #include <Proof.h>
19 
20 #ifndef HAVE_MINISAT
21 #error "Expected HAVE_MINISAT"
22 #endif
23 
24 void convert(const bvt &bv, vec<Lit> &dest)
25 {
26  dest.growTo(bv.size());
27 
28  for(unsigned i=0; i<bv.size(); i++)
29  dest[i]=Lit(bv[i].var_no(), bv[i].sign());
30 }
31 
32 class minisat_prooft:public ProofTraverser
33 {
34 public:
35  virtual void root(const vec<Lit> &c)
36  {
37  resolution_proof.clauses.push_back(clauset());
38  resolution_proof.clauses.back().is_root=true;
39  resolution_proof.clauses.back().root_clause.resize(c.size());
40 // resolution_proof.clauses.back().pid = resolution_proof.partition_id;
41 
42  for(int i=0; i<c.size(); i++)
43  {
44  resolution_proof.clauses.back().root_clause[i]=
45  literalt(var(c[i]), sign(c[i]));
46 // if(var(c[i]) > resolution_proof.no_vars)
47 // resolution_proof.no_vars = var(c[i]);
48  }
49  }
50 
51  virtual void chain(const vec<ClauseId> &cs, const vec<Var> &xs);
52 
53  virtual void deleted(ClauseId c) { }
54  virtual void done() { }
55  virtual ~minisat_prooft() { }
56 
58 };
59 
60 void minisat_prooft::chain(const vec<ClauseId> &cs, const vec<Var> &xs)
61 {
62  PRECONDITION(cs.size() == xs.size() + 1);
63 
64  resolution_proof.clauses.push_back(clauset());
66 
67  c.is_root=false;
68  // c.pid = resolution_proof.partition_id;
69  c.first_clause_id=cs[0];
70  c.steps.resize(xs.size());
71 
72  // copy clause IDs
73  int c_id=resolution_proof.clauses.size();
74 
75  for(int i=0; i<xs.size(); i++)
76  {
77  // must be decreasing
78  INVARIANT(cs[i] < c_id, "clause ID should be within bounds");
79  c.steps[i].clause_id=cs[i+1];
80  c.steps[i].pivot_var_no=xs[i];
81  }
82 }
83 
85 {
86  if(a.is_true())
87  return tvt(true);
88  else if(a.is_false())
89  return tvt(false);
90 
91  tvt result;
92 
93  INVARIANT(a.var_no() != 0, "variable number should be set");
94  INVARIANT(
95  a.var_no() < (unsigned)solver->model.size(),
96  "variable number should be within bounds");
97 
98  if(solver->model[a.var_no()]==l_True)
99  result=tvt(true);
100  else if(solver->model[a.var_no()]==l_False)
101  result=tvt(false);
102  else
104 
105  if(a.sign())
106  result=!result;
107 
108  return result;
109 }
110 
112 {
113  return "MiniSAT 1.14p";
114 }
115 
117 {
118  while((unsigned)solver->nVars()<no_variables())
119  solver->newVar();
120 }
121 
123 {
124  bvt new_bv;
125 
126  if(process_clause(bv, new_bv))
127  return;
128 
129  // Minisat can't do empty clauses
130  if(new_bv.empty())
131  {
132  empty_clause_added=true;
133  return;
134  }
135 
136  add_variables();
137 
138  vec<Lit> c;
139  convert(new_bv, c);
140 
141  INVARIANT(
142  std::all_of(
143  new_bv.begin(),
144  new_bv.end(),
145  [](const literalt &l) { return l.var_no() < (unsigned)solver->nVars(); }),
146  "variable number should be within bounds");
147 
148  solver->addClause(c);
149 
150  clause_counter++;
151 }
152 
154 {
156 
157  log.statistics() << (_no_variables - 1) << " variables, "
158  << solver->nClauses() << " clauses" << messaget::eom;
159 
160  add_variables();
161 
162  solver->simplifyDB();
163 
164  std::string msg;
165 
167  {
168  msg="empty clause: instance is UNSATISFIABLE";
169  }
170  else if(!solver->okay())
171  {
172  msg="SAT checker inconsistent: instance is UNSATISFIABLE";
173  }
174  else
175  {
176  vec<Lit> MiniSat_assumptions;
177  convert(assumptions, MiniSat_assumptions);
178 
179  if(solver->solve(MiniSat_assumptions))
180  {
181  msg="SAT checker: instance is SATISFIABLE";
182  log.status() << msg << messaget::eom;
183  status=SAT;
184  return P_SATISFIABLE;
185  }
186  else
187  msg="SAT checker: instance is UNSATISFIABLE";
188  }
189 
190  log.status() << msg << messaget::eom;
191  status=UNSAT;
192  return P_UNSATISFIABLE;
193 }
194 
196 {
197  unsigned v=a.var_no();
198  bool sign=a.sign();
199  solver->model.growTo(v+1);
200  value^=sign;
201  solver->model[v]=lbool(value);
202 }
203 
205 {
206  int v=a.var_no();
207 
208  for(int i=0; i<solver->conflict.size(); i++)
209  {
210  if(var(solver->conflict[i])==v)
211  return true;
212  }
213 
214  return false;
215 }
216 
218 {
219  empty_clause_added=false;
220  solver=new Solver;
221 }
222 
224 {
226  proof=new Proof(*minisat_proof);
227  // solver=new Solver;
228  solver->proof=proof;
229 }
230 
232 {
233  delete proof;
234  delete minisat_proof;
235 }
236 
238 {
239 }
240 
242 {
243 }
244 
246 {
247  delete solver;
248 }
249 
251 {
252  return "MiniSAT + Proof";
253 }
254 
256 {
258 
260 
261  if(status==UNSAT)
262  {
263  in_core.resize(no_variables(), false);
265  }
266 
267  return r;
268 }
269 
271 {
272  return "MiniSAT + Core";
273 }
274 
276 {
278 }
stepst steps
unsigned first_clause_id
statust status
Definition: cnf.h:87
size_t clause_counter
Definition: cnf.h:88
bool process_clause(const bvt &bv, bvt &dest) const
filter 'true' from clause, eliminate duplicates, recognise trivially satisfied clauses
Definition: cnf.cpp:424
virtual size_t no_variables() const override
Definition: cnf.h:42
size_t _no_variables
Definition: cnf.h:57
bool is_true() const
Definition: literal.h:156
bool sign() const
Definition: literal.h:88
var_not var_no() const
Definition: literal.h:83
bool is_false() const
Definition: literal.h:161
mstreamt & statistics() const
Definition: message.h:411
mstreamt & status() const
Definition: message.h:406
static eomt eom
Definition: message.h:289
virtual void root(const vec< Lit > &c)
virtual void done()
virtual void chain(const vec< ClauseId > &cs, const vec< Var > &xs)
virtual void deleted(ClauseId c)
simple_prooft resolution_proof
virtual ~minisat_prooft()
resultt
Definition: prop.h:101
messaget log
Definition: prop.h:134
void build_core(std::vector< bool > &in_core)
resultt do_prop_solve(const bvt &assumptions) override
void set_assignment(literalt a, bool value) override
std::string solver_text() const override
bool is_in_conflict(literalt l) const override
Returns true if an assumption is in the final conflict.
void lcnf(const bvt &bv) final
tvt l_get(literalt a) const override
std::string solver_text() const override
resultt do_prop_solve(const bvt &assumptions) override
std::vector< bool > in_core
std::string solver_text() const override
class minisat_prooft * minisat_proof
simple_prooft & get_resolution_proof()
Definition: threeval.h:20
static int8_t r
Definition: irep_hash.h:60
std::vector< literalt > bvt
Definition: literal.h:201
#define l_True
#define l_False
void convert(const bvt &bv, vec< Lit > &dest)
Equality Propagation.
#define PRECONDITION(CONDITION)
Definition: invariant.h:463