23 : old_goto_functions(model_old.goto_functions),
24 ns_old(model_old.symbol_table),
25 new_goto_functions(model_new.goto_functions),
26 ns_new(model_new.symbol_table)
37 goto_functionst::function_mapt::const_iterator old_fit =
39 goto_functionst::function_mapt::const_iterator new_fit =
46 : old_fit->second.body;
49 : new_fit->second.body;
51 return get_diff(old_goto_program, new_goto_program, entry->second);
59 goto_programt::instructionst::const_iterator old_it =
61 goto_programt::instructionst::const_iterator new_it =
66 for(differencest::const_reverse_iterator rit = differences.rbegin();
67 rit != differences.rend();
76 "old iterator reached the final goto instruction");
80 "new iterator reached the final goto instruction");
87 "old iterator reached the final goto instruction");
94 "new iterator reached the final goto instruction");
108 std::ostream &os)
const 111 get_diff(old_goto_program, new_goto_program, differences);
113 bool has_diff =
false;
114 for(
const auto &d : diff)
125 os <<
"/** " << identifier <<
" **/\n";
127 for(
const auto &d : diff)
151 std::size_t old_count = old_goto_program.
instructions.size();
152 std::size_t new_count = new_goto_program.
instructions.size();
155 differences.reserve(old_count + new_count);
158 goto_programt::instructionst::const_iterator old_it =
160 goto_programt::instructionst::const_iterator new_it =
177 goto_programt::instructionst::const_iterator old_rit =
179 goto_programt::instructionst::const_iterator new_rit =
182 while(old_rit != old_it && new_rit != new_it)
201 if(old_count == 0 && new_count == 0)
205 typedef std::vector<std::vector<std::size_t>> lcss_matrixt;
206 lcss_matrixt lcss_matrix(
207 old_count + 1, std::vector<size_t>(new_count + 1, 0));
210 std::size_t i = 1, j = 1;
211 for(goto_programt::instructionst::const_iterator old_it2 = old_it;
216 for(goto_programt::instructionst::const_iterator new_it2 = new_it;
221 lcss_matrix[i][j] += lcss_matrix[i - 1][j - 1] + 1;
224 std::max(lcss_matrix[i][j - 1], lcss_matrix[i - 1][j]);
232 std::cerr <<
"old_count=" << old_count <<
'\n';
233 std::cerr <<
"new_count=" << new_count <<
'\n';
234 for(i=0; i<=old_count; ++i)
236 for(j=0; j<=new_count; ++j)
239 if(lcss_matrix[i][j]<10)
241 std::cerr << lcss_matrix[i][j];
256 while(i > 0 || j > 0)
282 else if(lcss_matrix[i][j - 1] < lcss_matrix[i][j])
299 for(; old_it != old_goto_program.
instructions.begin(); --old_it)
325 differences=
lcss(old_goto_program, new_goto_program);
330 typedef std::map<irep_idt, goto_functionst::function_mapt::const_iterator>
333 function_mapt old_funcs, new_funcs;
336 old_funcs.insert(std::make_pair(it->first, it));
338 new_funcs.insert(std::make_pair(it->first, it));
342 function_mapt::const_iterator ito = old_funcs.begin();
343 for(function_mapt::const_iterator itn = new_funcs.begin();
344 itn != new_funcs.end();
347 for(; ito != old_funcs.end() && ito->first < itn->first; ++ito)
348 unified_diff(ito->first, ito->second->second.body, empty);
350 if(ito == old_funcs.end() || itn->first < ito->first)
351 unified_diff(itn->first, empty, itn->second->second.body);
355 ito->first == itn->first,
"old and new function names do not match");
357 itn->first, ito->second->second.body, itn->second->second.body);
361 for(; ito != old_funcs.end(); ++ito)
362 unified_diff(ito->first, ito->second->second.body, empty);
375 goto_functionst::function_mapt::const_iterator old_fit =
377 goto_functionst::function_mapt::const_iterator new_fit =
382 : old_fit->second.body;
385 : new_fit->second.body;
387 output_diff(
function, old_goto_program, new_goto_program, p.second, os);
irep_idt function
The function this instruction belongs to.
const differences_mapt & differences_map() const
const goto_functionst & old_goto_functions
static bool instructions_equal(const goto_programt::instructiont &ins1, const goto_programt::instructiont &ins2)
function_mapt function_map
std::ostream & output_instruction(const namespacet &ns, const irep_idt &identifier, std::ostream &out, const instructionst::value_type &instruction) const
Output a single instruction.
targett get_target() const
Returns the first (and only) successor for the usual case of a single target.
std::map< irep_idt, differencest > differences_mapt
goto_program_difft get_diff(const irep_idt &function) const
bool equals(const instructiont &other) const
Syntactic equality: two instructiont are equal if they have the same type, code, guard, number of targets, and labels.
targetst targets
The list of successor instructions.
This class represents an instruction in the GOTO intermediate representation.
void output_diff(const irep_idt &identifier, const goto_programt &old_goto_program, const goto_programt &new_goto_program, const differencest &differences, std::ostream &os) const
unified_difft(const goto_modelt &model_old, const goto_modelt &model_new)
std::vector< differencet > differencest
instructionst instructions
The list of instructions in the goto program.
dstringt has one field, an unsigned integer no which is an index into a static table of strings...
differences_mapt differences_map_
Unified diff (using LCSS) of goto functions.
A generic container class for the GOTO intermediate representation of one function.
void output(std::ostream &os) const
void unified_diff(const irep_idt &identifier, const goto_programt &old_goto_program, const goto_programt &new_goto_program)
static differencest lcss(const goto_programt &old_goto_program, const goto_programt &new_goto_program)
std::list< std::pair< goto_programt::const_targett, differencet > > goto_program_difft
#define forall_goto_functions(it, functions)
const goto_functionst & new_goto_functions