12 #ifndef CPROVER_GOTO_SYMEX_PARTIAL_ORDER_CONCURRENCY_H
13 #define CPROVER_GOTO_SYMEX_PARTIAL_ORDER_CONCURRENCY_H
88 return event->ssa_lhs.get_identifier();
118 const std::string &msg,
139 #include "abstract_event_structure.h"
148 typedef std::vector<evtt const*> ordered_evtst;
150 typedef ordered_evtst::const_iterator const_iterator;
151 typedef std::map<evtt const*, ordered_evtst::size_type> ordered_evts_mapt;
153 void add_event(
const evtt &evt)
156 ordered_evts.push_back(&evt);
157 if(!ordered_evts_map.insert(std::make_pair(&evt, offset)).second)
159 assert(ordered_evts.size()==ordered_evts_map.size());
161 if(evt.direction==evtt::D_SYNC ||
162 evt.direction==evtt::D_LWSYNC)
163 barriers.insert(barriers.end(), offset);
166 void add_events(const_iterator first, const_iterator last)
168 ordered_evts.reserve(ordered_evts.size()+last-first);
169 for( ; first!=last; ++first)
173 const_iterator begin()
const
175 return ordered_evts.begin();
178 const_iterator end()
const
180 return ordered_evts.end();
183 const_iterator find(
const evtt &evt)
const
185 ordered_evts_mapt::const_iterator entry=ordered_evts_map.find(&evt);
186 if(entry==ordered_evts_map.end())
189 return ordered_evts.begin()+entry->second;
192 std::list<const_iterator> barriers_after(
const evtt &evt)
const
194 const_iterator entry=find(evt);
196 return std::list<const_iterator>();
198 std::list<const_iterator> ret;
200 for(std::set<ordered_evtst::size_type>::const_iterator
201 lb=barriers.lower_bound(offset);
204 ret.push_back(ordered_evts.begin()+*lb);
209 std::list<const_iterator> barriers_before(
const evtt &evt)
const
211 const_iterator entry=find(evt);
213 return std::list<const_iterator>();
215 std::list<const_iterator> ret;
217 for(std::set<ordered_evtst::size_type>::const_iterator
219 ub!=barriers.end() && *ub<=offset;
221 ret.push_back(ordered_evts.begin()+*ub);
227 ordered_evtst ordered_evts;
228 ordered_evts_mapt ordered_evts_map;
229 std::set<ordered_evtst::size_type> barriers;
246 typedef std::map<evtt const*, std::map<evtt const*, exprt> > adj_matrixt;
247 typedef adj_matrixt adj_matricest[AC_N_AXIOMS];
248 typedef std::list<evtt const*> per_valuet;
249 typedef std::map<irep_idt, per_valuet> per_address_mapt;
250 typedef std::vector<numbered_evtst> numbered_per_thread_evtst;
258 void init(
const abstract_events_in_program_ordert &abstract_events_in_po);
259 void add_atomic_sections();
262 void add_program_order(adj_matricest &po);
263 void add_read_from(adj_matricest &rf);
264 void add_write_serialisation(adj_matricest &ws);
266 const adj_matricest &rf,
267 const adj_matricest &ws,
270 const adj_matricest &po,
271 const adj_matricest &rf,
272 const adj_matricest &fr);
280 # define S_PROP(t) ((t+1)<<1)
282 const acyclict check,
284 const unsigned step)
const;
286 const acyclict check,
289 const evtt::event_dirt other_dir)
const;
296 const std::string &po_name);
297 void add_atomic_sections(
const acyclict check);
298 void add_partial_order_constraint(
299 const acyclict check,
300 const std::string &po_name,
304 void add_partial_order_constraint(
305 const acyclict check,
306 const std::string &po_name,
308 const unsigned n1_step,
309 const evtt::event_dirt n1_o_d,
311 const unsigned n2_step,
312 const evtt::event_dirt n2_o_d,
315 const evtt* first_of(
const evtt &e1,
const evtt &e2)
const;
316 const numbered_evtst &get_thread(
const evtt &e)
const;
317 const numbered_per_thread_evtst &get_all_threads()
const
319 return per_thread_evt_no;
323 messaget &get_message() {
return message; }
324 std::map<std::string, unsigned> num_concurrency_constraints;
333 per_address_mapt reads_per_address, writes_per_address;
336 std::map<irep_idt, evtt> init_val;
339 const std::string prop_var;
343 numbered_per_thread_evtst per_thread_evt_no;
347 std::map<evtt const*, unsigned> barrier_id;
350 const std::string &prefix)
const;
351 std::vector<std::pair<symbol_exprt, symbol_exprt>>
352 atomic_section_bounds[AC_N_AXIOMS];
354 std::list<exprt> acyclic_constraints[AC_N_AXIOMS];
355 static std::string check_to_string(
const acyclict check);
358 typedef std::pair<evtt const*, std::pair<unsigned, evtt::event_dirt>>
360 typedef std::map<std::pair<evt_dir_pairt, evt_dir_pairt>,
362 pointwise_mapt edge_cache[AC_N_AXIOMS];
363 typedef std::map<evtt
const*,
364 std::list<std::pair<evtt const*, std::pair<exprt, std::string> > > >
366 edge_to_guardt edge_to_guard[AC_N_AXIOMS];
368 void add_sub_clock_rules();
370 typedef std::map<std::pair<irep_idt, irep_idt>,
symbol_exprt> clock_mapt;
371 clock_mapt clock_constraint_cache;
376 const std::string &po_name);
378 const acyclict check,
379 const std::string &po_name,
381 const unsigned n1_step,
382 const evtt::event_dirt n1_o_d,
384 const unsigned n2_step,
385 const evtt::event_dirt n2_o_d);
386 void build_partial_order_constraint(
387 const acyclict check,
388 const std::string &po_name,
390 const unsigned n1_step,
391 const evtt::event_dirt n1_o_d,
393 const unsigned n2_step,
394 const evtt::event_dirt n2_o_d,
398 std::string event_to_string(
const evtt &evt)
const;
400 const adj_matrixt &graph,
401 const std::string &edge_label,
static exprt guard(const exprt::operandst &guards, exprt cond)
Single SSA step in the equation.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Base class for all expressions.
Class that provides messages with a built-in verbosity 'level'.
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Base class for implementing memory models via additional constraints for SSA equations.
std::vector< event_it > event_listt
void add_init_writes(symex_target_equationt &)
For each shared read event and for each shared write event that appears after spawn or has false guar...
std::map< event_it, unsigned > numberingt
void build_event_lists(symex_target_equationt &equation, message_handlert &message_handler)
First call add_init_writes then for each shared read/write (or spawn) populate: 1) the address_map (w...
virtual ~partial_order_concurrencyt()
exprt before(event_it e1, event_it e2, unsigned axioms)
Build the partial order constraint for two events: if e1 and e2 are in the same atomic section then c...
irep_idt address(event_it event) const
Produce an address ID for an event.
symbol_exprt clock(event_it e, axiomt axiom)
Produce a clock symbol for some event.
virtual exprt before(event_it e1, event_it e2)=0
void build_clock_type()
Initialize the clock_type so that it can be used to number events.
std::map< irep_idt, a_rect > address_mapt
static irep_idt rw_clock_id(event_it e, axiomt axiom=AX_PROPAGATION)
Build identifier for the read/write clock variable.
void add_constraint(symex_target_equationt &equation, const exprt &cond, const std::string &msg, const symex_targett::sourcet &source) const
Simplify and add a constraint to equation.
partial_order_concurrencyt(const namespacet &_ns)
symex_target_equationt::SSA_stepst eventst
static irep_idt id(event_it event)
Produce the symbol ID for an event.
eventst::const_iterator event_it
Expression to hold a symbol (variable)
const irep_idt & get_identifier() const
Inheriting the interface of symex_targett this class represents the SSA form of the input program as ...
std::list< SSA_stept > SSA_stepst
The type of an expression, extends irept.
#define UNREACHABLE
This should be used to mark dead code.
ssa_exprt remove_level_2(ssa_exprt ssa)
Identifies source in the context of symbolic execution.
Generate Equation using Symbolic Execution.