CBMC
smt2_incremental_decision_procedure.cpp
Go to the documentation of this file.
1 // Author: Diffblue Ltd.
2 
4 
5 #include <util/arith_tools.h>
6 #include <util/expr.h>
7 #include <util/namespace.h>
8 #include <util/nodiscard.h>
9 #include <util/range.h>
10 #include <util/std_expr.h>
11 #include <util/string_utils.h>
12 #include <util/symbol.h>
13 
23 
24 #include <stack>
25 
29  smt_base_solver_processt &solver_process,
30  const smt_commandt &command,
31  const std::unordered_map<irep_idt, smt_identifier_termt> &identifier_table)
32 {
33  solver_process.send(command);
34  auto response = solver_process.receive_response(identifier_table);
35  if(response.cast<smt_success_responset>())
36  return solver_process.receive_response(identifier_table);
37  else
38  return response;
39 }
40 
43 {
44  if(const auto error = response.cast<smt_error_responset>())
45  {
46  return "SMT solver returned an error message - " +
47  id2string(error->message());
48  }
49  if(response.cast<smt_unsupported_responset>())
50  {
51  return {"SMT solver does not support given command."};
52  }
53  return {};
54 }
55 
68 static std::vector<exprt> gather_dependent_expressions(const exprt &expr)
69 {
70  std::vector<exprt> dependent_expressions;
71  expr.visit_pre([&](const exprt &expr_node) {
72  if(
73  can_cast_expr<symbol_exprt>(expr_node) ||
74  can_cast_expr<array_exprt>(expr_node) ||
75  can_cast_expr<array_of_exprt>(expr_node) ||
77  {
78  dependent_expressions.push_back(expr_node);
79  }
80  });
81  return dependent_expressions;
82 }
83 
85  const array_exprt &array,
86  const smt_identifier_termt &array_identifier)
87 {
88  identifier_table.emplace(array_identifier.identifier(), array_identifier);
89  const std::vector<exprt> &elements = array.operands();
90  const typet &index_type = array.type().index_type();
91  for(std::size_t i = 0; i < elements.size(); ++i)
92  {
94  const smt_assert_commandt element_definition{smt_core_theoryt::equal(
95  smt_array_theoryt::select(array_identifier, index),
96  convert_expr_to_smt(elements.at(i)))};
97  solver_process->send(element_definition);
98  }
99 }
100 
102  const array_of_exprt &array,
103  const smt_identifier_termt &array_identifier)
104 {
105  const smt_sortt index_type =
107  const smt_identifier_termt array_index_identifier{
108  id2string(array_identifier.identifier()) + "_index", index_type};
109  const smt_termt element_value = convert_expr_to_smt(array.what());
110 
111  const smt_assert_commandt elements_definition{smt_forall_termt{
112  {array_index_identifier},
114  smt_array_theoryt::select(array_identifier, array_index_identifier),
115  element_value)}};
116  solver_process->send(elements_definition);
117 }
118 
119 template <typename t_exprt>
121  const t_exprt &array)
122 {
123  const smt_sortt array_sort = convert_type_to_smt_sort(array.type());
124  INVARIANT(
125  array_sort.cast<smt_array_sortt>(),
126  "Converting array typed expression to SMT should result in a term of array "
127  "sort.");
128  const smt_identifier_termt array_identifier{
129  "array_" + std::to_string(array_sequence()), array_sort};
130  solver_process->send(smt_declare_function_commandt{array_identifier, {}});
131  initialize_array_elements(array, array_identifier);
132  expression_identifiers.emplace(array, array_identifier);
133 }
134 
136  const exprt &expr,
137  const irep_idt &symbol_identifier,
138  const std::unique_ptr<smt_base_solver_processt> &solver_process,
139  std::unordered_map<exprt, smt_identifier_termt, irep_hash>
140  &expression_identifiers,
141  std::unordered_map<irep_idt, smt_identifier_termt> &identifier_table)
142 {
143  const smt_declare_function_commandt function{
145  symbol_identifier, convert_type_to_smt_sort(expr.type())),
146  {}};
147  expression_identifiers.emplace(expr, function.identifier());
148  identifier_table.emplace(symbol_identifier, function.identifier());
149  solver_process->send(function);
150 }
151 
155  const exprt &expr)
156 {
157  std::unordered_set<exprt, irep_hash> seen_expressions =
159  .map([](const std::pair<exprt, smt_identifier_termt> &expr_identifier) {
160  return expr_identifier.first;
161  });
162  std::stack<exprt> to_be_defined;
163  const auto push_dependencies_needed = [&](const exprt &expr) {
164  bool result = false;
165  for(const auto &dependency : gather_dependent_expressions(expr))
166  {
167  if(!seen_expressions.insert(dependency).second)
168  continue;
169  result = true;
170  to_be_defined.push(dependency);
171  }
172  return result;
173  };
174  push_dependencies_needed(expr);
175  while(!to_be_defined.empty())
176  {
177  const exprt current = to_be_defined.top();
178  if(push_dependencies_needed(current))
179  continue;
180  if(const auto symbol_expr = expr_try_dynamic_cast<symbol_exprt>(current))
181  {
182  const irep_idt &identifier = symbol_expr->get_identifier();
183  const symbolt *symbol = nullptr;
184  if(ns.lookup(identifier, symbol) || symbol->value.is_nil())
185  {
187  *symbol_expr,
188  symbol_expr->get_identifier(),
192  }
193  else
194  {
195  if(push_dependencies_needed(symbol->value))
196  continue;
197  const smt_define_function_commandt function{
198  symbol->name, {}, convert_expr_to_smt(symbol->value)};
199  expression_identifiers.emplace(*symbol_expr, function.identifier());
200  identifier_table.emplace(identifier, function.identifier());
201  solver_process->send(function);
202  }
203  }
204  else if(const auto array_expr = expr_try_dynamic_cast<array_exprt>(current))
205  define_array_function(*array_expr);
206  else if(
207  const auto array_of_expr = expr_try_dynamic_cast<array_of_exprt>(current))
208  {
209  define_array_function(*array_of_expr);
210  }
211  else if(
212  const auto nondet_symbol =
213  expr_try_dynamic_cast<nondet_symbol_exprt>(current))
214  {
216  *nondet_symbol,
217  nondet_symbol->get_identifier(),
221  }
222  to_be_defined.pop();
223  }
224 }
225 
229  exprt expr,
230  const std::unordered_map<exprt, smt_identifier_termt, irep_hash>
231  &expression_identifiers)
232 {
233  expr.visit_pre([&](exprt &node) -> void {
234  auto find_result = expression_identifiers.find(node);
235  if(find_result == expression_identifiers.cend())
236  return;
237  const auto type = find_result->first.type();
238  node = symbol_exprt{find_result->second.identifier(), type};
239  });
240  return expr;
241 }
242 
244  const namespacet &_ns,
245  std::unique_ptr<smt_base_solver_processt> _solver_process,
246  message_handlert &message_handler)
247  : ns{_ns},
248  number_of_solver_calls{0},
249  solver_process(std::move(_solver_process)),
250  log{message_handler},
251  object_map{initial_smt_object_map()}
252 {
253  solver_process->send(
255  solver_process->send(smt_set_logic_commandt{smt_logic_allt{}});
256  solver_process->send(object_size_function.declaration);
257 }
258 
260  const exprt &expr)
261 {
262  if(
263  expression_handle_identifiers.find(expr) !=
265  {
266  return;
267  }
268 
272  expression_handle_identifiers.emplace(expr, function.identifier());
273  identifier_table.emplace(
274  function.identifier().identifier(), function.identifier());
275  solver_process->send(function);
276 }
277 
279  const exprt &expr)
280 {
281  expr.visit_pre([&](const exprt &expr_node) {
282  if(!can_cast_type<array_typet>(expr_node.type()))
283  return;
284  if(const auto with_expr = expr_try_dynamic_cast<with_exprt>(expr_node))
285  {
286  const auto index_expr = with_expr->where();
287  const auto index_term = convert_expr_to_smt(index_expr);
288  const auto index_identifier = "index_" + std::to_string(index_sequence());
289  const auto index_definition =
290  smt_define_function_commandt{index_identifier, {}, index_term};
291  expression_identifiers.emplace(index_expr, index_definition.identifier());
292  identifier_table.emplace(index_identifier, index_definition.identifier());
293  solver_process->send(
294  smt_define_function_commandt{index_identifier, {}, index_term});
295  }
296  });
297 }
298 
299 smt_termt
301 {
303  const exprt substituted =
305  track_expression_objects(substituted, ns, object_map);
307  substituted,
308  ns,
310  object_map,
313  substituted,
314  object_map,
317 }
318 
320 {
322  debug << "`handle` -\n " << expr.pretty(2, 0) << messaget::eom;
323  });
325  return expr;
326 }
327 
329  const exprt &expr,
330  const std::unordered_map<exprt, smt_identifier_termt, irep_hash>
331  &expression_handle_identifiers,
332  const std::unordered_map<exprt, smt_identifier_termt, irep_hash>
333  &expression_identifiers)
334 {
335  const auto handle_find_result = expression_handle_identifiers.find(expr);
336  if(handle_find_result != expression_handle_identifiers.cend())
337  return handle_find_result->second;
338  const auto expr_find_result = expression_identifiers.find(expr);
339  if(expr_find_result != expression_identifiers.cend())
340  return expr_find_result->second;
341  return {};
342 }
343 
345  const smt_termt &array,
346  const array_typet &type) const
347 {
348  INVARIANT(
349  type.is_complete(), "Array size is required for getting array values.");
350  const auto size = numeric_cast<std::size_t>(get(type.size()));
351  INVARIANT(
352  size,
353  "Size of array must be convertible to std::size_t for getting array value");
354  std::vector<exprt> elements;
355  const auto index_type = type.index_type();
356  elements.reserve(*size);
357  for(std::size_t index = 0; index < size; ++index)
358  {
359  elements.push_back(get_expr(
361  array,
363  from_integer(index, index_type),
364  object_map,
367  type.element_type()));
368  }
369  return array_exprt{elements, type};
370 }
371 
373  const smt_termt &descriptor,
374  const typet &type) const
375 {
376  const smt_get_value_commandt get_value_command{descriptor};
377  const smt_responset response = get_response_to_command(
378  *solver_process, get_value_command, identifier_table);
379  const auto get_value_response = response.cast<smt_get_value_responset>();
380  if(!get_value_response)
381  {
382  throw analysis_exceptiont{
383  "Expected get-value response from solver, but received - " +
384  response.pretty()};
385  }
386  if(get_value_response->pairs().size() > 1)
387  {
388  throw analysis_exceptiont{
389  "Expected single valuation pair in get-value response from solver, but "
390  "received multiple pairs - " +
391  response.pretty()};
392  }
394  get_value_response->pairs()[0].get().value(), type);
395 }
396 
398 {
400  debug << "`get` - \n " + expr.pretty(2, 0) << messaget::eom;
401  });
402  auto descriptor = [&]() -> optionalt<smt_termt> {
403  if(const auto index_expr = expr_try_dynamic_cast<index_exprt>(expr))
404  {
405  const auto array = get_identifier(
406  index_expr->array(),
409  const auto index = get_identifier(
410  index_expr->index(),
413  if(!array || !index)
414  return {};
415  return smt_array_theoryt::select(*array, *index);
416  }
417  return get_identifier(
419  }();
420  if(!descriptor)
421  {
422  if(gather_dependent_expressions(expr).empty())
423  {
424  INVARIANT(
426  "Objects in expressions being read should already be tracked from "
427  "point of being set/handled.");
428  descriptor = ::convert_expr_to_smt(
429  expr,
430  object_map,
433  }
434  else
435  {
436  const auto symbol_expr = expr_try_dynamic_cast<symbol_exprt>(expr);
437  INVARIANT(
438  symbol_expr, "Unhandled expressions are expected to be symbols");
439  // Note this case is currently expected to be encountered during trace
440  // generation for -
441  // * Steps which were removed via --slice-formula.
442  // * Getting concurrency clock values.
443  // The below implementation which returns the given expression was chosen
444  // based on the implementation of `smt2_convt::get` in the non-incremental
445  // smt2 decision procedure.
446  log.warning()
447  << "`get` attempted for unknown symbol, with identifier - \n"
448  << symbol_expr->get_identifier() << messaget::eom;
449  return expr;
450  }
451  }
452  if(const auto array_type = type_try_dynamic_cast<array_typet>(expr.type()))
453  {
454  if(array_type->is_incomplete())
455  return expr;
456  return get_expr(*descriptor, *array_type);
457  }
458  return get_expr(*descriptor, expr.type());
459 }
460 
462  std::ostream &out) const
463 {
464  UNIMPLEMENTED_FEATURE("printing of assignments.");
465 }
466 
467 std::string
469 {
470  return "incremental SMT2 solving via " + solver_process->description();
471 }
472 
473 std::size_t
475 {
476  return number_of_solver_calls;
477 }
478 
480 {
483  debug << "`set_to` (" << std::string{value ? "true" : "false"} << ") -\n "
484  << expr.pretty(2, 0) << messaget::eom;
485  });
486 
487  define_dependent_functions(expr);
488  auto converted_term = [&]() -> smt_termt {
489  const auto expression_handle_identifier =
490  expression_handle_identifiers.find(expr);
491  if(expression_handle_identifier != expression_handle_identifiers.cend())
492  return expression_handle_identifier->second;
493  else
494  return convert_expr_to_smt(expr);
495  }();
496  if(!value)
497  converted_term = smt_core_theoryt::make_not(converted_term);
498  solver_process->send(smt_assert_commandt{converted_term});
499 }
500 
502  const std::vector<exprt> &assumptions)
503 {
504  for(const auto &assumption : assumptions)
505  {
507  "pushing of assumption:\n " + assumption.pretty(2, 0));
508  }
509  UNIMPLEMENTED_FEATURE("`push` of empty assumptions.");
510 }
511 
513 {
514  UNIMPLEMENTED_FEATURE("`push`.");
515 }
516 
518 {
519  UNIMPLEMENTED_FEATURE("`pop`.");
520 }
521 
522 NODISCARD
524  const smt_check_sat_response_kindt &response_kind)
525 {
526  if(response_kind.cast<smt_sat_responset>())
528  if(response_kind.cast<smt_unsat_responset>())
530  if(response_kind.cast<smt_unknown_responset>())
532  UNREACHABLE;
533 }
534 
536 {
537  object_size_defined.resize(object_map.size());
538  for(const auto &key_value : object_map)
539  {
540  const decision_procedure_objectt &object = key_value.second;
541  if(object_size_defined[object.unique_id])
542  continue;
543  else
544  object_size_defined[object.unique_id] = true;
545  define_dependent_functions(object.size);
547  object.unique_id, convert_expr_to_smt(object.size)));
548  }
549 }
550 
552 {
555  const smt_responset result = get_response_to_command(
557  if(const auto check_sat_response = result.cast<smt_check_sat_responset>())
558  {
559  if(check_sat_response->kind().cast<smt_unknown_responset>())
560  log.error() << "SMT2 solver returned \"unknown\"" << messaget::eom;
561  return lookup_decision_procedure_result(check_sat_response->kind());
562  }
563  if(const auto problem = get_problem_messages(result))
564  throw analysis_exceptiont{*problem};
565  throw analysis_exceptiont{"Unexpected kind of response from SMT solver."};
566 }
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
smt2_incremental_decision_proceduret::define_dependent_functions
void define_dependent_functions(const exprt &expr)
Defines any functions which expr depends on, which have not yet been defined, along with their depend...
Definition: smt2_incremental_decision_procedure.cpp:154
smt_option_produce_modelst
Definition: smt_options.h:64
can_cast_expr< symbol_exprt >
bool can_cast_expr< symbol_exprt >(const exprt &base)
Definition: std_expr.h:206
smt_object_sizet::make_application
make_applicationt make_application
Definition: smt_object_size.h:23
smt2_incremental_decision_proceduret::identifier_table
std::unordered_map< irep_idt, smt_identifier_termt > identifier_table
This maps from the unsorted/untyped string/symbol for the identifiers which we have declared in SMT s...
Definition: smt2_incremental_decision_procedure.h:148
smt_error_responset
Definition: smt_responses.h:129
smt_set_logic_commandt
Definition: smt_commands.h:116
smt2_incremental_decision_proceduret::define_index_identifiers
void define_index_identifiers(const exprt &expr)
Definition: smt2_incremental_decision_procedure.cpp:278
send_function_definition
void send_function_definition(const exprt &expr, const irep_idt &symbol_identifier, const std::unique_ptr< smt_base_solver_processt > &solver_process, std::unordered_map< exprt, smt_identifier_termt, irep_hash > &expression_identifiers, std::unordered_map< irep_idt, smt_identifier_termt > &identifier_table)
Definition: smt2_incremental_decision_procedure.cpp:135
NODISCARD
#define NODISCARD
Definition: nodiscard.h:22
smt_identifier_termt
Stores identifiers in unescaped and unquoted form.
Definition: smt_terms.h:91
arith_tools.h
track_expression_objects
void track_expression_objects(const exprt &expression, const namespacet &ns, smt_object_mapt &object_map)
Finds all the object expressions in the given expression and adds them to the object map for cases wh...
Definition: object_tracking.cpp:80
type_size_mapping.h
UNIMPLEMENTED_FEATURE
#define UNIMPLEMENTED_FEATURE(FEATURE)
Definition: invariant.h:517
array_of_exprt::what
exprt & what()
Definition: std_expr.h:1515
array_typet::is_complete
bool is_complete() const
Definition: std_types.h:812
smt_sat_responset
Definition: smt_responses.h:68
string_utils.h
typet
The type of an expression, extends irept.
Definition: type.h:28
irept::pretty
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
Definition: irep.cpp:495
decision_procedure_objectt
Information the decision procedure holds about each object.
Definition: object_tracking.h:40
irept::find
const irept & find(const irep_idt &name) const
Definition: irep.cpp:106
convert_expr_to_smt
static smt_termt convert_expr_to_smt(const symbol_exprt &symbol_expr)
Definition: convert_expr_to_smt.cpp:117
smt_unsupported_responset
Definition: smt_responses.h:123
smt2_incremental_decision_proceduret::push
void push() override
Push a new context on the stack This context becomes a child context nested in the current context.
Definition: smt2_incremental_decision_procedure.cpp:512
decision_proceduret::resultt::D_UNSATISFIABLE
@ D_UNSATISFIABLE
smt_termt
Definition: smt_terms.h:20
smt_solver_process.h
get_response_to_command
static smt_responset get_response_to_command(smt_base_solver_processt &solver_process, const smt_commandt &command, const std::unordered_map< irep_idt, smt_identifier_termt > &identifier_table)
Issues a command to the solving process which is expected to optionally return a success status follo...
Definition: smt2_incremental_decision_procedure.cpp:28
smt_core_theory.h
nodiscard.h
smt_set_option_commandt
Definition: smt_commands.h:125
smt2_incremental_decision_proceduret::decision_procedure_text
std::string decision_procedure_text() const override
Return a textual description of the decision procedure.
Definition: smt2_incremental_decision_procedure.cpp:468
exprt
Base class for all expressions.
Definition: expr.h:55
smt_array_theoryt::select
static const smt_function_application_termt::factoryt< selectt > select
Definition: smt_array_theory.h:20
smt_core_theoryt::make_not
static const smt_function_application_termt::factoryt< nott > make_not
Definition: smt_core_theory.h:17
smt_sortt::cast
const sub_classt * cast() const &
array_of_exprt::type
const array_typet & type() const
Definition: std_expr.h:1505
smt_define_function_commandt
Definition: smt_commands.h:64
smt2_incremental_decision_proceduret::dec_solve
resultt dec_solve() override
Run the decision procedure to solve the problem.
Definition: smt2_incremental_decision_procedure.cpp:551
smt_base_solver_processt
Definition: smt_solver_process.h:15
smt2_incremental_decision_proceduret::get_number_of_solver_calls
std::size_t get_number_of_solver_calls() const override
Return the number of incremental solver calls.
Definition: smt2_incremental_decision_procedure.cpp:474
smt_check_sat_response_kindt
Definition: smt_responses.h:34
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
smt_responses.h
symbol_exprt
Expression to hold a symbol (variable)
Definition: std_expr.h:112
can_cast_expr< array_exprt >
bool can_cast_expr< array_exprt >(const exprt &base)
Definition: std_expr.h:1592
namespace.h
smt_get_value_responset
Definition: smt_responses.h:95
index_type
bitvector_typet index_type()
Definition: c_types.cpp:22
lookup_decision_procedure_result
static decision_proceduret::resultt lookup_decision_procedure_result(const smt_check_sat_response_kindt &response_kind)
Definition: smt2_incremental_decision_procedure.cpp:523
smt2_incremental_decision_proceduret::object_map
smt_object_mapt object_map
This map is used to track object related state.
Definition: smt2_incremental_decision_procedure.h:151
expr.h
smt2_incremental_decision_proceduret::print_assignment
void print_assignment(std::ostream &out) const override
Print satisfying assignment to out.
Definition: smt2_incremental_decision_procedure.cpp:461
decision_proceduret::resultt::D_SATISFIABLE
@ D_SATISFIABLE
array_typet::size
const exprt & size() const
Definition: std_types.h:800
namespacet
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:90
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
namespacet::lookup
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Definition: namespace.cpp:138
array_exprt::type
const array_typet & type() const
Definition: std_expr.h:1570
smt2_incremental_decision_proceduret::get_expr
exprt get_expr(const smt_termt &descriptor, const typet &type) const
Gets the value of descriptor from the solver and returns the solver response expressed as an exprt of...
Definition: smt2_incremental_decision_procedure.cpp:372
construct_value_expr_from_smt.h
messaget::error
mstreamt & error() const
Definition: message.h:399
smt_declare_function_commandt
Definition: smt_commands.h:46
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:47
smt_check_sat_commandt
Definition: smt_commands.h:40
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
smt_responset
Definition: smt_responses.h:9
smt2_incremental_decision_proceduret::handle_sequence
class smt2_incremental_decision_proceduret::sequencet handle_sequence
get_problem_messages
static optionalt< std::string > get_problem_messages(const smt_responset &response)
Definition: smt2_incremental_decision_procedure.cpp:42
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
can_cast_expr< array_of_exprt >
bool can_cast_expr< array_of_exprt >(const exprt &base)
Definition: std_expr.h:1527
smt_sortt
Definition: smt_sorts.h:17
smt2_incremental_decision_proceduret::pointer_sizes_map
type_size_mapt pointer_sizes_map
Precalculated type sizes used for pointer arithmetic.
Definition: smt2_incremental_decision_procedure.h:163
array_of_exprt
Array constructor from single element.
Definition: std_expr.h:1497
can_cast_type< array_typet >
bool can_cast_type< array_typet >(const typet &type)
Check whether a reference to a typet is a array_typet.
Definition: std_types.h:831
smt2_incremental_decision_proceduret::number_of_solver_calls
size_t number_of_solver_calls
The number of times dec_solve() has been called.
Definition: smt2_incremental_decision_procedure.h:104
construct_value_expr_from_smt
exprt construct_value_expr_from_smt(const smt_termt &value_term, const typet &type_to_construct)
Given a value_term and a type_to_construct, this function constructs a value exprt with a value based...
Definition: construct_value_expr_from_smt.cpp:115
smt_identifier_termt::identifier
irep_idt identifier() const
Definition: smt_terms.cpp:80
smt_object_sizet::make_definition
smt_commandt make_definition(std::size_t unique_id, smt_termt size) const
Makes the command to define the resulting size of calling the object size function with unique_id.
Definition: smt_object_size.cpp:26
smt_unsat_responset
Definition: smt_responses.h:74
symbol.h
Symbol table entry.
decision_proceduret::resultt::D_ERROR
@ D_ERROR
irept::is_nil
bool is_nil() const
Definition: irep.h:376
message_handlert
Definition: message.h:27
smt_commandt
Definition: smt_commands.h:13
range.h
smt_responset::pretty
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
Definition: irep.cpp:495
smt2_incremental_decision_proceduret::get
exprt get(const exprt &expr) const override
Return expr with variables replaced by values from satisfying assignment if available.
Definition: smt2_incremental_decision_procedure.cpp:397
smt2_incremental_decision_procedure.h
smt_check_sat_responset
Definition: smt_responses.h:86
optionalt
nonstd::optional< T > optionalt
Definition: optional.h:35
smt_forall_termt
Definition: smt_terms.h:225
objects_are_already_tracked
bool objects_are_already_tracked(const exprt &expression, const smt_object_mapt &object_map)
Finds whether all base object expressions in the given expression are already tracked in the given ob...
Definition: object_tracking.cpp:100
decision_proceduret::resultt
resultt
Result of running the decision procedure.
Definition: decision_procedure.h:43
smt2_incremental_decision_proceduret::object_size_function
smt_object_sizet object_size_function
Implementation of the SMT formula for the object size function.
Definition: smt2_incremental_decision_procedure.h:161
smt_array_sortt
Definition: smt_sorts.h:90
smt2_incremental_decision_proceduret::ensure_handle_for_expr_defined
void ensure_handle_for_expr_defined(const exprt &expr)
Definition: smt2_incremental_decision_procedure.cpp:259
smt2_incremental_decision_proceduret::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: smt2_incremental_decision_procedure.cpp:319
smt_commands.h
can_cast_type< bool_typet >
bool can_cast_type< bool_typet >(const typet &base)
Definition: std_types.h:44
symbolt::value
exprt value
Initial value of symbol.
Definition: symbol.h:34
smt_get_value_commandt
Definition: smt_commands.h:86
smt2_incremental_decision_proceduret::smt2_incremental_decision_proceduret
smt2_incremental_decision_proceduret(const namespacet &_ns, std::unique_ptr< smt_base_solver_processt > solver_process, message_handlert &message_handler)
Definition: smt2_incremental_decision_procedure.cpp:243
smt2_incremental_decision_proceduret::log
messaget log
For reporting errors, warnings and debugging information back to the user.
Definition: smt2_incremental_decision_procedure.h:110
array_typet
Arrays with given size.
Definition: std_types.h:762
smt2_incremental_decision_proceduret::pop
void pop() override
Pop whatever is on top of the stack.
Definition: smt2_incremental_decision_procedure.cpp:517
smt_assert_commandt
Definition: smt_commands.h:32
symbolt
Symbol table entry.
Definition: symbol.h:27
smt2_incremental_decision_proceduret::ns
const namespacet & ns
Namespace for looking up the expressions which symbol_exprts relate to.
Definition: smt2_incremental_decision_procedure.h:102
from_integer
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
Definition: arith_tools.cpp:100
smt_check_sat_response_kindt::cast
const sub_classt * cast() const &
messaget::conditional_output
void conditional_output(mstreamt &mstream, const std::function< void(mstreamt &)> &output_generator) const
Generate output to message_stream using output_generator if the configured verbosity is at least as h...
Definition: message.cpp:139
exprt::visit_pre
void visit_pre(std::function< void(exprt &)>)
Definition: expr.cpp:245
smt2_incremental_decision_proceduret::define_array_function
void define_array_function(const t_exprt &array)
Defines a function of array sort and asserts the element values from array_exprt or array_of_exprt.
Definition: smt2_incremental_decision_procedure.cpp:120
can_cast_expr< nondet_symbol_exprt >
bool can_cast_expr< nondet_symbol_exprt >(const exprt &base)
Definition: std_expr.h:277
smt_base_solver_processt::send
virtual void send(const smt_commandt &command)=0
Converts given SMT2 command to SMT2 string and sends it to the solver process.
smt2_incremental_decision_proceduret::define_object_sizes
void define_object_sizes()
Sends the solver the definitions of the object sizes.
Definition: smt2_incremental_decision_procedure.cpp:535
smt_core_theoryt::equal
static const smt_function_application_termt::factoryt< equalt > equal
Definition: smt_core_theory.h:57
smt2_incremental_decision_proceduret::set_to
void set_to(const exprt &expr, bool value) override
For a Boolean expression expr, add the constraint 'expr' if value is true, otherwise add 'not expr'.
Definition: smt2_incremental_decision_procedure.cpp:479
messaget::mstreamt
Definition: message.h:223
smt2_incremental_decision_proceduret::convert_expr_to_smt
smt_termt convert_expr_to_smt(const exprt &expr)
Add objects in expr to object_map if needed and convert to smt.
Definition: smt2_incremental_decision_procedure.cpp:300
smt_base_solver_processt::receive_response
virtual smt_responset receive_response(const std::unordered_map< irep_idt, smt_identifier_termt > &identifier_table)=0
smt2_incremental_decision_proceduret::array_sequence
class smt2_incremental_decision_proceduret::sequencet array_sequence
smt2_incremental_decision_proceduret::solver_process
std::unique_ptr< smt_base_solver_processt > solver_process
For handling the lifetime of and communication with the separate SMT solver process.
Definition: smt2_incremental_decision_procedure.h:108
exprt::operands
operandst & operands()
Definition: expr.h:94
messaget::debug
mstreamt & debug() const
Definition: message.h:429
smt2_incremental_decision_proceduret::expression_handle_identifiers
std::unordered_map< exprt, smt_identifier_termt, irep_hash > expression_handle_identifiers
When the handle(exprt) member function is called, the decision procedure commands the SMT solver to d...
Definition: smt2_incremental_decision_procedure.h:130
gather_dependent_expressions
static std::vector< exprt > gather_dependent_expressions(const exprt &expr)
Find all sub expressions of the given expr which need to be expressed as separate smt commands.
Definition: smt2_incremental_decision_procedure.cpp:68
smt_responset::cast
const sub_classt * cast() const &
Definition: smt_responses.cpp:36
messaget::warning
mstreamt & warning() const
Definition: message.h:404
associate_pointer_sizes
void associate_pointer_sizes(const exprt &expression, const namespacet &ns, type_size_mapt &type_size_map, const smt_object_mapt &object_map, const smt_object_sizet::make_applicationt &object_size)
This function populates the (pointer) type -> size map.
Definition: type_size_mapping.cpp:13
smt_terms.h
std_expr.h
smt2_incremental_decision_proceduret::expression_identifiers
std::unordered_map< exprt, smt_identifier_termt, irep_hash > expression_identifiers
As part of the decision procedure's overall translation of CBMCs exprts into SMT terms,...
Definition: smt2_incremental_decision_procedure.h:140
array_typet::index_type
typet index_type() const
The type of the index expressions into any instance of this type.
Definition: std_types.cpp:33
smt_array_theory.h
convert_type_to_smt_sort
static smt_sortt convert_type_to_smt_sort(const bool_typet &type)
Definition: convert_expr_to_smt.cpp:83
array_exprt
Array constructor from list of elements.
Definition: std_expr.h:1562
make_range
ranget< iteratort > make_range(iteratort begin, iteratort end)
Definition: range.h:524
substitute_identifiers
static exprt substitute_identifiers(exprt expr, const std::unordered_map< exprt, smt_identifier_termt, irep_hash > &expression_identifiers)
Replaces the sub expressions of expr which have been defined as separate functions in the smt solver,...
Definition: smt2_incremental_decision_procedure.cpp:228
symbolt::name
irep_idt name
The unique identifier.
Definition: symbol.h:40
smt_unknown_responset
Definition: smt_responses.h:80
smt2_incremental_decision_proceduret::object_size_defined
std::vector< bool > object_size_defined
The size of each object is separately defined as a pre-solving step.
Definition: smt2_incremental_decision_procedure.h:157
initial_smt_object_map
smt_object_mapt initial_smt_object_map()
Constructs an initial object map containing the null object.
Definition: object_tracking.cpp:66
validation_modet::INVARIANT
@ INVARIANT
convert_expr_to_smt.h
smt_success_responset
Definition: smt_responses.h:28
array_typet::element_type
const typet & element_type() const
The type of the elements of the array.
Definition: std_types.h:785
analysis_exceptiont
Thrown when an unexpected error occurs during the analysis (e.g., when the SAT solver returns an erro...
Definition: exception_utils.h:153
smt2_incremental_decision_proceduret::initialize_array_elements
void initialize_array_elements(const array_exprt &array, const smt_identifier_termt &array_identifier)
Generate and send to the SMT solver clauses asserting that each array element is as specified by arra...
Definition: smt2_incremental_decision_procedure.cpp:84