@@ -212,4 +212,82 @@ class location_sensitive_storaget : public trace_map_storaget
212
212
}
213
213
};
214
214
215
+ // The most precise form of storage
216
+ class history_sensitive_storaget : public trace_map_storaget
217
+ {
218
+ protected:
219
+ typedef std::map<trace_ptrt, state_ptrt, ai_history_baset::compare_historyt>
220
+ domain_mapt;
221
+ domain_mapt domain_map;
222
+
223
+ public:
224
+ cstate_ptrt abstract_state_before (
225
+ trace_ptrt p,
226
+ const ai_domain_factory_baset &fac) const override
227
+ {
228
+ auto it = domain_map.find (p);
229
+ if (it == domain_map.end ())
230
+ return fac.make (p->current_location ());
231
+
232
+ return it->second ;
233
+ }
234
+
235
+ cstate_ptrt abstract_state_before (
236
+ locationt t,
237
+ const ai_domain_factory_baset &fac) const override
238
+ {
239
+ auto traces = abstract_traces_before (t);
240
+
241
+ if (traces->size () == 0 )
242
+ {
243
+ return fac.make (t);
244
+ }
245
+ else if (traces->size () == 1 )
246
+ {
247
+ auto it = domain_map.find (*(traces->begin ()));
248
+ DATA_INVARIANT (
249
+ it != domain_map.end (), " domain_map must be in sync with trace_map" );
250
+ return it->second ;
251
+ }
252
+ else
253
+ {
254
+ // Need to merge all of the traces that reach this location
255
+ auto res = fac.make (t);
256
+
257
+ for (auto p : *traces)
258
+ {
259
+ auto it = domain_map.find (p);
260
+ DATA_INVARIANT (
261
+ it != domain_map.end (), " domain_map must be in sync with trace_map" );
262
+ fac.merge (*res, *(it->second ), p, p);
263
+ }
264
+
265
+ return cstate_ptrt (res.release ());
266
+ }
267
+ }
268
+
269
+ statet &get_state (trace_ptrt p, const ai_domain_factory_baset &fac) override
270
+ {
271
+ register_trace (p);
272
+
273
+ auto it = domain_map.find (p);
274
+ if (it == domain_map.end ())
275
+ {
276
+ std::shared_ptr<statet> d (fac.make (p->current_location ()));
277
+ auto jt = domain_map.emplace (p, d);
278
+ CHECK_RETURN (jt.second );
279
+ it = jt.first ;
280
+ }
281
+
282
+ return *(it->second );
283
+ }
284
+
285
+ void clear () override
286
+ {
287
+ trace_map_storaget::clear ();
288
+ domain_map.clear ();
289
+ return ;
290
+ }
291
+ };
292
+
215
293
#endif
0 commit comments