CBMC
scratch_program.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Loop Acceleration
4 
5 Author: Matt Lewis
6 
7 \*******************************************************************/
8 
11 
12 #include "scratch_program.h"
13 
15 
16 #include <goto-symex/slice.h>
17 
19 
20 #ifdef DEBUG
21 #include <iostream>
22 #endif
23 
24 bool scratch_programt::check_sat(bool do_slice, guard_managert &guard_manager)
25 {
26  fix_types();
27 
29 
30  remove_skip(*this);
31 
32 #ifdef DEBUG
33  std::cout << "Checking following program for satness:\n";
34  output(ns, "scratch", std::cout);
35 #endif
36 
37  goto_functiont this_goto_function;
38  this_goto_function.body.copy_from(*this);
39  auto get_goto_function =
40  [this, &this_goto_function](
41  const irep_idt &key) -> const goto_functionst::goto_functiont & {
42  if(key == goto_functionst::entry_point())
43  return this_goto_function;
44  else
45  return functions.function_map.at(key);
46  };
47 
48  symex_state = symex.initialize_entry_point_state(get_goto_function);
49 
51 
52  if(do_slice)
53  {
54  slice(equation);
55  }
56 
57  if(equation.count_assertions()==0)
58  {
59  // Symex sliced away all our assertions.
60 #ifdef DEBUG
61  std::cout << "Trivially unsat\n";
62 #endif
63  return false;
64  }
65 
67 
68 #ifdef DEBUG
69  std::cout << "Finished symex, invoking decision procedure.\n";
70 #endif
71 
72  switch((*checker)())
73  {
75  throw "error running the SMT solver";
76 
78  return true;
79 
81  return false;
82 
84  }
85 
87 }
88 
90 {
91  return checker->get(symex_state->rename<L2>(e, ns).get());
92 }
93 
95 {
96  instructions.insert(
97  instructions.end(),
98  new_instructions.begin(),
99  new_instructions.end());
100 }
101 
103  const exprt &lhs,
104  const exprt &rhs)
105 {
106  return add(goto_programt::make_assignment(lhs, rhs));
107 }
108 
110 {
112 }
113 
114 static void fix_types(exprt &expr)
115 {
116  Forall_operands(it, expr)
117  {
118  fix_types(*it);
119  }
120 
121  if(expr.id()==ID_equal ||
122  expr.id()==ID_notequal ||
123  expr.id()==ID_gt ||
124  expr.id()==ID_lt ||
125  expr.id()==ID_ge ||
126  expr.id()==ID_le)
127  {
128  auto &rel_expr = to_binary_relation_expr(expr);
129  exprt &lhs = rel_expr.lhs();
130  exprt &rhs = rel_expr.rhs();
131 
132  if(lhs.type()!=rhs.type())
133  {
134  typecast_exprt typecast(rhs, lhs.type());
135  rel_expr.rhs().swap(typecast);
136  }
137  }
138 }
139 
141 {
142  for(goto_programt::instructionst::iterator it=instructions.begin();
143  it!=instructions.end();
144  ++it)
145  {
146  if(it->is_assign())
147  {
148  if(it->assign_lhs().type() != it->assign_rhs().type())
149  {
150  typecast_exprt typecast{it->assign_rhs(), it->assign_lhs().type()};
151  it->assign_rhs_nonconst() = typecast;
152  }
153  }
154  else if(it->is_assume() || it->is_assert())
155  {
156  ::fix_types(it->condition_nonconst());
157  }
158  }
159 }
160 
162 {
163  for(patht::iterator it=path.begin();
164  it!=path.end();
165  ++it)
166  {
167  if(it->loc->is_assign() || it->loc->is_assume())
168  {
169  instructions.push_back(*it->loc);
170  }
171  else if(it->loc->is_goto())
172  {
173  if(it->guard.id()!=ID_nil)
174  {
176  }
177  }
178  else if(it->loc->is_assert())
179  {
180  add(goto_programt::make_assumption(it->loc->condition()));
181  }
182  }
183 }
184 
186 {
187  goto_programt scratch;
188 
189  scratch.copy_from(program);
190  destructive_append(scratch);
191 }
192 
194  goto_programt &program,
195  goto_programt::targett loop_header)
196 {
197  append(program);
198 
199  // Update any back jumps to the loop header.
200  (void)loop_header; // unused parameter
201  assume(false_exprt());
202 
204 
205  update();
206 
207  for(goto_programt::targett t=instructions.begin();
208  t!=instructions.end();
209  ++t)
210  {
211  if(t->is_backwards_goto())
212  {
213  t->targets.clear();
214  t->targets.push_back(end);
215  }
216  }
217 }
218 
220 {
221  optionst ret;
222  ret.set_option("simplify", true);
223  return ret;
224 }
void slice(symex_bmct &symex, symex_target_equationt &symex_target_equation, const namespacet &ns, const optionst &options, ui_message_handlert &ui_message_handler)
Definition: bmc_util.cpp:198
static exprt guard(const exprt::operandst &guards, exprt cond)
virtual exprt get(const exprt &) const =0
Return expr with variables replaced by values from satisfying assignment if available.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:38
Base class for all expressions.
Definition: expr.h:56
typet & type()
Return the type of the expression.
Definition: expr.h:84
The Boolean constant false.
Definition: std_expr.h:3064
function_mapt function_map
::goto_functiont goto_functiont
static irep_idt entry_point()
Get the identifier of the entry point to a goto model.
A goto function, consisting of function body (see body) and parameter identifiers (see parameter_iden...
Definition: goto_function.h:24
goto_programt body
Definition: goto_function.h:26
A generic container class for the GOTO intermediate representation of one function.
Definition: goto_program.h:73
static instructiont make_assumption(const exprt &g, const source_locationt &l=source_locationt::nil())
Definition: goto_program.h:945
instructionst instructions
The list of instructions in the goto program.
Definition: goto_program.h:622
void copy_from(const goto_programt &src)
Copy a full goto program, preserving targets.
void update()
Update all indices.
std::ostream & output(std::ostream &out) const
Output goto-program to given stream.
static instructiont make_end_function(const source_locationt &l=source_locationt::nil())
instructionst::iterator targett
Definition: goto_program.h:614
void destructive_append(goto_programt &p)
Appends the given program p to *this. p is destroyed.
Definition: goto_program.h:722
static instructiont make_assignment(const code_assignt &_code, const source_locationt &l=source_locationt::nil())
Create an assignment instruction.
std::list< instructiont > instructionst
Definition: goto_program.h:612
static instructiont make_skip(const source_locationt &l=source_locationt::nil())
Definition: goto_program.h:891
targett add(instructiont &&instruction)
Adds a given instruction at the end.
Definition: goto_program.h:739
virtual symbol_tablet symex_with_state(statet &state, const get_goto_functiont &get_goto_functions)
Symbolically execute the entire program starting from entry point.
Definition: symex_main.cpp:325
const irep_idt & id() const
Definition: irep.h:384
void set_option(const std::string &option, const bool value)
Definition: options.cpp:28
goto_functionst functions
bool check_sat(bool do_slice, guard_managert &guard_manager)
scratch_program_symext symex
targett assume(const exprt &guard)
void append_loop(goto_programt &program, goto_programt::targett loop_header)
targett assign(const exprt &lhs, const exprt &rhs)
symbol_tablet symex_symbol_table
static optionst get_default_options()
void append(goto_programt::instructionst &instructions)
decision_proceduret * checker
std::unique_ptr< goto_symex_statet > symex_state
exprt eval(const exprt &e)
void append_path(patht &path)
symex_target_equationt equation
std::size_t count_assertions() const
void convert(decision_proceduret &decision_procedure)
Interface method to initiate the conversion into a decision procedure format.
Semantic type conversion.
Definition: std_expr.h:2068
Decision Procedure Interface.
#define Forall_operands(it, expr)
Definition: expr.h:27
std::list< path_nodet > patht
Definition: path.h:44
void remove_skip(goto_programt &goto_program, goto_programt::targett begin, goto_programt::targett end)
remove unnecessary skip statements
Definition: remove_skip.cpp:87
Program Transformation.
@ L2
Definition: renamed.h:26
static void fix_types(exprt &expr)
Loop Acceleration.
Slicer for symex traces.
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:525
const binary_relation_exprt & to_binary_relation_expr(const exprt &expr)
Cast an exprt to a binary_relation_exprt.
Definition: std_expr.h:895
This is unused by this implementation of guards, but can be used by other implementations of the same...
Definition: guard_expr.h:20
std::unique_ptr< statet > initialize_entry_point_state(const get_goto_functiont &get_goto_function)