CBMC
Loading...
Searching...
No Matches
ai_history.h
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Abstract Interpretation
4
5Author: Martin Brain, martin.brain@cs.ox.ac.uk
6
7\*******************************************************************/
8
11
12#ifndef CPROVER_ANALYSES_AI_HISTORY_H
13#define CPROVER_ANALYSES_AI_HISTORY_H
14
15#include <memory>
16
17#include <util/json.h>
18#include <util/xml.h>
19
21
34
37{
38public:
40
43 typedef std::shared_ptr<const ai_history_baset> trace_ptrt;
44
45protected:
50 {
51 }
52
56
57public:
59 {
60 }
61
73 {
74 bool operator()(const trace_ptrt &l, const trace_ptrt &r) const
75 {
76 return *l < *r;
77 }
78 };
79 typedef std::set<trace_ptrt, compare_historyt> trace_sett; // Order matters!
80
81 enum class step_statust
82 {
83 NEW,
84 MERGED,
86 };
87
88 typedef std::pair<step_statust, trace_ptrt> step_returnt;
118 const trace_sett &others,
119 trace_ptrt caller_hist) const = 0;
120
122
124 virtual bool operator<(const ai_history_baset &op) const = 0;
125
127 virtual bool operator==(const ai_history_baset &op) const = 0;
128
131 virtual const locationt &current_location(void) const = 0;
132
139 virtual bool should_widen(const ai_history_baset &other) const
140 {
141 return false;
142 }
143
144 virtual void output(std::ostream &out) const
145 {
146 }
147 virtual jsont output_json(void) const;
148 virtual xmlt output_xml(void) const;
149};
150
155{
156protected:
157 // DATA_INVARIANT(current.is_dereferenceable(), "Must not be _::end()")
159
160public:
162 {
163 }
164
166 : ai_history_baset(old), current(old.current)
167 {
168 }
169
172 const trace_sett &others,
173 trace_ptrt caller_hist) const override
174 {
175 trace_ptrt next(new ahistoricalt(to));
176
177 if(others.empty())
178 {
179 return std::make_pair(step_statust::NEW, next);
180 }
181 else
182 {
183 // Aggressively merge histories because they are indistinguishable
184 INVARIANT(others.size() == 1, "Only needs one history per location");
185
186 const auto it = others.begin();
187 INVARIANT(
188 *(*(it)) == *next,
189 "The next location in history map must contain next history");
190
191 return std::make_pair(step_statust::MERGED, *it);
192 }
193 }
194
195 bool operator<(const ai_history_baset &op) const override
196 {
197 PRECONDITION(dynamic_cast<const ahistoricalt *>(&op) != nullptr);
198
199 return this->current_location()->location_number <
200 op.current_location()->location_number;
201 }
202
203 bool operator==(const ai_history_baset &op) const override
204 {
205 PRECONDITION(dynamic_cast<const ahistoricalt *>(&op) != nullptr);
206
207 // It would be nice to:
208 // return this->current == op.current
209 // But they may point to different goto_programs,
210 // giving undefined behaviour in C++
211 // So (safe due to data invariant & uniqueness of location numbers) ...
212 return this->current_location()->location_number ==
213 op.current_location()->location_number;
214 }
215
216 const locationt &current_location(void) const override
217 {
218 return current;
219 }
220
221 // Use default widening
222 // without history there is no reason to say any location is better than
223 // another to widen.
224 bool should_widen(const ai_history_baset &other) const override
225 {
226 return ai_history_baset::should_widen(other);
227 }
228
229 void output(std::ostream &out) const override
230 {
231 out << "ahistorical : location " << current_location()->location_number;
232 }
233};
234
235
251
253template <typename traceT>
263
264#endif // CPROVER_ANALYSES_AI_HISTORY_H
The common case of history is to only care about where you are now, not how you got there!...
Definition ai_history.h:155
ahistoricalt(locationt l)
Definition ai_history.h:161
locationt current
Definition ai_history.h:158
bool operator==(const ai_history_baset &op) const override
History objects should be comparable.
Definition ai_history.h:203
const locationt & current_location(void) const override
The current location in the history, used to compute the transformer POSTCONDITION(return value is de...
Definition ai_history.h:216
bool operator<(const ai_history_baset &op) const override
The order for history_sett.
Definition ai_history.h:195
ahistoricalt(const ahistoricalt &old)
Definition ai_history.h:165
step_returnt step(locationt to, const trace_sett &others, trace_ptrt caller_hist) const override
Step creates a new history by advancing the current one to location "to" It is given the set of all o...
Definition ai_history.h:170
bool should_widen(const ai_history_baset &other) const override
Domains with a substantial height may need to widen when merging this method allows the history to pr...
Definition ai_history.h:224
void output(std::ostream &out) const override
Definition ai_history.h:229
A history object is an abstraction / representation of the control-flow part of a set of traces.
Definition ai_history.h:37
virtual const locationt & current_location(void) const =0
The current location in the history, used to compute the transformer POSTCONDITION(return value is de...
std::shared_ptr< const ai_history_baset > trace_ptrt
History objects are intended to be immutable so they can be shared to reduce memory overhead.
Definition ai_history.h:43
ai_history_baset(const ai_history_baset &)
Definition ai_history.h:53
std::pair< step_statust, trace_ptrt > step_returnt
Definition ai_history.h:88
virtual bool operator<(const ai_history_baset &op) const =0
The order for history_sett.
virtual void output(std::ostream &out) const
Definition ai_history.h:144
static const trace_ptrt no_caller_history
Definition ai_history.h:121
virtual step_returnt step(locationt to, const trace_sett &others, trace_ptrt caller_hist) const =0
Step creates a new history by advancing the current one to location "to" It is given the set of all o...
virtual bool should_widen(const ai_history_baset &other) const
Domains with a substantial height may need to widen when merging this method allows the history to pr...
Definition ai_history.h:139
ai_history_baset(locationt)
Create a new history starting from a given location This is used to start the analysis from scratch P...
Definition ai_history.h:49
virtual jsont output_json(void) const
goto_programt::const_targett locationt
Definition ai_history.h:39
virtual bool operator==(const ai_history_baset &op) const =0
History objects should be comparable.
virtual xmlt output_xml(void) const
virtual ~ai_history_baset()
Definition ai_history.h:58
std::set< trace_ptrt, compare_historyt > trace_sett
Definition ai_history.h:79
As more detailed histories can get complex (for example, nested loops or deep, mutually recursive cal...
Definition ai_history.h:242
virtual ai_history_baset::trace_ptrt epoch(ai_history_baset::locationt)=0
Creates a new history from the given starting point.
virtual ~ai_history_factory_baset()
Definition ai_history.h:247
An easy factory implementation for histories that don't need parameters.
Definition ai_history.h:255
ai_history_baset::trace_ptrt epoch(ai_history_baset::locationt l) override
Creates a new history from the given starting point.
Definition ai_history.h:257
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
instructionst::const_iterator const_targett
Definition json.h:27
Definition xml.h:21
Concrete Goto Program.
static int8_t r
Definition irep_hash.h:60
#define PRECONDITION(CONDITION)
Definition invariant.h:463
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition invariant.h:423
In a number of places we need to work with sets of histories so that these (a) make use of the immuta...
Definition ai_history.h:73
bool operator()(const trace_ptrt &l, const trace_ptrt &r) const
Definition ai_history.h:74