CBMC
variable_encoding.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Variable Encoding
4 
5 Author: Daniel Kroening, dkr@amazon.com
6 
7 \*******************************************************************/
8 
11 
12 #include "variable_encoding.h"
13 
14 #include <util/exception_utils.h>
15 #include <util/format_expr.h>
16 #include <util/mathematical_expr.h>
17 #include <util/pointer_expr.h>
18 
19 #include "find_variables.h"
20 #include "state.h"
21 
22 #include <algorithm>
23 
25 {
26  // operands first
27  for(auto &op : src.operands())
28  op = variable_encoding(op, variables);
29 
30  if(src.id() == ID_forall)
31  {
32  auto &forall_expr = to_forall_expr(src);
33  if(
34  forall_expr.variables().size() == 1 &&
35  forall_expr.symbol().type().id() == ID_state)
36  {
38  .variables() = variables;
39  return std::move(forall_expr);
40  }
41  }
42  else if(src.id() == ID_function_application)
43  {
44  auto &function_application = to_function_application_expr(src);
45  if(
46  function_application.arguments().size() == 1 &&
47  function_application.arguments().front().type().id() == ID_state)
48  {
49  if(function_application.arguments().front().id() == ID_symbol)
50  {
51  exprt::operandst new_arguments;
52  for(auto &v : variables)
53  new_arguments.push_back(v);
54  function_application.arguments() = new_arguments;
55  }
56  else if(function_application.arguments().front().id() == ID_tuple)
57  {
59  function_application.arguments().front().operands().size() ==
60  variables.size(),
61  "tuple size must match");
62  auto operands = function_application.arguments().front().operands();
63  function_application.arguments() = operands;
64  }
65  else
66  throw analysis_exceptiont("can't convert " + format_to_string(src));
67  }
68  else
69  throw analysis_exceptiont("can't convert " + format_to_string(src));
70  }
71  else if(src.id() == ID_evaluate)
72  {
73  auto &evaluate_expr = to_evaluate_expr(src);
74  if(evaluate_expr.address().id() == ID_object_address)
75  return symbol_exprt(
76  to_object_address_expr(evaluate_expr.address()).object_expr());
77  else
78  throw analysis_exceptiont("can't convert " + format_to_string(src));
79  }
80  else if(src.id() == ID_update_state)
81  {
82  auto &update_state_expr = to_update_state_expr(src);
83  if(update_state_expr.address().id() == ID_object_address)
84  {
85  auto lhs_symbol =
86  to_object_address_expr(update_state_expr.address()).object_expr();
87  exprt::operandst operands;
88  for(auto &v : variables)
89  {
90  if(v == lhs_symbol)
91  operands.push_back(update_state_expr.new_value());
92  else
93  operands.push_back(v);
94  }
95  return tuple_exprt(operands, typet(ID_state));
96  }
97  else
98  throw analysis_exceptiont("can't convert " + format_to_string(src));
99  }
100 
101  return src;
102 }
103 
104 void variable_encoding(std::vector<exprt> &constraints)
105 {
106  binding_exprt::variablest variables;
107 
108  for(auto &v : find_variables(constraints))
109  variables.push_back(v);
110 
111  if(variables.empty())
112  throw analysis_exceptiont("no variables found");
113 
114  // sort alphabetically
115  std::sort(
116  variables.begin(),
117  variables.end(),
118  [](const symbol_exprt &a, const symbol_exprt &b) {
119  return id2string(a.get_identifier()) < id2string(b.get_identifier());
120  });
121 
122  for(auto &c : constraints)
123  c = variable_encoding(c, variables);
124 }
Thrown when an unexpected error occurs during the analysis (e.g., when the SAT solver returns an erro...
std::vector< symbol_exprt > variablest
Definition: std_expr.h:3101
Base class for all expressions.
Definition: expr.h:56
std::vector< exprt > operandst
Definition: expr.h:58
operandst & operands()
Definition: expr.h:94
const irep_idt & id() const
Definition: irep.h:384
symbol_exprt object_expr() const
Expression to hold a symbol (variable)
Definition: std_expr.h:131
The type of an expression, extends irept.
Definition: type.h:29
#define forall_expr(it, expr)
Definition: expr.h:32
std::unordered_set< symbol_exprt, irep_hash > find_variables(const std::vector< exprt > &src)
Returns the set of program variables (as identified by object_address expressions) in the given expre...
Find Variables.
std::string format_to_string(const T &o)
Definition: format.h:43
API to expression classes for 'mathematical' expressions.
const function_application_exprt & to_function_application_expr(const exprt &expr)
Cast an exprt to a function_application_exprt.
const forall_exprt & to_forall_expr(const exprt &expr)
API to expression classes for Pointers.
const object_address_exprt & to_object_address_expr(const exprt &expr)
Cast an exprt to an object_address_exprt.
Definition: pointer_expr.h:643
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition: invariant.h:534
const update_state_exprt & to_update_state_expr(const exprt &expr)
Cast an exprt to a update_state_exprt.
Definition: state.h:200
const evaluate_exprt & to_evaluate_expr(const exprt &expr)
Cast an exprt to a evaluate_exprt.
Definition: state.h:130
exprt variable_encoding(exprt src, const binding_exprt::variablest &variables)
Variable Encoding.