CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
solver.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Solver
4
5Author: Daniel Kroening, dkr@amazon.com
6
7\*******************************************************************/
8
11
12#include "solver.h"
13
14#include <util/format_expr.h>
15
16#include "address_taken.h"
17#include "generalization.h"
18#include "inductiveness.h"
19#include "report_properties.h"
20#include "report_traces.h"
21#include "solver_progress.h"
22#include "solver_types.h"
23
24#include <iostream>
25
27{
28public:
30 std::chrono::time_point<std::chrono::steady_clock> &_dest)
31 : dest(_dest)
32 {
33 }
34
36 {
37 dest = std::chrono::steady_clock::now();
38 }
39
40protected:
41 std::chrono::time_point<std::chrono::steady_clock> &dest;
42};
43
44void solver(
45 std::vector<framet> &frames,
46 const std::unordered_set<symbol_exprt, irep_hash> &address_taken,
48 const namespacet &ns,
49 std::vector<propertyt> &properties,
50 std::size_t property_index)
51{
52 auto &property = properties[property_index];
53
54 property.start = std::chrono::steady_clock::now();
56
57 // Clean up
58 for(auto &frame : frames)
59 frame.reset();
60
61 // We start with I = P.
62 frames[property.frame.index].add_invariant(property.condition);
63
64 for(unsigned iteration = 0; true; iteration++)
65 {
66 if(iteration == 3) // limit the effort
67 {
68 property.status = propertyt::DROPPED;
69 return; // give up
70 }
71
72 if(solver_options.verbose)
73 std::cout << "Doing " << format(property.condition) << " iteration "
74 << iteration + 1 << '\n';
75
76 auto result = inductiveness_check(
78
79 switch(result.outcome)
80 {
82 property.status = propertyt::PASS;
83 return; // done
84
86 if(iteration == 0)
87 {
88 // no generalization done, so this is a counterexample
89 property.status = propertyt::REFUTED;
90 return; // DONE
91 }
92 else
93 {
94 // Invariant was generalized too much. Try something weaker.
95 property.status = propertyt::DROPPED;
96 return;
97 }
98
100 // Invariant is too weak or too strong to be inductive.
102 break;
103 }
104 }
105}
106
108 const std::vector<exprt> &constraints,
110 const namespacet &ns)
111{
112 const auto address_taken = ::address_taken(constraints);
113
114#if 0
115 if(solver_options.verbose)
116 {
117 for(auto &a : address_taken)
118 std::cout << "address_taken: " << format(a) << '\n';
119 }
120#endif
121
122 auto frames = setup_frames(constraints);
123
124 find_implications(constraints, frames);
125
126 auto properties = find_properties(constraints, frames);
127
128 if(properties.empty())
129 {
130 std::cout << "\nThere are no properties to show.\n";
132 }
133
134 solver_progresst solver_progress(properties.size(), solver_options.verbose);
135
136 // solve each property separately, in order of occurence
137 for(std::size_t i = 0; i < properties.size(); i++)
138 {
140 solver(frames, address_taken, solver_options, ns, properties, i);
141 }
142
143 solver_progress.finished();
144
145 // reporting
146 report_properties(properties);
147
148 if(solver_options.trace)
149 report_traces(frames, properties, solver_options.verbose, ns);
150
151 // overall outcome
152 return overall_outcome(properties);
153}
std::unordered_set< symbol_exprt, irep_hash > address_taken(const std::vector< exprt > &src)
Address Taken.
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
ait()
Definition ai.h:565
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition namespace.h:91
std::chrono::time_point< std::chrono::steady_clock > & dest
Definition solver.cpp:41
take_time_resourcet(std::chrono::time_point< std::chrono::steady_clock > &_dest)
Definition solver.cpp:29
static format_containert< T > format(const T &o)
Definition format.h:37
void generalization(std::vector< framet > &frames, const workt &dropped, const propertyt &property, const solver_optionst &solver_options)
Generalization.
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)
Inductiveness.
solver_resultt overall_outcome(const std::vector< propertyt > &properties)
void report_properties(const std::vector< propertyt > &properties)
Property Reporting.
void report_traces(const std::vector< framet > &frames, const std::vector< propertyt > &properties, bool verbose, const namespacet &ns)
Report Traces.
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)
Definition solver.cpp:44
Equality Propagation.
solver_resultt
Definition solver.h:21
Solver Progress Reporting.
std::vector< framet > setup_frames(const std::vector< exprt > &constraints)
void find_implications(const std::vector< exprt > &constraints, std::vector< framet > &frames)
std::vector< propertyt > find_properties(const std::vector< exprt > &constraints, const std::vector< framet > &frames)