void termination_baset::find_required_steps( const goto_tracet &goto_trace, goto_tracet::stepst::const_iterator &loop_begin, required_stepst &required_steps, const std::string &prefix) const { find_symbols_sett required_symbols; unsigned before=0, after=1; // initialize: find all (potential) loop exits and // remember the symbols in them for(goto_tracet::stepst::const_iterator it1=loop_begin; it1!=goto_trace.steps.end(); it1++) { if(it1->pc->is_goto() && it1->pc->function==loop_begin->pc->function) { bool found_next=false, found_target=false; goto_programt::const_targett next=it1->pc; next++; goto_programt::const_targett target=it1->pc->targets.front(); for(goto_tracet::stepst::const_iterator it2=loop_begin; it2!=goto_trace.steps.end(); it2++) { if(it1!=it2) { if(it2->pc==next) found_next=true; else if(it2->pc==target) found_target=true; } } if(!found_target || !found_next) { exprt temp=it1->cond_expr; remove_ssa_ids(temp); find_symbols(temp, required_symbols); } } } #if 0 std::cout << "INITIAL SYMBOLS: "; for(find_symbols_sett::const_iterator it=required_symbols.begin(); it!=required_symbols.end(); it++) std::cout << *it << ", "; std::cout << std::endl; #endif // get the fixpoint while(before!=after) { before=required_symbols.size(); for(goto_tracet::stepst::const_iterator step=loop_begin; step!=goto_trace.steps.end(); step++) { find_symbols_sett intersection; if(step->is_assignment()) { exprt lhs, rhs; const codet &code=to_code(step->pc->code); if(code.get_statement()==ID_assign) { const code_assignt &acode=to_code_assign(step->pc->code); lhs=acode.lhs(); rhs=acode.rhs(); } else if(code.get_statement()==ID_function_call) { const code_function_callt fcode=to_code_function_call(step->pc->code); lhs=fcode.lhs(); rhs=fcode.op2(); } else throw "Unexpected assign statement"; if(lhs.id()==ID_symbol && has_prefix(lhs.get_string(ID_identifier), prefix)) { // if we depend on the RHS syms, we also need the pre-symbol find_symbols_sett rhs_sym; find_symbols(rhs, rhs_sym); if(intersects(rhs_sym, required_symbols)) { find_symbols(lhs, required_symbols); required_steps.insert(&(*step)); } } else { find_symbols_sett lhs_sym; if(lhs.id()==ID_index) find_symbols(lhs.op0(), lhs_sym); // we're not modifying the index else find_symbols(lhs, lhs_sym); if(intersects(lhs_sym, required_symbols)) { find_symbols(rhs, required_symbols); required_steps.insert(&(*step)); } } } else if(step->is_assume()) { find_symbols_sett syms; find_symbols(step->pc->guard, syms); if(intersects(syms, required_symbols)) { required_symbols.insert(syms.begin(), syms.end()); required_steps.insert(&(*step)); } } } after=required_symbols.size(); #if 0 std::cout << "REQUIRED SYMBOLS: "; for(find_symbols_sett::const_iterator it=required_symbols.begin(); it!=required_symbols.end(); it++) std::cout << *it << ", "; std::cout << std::endl; #endif } }