CBMC
prop_conv_solver.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 "prop_conv_solver.h"
10 
11 #include <util/range.h>
12 
13 #include <algorithm>
14 #include <chrono>
15 
16 #include "literal_expr.h"
17 
19 {
21 }
22 
24 {
25  for(const auto &bit : bv)
26  if(!bit.is_constant())
27  set_frozen(bit);
28 }
29 
31 {
32  prop.set_frozen(a);
33 }
34 
36 {
37  freeze_all = true;
38 }
39 
41 {
42  // We can only improve Booleans.
43  if(expr.type().id() != ID_bool)
44  return expr;
45 
46  // We convert to a literal to obtain a 'small' handle
47  literalt l = convert(expr);
48 
49  // The literal may be a constant as a result of non-trivial
50  // propagation. We return constants as such.
51  if(l.is_true())
52  return true_exprt();
53  else if(l.is_false())
54  return false_exprt();
55 
56  // freeze to enable incremental use
57  set_frozen(l);
58 
59  return literal_exprt(l);
60 }
61 
63 {
64  auto result =
65  symbols.insert(std::pair<irep_idt, literalt>(identifier, literalt()));
66 
67  if(!result.second)
68  return result.first->second;
69 
70  literalt literal = prop.new_variable();
71  prop.set_variable_name(literal, identifier);
72 
73  // insert
74  result.first->second = literal;
75 
76  return literal;
77 }
78 
80 {
81  // trivial cases
82 
83  if(expr.is_true())
84  {
85  return true;
86  }
87  else if(expr.is_false())
88  {
89  return false;
90  }
91  else if(expr.id() == ID_symbol)
92  {
93  symbolst::const_iterator result =
95 
96  // This may fail if the symbol isn't Boolean or
97  // not in the formula.
98  if(result == symbols.end())
99  return {};
100 
101  return prop.l_get(result->second).is_true();
102  }
103  else if(expr.id() == ID_literal)
104  {
105  return prop.l_get(to_literal_expr(expr).get_literal()).is_true();
106  }
107 
108  // sub-expressions
109 
110  if(expr.id() == ID_not)
111  {
112  if(expr.type().id() == ID_bool)
113  {
114  auto tmp = get_bool(to_not_expr(expr).op());
115  if(tmp.has_value())
116  return !*tmp;
117  else
118  return {};
119  }
120  }
121  else if(expr.id() == ID_and || expr.id() == ID_or)
122  {
123  if(expr.type().id() == ID_bool && expr.operands().size() >= 1)
124  {
125  forall_operands(it, expr)
126  {
127  auto tmp = get_bool(*it);
128  if(!tmp.has_value())
129  return {};
130 
131  if(expr.id() == ID_and)
132  {
133  if(*tmp == false)
134  return false;
135  }
136  else // or
137  {
138  if(*tmp == true)
139  return true;
140  }
141  }
142 
143  return expr.id() == ID_and;
144  }
145  }
146 
147  // check cache
148 
149  cachet::const_iterator cache_result = cache.find(expr);
150  if(cache_result == cache.end())
151  return {}; // not in formula
152  else
153  return prop.l_get(cache_result->second).is_true();
154 }
155 
157 {
158  if(!use_cache || expr.id() == ID_symbol || expr.id() == ID_constant)
159  {
160  literalt literal = convert_bool(expr);
161  if(freeze_all && !literal.is_constant())
162  prop.set_frozen(literal);
163  return literal;
164  }
165 
166  // check cache first
167  auto result = cache.insert({expr, literalt()});
168 
169  // get a reference to the cache entry
170  auto &cache_entry = result.first->second;
171 
172  if(!result.second) // found in cache
173  return cache_entry;
174 
175  // The following may invalidate the iterator result.first,
176  // but note that the _reference_ is guaranteed to remain valid.
177  literalt literal = convert_bool(expr);
178 
179  // store the literal in the cache using the reference
180  cache_entry = literal;
181 
182  if(freeze_all && !literal.is_constant())
183  prop.set_frozen(literal);
184 
185 #if 0
186  std::cout << literal << "=" << expr << '\n';
187 #endif
188 
189  return literal;
190 }
191 
193 {
194  PRECONDITION(expr.type().id() == ID_bool);
195 
196  const exprt::operandst &op = expr.operands();
197 
198  if(expr.is_constant())
199  {
200  if(expr.is_true())
201  return const_literal(true);
202  else
203  {
204  INVARIANT(
205  expr.is_false(),
206  "constant expression of type bool should be either true or false");
207  return const_literal(false);
208  }
209  }
210  else if(expr.id() == ID_symbol)
211  {
212  return get_literal(to_symbol_expr(expr).get_identifier());
213  }
214  else if(expr.id() == ID_literal)
215  {
216  return to_literal_expr(expr).get_literal();
217  }
218  else if(expr.id() == ID_nondet_symbol)
219  {
220  return prop.new_variable();
221  }
222  else if(expr.id() == ID_implies)
223  {
224  const implies_exprt &implies_expr = to_implies_expr(expr);
225  return prop.limplies(
226  convert(implies_expr.op0()), convert(implies_expr.op1()));
227  }
228  else if(expr.id() == ID_if)
229  {
230  const if_exprt &if_expr = to_if_expr(expr);
231  return prop.lselect(
232  convert(if_expr.cond()),
233  convert(if_expr.true_case()),
234  convert(if_expr.false_case()));
235  }
236  else if(expr.id() == ID_constraint_select_one)
237  {
239  op.size() >= 2,
240  "constraint_select_one should have at least two operands");
241 
242  std::vector<literalt> op_bv;
243  op_bv.reserve(op.size());
244 
245  forall_operands(it, expr)
246  op_bv.push_back(convert(*it));
247 
248  // add constraints
249 
250  bvt b;
251  b.reserve(op_bv.size() - 1);
252 
253  for(unsigned i = 1; i < op_bv.size(); i++)
254  b.push_back(prop.lequal(op_bv[0], op_bv[i]));
255 
257 
258  return op_bv[0];
259  }
260  else if(
261  expr.id() == ID_or || expr.id() == ID_and || expr.id() == ID_xor ||
262  expr.id() == ID_nor || expr.id() == ID_nand)
263  {
264  INVARIANT(
265  !op.empty(),
266  "operator '" + expr.id_string() + "' takes at least one operand");
267 
268  bvt bv;
269 
270  for(const auto &operand : op)
271  bv.push_back(convert(operand));
272 
273  if(!bv.empty())
274  {
275  if(expr.id() == ID_or)
276  return prop.lor(bv);
277  else if(expr.id() == ID_nor)
278  return !prop.lor(bv);
279  else if(expr.id() == ID_and)
280  return prop.land(bv);
281  else if(expr.id() == ID_nand)
282  return !prop.land(bv);
283  else if(expr.id() == ID_xor)
284  return prop.lxor(bv);
285  }
286  }
287  else if(expr.id() == ID_not)
288  {
289  INVARIANT(op.size() == 1, "not takes one operand");
290  return !convert(op.front());
291  }
292  else if(expr.id() == ID_equal || expr.id() == ID_notequal)
293  {
294  INVARIANT(op.size() == 2, "equality takes two operands");
295  bool equal = (expr.id() == ID_equal);
296 
297  if(op[0].type().id() == ID_bool && op[1].type().id() == ID_bool)
298  {
299  literalt tmp1 = convert(op[0]), tmp2 = convert(op[1]);
300  return equal ? prop.lequal(tmp1, tmp2) : prop.lxor(tmp1, tmp2);
301  }
302  }
303  else if(expr.id() == ID_named_term)
304  {
305  const auto &named_term_expr = to_named_term_expr(expr);
306  literalt value_converted = convert(named_term_expr.value());
307  set_to_true(
308  equal_exprt(named_term_expr.symbol(), literal_exprt(value_converted)));
309  return value_converted;
310  }
311 
312  return convert_rest(expr);
313 }
314 
316 {
317  // fall through
318  ignoring(expr);
319  return prop.new_variable();
320 }
321 
323 {
325  return true;
326 
327  // optimization for constraint of the form
328  // new_variable = value
329 
330  if(expr.lhs().id() == ID_symbol)
331  {
332  const irep_idt &identifier = to_symbol_expr(expr.lhs()).get_identifier();
333 
334  literalt tmp = convert(expr.rhs());
335 
336  std::pair<symbolst::iterator, bool> result =
337  symbols.insert(std::pair<irep_idt, literalt>(identifier, tmp));
338 
339  if(result.second)
340  return false; // ok, inserted!
341 
342  // nah, already there
343  }
344 
345  return true;
346 }
347 
349 {
350  PRECONDITION(expr.type().id() == ID_bool);
351 
352  const bool has_only_boolean_operands = std::all_of(
353  expr.operands().begin(), expr.operands().end(), [](const exprt &expr) {
354  return expr.type().id() == ID_bool;
355  });
356 
357  if(has_only_boolean_operands)
358  {
359  if(expr.id() == ID_not)
360  {
361  add_constraints_to_prop(to_not_expr(expr).op(), !value);
362  return;
363  }
364  else
365  {
366  if(value)
367  {
368  // set_to_true
369 
370  if(expr.id() == ID_and)
371  {
372  forall_operands(it, expr)
373  add_constraints_to_prop(*it, true);
374 
375  return;
376  }
377  else if(expr.id() == ID_or)
378  {
379  // Special case for a CNF-clause,
380  // i.e., a constraint that's a disjunction.
381 
382  if(!expr.operands().empty())
383  {
384  bvt bv;
385  bv.reserve(expr.operands().size());
386 
387  forall_operands(it, expr)
388  bv.push_back(convert(*it));
389 
390  prop.lcnf(bv);
391  return;
392  }
393  }
394  else if(expr.id() == ID_implies)
395  {
396  const auto &implies_expr = to_implies_expr(expr);
397  literalt l_lhs = convert(implies_expr.lhs());
398  literalt l_rhs = convert(implies_expr.rhs());
399  prop.lcnf(!l_lhs, l_rhs);
400  return;
401  }
402  else if(expr.id() == ID_equal)
403  {
405  return;
406  }
407  }
408  else
409  {
410  // set_to_false
411  if(expr.id() == ID_implies) // !(a=>b) == (a && !b)
412  {
413  const implies_exprt &implies_expr = to_implies_expr(expr);
414 
415  add_constraints_to_prop(implies_expr.op0(), true);
416  add_constraints_to_prop(implies_expr.op1(), false);
417  return;
418  }
419  else if(expr.id() == ID_or) // !(a || b) == (!a && !b)
420  {
421  forall_operands(it, expr)
422  add_constraints_to_prop(*it, false);
423  return;
424  }
425  }
426  }
427  }
428 
429  // fall back to convert
430  prop.l_set_to(convert(expr), value);
431 }
432 
434 {
435  // fall through
436 
437  log.warning() << "warning: ignoring " << expr.pretty() << messaget::eom;
438 }
439 
441 {
442 }
443 
445 {
446  // post-processing isn't incremental yet
448  {
449  const auto post_process_start = std::chrono::steady_clock::now();
450 
451  log.statistics() << "Post-processing" << messaget::eom;
453  post_processing_done = true;
454 
455  const auto post_process_stop = std::chrono::steady_clock::now();
456  std::chrono::duration<double> post_process_runtime =
457  std::chrono::duration<double>(post_process_stop - post_process_start);
458  log.status() << "Runtime Post-process: " << post_process_runtime.count()
459  << "s" << messaget::eom;
460  }
461 
462  log.statistics() << "Solving with " << prop.solver_text() << messaget::eom;
463 
464  switch(prop.prop_solve())
465  {
467  return resultt::D_SATISFIABLE;
471  return resultt::D_ERROR;
472  }
473 
474  UNREACHABLE;
475 }
476 
478 {
479  if(expr.type().id() == ID_bool)
480  {
481  auto value = get_bool(expr);
482 
483  if(value.has_value())
484  {
485  if(*value)
486  return true_exprt();
487  else
488  return false_exprt();
489  }
490  }
491 
492  exprt tmp = expr;
493  for(auto &op : tmp.operands())
494  {
495  exprt tmp_op = get(op);
496  op.swap(tmp_op);
497  }
498  return tmp;
499 }
500 
501 void prop_conv_solvert::print_assignment(std::ostream &out) const
502 {
503  for(const auto &symbol : symbols)
504  out << symbol.first << " = " << prop.l_get(symbol.second) << '\n';
505 }
506 
508 {
510 }
511 
512 const char *prop_conv_solvert::context_prefix = "prop_conv::context$";
513 
514 void prop_conv_solvert::set_to(const exprt &expr, bool value)
515 {
516  if(assumption_stack.empty())
517  {
518  // We are in the root context.
519  add_constraints_to_prop(expr, value);
520  }
521  else
522  {
523  // We have a child context. We add context_literal ==> expr to the formula.
525  or_exprt(literal_exprt(!assumption_stack.back()), expr), value);
526  }
527 }
528 
529 void prop_conv_solvert::push(const std::vector<exprt> &assumptions)
530 {
531  // We push the given assumptions as a single context onto the stack.
532  assumption_stack.reserve(assumption_stack.size() + assumptions.size());
533  for(const auto &assumption : assumptions)
534  assumption_stack.push_back(to_literal_expr(assumption).get_literal());
535  context_size_stack.push_back(assumptions.size());
536 
538 }
539 
541 {
542  // We create a new context literal.
543  literalt context_literal = convert(symbol_exprt(
545 
546  assumption_stack.push_back(context_literal);
547  context_size_stack.push_back(1);
548 
550 }
551 
553 {
554  // We remove the context from the stack.
555  assumption_stack.resize(assumption_stack.size() - context_size_stack.back());
556  context_size_stack.pop_back();
557 
559 }
560 
561 // This method out-of-line because gcc-5.5.0-12ubuntu1 20171010 miscompiles it
562 // when inline (in certain build configurations, notably -O2 -g0) by producing
563 // a non-virtual thunk with c++03 ABI but a function body with c++11 ABI, the
564 // mismatch leading to a missing vtable entry and consequent null-pointer deref
565 // whenever this function is called.
567 {
568  return "propositional reduction";
569 }
UNREACHABLE
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:503
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
prop_conv_solvert::equality_propagation
bool equality_propagation
Definition: prop_conv_solver.h:75
prop_conv_solvert::assumption_stack
bvt assumption_stack
Assumptions on the stack.
Definition: prop_conv_solver.h:137
literal_exprt::get_literal
literalt get_literal() const
Definition: literal_expr.h:26
propt::set_assumptions
virtual void set_assumptions(const bvt &)
Definition: prop.h:86
binary_exprt::rhs
exprt & rhs()
Definition: std_expr.h:623
propt::solver_text
virtual const std::string solver_text()=0
prop_conv_solvert::context_size_stack
std::vector< size_t > context_size_stack
assumption_stack is segmented in contexts; Number of assumptions in each context on the stack
Definition: prop_conv_solver.h:144
bvt
std::vector< literalt > bvt
Definition: literal.h:201
irept::pretty
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
Definition: irep.cpp:495
messaget::status
mstreamt & status() const
Definition: message.h:414
to_if_expr
const if_exprt & to_if_expr(const exprt &expr)
Cast an exprt to an if_exprt.
Definition: std_expr.h:2403
propt::resultt::P_UNSATISFIABLE
@ P_UNSATISFIABLE
if_exprt
The trinary if-then-else operator.
Definition: std_expr.h:2322
decision_proceduret::resultt::D_UNSATISFIABLE
@ D_UNSATISFIABLE
prop_conv_solvert::symbols
symbolst symbols
Definition: prop_conv_solver.h:121
prop_conv_solvert::freeze_all
bool freeze_all
Definition: prop_conv_solver.h:76
propt::new_variable
virtual literalt new_variable()=0
prop_conv_solvert::context_literal_counter
std::size_t context_literal_counter
To generate unique literal names for contexts.
Definition: prop_conv_solver.h:140
exprt
Base class for all expressions.
Definition: expr.h:55
binary_exprt::lhs
exprt & lhs()
Definition: std_expr.h:613
decision_proceduret::set_to_true
void set_to_true(const exprt &expr)
For a Boolean expression expr, add the constraint 'expr'.
Definition: decision_procedure.cpp:23
prop_conv_solvert::finish_eager_conversion
virtual void finish_eager_conversion()
Definition: prop_conv_solver.cpp:440
propt::lor
virtual literalt lor(literalt a, literalt b)=0
propt::l_set_to_true
void l_set_to_true(literalt a)
Definition: prop.h:50
propt::l_set_to
virtual void l_set_to(literalt a, bool value)
Definition: prop.h:45
bool_typet
The Boolean type.
Definition: std_types.h:35
to_string
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
Definition: string_constraint.cpp:58
messaget::eom
static eomt eom
Definition: message.h:297
exprt::is_true
bool is_true() const
Return whether the expression is a constant representing true.
Definition: expr.cpp:34
prop_conv_solvert::convert_bool
virtual literalt convert_bool(const exprt &expr)
Definition: prop_conv_solver.cpp:192
symbol_exprt
Expression to hold a symbol (variable)
Definition: std_expr.h:112
propt::land
virtual literalt land(literalt a, literalt b)=0
equal_exprt
Equality.
Definition: std_expr.h:1305
if_exprt::false_case
exprt & false_case()
Definition: std_expr.h:2360
exprt::is_false
bool is_false() const
Return whether the expression is a constant representing false.
Definition: expr.cpp:43
to_literal_expr
const literal_exprt & to_literal_expr(const exprt &expr)
Cast a generic exprt to a literal_exprt.
Definition: literal_expr.h:56
prop_conv_solvert::ignoring
virtual void ignoring(const exprt &expr)
Definition: prop_conv_solver.cpp:433
decision_proceduret::resultt::D_SATISFIABLE
@ D_SATISFIABLE
prop_conv_solvert::handle
exprt handle(const exprt &expr) override
Generate a handle, which is an expression that has the same value as the argument in any model that i...
Definition: prop_conv_solver.cpp:40
prop_conv_solvert::cache
cachet cache
Definition: prop_conv_solver.h:126
prop_conv_solver.h
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
literalt::is_true
bool is_true() const
Definition: literal.h:156
prop_conv_solvert::set_frozen
void set_frozen(literalt)
Definition: prop_conv_solver.cpp:30
propt::lxor
virtual literalt lxor(literalt a, literalt b)=0
propt::prop_solve
resultt prop_solve()
Definition: prop.cpp:29
prop_conv_solvert::post_processing_done
bool post_processing_done
Definition: prop_conv_solver.h:108
or_exprt
Boolean OR.
Definition: std_expr.h:2178
DATA_INVARIANT
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition: invariant.h:510
propt::limplies
virtual literalt limplies(literalt a, literalt b)=0
prop_conv_solvert::context_prefix
static const char * context_prefix
Definition: prop_conv_solver.h:134
get_identifier
static optionalt< smt_termt > get_identifier(const exprt &expr, const std::unordered_map< exprt, smt_identifier_termt, irep_hash > &expression_handle_identifiers, const std::unordered_map< exprt, smt_identifier_termt, irep_hash > &expression_identifiers)
Definition: smt2_incremental_decision_procedure.cpp:328
forall_operands
#define forall_operands(it, expr)
Definition: expr.h:20
propt::resultt::P_ERROR
@ P_ERROR
propt::resultt::P_SATISFIABLE
@ P_SATISFIABLE
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
symbol_exprt::get_identifier
const irep_idt & get_identifier() const
Definition: std_expr.h:142
literal_exprt
Definition: literal_expr.h:17
literalt::is_false
bool is_false() const
Definition: literal.h:161
irept::id_string
const std::string & id_string() const
Definition: irep.h:399
prop_conv_solvert::get
exprt get(const exprt &expr) const override
Return expr with variables replaced by values from satisfying assignment if available.
Definition: prop_conv_solver.cpp:477
const_literal
literalt const_literal(bool value)
Definition: literal.h:188
to_symbol_expr
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:222
decision_proceduret::resultt::D_ERROR
@ D_ERROR
prop_conv_solvert::set_all_frozen
void set_all_frozen()
Definition: prop_conv_solver.cpp:35
irept::id
const irep_idt & id() const
Definition: irep.h:396
propt::set_frozen
virtual void set_frozen(literalt)
Definition: prop.h:112
range.h
exprt::operandst
std::vector< exprt > operandst
Definition: expr.h:58
false_exprt
The Boolean constant false.
Definition: std_expr.h:3016
propt::get_number_of_solver_calls
std::size_t get_number_of_solver_calls() const
Definition: prop.cpp:35
prop_conv_solvert::get_literal
virtual literalt get_literal(const irep_idt &symbol)
Definition: prop_conv_solver.cpp:62
optionalt
nonstd::optional< T > optionalt
Definition: optional.h:35
propt::is_in_conflict
virtual bool is_in_conflict(literalt l) const =0
Returns true if an assumption is in the final conflict.
prop_conv_solvert::convert
literalt convert(const exprt &expr) override
Convert a Boolean expression and return the corresponding literal.
Definition: prop_conv_solver.cpp:156
decision_proceduret::resultt
resultt
Result of running the decision procedure.
Definition: decision_procedure.h:43
prop_conv_solvert::convert_rest
virtual literalt convert_rest(const exprt &expr)
Definition: prop_conv_solver.cpp:315
prop_conv_solvert::use_cache
bool use_cache
Definition: prop_conv_solver.h:74
propt::set_variable_name
virtual void set_variable_name(literalt, const irep_idt &)
Definition: prop.h:91
prop_conv_solvert::add_constraints_to_prop
void add_constraints_to_prop(const exprt &expr, bool value)
Helper method used by set_to for adding the constraints to prop.
Definition: prop_conv_solver.cpp:348
propt::lequal
virtual literalt lequal(literalt a, literalt b)=0
prop_conv_solvert::is_in_conflict
bool is_in_conflict(const exprt &expr) const override
Returns true if an expression is in the final conflict leading to UNSAT.
Definition: prop_conv_solver.cpp:18
if_exprt::true_case
exprt & true_case()
Definition: std_expr.h:2350
propt::l_get
virtual tvt l_get(literalt a) const =0
to_not_expr
const not_exprt & to_not_expr(const exprt &expr)
Cast an exprt to an not_exprt.
Definition: std_expr.h:2303
prop_conv_solvert::decision_procedure_text
std::string decision_procedure_text() const override
Return a textual description of the decision procedure.
Definition: prop_conv_solver.cpp:566
to_implies_expr
const implies_exprt & to_implies_expr(const exprt &expr)
Cast an exprt to a implies_exprt.
Definition: std_expr.h:2159
prop_conv_solvert::dec_solve
decision_proceduret::resultt dec_solve() override
Run the decision procedure to solve the problem.
Definition: prop_conv_solver.cpp:444
exprt::is_constant
bool is_constant() const
Return whether the expression is a constant.
Definition: expr.cpp:27
if_exprt::cond
exprt & cond()
Definition: std_expr.h:2340
literalt
Definition: literal.h:25
to_equal_expr
const equal_exprt & to_equal_expr(const exprt &expr)
Cast an exprt to an equal_exprt.
Definition: std_expr.h:1347
prop_conv_solvert::print_assignment
void print_assignment(std::ostream &out) const override
Print satisfying assignment to out.
Definition: prop_conv_solver.cpp:501
implies_exprt
Boolean implication.
Definition: std_expr.h:2133
prop_conv_solvert::log
messaget log
Definition: prop_conv_solver.h:132
exprt::operands
operandst & operands()
Definition: expr.h:94
literalt::is_constant
bool is_constant() const
Definition: literal.h:166
to_named_term_expr
const named_term_exprt & to_named_term_expr(const exprt &expr)
Cast an exprt to a named_term_exprt.
Definition: std_expr.h:3602
true_exprt
The Boolean constant true.
Definition: std_expr.h:3007
messaget::warning
mstreamt & warning() const
Definition: message.h:404
prop_conv_solvert::push
void push() override
Push a new context on the stack This context becomes a child context nested in the current context.
Definition: prop_conv_solver.cpp:540
binary_exprt::op1
exprt & op1()
Definition: expr.h:128
prop_conv_solvert::pop
void pop() override
Pop whatever is on top of the stack.
Definition: prop_conv_solver.cpp:552
prop_conv_solvert::get_bool
virtual optionalt< bool > get_bool(const exprt &expr) const
Get a boolean value from the model if the formula is satisfiable.
Definition: prop_conv_solver.cpp:79
propt::lselect
virtual literalt lselect(literalt a, literalt b, literalt c)=0
propt::lcnf
void lcnf(literalt l0, literalt l1)
Definition: prop.h:56
literal_expr.h
prop_conv_solvert::set_to
void set_to(const exprt &expr, bool value) override
For a Boolean expression expr, add the constraint 'current_context => expr' if value is true,...
Definition: prop_conv_solver.cpp:514
binary_exprt::op0
exprt & op0()
Definition: expr.h:125
validation_modet::INVARIANT
@ INVARIANT
prop_conv_solvert::prop
propt & prop
Definition: prop_conv_solver.h:130
tvt::is_true
bool is_true() const
Definition: threeval.h:25
messaget::statistics
mstreamt & statistics() const
Definition: message.h:419
prop_conv_solvert::set_equality_to_true
virtual bool set_equality_to_true(const equal_exprt &expr)
Definition: prop_conv_solver.cpp:322
prop_conv_solvert::get_number_of_solver_calls
std::size_t get_number_of_solver_calls() const override
Return the number of incremental solver calls.
Definition: prop_conv_solver.cpp:507