cprover
symex_bmc_incremental_one_loop.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Incremental Bounded Model Checking for ANSI-C
4 
5 Author: Peter Schrammel, Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
9 #include <limits>
10 
11 #include <util/source_location.h>
12 #include <util/xml.h>
13 
15 
17  message_handlert &message_handler,
18  const symbol_tablet &outer_symbol_table,
19  symex_target_equationt &target,
20  const optionst &options,
21  path_storaget &path_storage,
22  guard_managert &guard_manager,
23  ui_message_handlert::uit output_ui)
24  : symex_bmct(
25  message_handler,
26  outer_symbol_table,
27  target,
28  options,
29  path_storage,
30  guard_manager),
31  incr_loop_id(options.get_option("incremental-loop")),
32  incr_max_unwind(
33  options.is_set("unwind-max") ? options.get_signed_int_option("unwind-max")
34  : std::numeric_limits<unsigned>::max()),
35  incr_min_unwind(
36  options.is_set("unwind-min") ? options.get_signed_int_option("unwind-min")
37  : 0),
38  output_ui(output_ui)
39 {
40  // the intended behaviour is to stop asserts that are violated before the
41  // unwind
42  // therefore if the min-unwind is 1, then we do one unwind and immediately
43  // start checking for properties
45  incr_min_unwind > 1 &&
46  options.get_bool_option("ignore-properties-before-unwind-min");
47 }
48 
50  const symex_targett::sourcet &source,
51  const call_stackt &context,
52  unsigned unwind)
53 {
54  const irep_idt id = goto_programt::loop_id(source.function_id, *source.pc);
55 
56  tvt abort_unwind_decision;
57  unsigned this_loop_limit = std::numeric_limits<unsigned>::max();
58 
59  // use the incremental limits if it is the specified incremental loop
60  if(id == incr_loop_id)
61  {
62  this_loop_limit = incr_max_unwind;
63  if(unwind + 1 >= incr_min_unwind)
64  ignore_assertions = false;
65 
66  abort_unwind_decision = tvt(unwind >= this_loop_limit);
67  }
68  else
69  {
70  for(auto handler : loop_unwind_handlers)
71  {
72  abort_unwind_decision =
73  handler(context, source.pc->loop_number, unwind, this_loop_limit);
74  if(abort_unwind_decision.is_known())
75  break;
76  }
77 
78  // If no handler gave an opinion, use standard command-line --unwindset
79  // / --unwind options to decide:
80  if(abort_unwind_decision.is_unknown())
81  {
82  auto limit = unwindset.get_limit(id, source.thread_nr);
83 
84  if(!limit.has_value())
85  abort_unwind_decision = tvt(false);
86  else
87  abort_unwind_decision = tvt(unwind >= *limit);
88  }
89  }
90 
91  INVARIANT(
92  abort_unwind_decision.is_known(), "unwind decision should be taken by now");
93  bool abort = abort_unwind_decision.is_true();
94 
95  log_unwinding(unwind);
96  log.statistics() << (abort ? "Not unwinding" : "Unwinding") << " loop " << id
97  << " iteration " << unwind;
98 
99  if(this_loop_limit != std::numeric_limits<unsigned>::max())
100  log.statistics() << " (" << this_loop_limit << " max)";
101 
102  log.statistics() << " " << source.pc->source_location << " thread "
103  << source.thread_nr << log.eom;
104 
105  return abort;
106 }
107 
112  const irep_idt &loop_id,
113  unsigned unwind)
114 {
115  if(unwind < incr_min_unwind)
116  return false;
117 
118  // loop specified by incremental-loop
119  return (loop_id == incr_loop_id);
120 }
121 
123  const get_goto_functiont &get_goto_function,
124  symbol_tablet &new_symbol_table)
125 {
127 
128  symex_with_state(*state, get_goto_function, new_symbol_table);
129 
130  return should_pause_symex;
131 }
132 
134  const get_goto_functiont &get_goto_function)
135 {
136  should_pause_symex = false;
137 
138  symex_with_state(*state, get_goto_function, state->symbol_table);
139 
140  return should_pause_symex;
141 }
143 {
144  structured_datat data{{{labelt({"current", "unwinding"}),
146  json_numbert{std::to_string(unwind)})}}};
147  log.statistics() << data;
148 }
goto_symext::symex_with_state
virtual void symex_with_state(statet &state, const get_goto_functiont &get_goto_functions, symbol_tablet &new_symbol_table)
Symbolically execute the entire program starting from entry point.
Definition: symex_main.cpp:324
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:37
json_numbert
Definition: json.h:291
symbol_tablet
The symbol table.
Definition: symbol_table.h:20
structured_data_entryt::data_node
static structured_data_entryt data_node(const jsont &data)
Definition: structured_data.cpp:64
symex_bmct::loop_unwind_handlers
std::vector< loop_unwind_handlert > loop_unwind_handlers
Callbacks that may provide an unwind/do-not-unwind decision for a loop.
Definition: symex_bmc.h:90
symex_bmct::unwindset
unwindsett unwindset
Definition: symex_bmc.h:86
optionst
Definition: options.h:23
symex_bmc_incremental_one_loop.h
symex_targett::sourcet::pc
goto_programt::const_targett pc
Definition: symex_target.h:43
path_storaget
Storage for symbolic execution paths to be resumed later.
Definition: path_storage.h:38
data
Definition: kdev_t.h:24
goto_symext::ignore_assertions
bool ignore_assertions
If this flag is set to true then assertions will be temporarily ignored by the symbolic executions.
Definition: goto_symex.h:169
symex_bmc_incremental_one_loopt::check_break
bool check_break(const irep_idt &loop_id, unsigned unwind) override
Defines condition for interrupting symbolic execution for incremental BMC.
Definition: symex_bmc_incremental_one_loop.cpp:111
symex_targett::sourcet::thread_nr
unsigned thread_nr
Definition: symex_target.h:39
tvt::is_unknown
bool is_unknown() const
Definition: threeval.h:27
to_string
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
Definition: string_constraint.cpp:55
messaget::eom
static eomt eom
Definition: message.h:297
call_stackt
Definition: call_stack.h:15
xml.h
goto_symext::initialize_entry_point_state
std::unique_ptr< statet > initialize_entry_point_state(const get_goto_functiont &get_goto_function)
Initialize the symbolic execution and the given state with the beginning of the entry point function.
Definition: symex_main.cpp:403
tvt::is_known
bool is_known() const
Definition: threeval.h:28
unwindsett::get_limit
optionalt< unsigned > get_limit(const irep_idt &loop, unsigned thread_id) const
Definition: unwindset.cpp:73
goto_programt::loop_id
static irep_idt loop_id(const irep_idt &function_id, const instructiont &instruction)
Human-readable loop name.
Definition: goto_program.h:755
ui_message_handlert::uit
uit
Definition: ui_message.h:22
goto_symext::log
messaget log
The messaget to write log messages to.
Definition: goto_symex.h:276
guard_expr_managert
This is unused by this implementation of guards, but can be used by other implementations of the same...
Definition: guard_expr.h:23
symex_bmc_incremental_one_loopt::state
std::unique_ptr< goto_symext::statet > state
Definition: symex_bmc_incremental_one_loop.h:40
labelt
Definition: structured_data.h:17
source_location.h
message_handlert
Definition: message.h:28
symex_bmc_incremental_one_loopt::incr_max_unwind
const unsigned incr_max_unwind
Definition: symex_bmc_incremental_one_loop.h:37
tvt
Definition: threeval.h:20
structured_datat
A way of representing nested key/value data.
Definition: structured_data.h:74
symex_target_equationt
Inheriting the interface of symex_targett this class represents the SSA form of the input program as ...
Definition: symex_target_equation.h:41
symex_bmc_incremental_one_loopt::should_stop_unwind
bool should_stop_unwind(const symex_targett::sourcet &source, const call_stackt &context, unsigned unwind) override
Determine whether to unwind a loop.
Definition: symex_bmc_incremental_one_loop.cpp:49
optionst::get_bool_option
bool get_bool_option(const std::string &option) const
Definition: options.cpp:44
goto_symext::get_goto_function
static get_goto_functiont get_goto_function(abstract_goto_modelt &goto_model)
Return a function to get/load a goto function from the given goto model Create a default delegate to ...
Definition: symex_main.cpp:493
symex_bmc_incremental_one_loopt::incr_min_unwind
const unsigned incr_min_unwind
Definition: symex_bmc_incremental_one_loop.h:38
symex_bmc_incremental_one_loopt::incr_loop_id
const irep_idt incr_loop_id
Definition: symex_bmc_incremental_one_loop.h:36
symex_bmc_incremental_one_loopt::resume
bool resume(const get_goto_functiont &get_goto_function)
Return true if symex can be resumed.
Definition: symex_bmc_incremental_one_loop.cpp:133
goto_symext::get_goto_functiont
std::function< const goto_functionst::goto_functiont &(const irep_idt &)> get_goto_functiont
The type of delegate functions that retrieve a goto_functiont for a particular function identifier.
Definition: goto_symex.h:95
symex_bmc_incremental_one_loopt::symex_bmc_incremental_one_loopt
symex_bmc_incremental_one_loopt(message_handlert &, const symbol_tablet &outer_symbol_table, symex_target_equationt &, const optionst &, path_storaget &, guard_managert &, ui_message_handlert::uit output_ui)
Definition: symex_bmc_incremental_one_loop.cpp:16
symex_bmct
Definition: symex_bmc.h:26
symex_bmc_incremental_one_loopt::log_unwinding
void log_unwinding(unsigned unwind)
Definition: symex_bmc_incremental_one_loop.cpp:142
symex_targett::sourcet
Identifies source in the context of symbolic execution.
Definition: symex_target.h:38
symex_bmc_incremental_one_loopt::from_entry_point_of
bool from_entry_point_of(const get_goto_functiont &get_goto_function, symbol_tablet &new_symbol_table)
Return true if symex can be resumed.
Definition: symex_bmc_incremental_one_loop.cpp:122
symex_targett::sourcet::function_id
irep_idt function_id
Definition: symex_target.h:40
validation_modet::INVARIANT
@ INVARIANT
tvt::is_true
bool is_true() const
Definition: threeval.h:25
messaget::statistics
mstreamt & statistics() const
Definition: message.h:419
goto_symext::should_pause_symex
bool should_pause_symex
Set when states are pushed onto the workqueue If this flag is set at the end of a symbolic execution ...
Definition: goto_symex.h:165