CBMC
horn_encoding.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Horn-clause Encoding
4 
5 Author: Daniel Kroening
6 
7 Date: June 2015
8 
9 \*******************************************************************/
10 
13 
14 #include "horn_encoding.h"
15 
16 #include <util/c_types.h>
17 #include <util/exception_utils.h>
18 #include <util/format_expr.h>
19 #include <util/mathematical_expr.h>
20 #include <util/pointer_expr.h>
21 #include <util/prefix.h>
22 #include <util/replace_symbol.h>
23 #include <util/std_code.h>
24 #include <util/std_expr.h>
25 
27 
28 #include <solvers/smt2/smt2_conv.h>
29 
30 #include <algorithm>
31 #include <ostream>
32 #include <unordered_set>
33 
34 class state_typet : public typet
35 {
36 public:
37  state_typet() : typet(ID_state)
38  {
39  }
40 };
41 
43 {
45 }
46 
47 static inline symbol_exprt state_expr()
48 {
49  return symbol_exprt(u8"\u03c2", state_typet());
50 }
51 
53 {
54 public:
56  : binary_exprt(
57  std::move(state),
58  ID_evaluate,
59  std::move(address),
60  std::move(type))
61  {
62  PRECONDITION(this->state().type().id() == ID_state);
63  PRECONDITION(this->address().type().id() == ID_pointer);
64  }
65 
66  const exprt &state() const
67  {
68  return op0();
69  }
70 
72  {
73  return op0();
74  }
75 
76  const exprt &address() const
77  {
78  return op1();
79  }
80 };
81 
88 inline const evaluate_exprt &to_evaluate_expr(const exprt &expr)
89 {
90  PRECONDITION(expr.id() == ID_evaluate);
91  const evaluate_exprt &ret = static_cast<const evaluate_exprt &>(expr);
92  validate_expr(ret);
93  return ret;
94 }
95 
98 {
99  PRECONDITION(expr.id() == ID_evaluate);
100  evaluate_exprt &ret = static_cast<evaluate_exprt &>(expr);
101  validate_expr(ret);
102  return ret;
103 }
104 
106 {
107 public:
109  : ternary_exprt(
110  ID_update_state,
111  std::move(state),
112  std::move(address),
113  std::move(new_value),
114  state_typet())
115  {
116  // PRECONDITION(this->state().id() == ID_state);
117  PRECONDITION(this->address().type().id() == ID_pointer);
118  }
119 
120  const exprt &state() const
121  {
122  return op0();
123  }
124 
126  {
127  return op0();
128  }
129 
130  const exprt &address() const
131  {
132  return op1();
133  }
134 
135  const exprt &new_value() const
136  {
137  return op2();
138  }
139 };
140 
148 {
149  PRECONDITION(expr.id() == ID_update_state);
150  const update_state_exprt &ret = static_cast<const update_state_exprt &>(expr);
151  validate_expr(ret);
152  return ret;
153 }
154 
157 {
158  PRECONDITION(expr.id() == ID_update_state);
159  update_state_exprt &ret = static_cast<update_state_exprt &>(expr);
160  validate_expr(ret);
161  return ret;
162 }
163 
165 {
166 public:
168  : ternary_exprt(
169  ID_allocate,
170  std::move(state),
171  std::move(address),
172  std::move(size),
173  state_typet())
174  {
175  PRECONDITION(this->state().type().id() == ID_state);
176  PRECONDITION(this->address().type().id() == ID_pointer);
177  }
178 
179  const exprt &state() const
180  {
181  return op0();
182  }
183 
185  {
186  return op0();
187  }
188 
189  const exprt &address() const
190  {
191  return op1();
192  }
193 
194  const exprt &size() const
195  {
196  return op2();
197  }
198 };
199 
206 inline const allocate_exprt &to_allocate_expr(const exprt &expr)
207 {
208  PRECONDITION(expr.id() == ID_allocate);
209  const allocate_exprt &ret = static_cast<const allocate_exprt &>(expr);
210  validate_expr(ret);
211  return ret;
212 }
213 
215 {
216 public:
217  virtual void annotation(const std::string &)
218  {
219  }
220 
221  virtual void set_to_true(source_locationt, exprt) = 0;
222 
223  void set_to_true(exprt expr)
224  {
225  set_to_true(source_location, std::move(expr));
226  }
227 
228  void set_source_location(source_locationt __source_location)
229  {
230  source_location = std::move(__source_location);
231  }
232 
233  virtual ~encoding_targett() = default;
234 
235 protected:
237 };
238 
240 {
241 public:
242  container_encoding_targett() = default;
243 
244  using constraintst = std::vector<exprt>;
246 
248  {
251 
252  constraints.emplace_back(std::move(expr));
253  }
254 
255 protected:
257 };
258 
259 static inline void operator<<(encoding_targett &target, exprt constraint)
260 {
261  target.set_to_true(std::move(constraint));
262 }
263 
264 static inline void
266 {
267  for(const auto &constraint : src.constraints)
268  target << constraint;
269 }
270 
272 {
273 public:
274  smt2_encoding_targett(const namespacet &ns, std::ostream &_out)
275  : out(_out),
276  smt2_conv(ns, "", "cprover", "", smt2_convt::solvert::GENERIC, _out)
277  {
279  smt2_conv.use_as_const = true;
280  }
281 
283  {
284  // finish the conversion to SMT-LIB2
285  smt2_conv();
286  }
287 
288  void set_to_true(source_locationt, exprt expr) override
289  {
290  smt2_conv.set_to_true(std::move(expr));
291  }
292 
293  void annotation(const std::string &text) override
294  {
295  if(text.empty())
296  out << '\n';
297  else
298  out << ';' << ' ' << text << '\n';
299  }
300 
301 protected:
302  std::ostream &out;
304 };
305 
307 {
308 public:
309  explicit ascii_encoding_targett(std::ostream &_out) : out(_out)
310  {
311  }
312 
313  void set_to_true(source_locationt, exprt) override;
314 
315  void annotation(const std::string &text) override
316  {
317  out << text << '\n';
318  }
319 
320 protected:
321  std::ostream &out;
322  std::size_t counter = 0;
323 };
324 
325 static void find_variables_rec(
326  const exprt &src,
327  std::unordered_set<symbol_exprt, irep_hash> &result)
328 {
329  if(src.id() == ID_object_address)
330  result.insert(to_object_address_expr(src).object_expr());
331  else
332  {
333  for(auto &op : src.operands())
334  find_variables_rec(op, result);
335  }
336 }
337 
339 {
340 public:
341  explicit state_encodingt(const goto_functionst &__goto_functions)
342  : goto_functions(__goto_functions)
343  {
344  }
345 
346  void operator()(
347  const goto_functionst::function_mapt::const_iterator,
348  encoding_targett &);
349 
350  void encode(
351  const goto_functiont &,
352  const std::string &state_prefix,
353  const std::string &annotation,
354  const symbol_exprt &entry_state,
355  const exprt &return_lhs,
356  encoding_targett &);
357 
358 protected:
361 
363  symbol_exprt state_expr_with_suffix(loct, const std::string &suffix) const;
364  symbol_exprt out_state_expr(loct, bool taken) const;
366  std::vector<symbol_exprt> incoming_symbols(loct) const;
367  exprt evaluate_expr(loct, const exprt &, const exprt &) const;
369  loct,
370  const exprt &,
371  const exprt &,
372  const std::unordered_set<symbol_exprt, irep_hash> &) const;
374  loct,
375  const exprt &,
376  std::vector<symbol_exprt> &nondet_symbols) const;
377  exprt evaluate_expr(loct, const exprt &) const;
378  exprt address_rec(loct, const exprt &, exprt) const;
379  static exprt state_lambda_expr(exprt);
382  void setup_incoming(const goto_functiont &);
383  exprt assignment_constraint(loct, exprt lhs, exprt rhs) const;
386 
387  std::string state_prefix;
388  std::string annotation;
392  using incomingt = std::map<loct, std::vector<loct>>;
394 };
395 
397 {
398  return state_expr_with_suffix(loc, "");
399 }
400 
402  loct loc,
403  const std::string &suffix) const
404 {
405  irep_idt identifier =
406  state_prefix + std::to_string(loc->location_number) + suffix;
407  return symbol_exprt(identifier, state_predicate_type());
408 }
409 
411 {
412  return state_expr_with_suffix(loc, taken ? "T" : "");
413 }
414 
415 std::vector<symbol_exprt> state_encodingt::incoming_symbols(loct loc) const
416 {
417  auto incoming_it = incoming.find(loc);
418 
419  DATA_INVARIANT(incoming_it != incoming.end(), "incoming is complete");
420 
421  std::vector<symbol_exprt> symbols;
422  symbols.reserve(incoming_it->second.size());
423 
424  for(auto &loc_in : incoming_it->second)
425  {
426  std::string suffix;
427 
428  // conditional jump from loc_in to loc?
429  if(
430  loc_in->is_goto() && !loc_in->condition().is_true() &&
431  loc != std::next(loc_in))
432  {
433  suffix = "T";
434  }
435 
436  symbols.push_back(state_expr_with_suffix(loc_in, suffix));
437  }
438 
439  return symbols;
440 }
441 
443 {
444  if(loc == first_loc)
445  return entry_state;
446 
447  auto incoming_symbols = this->incoming_symbols(loc);
448 
449  if(incoming_symbols.size() == 1)
450  return incoming_symbols.front();
451  else
452  return state_expr_with_suffix(loc, "in");
453 }
454 
456  loct loc,
457  const exprt &state,
458  const exprt &what) const
459 {
460  return evaluate_expr_rec(loc, state, what, {});
461 }
462 
464  loct loc,
465  const exprt &what,
466  std::vector<symbol_exprt> &nondet_symbols) const
467 {
468  if(what.id() == ID_side_effect)
469  {
470  auto &side_effect = to_side_effect_expr(what);
471  auto statement = side_effect.get_statement();
472  if(statement == ID_nondet)
473  {
474  irep_idt identifier =
475  "nondet::" + state_prefix + std::to_string(loc->location_number);
476  auto symbol = symbol_exprt(identifier, side_effect.type());
477  nondet_symbols.push_back(symbol);
478  return std::move(symbol);
479  }
480  else
481  return what; // leave it
482  }
483  else
484  {
485  exprt tmp = what;
486  for(auto &op : tmp.operands())
487  op = replace_nondet_rec(loc, op, nondet_symbols);
488  return tmp;
489  }
490 }
491 
493  loct loc,
494  const exprt &state,
495  const exprt &what,
496  const std::unordered_set<symbol_exprt, irep_hash> &bound_symbols) const
497 {
498  PRECONDITION(state.type().id() == ID_state);
499 
500  if(what.id() == ID_symbol)
501  {
502  const auto &symbol_expr = to_symbol_expr(what);
503 
504  if(bound_symbols.find(symbol_expr) == bound_symbols.end())
505  {
506  return evaluate_exprt(state, address_rec(loc, state, what), what.type());
507  }
508  else
509  return what; // leave as is
510  }
511  else if(
512  what.id() == ID_dereference || what.id() == ID_member ||
513  what.id() == ID_index)
514  {
515  return evaluate_exprt(state, address_rec(loc, state, what), what.type());
516  }
517  else if(what.id() == ID_forall || what.id() == ID_exists)
518  {
519  auto new_quantifier_expr = to_quantifier_expr(what); // copy
520  auto new_bound_symbols = bound_symbols; // copy
521 
522  for(const auto &v : new_quantifier_expr.variables())
523  new_bound_symbols.insert(v);
524 
525  new_quantifier_expr.where() = evaluate_expr_rec(
526  loc, state, new_quantifier_expr.where(), new_bound_symbols);
527 
528  return std::move(new_quantifier_expr);
529  }
530  else if(what.id() == ID_address_of)
531  {
532  const auto &object = to_address_of_expr(what).object();
533  return address_rec(loc, state, object);
534  }
535  else if(what.id() == ID_r_ok || what.id() == ID_w_ok || what.id() == ID_rw_ok)
536  {
537  // we need to add the state
538  const auto &r_or_w_ok_expr = to_r_or_w_ok_expr(what);
539  auto pointer =
540  evaluate_expr_rec(loc, state, r_or_w_ok_expr.pointer(), bound_symbols);
541  auto size =
542  evaluate_expr_rec(loc, state, r_or_w_ok_expr.size(), bound_symbols);
543  return ternary_exprt(what.id(), state, pointer, size, what.type());
544  }
545  else
546  {
547  exprt tmp = what;
548  for(auto &op : tmp.operands())
549  op = evaluate_expr_rec(loc, state, op, bound_symbols);
550  return tmp;
551  }
552 }
553 
555 {
556  return evaluate_expr(loc, in_state_expr(loc), what);
557 }
558 
560 {
561  return lambda_exprt({state_expr()}, std::move(what));
562 }
563 
565 {
566  return forall_exprt(
567  {state_expr()},
570  std::move(what)));
571 }
572 
574  const
575 {
576  return forall_exprt(
577  {state_expr()},
579  and_exprt(
581  std::move(condition)),
582  std::move(what)));
583 }
584 
586  const
587 {
588  if(expr.id() == ID_symbol)
589  {
590  if(expr.type().id() == ID_array)
591  {
592  const auto &element_type = to_array_type(expr.type()).element_type();
593  return object_address_exprt(
594  to_symbol_expr(expr), pointer_type(element_type));
595  }
596  else
597  return object_address_exprt(to_symbol_expr(expr));
598  }
599  else if(expr.id() == ID_member)
600  {
601  auto compound = to_member_expr(expr).struct_op();
602  auto compound_address = address_rec(loc, state, std::move(compound));
603  auto component_name = to_member_expr(expr).get_component_name();
604 
605  if(expr.type().id() == ID_array)
606  {
607  const auto &element_type = to_array_type(expr.type()).element_type();
608  return field_address_exprt(
609  std::move(compound_address),
610  component_name,
611  pointer_type(element_type));
612  }
613  else
614  {
615  return field_address_exprt(
616  std::move(compound_address), component_name, pointer_type(expr.type()));
617  }
618  }
619  else if(expr.id() == ID_index)
620  {
621  auto array = to_index_expr(expr).array();
622  auto index_evaluated =
623  evaluate_expr(loc, state, to_index_expr(expr).index());
624  auto array_address = address_rec(loc, state, std::move(array));
625  return element_address_exprt(
626  std::move(array_address), std::move(index_evaluated));
627  }
628  else if(expr.id() == ID_dereference)
629  return evaluate_expr(loc, state, to_dereference_expr(expr).pointer());
630  else if(expr.id() == ID_string_constant)
631  {
632  // TBD.
634  "can't do string literals", expr.source_location());
635  }
636  else if(expr.id() == ID_array)
637  {
638  // TBD.
640  "can't do array literals", expr.source_location());
641  }
642  else if(expr.id() == ID_union)
643  {
644  // TBD.
646  "can't do union literals", expr.source_location());
647  }
648  else
649  return nil_exprt();
650 }
651 
653  const
654 {
655  auto s = state_expr();
656 
657  auto address = address_rec(loc, s, lhs);
658 
659  exprt rhs_evaluated = evaluate_expr(loc, s, rhs);
660 
661  std::vector<symbol_exprt> nondet_symbols;
662  exprt new_value = replace_nondet_rec(loc, rhs_evaluated, nondet_symbols);
663 
664  auto new_state = update_state_exprt(s, address, new_value);
665 
666  forall_exprt::variablest binding = {state_expr()};
667  binding.insert(binding.end(), nondet_symbols.begin(), nondet_symbols.end());
668 
669  return forall_exprt(
670  std::move(binding),
673  function_application_exprt(out_state_expr(loc), {new_state})));
674 }
675 
677 {
678  forall_goto_program_instructions(it, goto_function.body)
679  incoming[it];
680 
681  forall_goto_program_instructions(it, goto_function.body)
682  {
683  if(it->is_goto())
684  incoming[it->get_target()].push_back(it);
685  }
686 
687  forall_goto_program_instructions(it, goto_function.body)
688  {
689  auto next = std::next(it);
690  if(it->is_goto() && it->condition().is_true())
691  {
692  }
693  else if(next != goto_function.body.instructions.end())
694  {
695  incoming[next].push_back(it);
696  }
697  }
698 }
699 
701 {
702  if(src.id() == ID_not)
703  return to_not_expr(src).op();
704  else
705  return not_exprt(src);
706 }
707 
710  encoding_targett &dest)
711 {
712  const auto &function = to_symbol_expr(loc->call_function());
713  const auto &type = to_code_type(function.type());
714  auto identifier = function.get_identifier();
715 
716  auto new_annotation = annotation + u8" \u2192 " + id2string(identifier);
717  dest.annotation(new_annotation);
718 
719  // malloc is special-cased
720  if(identifier == "malloc")
721  {
722  auto state = state_expr();
723  PRECONDITION(loc->call_arguments().size() == 1);
724  auto size_evaluated = evaluate_expr(loc, state, loc->call_arguments()[0]);
725 
726  auto lhs_address = address_rec(loc, state, loc->call_lhs());
727  exprt new_state = ternary_exprt(
728  ID_allocate, state, lhs_address, size_evaluated, state_typet());
729  dest << forall_states_expr(
730  loc, function_application_exprt(out_state_expr(loc), {new_state}));
731  return;
732  }
733 
734  // Find the function
735  auto f = goto_functions.function_map.find(identifier);
736  if(f == goto_functions.function_map.end())
737  DATA_INVARIANT(false, "failed find function in function_map");
738 
739  // Do we have a function body?
740  if(!f->second.body_available())
741  {
742  // no function body -- do LHS assignment nondeterministically, if any
743  if(loc->call_lhs().is_not_nil())
744  {
745  auto rhs = side_effect_expr_nondett(
746  loc->call_lhs().type(), loc->source_location());
747  dest << assignment_constraint(loc, loc->call_lhs(), std::move(rhs));
748  }
749  else
750  {
751  // This is a SKIP.
752  dest << equal_exprt(out_state_expr(loc), in_state_expr(loc));
753  }
754  }
755 
756  // Evaluate the arguments of the call in the 'in state'
757  exprt arguments_state = state_expr();
758 
759  for(std::size_t i = 0; i < type.parameters().size(); i++)
760  {
761  auto address = object_address_exprt(symbol_exprt(
762  f->second.parameter_identifiers[i], type.parameters()[i].type()));
763  auto argument = loc->call_arguments()[i];
764  auto value = evaluate_expr(loc, state_expr(), argument);
765  arguments_state = update_state_exprt(arguments_state, address, value);
766  }
767 
768  // Now assign them
769  auto function_entry_state = state_expr_with_suffix(loc, "Entry");
770  dest << forall_states_expr(
771  loc, function_application_exprt(function_entry_state, {arguments_state}));
772 
773  // now do the body, recursively
774  state_encodingt body_state_encoding(goto_functions);
775  auto new_state_prefix =
776  state_prefix + std::to_string(loc->location_number) + ".";
777  body_state_encoding.encode(
778  f->second,
779  new_state_prefix,
780  new_annotation,
781  function_entry_state,
782  nil_exprt(),
783  dest);
784 
785  // exit state of called function
786  auto exit_loc = std::prev(f->second.body.instructions.end());
787  irep_idt exit_state_identifier =
788  new_state_prefix + std::to_string(exit_loc->location_number);
789  auto exit_state = symbol_exprt(exit_state_identifier, state_predicate_type());
790 
791  // now link up return state
792  dest << equal_exprt(out_state_expr(loc), std::move(exit_state));
793 }
794 
797  encoding_targett &dest)
798 {
799  // Function pointer?
800  const auto &function = loc->call_function();
801  if(function.id() == ID_dereference)
802  {
803  // TBD.
805  "can't do function pointers", loc->source_location());
806  }
807  else if(function.id() == ID_symbol)
808  {
809  function_call_symbol(loc, dest);
810  }
811  else
812  {
814  false, "got function that's neither a symbol nor a function pointer");
815  }
816 }
817 
819  goto_functionst::function_mapt::const_iterator f_entry,
820  encoding_targett &dest)
821 {
822  const auto &goto_function = f_entry->second;
823 
824  if(goto_function.body.instructions.empty())
825  return;
826 
827  // initial state
828  auto in_state = symbol_exprt("SInitial", state_predicate_type());
829 
830  dest << forall_exprt(
831  {state_expr()},
834 
835  auto annotation = id2string(f_entry->first);
836 
837  encode(goto_function, "S", annotation, in_state, nil_exprt(), dest);
838 }
839 
841  const goto_functiont &goto_function,
842  const std::string &state_prefix,
843  const std::string &annotation,
844  const symbol_exprt &entry_state,
845  const exprt &return_lhs,
846  encoding_targett &dest)
847 {
848  first_loc = goto_function.body.instructions.begin();
849  this->state_prefix = state_prefix;
850  this->annotation = annotation;
851  this->entry_state = entry_state;
852  this->return_lhs = return_lhs;
853 
854  setup_incoming(goto_function);
855 
856  // constraints for each instruction
857  forall_goto_program_instructions(loc, goto_function.body)
858  {
859  // pass on the source code location
860  dest.set_source_location(loc->source_location());
861 
862  // constraints on the incoming state
863  {
864  auto incoming_symbols = this->incoming_symbols(loc);
865 
866  if(incoming_symbols.size() >= 2)
867  {
868  auto s = state_expr();
869  for(auto incoming_symbol : incoming_symbols)
870  {
871  dest << forall_exprt(
872  {s},
874  function_application_exprt(incoming_symbol, {s}),
876  }
877  }
878  }
879 
880  if(loc->is_assign())
881  {
882  auto &lhs = loc->assign_lhs();
883  auto &rhs = loc->assign_rhs();
884 
885  if(lhs.type().id() == ID_array)
886  {
887  // skip
888  dest << equal_exprt(out_state_expr(loc), in_state_expr(loc));
889  }
890  else if(lhs.type().id() == ID_struct_tag)
891  {
892  // skip
893  dest << equal_exprt(out_state_expr(loc), in_state_expr(loc));
894  }
895  else if(
896  lhs.id() == ID_symbol &&
897  has_prefix(
899  to_symbol_expr(lhs).get_identifier() != CPROVER_PREFIX "rounding_mode")
900  {
901  // skip for now
902  dest << equal_exprt(out_state_expr(loc), in_state_expr(loc));
903  }
904  else
905  dest << assignment_constraint(loc, lhs, rhs);
906  }
907  else if(loc->is_assume())
908  {
909  // we produce ∅ when the assumption is false
910  auto state = state_expr();
911  auto condition_evaluated = evaluate_expr(loc, state, loc->condition());
912 
913  dest << forall_states_expr(
914  loc,
915  condition_evaluated,
917  }
918  else if(loc->is_goto())
919  {
920  // We produce ∅ when the 'other' branch is taken. Get the condition.
921  const auto &condition = loc->condition();
922 
923  if(condition.is_true())
924  {
925  dest << equal_exprt(out_state_expr(loc), in_state_expr(loc));
926  }
927  else
928  {
929  auto state = state_expr();
930  auto condition_evaluated = evaluate_expr(loc, state, condition);
931 
932  dest << forall_states_expr(
933  loc,
934  condition_evaluated,
935  function_application_exprt(out_state_expr(loc, true), {state}));
936 
937  dest << forall_states_expr(
938  loc,
939  simplifying_not(condition_evaluated),
940  function_application_exprt(out_state_expr(loc, false), {state}));
941  }
942  }
943  else if(loc->is_assert())
944  {
945  // all assertions need to hold
946  dest << forall_states_expr(
947  loc, evaluate_expr(loc, state_expr(), loc->condition()));
948 
949  dest << equal_exprt(out_state_expr(loc), in_state_expr(loc));
950  }
951  else if(
952  loc->is_skip() || loc->is_assert() || loc->is_location() ||
953  loc->is_end_function() || loc->is_other())
954  {
955  dest << equal_exprt(out_state_expr(loc), in_state_expr(loc));
956  }
957  else if(loc->is_decl() || loc->is_dead())
958  {
959  // may wish to havoc the symbol
960  dest << equal_exprt(out_state_expr(loc), in_state_expr(loc));
961  }
962  else if(loc->is_function_call())
963  {
964  function_call(loc, dest);
965  }
966  else if(loc->is_set_return_value())
967  {
968  const auto &rhs = loc->return_value();
969 
970  if(return_lhs.is_nil())
971  {
972  // treat these as assignments to a special symbol named 'return_value'
973  auto lhs = symbol_exprt("return_value", rhs.type());
974  dest << assignment_constraint(loc, std::move(lhs), std::move(rhs));
975  }
976  else
977  {
978  }
979  }
980  }
981 }
982 
984  const goto_modelt &goto_model,
985  bool program_is_inlined,
986  encoding_targett &dest)
987 {
988  if(program_is_inlined)
989  {
990  auto f_entry = goto_model.goto_functions.function_map.find(
992 
993  if(f_entry == goto_model.goto_functions.function_map.end())
994  throw incorrect_goto_program_exceptiont("The program has no entry point");
995 
996  dest.annotation("function " + id2string(f_entry->first));
997 
998  state_encodingt{goto_model.goto_functions}(f_entry, dest);
999  }
1000  else
1001  {
1002  // sort alphabetically
1003  const auto sorted = goto_model.goto_functions.sorted();
1004  const namespacet ns(goto_model.symbol_table);
1005  for(auto &f : sorted)
1006  {
1007  const auto &symbol = ns.lookup(f->first);
1008  if(
1009  f->first == goto_functionst::entry_point() ||
1011  {
1012  dest.annotation("");
1013  dest.annotation("function " + id2string(f->first));
1014  state_encodingt{goto_model.goto_functions}(f, dest);
1015  }
1016  }
1017  }
1018 }
1019 
1020 std::unordered_set<symbol_exprt, irep_hash>
1021 find_variables(const std::vector<exprt> &src)
1022 {
1023  std::unordered_set<symbol_exprt, irep_hash> result;
1024 
1025  for(auto &expr : src)
1026  find_variables_rec(expr, result);
1027 
1028  return result;
1029 }
1030 
1031 static typet
1033 {
1035  for(auto &v : variables)
1036  domain.push_back(v.type());
1037 
1038  return mathematical_function_typet(std::move(domain), bool_typet());
1039 }
1040 
1042 {
1043  // operands first
1044  for(auto &op : src.operands())
1045  op = variable_encoding(op, variables);
1046 
1047  if(src.id() == ID_forall)
1048  {
1049  auto &forall_expr = to_forall_expr(src);
1050  if(
1051  forall_expr.variables().size() >= 1 &&
1052  forall_expr.variables().front().type().id() == ID_state)
1053  {
1054  // replace 'state' by the program variables
1055  forall_exprt::variablest new_variables = variables;
1056  new_variables.insert(
1057  new_variables.end(),
1058  forall_expr.variables().begin() + 1,
1059  forall_expr.variables().end());
1060  forall_expr
1061  .variables() = std::move(new_variables);
1062  return std::move(forall_expr);
1063  }
1064  }
1065  else if(src.id() == ID_function_application)
1066  {
1067  auto &function_application = to_function_application_expr(src);
1068  if(
1069  function_application.arguments().size() == 1 &&
1070  function_application.arguments().front().type().id() == ID_state)
1071  {
1072  function_application.function().type() =
1073  new_state_predicate_type(variables);
1074 
1075  if(function_application.arguments().front().id() == ID_symbol)
1076  {
1077  exprt::operandst new_arguments;
1078  for(auto &v : variables)
1079  new_arguments.push_back(v);
1080  function_application.arguments() = new_arguments;
1081  }
1082  else if(function_application.arguments().front().id() == ID_tuple)
1083  {
1085  function_application.arguments().front().operands().size() ==
1086  variables.size(),
1087  "tuple size must match");
1088  auto operands = function_application.arguments().front().operands();
1089  function_application.arguments() = operands;
1090  }
1091  else
1092  throw analysis_exceptiont("can't convert " + format_to_string(src));
1093  }
1094  else
1095  throw analysis_exceptiont("can't convert " + format_to_string(src));
1096  }
1097  else if(src.id() == ID_evaluate)
1098  {
1099  auto &evaluate_expr = to_evaluate_expr(src);
1100  if(evaluate_expr.address().id() == ID_object_address)
1101  return symbol_exprt(
1102  to_object_address_expr(evaluate_expr.address()).object_expr());
1103  else
1104  throw analysis_exceptiont("can't convert " + format_to_string(src));
1105  }
1106  else if(src.id() == ID_update_state)
1107  {
1108  auto &update_state_expr = to_update_state_expr(src);
1109  if(update_state_expr.address().id() == ID_object_address)
1110  {
1111  auto lhs_symbol =
1112  to_object_address_expr(update_state_expr.address()).object_expr();
1113  exprt::operandst operands;
1114  for(auto &v : variables)
1115  {
1116  if(v == lhs_symbol)
1117  operands.push_back(update_state_expr.new_value());
1118  else
1119  operands.push_back(v);
1120  }
1121  return tuple_exprt(operands, typet(ID_state));
1122  }
1123  else
1124  throw analysis_exceptiont("can't convert " + format_to_string(src));
1125  }
1126 
1127  return src;
1128 }
1129 
1130 void variable_encoding(std::vector<exprt> &constraints)
1131 {
1132  binding_exprt::variablest variables;
1133 
1134  for(auto &v : find_variables(constraints))
1135  variables.push_back(v);
1136 
1137  if(variables.empty())
1138  throw analysis_exceptiont("no variables found");
1139 
1140  // sort alphabetically
1141  std::sort(
1142  variables.begin(),
1143  variables.end(),
1144  [](const symbol_exprt &a, const symbol_exprt &b) {
1145  return id2string(a.get_identifier()) < id2string(b.get_identifier());
1146  });
1147 
1148  for(auto &c : constraints)
1149  c = variable_encoding(c, variables);
1150 }
1151 
1152 void equality_propagation(std::vector<exprt> &constraints)
1153 {
1154  replace_symbolt values;
1155 
1156  std::vector<exprt> new_constraints;
1157  new_constraints.reserve(constraints.size());
1158 
1159  // forward-propagation of equalities
1160  for(auto &expr : constraints)
1161  {
1162  bool retain_constraint = true;
1163 
1164  // apply the map
1165  values(expr);
1166 
1167  if(expr.id() == ID_equal)
1168  {
1169  const auto &equal_expr = to_equal_expr(expr);
1170  if(equal_expr.lhs().id() == ID_symbol)
1171  {
1172  const auto &symbol_expr = to_symbol_expr(equal_expr.lhs());
1173 
1174  // this is a (deliberate) no-op when the symbol is already in the map
1175  if(values.replaces_symbol(symbol_expr.get_identifier()))
1176  {
1177  }
1178  else
1179  {
1180  values.insert(symbol_expr, equal_expr.rhs());
1181  // insertion has happened
1182  retain_constraint = false;
1183  }
1184  }
1185  }
1186 
1187  if(retain_constraint)
1188  new_constraints.push_back(std::move(expr));
1189  }
1190 
1191  constraints = std::move(new_constraints);
1192 
1193  // apply the map again, to catch any backwards definitions
1194  for(auto &expr : constraints)
1195  {
1196  if(expr.id() == ID_equal && to_equal_expr(expr).lhs().id() == ID_symbol)
1197  {
1198  // it's a definition
1199  }
1200  else
1201  {
1202  // apply the map
1203  values(expr);
1204  }
1205  }
1206 }
1207 
1208 void horn_encoding(const goto_modelt &goto_model, std::ostream &out)
1209 {
1210  const namespacet ns(goto_model.symbol_table);
1211 
1212  container_encoding_targett container;
1213  state_encoding(goto_model, true, container);
1214 
1215  equality_propagation(container.constraints);
1216 
1217  variable_encoding(container.constraints);
1218 
1219  smt2_encoding_targett dest(ns, out);
1220  dest << container;
1221 }
exprt::op2
exprt & op2()
Definition: expr.h:131
ascii_encoding_targett::annotation
void annotation(const std::string &text) override
Definition: horn_encoding.cpp:315
exception_utils.h
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
goto_functiont::body
goto_programt body
Definition: goto_function.h:26
simplifying_not
static exprt simplifying_not(exprt src)
Definition: horn_encoding.cpp:700
to_r_or_w_ok_expr
const r_or_w_ok_exprt & to_r_or_w_ok_expr(const exprt &expr)
Definition: pointer_expr.h:764
to_code_with_contract_type
const code_with_contract_typet & to_code_with_contract_type(const typet &type)
Cast a typet to a code_with_contract_typet.
Definition: c_types.h:447
smt2_conv.h
smt2_encoding_targett::~smt2_encoding_targett
~smt2_encoding_targett()
Definition: horn_encoding.cpp:282
state_encodingt::forall_states_expr
exprt forall_states_expr(loct, exprt) const
Definition: horn_encoding.cpp:564
horn_encoding
void horn_encoding(const goto_modelt &goto_model, std::ostream &out)
Definition: horn_encoding.cpp:1208
horn_encoding.h
replace_symbolt::replaces_symbol
bool replaces_symbol(const irep_idt &id) const
Definition: replace_symbol.h:74
state_encodingt::replace_nondet_rec
exprt replace_nondet_rec(loct, const exprt &, std::vector< symbol_exprt > &nondet_symbols) const
Definition: horn_encoding.cpp:463
ascii_encoding_targett
Definition: horn_encoding.cpp:306
to_update_state_expr
const update_state_exprt & to_update_state_expr(const exprt &expr)
Cast an exprt to a update_state_exprt.
Definition: horn_encoding.cpp:147
address_of_exprt::object
exprt & object()
Definition: pointer_expr.h:380
state_encodingt::incoming
incomingt incoming
Definition: horn_encoding.cpp:393
goto_functionst::sorted
std::vector< function_mapt::const_iterator > sorted() const
returns a vector of the iterators in alphabetical order
Definition: goto_functions.cpp:64
forall_exprt
A forall expression.
Definition: mathematical_expr.h:337
to_dereference_expr
const dereference_exprt & to_dereference_expr(const exprt &expr)
Cast an exprt to a dereference_exprt.
Definition: pointer_expr.h:716
typet
The type of an expression, extends irept.
Definition: type.h:28
allocate_exprt::state
const exprt & state() const
Definition: horn_encoding.cpp:179
field_address_exprt
Operator to return the address of a field relative to a base address.
Definition: pointer_expr.h:494
ternary_exprt
An expression with three operands.
Definition: std_expr.h:48
u8
uint64_t u8
Definition: bytecode_info.h:58
to_index_expr
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
Definition: std_expr.h:1478
replace_symbol.h
source_locationt::nil
static const source_locationt & nil()
Definition: source_location.h:177
state_encodingt::out_state_expr
symbol_exprt out_state_expr(loct) const
Definition: horn_encoding.cpp:396
prefix.h
and_exprt
Boolean AND.
Definition: std_expr.h:2070
goto_model.h
new_state_predicate_type
static typet new_state_predicate_type(const binding_exprt::variablest &variables)
Definition: horn_encoding.cpp:1032
allocate_exprt::allocate_exprt
allocate_exprt(exprt state, exprt address, exprt size)
Definition: horn_encoding.cpp:167
exprt
Base class for all expressions.
Definition: expr.h:55
encoding_targett::~encoding_targett
virtual ~encoding_targett()=default
goto_modelt
Definition: goto_model.h:25
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
binary_exprt
A base class for binary expressions.
Definition: std_expr.h:582
update_state_exprt::address
const exprt & address() const
Definition: horn_encoding.cpp:130
container_encoding_targett::container_encoding_targett
container_encoding_targett()=default
smt2_encoding_targett
Definition: horn_encoding.cpp:271
exprt::op0
exprt & op0()
Definition: expr.h:125
state_encodingt
Definition: horn_encoding.cpp:338
irep_idt
dstringt irep_idt
Definition: irep.h:37
bool_typet
The Boolean type.
Definition: std_types.h:35
state_encodingt::first_loc
loct first_loc
Definition: horn_encoding.cpp:389
to_string
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
Definition: string_constraint.cpp:58
evaluate_exprt::state
exprt & state()
Definition: horn_encoding.cpp:71
to_side_effect_expr
side_effect_exprt & to_side_effect_expr(exprt &expr)
Definition: std_code.h:1506
goto_functionst::function_map
function_mapt function_map
Definition: goto_functions.h:29
symbol_exprt
Expression to hold a symbol (variable)
Definition: std_expr.h:112
evaluate_exprt::address
const exprt & address() const
Definition: horn_encoding.cpp:76
equal_exprt
Equality.
Definition: std_expr.h:1305
container_encoding_targett::constraints
constraintst constraints
Definition: horn_encoding.cpp:245
variable_encoding
exprt variable_encoding(exprt src, const binding_exprt::variablest &variables)
Definition: horn_encoding.cpp:1041
validate_expr
void validate_expr(const shuffle_vector_exprt &value)
Definition: c_expr.h:81
incorrect_goto_program_exceptiont
Thrown when a goto program that's being processed is in an invalid format, for example passing the wr...
Definition: exception_utils.h:91
encoding_targett::set_to_true
virtual void set_to_true(source_locationt, exprt)=0
allocate_exprt::size
const exprt & size() const
Definition: horn_encoding.cpp:194
object_address_exprt::object_expr
symbol_exprt object_expr() const
Definition: pointer_expr.cpp:137
smt2_encoding_targett::set_to_true
void set_to_true(source_locationt, exprt expr) override
Definition: horn_encoding.cpp:288
namespacet
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:90
find_variables_rec
static void find_variables_rec(const exprt &src, std::unordered_set< symbol_exprt, irep_hash > &result)
Definition: horn_encoding.cpp:325
state_encodingt::return_lhs
exprt return_lhs
Definition: horn_encoding.cpp:391
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
to_allocate_expr
const allocate_exprt & to_allocate_expr(const exprt &expr)
Cast an exprt to a allocate_exprt.
Definition: horn_encoding.cpp:206
irept::is_not_nil
bool is_not_nil() const
Definition: irep.h:380
container_encoding_targett::constraintst
std::vector< exprt > constraintst
Definition: horn_encoding.cpp:244
update_state_exprt::state
const exprt & state() const
Definition: horn_encoding.cpp:120
object_address_exprt
Operator to return the address of an object.
Definition: pointer_expr.h:426
to_code_type
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Definition: std_types.h:744
has_prefix
bool has_prefix(const std::string &s, const std::string &prefix)
Definition: converter.cpp:13
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
equality_propagation
void equality_propagation(std::vector< exprt > &constraints)
Definition: horn_encoding.cpp:1152
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:47
to_object_address_expr
const object_address_exprt & to_object_address_expr(const exprt &expr)
Cast an exprt to an object_address_exprt.
Definition: pointer_expr.h:474
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
state_encodingt::goto_functions
const goto_functionst & goto_functions
Definition: horn_encoding.cpp:360
update_state_exprt::state
exprt & state()
Definition: horn_encoding.cpp:125
member_exprt::struct_op
const exprt & struct_op() const
Definition: std_expr.h:2832
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
nil_exprt
The NIL expression.
Definition: std_expr.h:3025
smt2_encoding_targett::smt2_conv
smt2_convt smt2_conv
Definition: horn_encoding.cpp:303
pointer_expr.h
find_variables
std::unordered_set< symbol_exprt, irep_hash > find_variables(const std::vector< exprt > &src)
Definition: horn_encoding.cpp:1021
state_expr
static symbol_exprt state_expr()
Definition: horn_encoding.cpp:47
state_encodingt::setup_incoming
void setup_incoming(const goto_functiont &)
Definition: horn_encoding.cpp:676
exprt::op1
exprt & op1()
Definition: expr.h:128
function_application_exprt
Application of (mathematical) function.
Definition: mathematical_expr.h:196
encoding_targett::annotation
virtual void annotation(const std::string &)
Definition: horn_encoding.cpp:217
binding_exprt::variablest
std::vector< symbol_exprt > variablest
Definition: std_expr.h:3054
mathematical_function_typet::domaint
std::vector< typet > domaint
Definition: mathematical_types.h:63
state_predicate_type
static mathematical_function_typet state_predicate_type()
Definition: horn_encoding.cpp:42
state_encodingt::function_call
void function_call(goto_programt::const_targett, encoding_targett &)
Definition: horn_encoding.cpp:795
pointer_type
pointer_typet pointer_type(const typet &subtype)
Definition: c_types.cpp:253
index_exprt::array
exprt & array()
Definition: std_expr.h:1440
to_symbol_expr
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:222
format_to_string
std::string format_to_string(const T &o)
Definition: format.h:43
irept::is_nil
bool is_nil() const
Definition: irep.h:376
irept::id
const irep_idt & id() const
Definition: irep.h:396
goto_functiont
A goto function, consisting of function body (see body) and parameter identifiers (see parameter_iden...
Definition: goto_function.h:23
exprt::operandst
std::vector< exprt > operandst
Definition: expr.h:58
evaluate_exprt::state
const exprt & state() const
Definition: horn_encoding.cpp:66
unary_exprt::op
const exprt & op() const
Definition: std_expr.h:326
encoding_targett
Definition: horn_encoding.cpp:214
replace_symbolt::insert
void insert(const class symbol_exprt &old_expr, const exprt &new_expr)
Sets old_expr to be replaced by new_expr if we don't already have a replacement; otherwise does nothi...
Definition: replace_symbol.cpp:24
smt2_convt::use_array_of_bool
bool use_array_of_bool
Definition: smt2_conv.h:62
state_encodingt::address_rec
exprt address_rec(loct, const exprt &, exprt) const
Definition: horn_encoding.cpp:585
state_encodingt::incoming_symbols
std::vector< symbol_exprt > incoming_symbols(loct) const
Definition: horn_encoding.cpp:415
std_code.h
update_state_exprt::new_value
const exprt & new_value() const
Definition: horn_encoding.cpp:135
evaluate_exprt::evaluate_exprt
evaluate_exprt(exprt state, exprt address, typet type)
Definition: horn_encoding.cpp:55
state_typet::state_typet
state_typet()
Definition: horn_encoding.cpp:37
state_encoding
void state_encoding(const goto_modelt &goto_model, bool program_is_inlined, encoding_targett &dest)
Definition: horn_encoding.cpp:983
container_encoding_targett::set_to_true
void set_to_true(source_locationt source_location, exprt expr) override
Definition: horn_encoding.cpp:247
smt2_convt
Definition: smt2_conv.h:36
source_locationt
Definition: source_location.h:18
encoding_targett::set_to_true
void set_to_true(exprt expr)
Definition: horn_encoding.cpp:223
allocate_exprt::address
const exprt & address() const
Definition: horn_encoding.cpp:189
side_effect_expr_nondett
A side_effect_exprt that returns a non-deterministically chosen value.
Definition: std_code.h:1519
smt2_encoding_targett::out
std::ostream & out
Definition: horn_encoding.cpp:302
ascii_encoding_targett::out
std::ostream & out
Definition: horn_encoding.cpp:321
state_encodingt::operator()
void operator()(const goto_functionst::function_mapt::const_iterator, encoding_targett &)
Definition: horn_encoding.cpp:818
goto_programt::instructions
instructionst instructions
The list of instructions in the goto program.
Definition: goto_program.h:592
encoding_targett::set_source_location
void set_source_location(source_locationt __source_location)
Definition: horn_encoding.cpp:228
goto_functionst
A collection of goto functions.
Definition: goto_functions.h:24
format_expr.h
state_encodingt::evaluate_expr_rec
exprt evaluate_expr_rec(loct, const exprt &, const exprt &, const std::unordered_set< symbol_exprt, irep_hash > &) const
Definition: horn_encoding.cpp:492
code_with_contract_typet::has_contract
bool has_contract() const
Definition: c_types.h:369
state_encodingt::assignment_constraint
exprt assignment_constraint(loct, exprt lhs, exprt rhs) const
Definition: horn_encoding.cpp:652
state_encodingt::in_state_expr
symbol_exprt in_state_expr(loct) const
Definition: horn_encoding.cpp:442
update_state_exprt::update_state_exprt
update_state_exprt(exprt state, exprt address, exprt new_value)
Definition: horn_encoding.cpp:108
smt2_encoding_targett::annotation
void annotation(const std::string &text) override
Definition: horn_encoding.cpp:293
goto_modelt::goto_functions
goto_functionst goto_functions
GOTO functions.
Definition: goto_model.h:33
smt2_encoding_targett::smt2_encoding_targett
smt2_encoding_targett(const namespacet &ns, std::ostream &_out)
Definition: horn_encoding.cpp:274
to_quantifier_expr
const quantifier_exprt & to_quantifier_expr(const exprt &expr)
Cast an exprt to a quantifier_exprt.
Definition: mathematical_expr.h:319
update_state_exprt
Definition: horn_encoding.cpp:105
to_not_expr
const not_exprt & to_not_expr(const exprt &expr)
Cast an exprt to an not_exprt.
Definition: std_expr.h:2303
lambda_exprt
A (mathematical) lambda expression.
Definition: mathematical_expr.h:421
evaluate_exprt
Definition: horn_encoding.cpp:52
container_encoding_targett::last_source_location
source_locationt last_source_location
Definition: horn_encoding.cpp:256
state_encodingt::function_call_symbol
void function_call_symbol(goto_programt::const_targett, encoding_targett &)
Definition: horn_encoding.cpp:708
CPROVER_PREFIX
#define CPROVER_PREFIX
Definition: cprover_prefix.h:14
allocate_exprt::state
exprt & state()
Definition: horn_encoding.cpp:184
to_array_type
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
Definition: std_types.h:844
to_equal_expr
const equal_exprt & to_equal_expr(const exprt &expr)
Cast an exprt to an equal_exprt.
Definition: std_expr.h:1347
state_encodingt::evaluate_expr
exprt evaluate_expr(loct, const exprt &, const exprt &) const
Definition: horn_encoding.cpp:455
to_evaluate_expr
const evaluate_exprt & to_evaluate_expr(const exprt &expr)
Cast an exprt to a evaluate_exprt.
Definition: horn_encoding.cpp:88
state_encodingt::state_lambda_expr
static exprt state_lambda_expr(exprt)
Definition: horn_encoding.cpp:559
to_member_expr
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
Definition: std_expr.h:2886
goto_programt::const_targett
instructionst::const_iterator const_targett
Definition: goto_program.h:587
state_encodingt::entry_state
symbol_exprt entry_state
Definition: horn_encoding.cpp:390
state_encodingt::state_expr_with_suffix
symbol_exprt state_expr_with_suffix(loct, const std::string &suffix) const
Definition: horn_encoding.cpp:401
member_exprt::get_component_name
irep_idt get_component_name() const
Definition: std_expr.h:2816
implies_exprt
Boolean implication.
Definition: std_expr.h:2133
tuple_exprt
Definition: mathematical_expr.h:181
state_encodingt::state_encodingt
state_encodingt(const goto_functionst &__goto_functions)
Definition: horn_encoding.cpp:341
to_address_of_expr
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
Definition: pointer_expr.h:408
ascii_encoding_targett::ascii_encoding_targett
ascii_encoding_targett(std::ostream &_out)
Definition: horn_encoding.cpp:309
exprt::operands
operandst & operands()
Definition: expr.h:94
state_typet
Definition: horn_encoding.cpp:34
goto_functionst::entry_point
static irep_idt entry_point()
Get the identifier of the entry point to a goto model.
Definition: goto_functions.h:92
forall_expr
#define forall_expr(it, expr)
Definition: expr.h:32
state_encodingt::incomingt
std::map< loct, std::vector< loct > > incomingt
Definition: horn_encoding.cpp:392
exprt::add_source_location
source_locationt & add_source_location()
Definition: expr.h:216
encoding_targett::source_location
source_locationt source_location
Definition: horn_encoding.cpp:236
container_encoding_targett
Definition: horn_encoding.cpp:239
smt2_convt::use_as_const
bool use_as_const
Definition: smt2_conv.h:63
state_encodingt::annotation
std::string annotation
Definition: horn_encoding.cpp:388
true_exprt
The Boolean constant true.
Definition: std_expr.h:3007
ascii_encoding_targett::set_to_true
void set_to_true(source_locationt, exprt) override
element_address_exprt
Operator to return the address of an array element relative to a base address.
Definition: pointer_expr.h:578
allocate_exprt
Definition: horn_encoding.cpp:164
std_expr.h
state_encodingt::encode
void encode(const goto_functiont &, const std::string &state_prefix, const std::string &annotation, const symbol_exprt &entry_state, const exprt &return_lhs, encoding_targett &)
Definition: horn_encoding.cpp:840
exprt::source_location
const source_locationt & source_location() const
Definition: expr.h:211
operator<<
static void operator<<(encoding_targett &target, exprt constraint)
Definition: horn_encoding.cpp:259
goto_modelt::symbol_table
symbol_tablet symbol_table
Symbol table.
Definition: goto_model.h:30
mathematical_function_typet
A type for mathematical functions (do not confuse with functions/methods in code)
Definition: mathematical_types.h:58
c_types.h
to_function_application_expr
const function_application_exprt & to_function_application_expr(const exprt &expr)
Cast an exprt to a function_application_exprt.
Definition: mathematical_expr.h:247
state_encodingt::state_prefix
std::string state_prefix
Definition: horn_encoding.cpp:387
forall_goto_program_instructions
#define forall_goto_program_instructions(it, program)
Definition: goto_program.h:1229
ascii_encoding_targett::counter
std::size_t counter
Definition: horn_encoding.cpp:322
to_forall_expr
const forall_exprt & to_forall_expr(const exprt &expr)
Definition: mathematical_expr.h:362
state_encodingt::loct
goto_programt::const_targett loct
Definition: horn_encoding.cpp:359
replace_symbolt
Replace a symbol expression by a given expression.
Definition: replace_symbol.h:27
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
mathematical_expr.h
not_exprt
Boolean negation.
Definition: std_expr.h:2277