CBMC
solver_types.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Solver Types
4 
5 Author: Daniel Kroening, dkr@amazon.com
6 
7 \*******************************************************************/
8 
11 
12 #include "solver_types.h"
13 
14 #include <util/format_expr.h>
15 
16 #include "free_symbols.h"
17 
18 #include <iostream>
19 #include <set>
20 
22 {
23  if(invariant.id() == ID_and)
24  {
25  for(const auto &conjunct : to_and_expr(invariant).operands())
26  add_auxiliary(conjunct);
27  }
28  else
29  {
30  auxiliaries_set.insert(invariant);
31  auxiliaries.push_back(std::move(invariant));
32  }
33 }
34 
36 {
37  if(invariant.id() == ID_and)
38  {
39  for(const auto &conjunct : to_and_expr(invariant).operands())
40  add_invariant(conjunct);
41  }
42  else
43  {
44  invariants_set.insert(invariant);
45  invariants.push_back(std::move(invariant));
46  }
47 }
48 
49 void framet::add_obligation(exprt obligation)
50 {
51  if(obligation.id() == ID_and)
52  {
53  for(const auto &conjunct : to_and_expr(obligation).operands())
54  add_obligation(conjunct);
55  }
56  else
57  {
58  obligations_set.insert(obligation);
59  obligations.push_back(std::move(obligation));
60  }
61 }
62 
63 frame_mapt build_frame_map(const std::vector<framet> &frames)
64 {
65  frame_mapt frame_map;
66 
67  for(std::size_t i = 0; i < frames.size(); i++)
68  frame_map[frames[i].symbol] = frame_reft(i);
69 
70  return frame_map;
71 }
72 
73 std::vector<framet> setup_frames(const std::vector<exprt> &constraints)
74 {
75  std::set<symbol_exprt> states_set;
76  std::vector<framet> frames;
77 
78  for(auto &c : constraints)
79  {
80  auto &location = c.source_location();
81  free_symbols(c, [&states_set, &location, &frames](const symbol_exprt &s) {
82  auto insert_result = states_set.insert(s);
83  if(insert_result.second)
84  frames.emplace_back(s, location, frame_reft(frames.size()));
85  });
86  }
87 
88  return frames;
89 }
90 
92  const std::vector<exprt> &constraints,
93  std::vector<framet> &frames)
94 {
95  const auto frame_map = build_frame_map(frames);
96 
97  for(const auto &c : constraints)
98  {
99  // look for ∀ ς : state . Sxx(ς) ⇒ Syy(...)
100  // and ∀ ς : state . Sxx(ς) ⇒ ...
101  if(c.id() == ID_forall && to_forall_expr(c).where().id() == ID_implies)
102  {
103  auto &implication = to_implies_expr(to_forall_expr(c).where());
104 
105  if(
106  implication.rhs().id() == ID_function_application &&
108  ID_symbol)
109  {
110  auto &rhs_symbol = to_symbol_expr(
112  auto s_it = frame_map.find(rhs_symbol);
113  if(s_it != frame_map.end())
114  {
115  frames[s_it->second.index].implications.emplace_back(
117  }
118  }
119  }
120  }
121 }
122 
124 find_frame(const frame_mapt &frame_map, const symbol_exprt &frame_symbol)
125 {
126  auto entry = frame_map.find(frame_symbol);
127 
128  if(entry == frame_map.end())
129  PRECONDITION(false);
130 
131  return entry->second;
132 }
133 
134 std::vector<propertyt> find_properties(
135  const std::vector<exprt> &constraints,
136  const std::vector<framet> &frames)
137 {
138  const auto frame_map = build_frame_map(frames);
139  std::vector<propertyt> properties;
140 
141  for(const auto &c : constraints)
142  {
143  // look for ∀ ς : state . Sxx(ς) ⇒ ...
144  if(c.id() == ID_forall && to_forall_expr(c).where().id() == ID_implies)
145  {
146  auto &implication = to_implies_expr(to_forall_expr(c).where());
147 
148  if(
149  implication.rhs().id() != ID_function_application &&
150  implication.lhs().id() == ID_function_application &&
152  ID_symbol)
153  {
154  auto &lhs_symbol = to_symbol_expr(
156  auto lhs_frame = find_frame(frame_map, lhs_symbol);
157  properties.emplace_back(
158  c.source_location(), lhs_frame, implication.rhs());
159  }
160  }
161  }
162 
163  return properties;
164 }
165 
167 {
168  // Sxx(ς) ⇒ p(ς)
169  return src.rhs();
170 }
171 
172 void dump(
173  const std::vector<framet> &frames,
174  const propertyt &property,
175  bool values,
176  bool implications)
177 {
178  for(const auto &f : frames)
179  {
180  std::cout << "FRAME: " << format(f.symbol) << '\n';
181 
182  if(implications)
183  {
184  for(auto &c : f.implications)
185  {
186  std::cout << " implication: ";
187  std::cout << format(c.lhs) << " -> " << format(c.rhs);
188  std::cout << '\n';
189  }
190  }
191 
192  if(values)
193  {
194  for(auto &i : f.invariants)
195  std::cout << " invariant: " << format(i) << '\n';
196 
197  for(auto &i : f.obligations)
198  std::cout << " obligation: " << format(i) << '\n';
199 
200  for(auto &i : f.auxiliaries)
201  std::cout << " auxiliary: " << format(i) << '\n';
202  }
203 
204  if(property.frame == f.ref)
205  std::cout << " property: " << format(property.condition) << '\n';
206  }
207 }
exprt & rhs()
Definition: std_expr.h:678
Base class for all expressions.
Definition: expr.h:56
std::unordered_set< exprt, irep_hash > invariants_set
Definition: solver_types.h:57
std::vector< exprt > obligations
Definition: solver_types.h:60
std::unordered_set< exprt, irep_hash > auxiliaries_set
Definition: solver_types.h:65
void add_invariant(exprt)
void add_auxiliary(exprt)
std::unordered_set< exprt, irep_hash > obligations_set
Definition: solver_types.h:61
std::vector< exprt > auxiliaries
Definition: solver_types.h:64
void add_obligation(exprt)
std::vector< exprt > invariants
Definition: solver_types.h:56
Boolean implication.
Definition: std_expr.h:2183
const irep_idt & id() const
Definition: irep.h:388
exprt condition
Definition: solver_types.h:135
frame_reft frame
Definition: solver_types.h:134
Expression to hold a symbol (variable)
Definition: std_expr.h:131
static format_containert< T > format(const T &o)
Definition: format.h:37
void free_symbols(const exprt &expr, const std::function< void(const symbol_exprt &)> &f)
Free Symbols.
static exprt implication(exprt lhs, exprt rhs)
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)
frame_reft find_frame(const frame_mapt &frame_map, const symbol_exprt &frame_symbol)
std::vector< propertyt > find_properties(const std::vector< exprt > &constraints, const std::vector< framet > &frames)
frame_mapt build_frame_map(const std::vector< framet > &frames)
void find_implications(const std::vector< exprt > &constraints, std::vector< framet > &frames)
std::vector< framet > setup_frames(const std::vector< exprt > &constraints)
exprt property_predicate(const implies_exprt &src)
void dump(const std::vector< framet > &frames, const propertyt &property, bool values, bool implications)
std::unordered_map< symbol_exprt, frame_reft, irep_hash > frame_mapt
Definition: solver_types.h:38
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:272
const and_exprt & to_and_expr(const exprt &expr)
Cast an exprt to a and_exprt.
Definition: std_expr.h:2167
const implies_exprt & to_implies_expr(const exprt &expr)
Cast an exprt to a implies_exprt.
Definition: std_expr.h:2208