31 const std::unordered_set<exprt, irep_hash> &a1,
32 const std::unordered_set<exprt, irep_hash> &a2,
33 const std::unordered_set<exprt, irep_hash> &a3,
35 const std::unordered_set<symbol_exprt, irep_hash> &
address_taken,
45 if(a1.find(b) != a1.end())
54 satcheckt satcheck(message_handler);
61 for(
auto &a_conjunct : a1)
64 for(
auto &a_conjunct : a2)
67 for(
auto &a_conjunct : a3)
85 throw "error reported by solver";
93 return std::count_if(path.begin(), path.end(), [f](
const frame_reft &frame) {
99 std::vector<framet> &frames,
100 const std::unordered_set<symbol_exprt, irep_hash> &
address_taken,
103 std::vector<propertyt> &properties,
104 std::size_t property_index)
107 auto &
property = properties[property_index];
110 for(std::size_t i = 0; i < property_index; i++)
112 const auto &p = properties[i];
113 if(p.status == propertyt::PASS)
114 frames[p.frame.index].add_auxiliary(p.condition);
117 std::vector<workt> queue;
118 std::vector<workt> dropped;
129 auto frame_ref =
find_frame(frame_map, symbol);
130 auto &f = frames[frame_ref.index];
135 std::cout <<
"F: " <<
format(symbol) <<
" <- " <<
format(invariant)
143 for(
const auto &invariant : f.invariants)
146 std::cout <<
'I' << std::setw(2) << frame_ref.index <<
' ';
147 std::cout <<
format(invariant);
150 for(
const auto &obligation : f.obligations)
153 std::cout <<
'O' << std::setw(2) << frame_ref.index <<
' ';
154 std::cout <<
format(obligation);
164 if(invariant.is_true())
167 std::cout <<
"trivial\n";
179 std::cout <<
"subsumed " <<
format(invariant) <<
'\n';
186 <<
format(invariant) <<
'\n';
187 dropped.emplace_back(frame_ref, invariant, path);
193 std::cout <<
format(invariant) <<
'\n';
196 frames[frame_ref.index].add_obligation(invariant);
199 auto new_path = path;
200 new_path.push_back(frame_ref);
201 queue.emplace_back(f.ref, std::move(invariant), std::move(new_path));
206 for(std::size_t frame_index = 0; frame_index < frames.size(); frame_index++)
209 for(
auto &cond : frames[frame_index].invariants)
210 queue.emplace_back(frame_ref, cond,
workt::patht{frame_ref});
214 for(
auto &frame : frames)
216 frame.obligations.clear();
217 frame.obligations_set.clear();
220 while(!queue.empty())
222 auto work = queue.back();
228 dump(frames, property,
true,
true);
std::unordered_set< symbol_exprt, irep_hash > address_taken(const std::vector< exprt > &src)
static std::ostream & blue(std::ostream &)
static std::ostream & reset(std::ostream &)
static std::ostream & faint(std::ostream &)
static std::ostream & red(std::ostream &)
Base class for all expressions.
bool is_true() const
Return whether the expression is a constant representing true.
The Boolean constant false.
static inductiveness_resultt inductive()
static inductiveness_resultt step_case_fail(workt dropped)
static inductiveness_resultt base_case_fail(workt refuted)
void set_verbosity(unsigned _verbosity)
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Expression to hold a symbol (variable)
std::optional< propertyt::tracet > counterexample_found(const std::vector< framet > &frames, const workt &work, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, bool verbose, const namespacet &ns)
void show_assignment(const bv_pointers_widet &solver)
inductiveness_resultt inductiveness_check(std::vector< framet > &frames, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, const solver_optionst &solver_options, const namespacet &ns, std::vector< propertyt > &properties, std::size_t property_index)
std::size_t count_frame(const workt::patht &path, frame_reft f)
bool is_subsumed(const std::unordered_set< exprt, irep_hash > &a1, const std::unordered_set< exprt, irep_hash > &a2, const std::unordered_set< exprt, irep_hash > &a3, const exprt &b, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, bool verbose, const namespacet &ns)
void propagate(const std::vector< framet > &frames, const workt &work, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, bool verbose, const namespacet &ns, const std::function< void(const symbol_exprt &, exprt, const workt::patht &)> &propagator)
void solver(std::vector< framet > &frames, const std::unordered_set< symbol_exprt, irep_hash > &address_taken, const solver_optionst &solver_options, const namespacet &ns, std::vector< propertyt > &properties, std::size_t property_index)
frame_reft find_frame(const frame_mapt &frame_map, const symbol_exprt &frame_symbol)
frame_mapt build_frame_map(const std::vector< framet > &frames)
void dump(const std::vector< framet > &frames, const propertyt &property, bool values, bool implications)
#define UNREACHABLE
This should be used to mark dead code.
std::vector< frame_reft > patht