CBMC
satcheck_cadical.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Michael Tautschnig
6 
7 \*******************************************************************/
8 
9 #ifdef HAVE_CADICAL
10 
11 # include "satcheck_cadical.h"
12 
13 # include <util/exception_utils.h>
14 # include <util/invariant.h>
15 # include <util/narrow.h>
16 # include <util/threeval.h>
17 
18 # include <cadical.hpp>
19 
21 {
22  if(a.is_constant())
23  return tvt(a.sign());
24 
25  tvt result;
26 
27  if(a.var_no() > narrow<unsigned>(solver->vars()))
29 
30  const int val = solver->val(a.dimacs());
31  if(val>0)
32  result = tvt(true);
33  else if(val<0)
34  result = tvt(false);
35  else
37 
38  return result;
39 }
40 
41 std::string satcheck_cadical_baset::solver_text() const
42 {
43  return std::string("CaDiCaL ") + solver->version();
44 }
45 
46 void satcheck_cadical_baset::lcnf(const bvt &bv)
47 {
48  for(const auto &lit : bv)
49  {
50  if(lit.is_true())
51  return;
52  else if(!lit.is_false())
53  INVARIANT(lit.var_no() < no_variables(), "reject out of bound variables");
54  }
55 
56  for(const auto &lit : bv)
57  {
58  if(!lit.is_false())
59  {
60  // add literal with correct sign
61  solver->add(lit.dimacs());
62  }
63  }
64  solver->add(0); // terminate clause
65 
66  if(solver_hardness)
67  {
68  // To map clauses to lines of program code, track clause indices in the
69  // dimacs cnf output. Dimacs output is generated after processing
70  // clauses to remove duplicates and clauses that are trivially true.
71  // Here, a clause is checked to see if it can be thus eliminated. If
72  // not, add the clause index to list of clauses in
73  // solver_hardnesst::register_clause().
74  static size_t cnf_clause_index = 0;
75  bvt cnf;
76  bool clause_removed = process_clause(bv, cnf);
77 
78  if(!clause_removed)
79  cnf_clause_index++;
80 
81  solver_hardness->register_clause(
82  bv, cnf, cnf_clause_index, !clause_removed);
83  }
84 
86 }
87 
89 {
90  INVARIANT(status != statust::ERROR, "there cannot be an error");
91 
92  log.statistics() << (no_variables() - 1) << " variables, " << clause_counter
93  << " clauses" << messaget::eom;
94 
95  // if assumptions contains false, we need this to be UNSAT
96  for(const auto &a : assumptions)
97  {
98  if(a.is_false())
99  {
100  log.status() << "got FALSE as assumption: instance is UNSATISFIABLE"
101  << messaget::eom;
104  }
105  }
106 
107  for(const auto &a : assumptions)
108  if(!a.is_true())
109  solver->assume(a.dimacs());
110 
111  // set preprocessing and inprocessing limits
112  auto limit1_ret = solver->limit("preprocessing", preprocessing_limit);
113  CHECK_RETURN(limit1_ret);
114  auto limit2_ret = solver->limit("localsearch", localsearch_limit);
115  CHECK_RETURN(limit2_ret);
116 
117  switch(solver->solve())
118  {
119  case 10:
120  log.status() << "SAT checker: instance is SATISFIABLE" << messaget::eom;
122  return resultt::P_SATISFIABLE;
123  case 20:
124  log.status() << "SAT checker: instance is UNSATISFIABLE" << messaget::eom;
125  break;
126  default:
127  log.status() << "SAT checker: solving returned without solution"
128  << messaget::eom;
129  throw analysis_exceptiont(
130  "solving inside CaDiCaL SAT solver has been interrupted");
131  }
132 
135 }
136 
138 {
139  INVARIANT(!a.is_constant(), "cannot set an assignment for a constant");
140  INVARIANT(false, "method not supported");
141 }
142 
144  int _preprocessing_limit,
145  int _localsearch_limit,
146  message_handlert &message_handler)
147  : cnf_solvert(message_handler),
148  solver(new CaDiCaL::Solver()),
149  preprocessing_limit(_preprocessing_limit),
150  localsearch_limit(_localsearch_limit)
151 {
152  solver->set("quiet", 1);
153 }
154 
156 {
157  delete solver;
158 }
159 
161 {
162  return solver->failed(a.dimacs());
163 }
164 
165 #endif
Thrown when an unexpected error occurs during the analysis (e.g., when the SAT solver returns an erro...
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
std::unique_ptr< clause_hardness_collectort > solver_hardness
bool is_true() const
Definition: literal.h:156
bool sign() const
Definition: literal.h:88
bool is_constant() const
Definition: literal.h:166
int dimacs() const
Definition: literal.h:117
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
resultt
Definition: prop.h:101
messaget log
Definition: prop.h:134
virtual ~satcheck_cadical_baset()
void lcnf(const bvt &bv) override
std::string solver_text() const override
satcheck_cadical_baset(int preprocessing_limit, int localsearch_limit, message_handlert &)
CaDiCaL::Solver * solver
tvt l_get(literalt a) const override
bool is_in_conflict(literalt a) const override
Returns true if an assumption is in the final conflict.
void set_assignment(literalt a, bool value) override
resultt do_prop_solve(const bvt &assumptions) override
Definition: threeval.h:20
std::vector< literalt > bvt
Definition: literal.h:201
void solver(std::vector< framet > &frames, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, const solver_optionst &solver_options, const namespacet &ns, std::vector< propertyt > &properties, std::size_t property_index)
Definition: solver.cpp:44
#define CHECK_RETURN(CONDITION)
Definition: invariant.h:495