void concurrency_instrumentationt::instrument(exprt &expr) { std::set<exprt> symbols; find_symbols(expr, symbols); replace_symbolt replace_symbol; for(std::set<exprt>::const_iterator s_it=symbols.begin(); s_it!=symbols.end(); s_it++) { if(s_it->id()==ID_symbol) { const irep_idt identifier= to_symbol_expr(*s_it).get_identifier(); shared_varst::const_iterator v_it=shared_vars.find(identifier); if(v_it!=shared_vars.end()) { index_exprt new_expr; //new_expr.array()=symbol_expr(); //new_expr.index()=symbol_expr(); replace_symbol.insert(identifier, new_expr); } } } }
int main ( int argc, char **argv ) { read_args ( argc, argv ); yyparse (); #ifdef DUMPTREES FILE *pre = fopen ( "pre.tree", "w" ), *post = fopen ( "post.tree", "w" ); print_node ( pre, root, 0 ); #endif root = simplify_tree ( root ); #ifdef DUMPTREES print_node ( post, root, 0 ); fclose ( pre ); fclose ( post ); #endif init_scopes ( 256 ); find_symbols ( root ); destroy_scopes (); destroy_subtree ( root ); exit ( EXIT_SUCCESS ); }
bool find_symbols(expression const e, std::function<bool(symbol)> const selector, std::unordered_set<symbol,symbol::hash>& output) { if (selector(get_symbol(e))) output.insert(get_symbol(e)); for (uint64_t i = 0ULL; i < num_parameters(e); ++i) find_symbols(argument(e,i),selector,output); return !output.empty(); }
void preconditiont::compute_rec(exprt &dest) { if(dest.id()==ID_address_of) { // only do index! assert(dest.operands().size()==1); compute_address_of(dest.op0()); } else if(dest.id()==ID_symbol) { if(dest.get(ID_identifier)== s.get_original_name(SSA_step.ssa_lhs.get_identifier())) { dest=SSA_step.ssa_rhs; s.get_original_name(dest); } } else if(dest.id()==ID_dereference) { assert(dest.operands().size()==1); const irep_idt &lhs_identifier= s.get_original_name(SSA_step.ssa_lhs.get_identifier()); // aliasing may happen here value_setst::valuest expr_set; value_sets.get_values(target, dest.op0(), expr_set); hash_set_cont<irep_idt, irep_id_hash> symbols; for(value_setst::valuest::const_iterator it=expr_set.begin(); it!=expr_set.end(); it++) find_symbols(*it, symbols); if(symbols.find(lhs_identifier)!=symbols.end()) { // may alias! exprt tmp; tmp.swap(dest.op0()); dereference(target, tmp, ns, value_sets); dest.swap(tmp); compute_rec(dest); } else { // nah, ok compute_rec(dest.op0()); } } else Forall_operands(it, dest) compute_rec(*it); }
/*******************************************************************\ Function: acdl_analyze_conflict_baset::get_first_contradiction Inputs: Outputs: Purpose: \*******************************************************************/ int acdl_analyze_conflict_baset::first_contradiction_on_trail( const exprt& expr, acdl_conflict_grapht &graph, int trail_start, int trail_end) { acdl_domaint::valuet relevant_expr; acdl_domaint::varst exp_symbols; find_symbols(expr, exp_symbols); for(int i=trail_start; i<=trail_end; i++) { exprt& trail_exp=graph.prop_trail[i]; acdl_domaint::varst v_symbol; find_symbols(trail_exp, v_symbol); for(acdl_domaint::varst::iterator it1=v_symbol.begin(); it1!=v_symbol.end(); it1++) { bool is_in=exp_symbols.find(*it1)!=exp_symbols.end(); if(is_in) { bool status=domain.compare(expr, trail_exp); if(status==domain.CONFLICT) return i; } } } assert(0); }
void bv_refinementt::freeze_lazy_constraints() { if(!lazy_arrays) return; for(std::list<lazy_constraintt>::iterator l_it = lazy_array_constraints.begin(); l_it != lazy_array_constraints.end(); ++l_it) { std::set<symbol_exprt> symbols; find_symbols(l_it->lazy,symbols); for(std::set<symbol_exprt>::const_iterator it = symbols.begin(); it != symbols.end(); ++it) { bvt bv = convert_bv(l_it->lazy); forall_literals(b_it, bv) if(!b_it->is_constant()) prop.set_frozen(*b_it); } } }
void predabs_domaint::project_on_vars( valuet &value, const var_sett &vars, exprt &result) { const templ_valuet &v=static_cast<const templ_valuet &>(value); assert(v.size()==templ.size()); exprt::operandst c; for(std::size_t row=0; row<templ.size(); row++) { const template_rowt &templ_row=templ[row]; std::set<symbol_exprt> symbols; find_symbols(templ_row.expr, symbols); bool pure=true; for(const auto &symbol : symbols) { if(vars.find(symbol)==vars.end()) { pure=false; break; } } if(!pure) continue; const row_valuet &row_v=v[row]; if(templ_row.kind==LOOP) { c.push_back( implies_exprt( templ_row.pre_guard, implies_exprt(row_v, templ_row.expr))); } else { c.push_back(implies_exprt(row_v, templ_row.expr)); } } result=conjunction(c); }
void concurrency_instrumentationt::collect(const exprt &expr) { std::set<exprt> symbols; find_symbols(expr, symbols); for(std::set<exprt>::const_iterator s_it=symbols.begin(); s_it!=symbols.end(); s_it++) { if(s_it->id()==ID_symbol) { const irep_idt identifier= to_symbol_expr(*s_it).get_identifier(); namespacet ns(symbol_table); const symbolt &symbol=ns.lookup(identifier); if(!symbol.is_state_var) continue; if(symbol.is_thread_local) { if(thread_local_vars.find(identifier)!=thread_local_vars.end()) continue; thread_local_vart &thread_local_var=thread_local_vars[identifier]; thread_local_var.type=symbol.type; } else { if(shared_vars.find(identifier)!=shared_vars.end()) continue; shared_vart &shared_var=shared_vars[identifier]; shared_var.type=symbol.type; } } } }
literalt dplib_convt::convert_rest(const exprt &expr) { //dplib_prop.out << "%% E: " << expr << std::endl; literalt l=prop.new_variable(); find_symbols(expr); if(expr.id()==ID_equal || expr.id()==ID_notequal) { assert(expr.operands().size()==2); dplib_prop.out << "ASSERT " << dplib_prop.dplib_literal(l) << " <=> ("; convert_dplib_expr(expr.op0()); dplib_prop.out << ((expr.id()==ID_equal)?"=":"/="); convert_dplib_expr(expr.op1()); dplib_prop.out << ");" << std::endl; } return l; }
literalt cvc_convt::convert(const exprt &expr) { //out << "%% E: " << expr << std::endl; if(expr.type().id()!=ID_bool) { std::string msg="cvc_convt::convert got " "non-boolean expression: "; msg+=expr.pretty(); throw msg; } // Three special cases in which we don't need to generate // a handle. if(expr.is_true()) return const_literal(true); else if(expr.is_false()) return const_literal(false); else if(expr.id()==ID_literal) return to_literal_expr(expr).get_literal(); // Generate new handle literalt l(no_boolean_variables, false); no_boolean_variables++; find_symbols(expr); // define new handle out << "ASSERT "; convert_literal(l); out << " <=> ("; convert_expr(expr); out << ");" << std::endl << std::endl; return l; }
void polynomial_acceleratort::stash_variables(scratch_programt &program, expr_sett modified, substitutiont &substitution) { find_symbols_sett vars; for (expr_sett::iterator it = modified.begin(); it != modified.end(); ++it) { find_symbols(*it, vars); } irep_idt loop_counter_name = to_symbol_expr(loop_counter).get_identifier(); vars.erase(loop_counter_name); for (find_symbols_sett::iterator it = vars.begin(); it != vars.end(); ++it) { symbolt orig = symbol_table.lookup(*it); symbolt stashed_sym = utils.fresh_symbol("polynomial::stash", orig.type); substitution[orig.symbol_expr()] = stashed_sym.symbol_expr(); program.assign(stashed_sym.symbol_expr(), orig.symbol_expr()); } }
unsigned acdl_analyze_conflict_baset::get_earliest_contradiction( const local_SSAt &SSA, acdl_conflict_grapht &graph, acdl_domaint::meet_irreduciblet &exp) { acdl_domaint::varst exp_symbols; // get symbols from this meet irreducible find_symbols(exp, exp_symbols); #ifdef DEBUG std::cout << "Searching for earliest contradiction of literal " << from_expr(SSA.ns, "", exp) << std::endl; #endif // search for contradiction from beginning unsigned lower_index, upper_index; unsigned control_trail_size=graph.control_trail.size(); unsigned search_level=0; while(search_level<=control_trail_size-1) { acdl_domaint::valuet val_perdecision; #ifdef DEBUG std::cout << "searching for contradiction at level " << search_level << std::endl; #endif upper_index=graph.control_trail[search_level]; if(search_level==0) lower_index=0; else lower_index=graph.control_trail[search_level-1]; #ifdef DEBUG std::cout << "Upper index is " << upper_index << "lower index is " << lower_index << std::endl; #endif // [TODO] check for empty propagation trail if(upper_index==lower_index) { search_level=search_level+1; continue; } // now traverse the prop_trail for(unsigned k=lower_index;k<=upper_index-1;k++) { // std::cout << "The matched expression is: " << from_expr(SSA.ns, "", graph.prop_trail[k]) << std::endl; assert(k >= 0); exprt prop_exp=graph.prop_trail[k]; val_perdecision.push_back(prop_exp); if(k==upper_index-1) break; } // assert that the deductions for this decision are consistent assert(domain.check_val_consistency(val_perdecision)); // push the contradicted literal val_perdecision.push_back(exp); bool status=domain.check_val_satisfaction(val_perdecision); if(status==0) { #ifdef DEBUG std::cout << "Found contradiction at decision level " << search_level << "for " << from_expr(SSA.ns, "", exp) << std::endl; #endif return search_level; } search_level=search_level+1; } #ifdef DEBUG std::cout << "searching for contradiction at the current level" << std::endl; #endif acdl_domaint::valuet matched_expr; int control_point=graph.control_trail.back(); // traverse from the back of prop_trail, last element is false_exprt // since the deduction at the current level leads to conflict, // so the deduction are by construction UNSAT // so, we need to iterate over all elements explicitly // for this segment of propagation trail which corresponds to // the current decision level. For other decision levels, we do // not need to explicitly traverse the propagation trail segment for(unsigned j=control_point;j<=graph.prop_trail.size()-1;j++) { // std::cout << "The matched expression is: " << from_expr(SSA.ns, "", graph.prop_trail[j]) << std::endl; assert(graph.prop_trail[graph.prop_trail.size()-1]==false_exprt()); // find contradiction by traversing the prop_trail // and finding the relevant meet irreducibles exprt prop_exp=graph.prop_trail[j]; acdl_domaint::varst prop_symbols; // get symbols from this meet irreducible find_symbols(prop_exp, prop_symbols); // check if this symbol is in dec_symbols for(acdl_domaint::varst::iterator it=prop_symbols.begin(); it!=prop_symbols.end(); it++) { bool is_in=exp_symbols.find(*it)!=exp_symbols.end(); if(is_in) { // std::cout << "Hey !!! found contradiction with " << from_expr(SSA.ns, "", prop_exp) << std::endl; matched_expr.push_back(prop_exp); break; } } #if 0 exprt prop_exp=graph.prop_trail[j]; if(prop_exp!=false_exprt()) { std::cout << "The matched expression is: " << from_expr(SSA.ns, "", prop_exp) << std::endl; matched_expr.push_back(prop_exp); } #endif } // push the contradicted literal matched_expr.push_back(exp); bool status=domain.check_val_satisfaction(matched_expr); if(status==0) { #ifdef DEBUG std::cout << "Found contradiction at current decision level for " << from_expr(SSA.ns, "", exp) << std::endl; #endif return graph.current_level; } // if the control reaches here, // that means no contradiction // has been found at previous levels return 0; }
bool find_unintepreted_symbols(expression const e, std::unordered_set<symbol,symbol::hash>& output) { return find_symbols(e,std::not1(std::function<bool(symbol)>(&symbol_is_interpreted)),output); }
void acdl_analyze_conflict_baset::get_ai_reason(const local_SSAt &SSA, acdl_conflict_grapht &graph, acdl_domaint::valuet &reason) { #if 0 // collect all propagations in the reason // upto the point where first decision was made // iterate upto trail_size-2 since the last node // is a FALSE node int control_point=graph.control_trail[0]; for(unsigned i=control_point;i<graph.prop_trail.size()-2;i++) { exprt prop_exp=graph.prop_trail[i]; reason.push_back(prop_exp); } #endif // just take all decisions as reason for(unsigned i=0;i<graph.dec_trail.size();i++) { exprt dec_exp=graph.dec_trail[i]; reason.push_back(dec_exp); } // now normalize the reason since there may be // lot of redundant decisions // domain.normalize(reason); #if 0 // Step 1: collect all decision variables by traversing the decision trail // (decisions follow the templates x<=0, y>10) // Step 2: traverse the prop_trail from back and collect the meet // irreducibles involving these variables // Step 3: Store these meet irreducibles from step 2 in reason acdl_domaint::varst dec_symbols; for(unsigned i=0;i<graph.dec_trail.size();i++) { exprt dec_exp=graph.dec_trail[i]; acdl_domaint::varst symbols; find_symbols(dec_exp, symbols); dec_symbols.insert(symbols.begin(), symbols.end()); } #ifdef DEBUG std::cout << "Print all decision symbols so far: " << std::endl; for(acdl_domaint::varst::iterator it=dec_symbols.begin(); it!=dec_symbols.end(); it++) std::cout << *it << std::endl; #endif int control_point=graph.control_trail.back(); // traverse from the back of prop_trail to // get the latest value, retrieve latest values // from only this deduction stage for(unsigned j=graph.prop_trail.size()-1;j>control_point;j--) { exprt prop_exp=graph.prop_trail[j]; acdl_domaint::varst prop_symbols; // get symbols from this meet irreducible find_symbols(prop_exp, prop_symbols); // check if this symbol is in dec_symbols for(acdl_domaint::varst::iterator it=prop_symbols.begin(); it!=prop_symbols.end(); it++) { bool is_in=dec_symbols.find(*it)!=dec_symbols.end(); if(is_in) { reason.push_back(prop_exp); break; } } } #endif }
bodyt termination_baset::get_body( goto_tracet::stepst::const_iterator &loop_begin, const goto_tracet &trace) { bodyt result_body; exprt::operandst op; const goto_trace_stept &assertion=trace.steps.back(); // let's get a loop number as well: assert(assertion.pc->guard.id()=="=>"); std::string c_str = assertion.pc->guard.op0().get_string("identifier"); std::string prefix = termination_prefix+ c_str.substr(c_str.rfind("_")+1) + "::"; // find out what we actually need required_stepst required_steps; find_required_steps(trace, loop_begin, required_steps, prefix); /* We perform a new SSA-conversion. However, since we can only get a single path through the program, there are no joins and thus no phi-functions. We just increment counters. */ std::map<irep_idt, unsigned> ssa_counters; replace_idt replace_id; // get the required body constraints for(goto_tracet::stepst::const_iterator step=loop_begin; step!=--trace.steps.end(); step++) { last_path.push_back(step->pc); // required_stepst::const_iterator fit=required_steps.find(&(*step)); // if(fit==required_steps.end()) continue; switch(step->pc->type) { case ASSIGN: { const code_assignt &code=to_code_assign(step->pc->code); find_symbols_sett w; find_symbols_w(code.lhs(), w); equal_exprt equality(code.lhs(), code.rhs()); replace_id.replace(equality.rhs()); // All the written ones get their SSA-ID updated for(find_symbols_sett::const_iterator it=w.begin(); it!=w.end(); it++) { // Are we writing a pre-variable? if(has_prefix(id2string(*it), prefix)) { assert(code.rhs().id()==ID_symbol); const irep_idt &post_id=code.rhs().get(ID_identifier); const irep_idt &pre_id=code.lhs().get(ID_identifier); result_body.variable_map[post_id]=pre_id; // the RHS gets a #0 id irep_idt new_id=id2string(post_id)+"!0"; replace_id.insert(post_id, new_id); equality.rhs().set(ID_identifier, new_id); } else { const irep_idt &old_id=*it; unsigned cur=++ssa_counters[old_id]; // 0 is never used // gets a new ID irep_idt new_id=id2string(old_id)+"!"+i2string(cur); replace_id.insert(old_id, new_id); } } replace_id.replace(equality.lhs()); op.push_back(equality); break; } case ASSUME: case ASSERT: { if(!step->cond_expr.is_true() && !step->cond_expr.is_nil()) { exprt guard=step->cond_expr; // That's SSA! remove_ssa_ids(guard); // exprt guard=step->pc->guard; find_symbols_sett syms; find_symbols(guard, syms); for(find_symbols_sett::const_iterator it=syms.begin(); it!=syms.end(); it++) { if(ssa_counters.find(*it)==ssa_counters.end()) { irep_idt new_id=id2string(*it)+"!"+i2string(++ssa_counters[*it]); replace_id.insert(*it, new_id); } } replace_id.replace(guard); if(!step->cond_value) guard.negate(); op.push_back(guard); } break; } case GOTO: { if(!step->cond_expr.is_nil()) { // exprt guard=step->pc->guard; exprt guard=step->cond_expr; remove_ssa_ids(guard); find_symbols_sett syms; find_symbols(guard, syms); for(find_symbols_sett::const_iterator it=syms.begin(); it!=syms.end(); it++) { if(ssa_counters.find(*it)==ssa_counters.end()) { ssa_counters[*it]=0; irep_idt new_id=id2string(*it)+"!"+i2string(0); replace_id.insert(*it, new_id); } } replace_id.replace(guard); if(!step->cond_value) guard.negate(); op.push_back(guard); } break; } case DECL: /* nothing */ break; case LOCATION: /* These can show up here? */ break; default: throw std::string("unexpected instruction type."); } } // the final result, which (again) contains SSA variables exprt &body_expr = result_body.body_relation; body_expr = and_exprt(op); if(result_body.variable_map.empty()) { // used to be: // throw "BUG: No variables found; path missing."; // Though: No variable is ever saved, i.e., this loop // must be completely nondeterministic. warning("No pre-variables found; this " "loop is completely non-deterministic."); body_expr=false_exprt(); } // The last SSA-occurrence of a variable is the // output variable and it gets its non-SSA name. replace_idt last_map; for(std::map<irep_idt, unsigned>::const_iterator it=ssa_counters.begin(); it!=ssa_counters.end(); it++) { const irep_idt &id=it->first; unsigned last=it->second; irep_idt last_name=id2string(id)+"!"+i2string(last); last_map.insert(last_name, id); } last_map.replace(body_expr); replace_nondet_sideeffects(body_expr); return result_body; }
void acceleratet::add_dirty_checks() { for(expr_mapt::iterator it=dirty_vars_map.begin(); it!=dirty_vars_map.end(); ++it) { goto_programt::instructiont assign(ASSIGN); assign.code=code_assignt(it->second, false_exprt()); program.insert_before_swap(program.instructions.begin(), assign); } goto_programt::targett next; for(goto_programt::targett it=program.instructions.begin(); it!=program.instructions.end(); it=next) { next=it; ++next; // If this is an assign to a tracked variable, clear the dirty flag. // Note: this order of insertions means that we assume each of the read // variables is clean _before_ clearing any dirty flags. if(it->is_assign()) { exprt &lhs=it->code.op0(); expr_mapt::iterator dirty_var=dirty_vars_map.find(lhs); if(dirty_var!=dirty_vars_map.end()) { goto_programt::instructiont clear_flag(ASSIGN); clear_flag.code=code_assignt(dirty_var->second, false_exprt()); program.insert_before_swap(it, clear_flag); } } // Find which symbols are read, i.e. those appearing in a guard or on // the right hand side of an assignment. Assume each is not dirty. find_symbols_sett read; find_symbols(it->guard, read); if(it->is_assign()) { find_symbols(it->code.op1(), read); } for(find_symbols_sett::iterator jt=read.begin(); jt!=read.end(); ++jt) { const exprt &var=ns.lookup(*jt).symbol_expr(); expr_mapt::iterator dirty_var=dirty_vars_map.find(var); if(dirty_var==dirty_vars_map.end()) { continue; } goto_programt::instructiont not_dirty(ASSUME); not_dirty.guard=not_exprt(dirty_var->second); program.insert_before_swap(it, not_dirty); } } }
void acdl_worklist_orderedt::initialize (const local_SSAt &SSA, const exprt &assertion, const exprt& additional_constraint) { // ********************************************************************** // Initialization Strategy: Guarantees top-down and bottom-up propagation // Assertions -- Top // Leaf node -- Middle // Rest -- Bottom // ********************************************************************** typedef std::list<acdl_domaint::statementt> assert_worklistt; assert_worklistt assert_worklist; typedef std::list<acdl_domaint::statementt> predecs_worklistt; predecs_worklistt predecs_worklist; typedef std::list<acdl_domaint::statementt> leaf_worklistt; leaf_worklistt leaf_worklist; typedef std::list<acdl_domaint::statementt> inter_worklistt; inter_worklistt inter_worklist; assert_listt assert_list; #if 0 if (SSA.nodes.empty ()) return; #endif if(statements.empty()) return; // insert the assertions like (!(a1 && a2 && a3)) on to the worklist #if 0 and_exprt::operandst and_expr; for (local_SSAt::nodest::const_iterator n_it=SSA.nodes.begin (); n_it!=SSA.nodes.end (); n_it++) { for (local_SSAt::nodet::assertionst::const_iterator a_it= n_it->assertions.begin (); a_it!=n_it->assertions.end (); a_it++) { push_into_list(assert_worklist, *a_it); and_expr.push_back(*a_it); push_into_assertion_list(assert_list, not_exprt(*a_it)); // push into worklist_vars acdl_domaint::varst avars; find_symbols(*a_it, avars); worklist_vars.insert(avars.begin(), avars.end()); } } #endif push_into_list(assert_worklist, assertion); push_into_assertion_list(assert_list, not_exprt(assertion)); acdl_domaint::varst avars; find_symbols(assertion, avars); worklist_vars.insert(avars.begin(), avars.end()); // Now compute the transitive dependencies // compute fixpoint mu X. assert_nodes u predecessor(X) while(!assert_worklist.empty() > 0) { #ifdef DEBUG std::cout << "Populating the worklist" << std::endl; #endif // collect all the leaf nodes const acdl_domaint::statementt statement=pop_from_list(assert_worklist); // select vars in the present statement acdl_domaint::varst vars; select_vars (statement, vars); // compute the predecessors update(SSA, vars, predecs_worklist, statement, assertion); // std::list<acdl_domaint::statementt>::iterator // iterassert=std::find(assert_list.begin(), assert_list.end(), statement); for(std::list<acdl_domaint::statementt>::const_iterator it=predecs_worklist.begin(); it!=predecs_worklist.end(); ++it) { std::list<acdl_domaint::statementt>::iterator finditer= std::find(worklist.begin(), worklist.end(), *it); // This is required to prevent inserting // individual assertions to the worklist std::list<acdl_domaint::statementt>::iterator iterassert= std::find(assert_list.begin(), assert_list.end(), *it); if(finditer==worklist.end() && iterassert==assert_list.end()) { // never seen this statement before push(*it); push_into_assertion_list(assert_worklist, *it); } } } #ifdef DEBUG std::cout << "The content of the sliced but unordered worklist is as follows: " << std::endl; for(std::list<acdl_domaint::statementt>::const_iterator it=worklist.begin(); it!=worklist.end(); ++it) { std::cout << "Sliced Unordered Worklist Element::" << from_expr(SSA.ns, "", *it) << std::endl; } #endif // order the leaf nodes right after all assertions for(std::list<acdl_domaint::statementt>::const_iterator it=worklist.begin(); it!=worklist.end(); ++it) { if(it->id()==ID_equal) { exprt expr_rhs=to_equal_expr(*it).rhs(); if(expr_rhs.id()==ID_constant || expr_rhs.is_true() || expr_rhs.is_false()) { push_into_list(leaf_worklist, *it); } else if(expr_rhs.type().id()!=ID_constant) { push_into_list(inter_worklist, *it); } } else { push_into_list(inter_worklist, *it); } } #if 0 // order the leaf nodes right after all assertions for(std::list<acdl_domaint::statementt>::const_iterator it=worklist.begin(); it!=worklist.end(); ++it) { // Do we need to separately treat ID_constraint ? if(it->id()==ID_equal) { exprt expr_rhs=to_equal_expr(*it).rhs(); if(expr_rhs.id()==ID_constant) push_into_list(leaf_worklist, *it); // We do not push nondet elements in to the worklist /* std::string str("nondet"); std::string rhs_str=id2string(expr_rhs.get(ID_identifier)); std::size_t found=rhs_str.find(str); // push the nondet statement in rhs if(found!=std::string::npos) push_into_list(leaf_worklist, *it); */ // exprt expr_rhs=expr.rhs(); // select vars in the present statement acdl_domaint::varst vars_rhs; select_vars (expr_rhs, vars_rhs); for(std::list<acdl_domaint::statementt>::const_iterator it1=worklist.begin(); it1!=worklist.end(); ++it1) { if(*it==*it1) continue; /*else { if(!(check_statement(*it1, vars_rhs))) { // *it is a leaf node // push_into_worklist(leaf_worklist, *it); }*/ // this is an intermediate node, not leaf else { // pop the element from the list // const acdl_domaint::statementt statement=pop_from_worklist(worklist); push_into_list(inter_worklist, *it); } } } } #endif #ifdef DEBUG for(std::list<acdl_domaint::statementt>::const_iterator it=leaf_worklist.begin(); it!=leaf_worklist.end(); ++it) { std::cout << "Leaf Element::" << from_expr(SSA.ns, "", *it) << std::endl; } for(std::list<acdl_domaint::statementt>::const_iterator it=inter_worklist.begin(); it!=inter_worklist.end(); ++it) { std::cout << "Intermediate Worklist Element::" << from_expr(SSA.ns, "", *it) << std::endl; } #endif // Now prepare the final worklist worklist.clear(); #if 0 // insert assertions // Push the negation of the assertions into the worklist unsigned int size=and_expr.size(); exprt::operandst::const_iterator it=and_expr.begin(); if(size==1) { exprt::operandst::const_iterator it=and_expr.begin(); #ifdef DEBUG std::cout << "First single assertion push: " << *it << std::endl; #endif exprt exp=*it; // push this into worklist at the end as TOP element not_exprt not_exp(exp); worklist.push_back(not_exp); } else { and_exprt final_and; std::swap(final_and.operands(), and_expr); not_exprt not_exp(final_and); #ifdef DEBUG // push this into worklist at the end as TOP element std::cout << "First push: " << not_exp.pretty() << std::endl; #endif worklist.push_back(not_exp); } #endif // push the assertion and additional constriant // in to the worklist worklist.push_back(not_exprt(assertion)); if(additional_constraint!=true_exprt()) worklist.push_back(additional_constraint); acdl_domaint::varst var_leaf; // insert leaf nodes while(!leaf_worklist.empty() > 0) { const acdl_domaint::statementt statement=pop_from_list(leaf_worklist); push_into_list (worklist, statement); acdl_domaint::varst lvars; find_symbols(statement, lvars); var_leaf.insert(lvars.begin(), lvars.end()); } // insert intermediate nodes while(!inter_worklist.empty() > 0) { const acdl_domaint::statementt statement=pop_from_list(inter_worklist); push_into_list (worklist, statement); // push into worklist_vars acdl_domaint::varst avars; find_symbols(statement, avars); // do not insert any leaf variables for(acdl_domaint::varst::const_iterator it=avars.begin(); it!=avars.end(); ++it) { if(var_leaf.find(*it)==var_leaf.end()) worklist_vars.insert(*it); } } #ifdef DEBUG std::cout << "The content of the ordered worklist is as follows: " << std::endl; for(std::list<acdl_domaint::statementt>::const_iterator it=worklist.begin(); it!=worklist.end(); ++it) std::cout << "Worklist Element::" << from_expr(SSA.ns, "", *it) << std::endl; #endif #if 0 // ********************************************** // Initialization Strategy: Add only assertions // ********************************************** if (SSA.nodes.empty ()) return; // insert the assertions like (!(a1 && a2 && a3)) on to the worklist and_exprt::operandst and_expr; for (local_SSAt::nodest::const_iterator n_it=SSA.nodes.begin (); n_it!=SSA.nodes.end (); n_it++) { for (local_SSAt::nodet::assertionst::const_iterator a_it= n_it->assertions.begin (); a_it!=n_it->assertions.end (); a_it++) { and_expr.push_back(*a_it); } } unsigned int size=and_expr.size(); #ifdef DEBUG std::cout << "The number of Assertions are : " << size << std::endl; #endif exprt::operandst::const_iterator it=and_expr.begin(); std::cout << "First single assertion push: " << *it << std::endl; if(size==1) { exprt::operandst::const_iterator it=and_expr.begin(); #ifdef DEBUG std::cout << "First single assertion push: " << *it << std::endl; #endif exprt exp=*it; not_exprt not_exp(exp); push(worklist, not_exp); } else { and_exprt final_and; std::swap(final_and.operands(), and_expr); not_exprt not_exp(final_and); #ifdef DEBUG std::cout << "First push: " << not_exp.pretty() << std::endl; #endif push(worklist, not_exp); } #endif #if 0 // ************************************************** // Initialization Strategy: Add the first SSA element // ************************************************** // check for equalities or constraints or next node if (SSA.nodes.empty ()) return; assert(!SSA.nodes.front ().equalities.empty ()); // insert the first SSA element on to the worklist push(worklist, SSA.nodes.front ().equalities.front ()); #ifdef DEBUG std::cout << "First push: " << from_expr (SSA.ns, "", SSA.nodes.front().equalities.front ()) << std::endl; #endif #endif }
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 } }
acdl_domaint::meet_irreduciblet acdl_decision_heuristics_randt::operator() (const local_SSAt &SSA, const acdl_domaint::valuet &value) { #ifdef DEBUG std::cout << "Printing all decision variables" << std::endl; for(std::set<exprt>::const_iterator it=decision_variables.begin(); it!=decision_variables.end(); it++) std::cout << from_expr(SSA.ns, "", *it) << " , " << std::endl; #endif // copy the value to non-constant value acdl_domaint::valuet v; for(unsigned k=0;k<value.size();k++) v.push_back(value[k]); // collect the non-singleton variables std::vector<exprt> non_singletons; std::vector<exprt> singletons; acdl_domaint::meet_irreduciblet val; for(std::set<exprt>::const_iterator it=decision_variables.begin(); it!=decision_variables.end(); ++it) { val=domain.split(value, *it); if(!val.is_false()) non_singletons.push_back(val); // collect all singleton variables else singletons.push_back(*it); } // [TODO] Do not pop decision variables since it // is possible that a decision has to be made on // a singleton variable after backtracking when it // is no more a singleton variable. /*for(std::vector<exprt>::const_iterator it=singletons.begin(); it!=singletons.end(); ++it) decision_variables.erase(decision_variables.find(*it)); */ // no more decisions can be made if(non_singletons.size()==0) { #ifdef DEBUG std::cout << "NO DECISIONS CAN BE MADE " << std::endl; #endif return false_exprt(); } #ifdef DEBUG std::cout << "Printing all non-singletons decision variables" << std::endl; for(std::vector<exprt>::const_iterator it=non_singletons.begin(); it!=non_singletons.end(); ++it) std::cout << from_expr(SSA.ns, "", *it) << " , " << std::endl; #endif std::vector<exprt> non_cond; std::vector<exprt> cond; std::string str("cond"); std::string name; // separate the non-singleton cond and non_cond variables for(std::vector<exprt>::const_iterator it=non_singletons.begin(); it!=non_singletons.end(); ++it) { // check if it is not of type x<=10 or x>=10 but // something like !cond or cond const exprt &e=*it; if(e.id()!=ID_le && e.id()!=ID_ge && e.id()!=ID_lt && e.id()!=ID_gt) { exprt exp=it->op0(); const irep_idt &identifier=exp.get(ID_identifier); name=id2string(identifier); std::size_t found=name.find(str); if (found!=std::string::npos) cond.push_back(*it); // cond.push_back(*it); } else non_cond.push_back(*it); } bool decision=false; // Make a decision while(!decision) { if(cond.size()==0) { #if 0 // choose non-cond decision variables that // are nondet-vars // choose input nondet variables if(nondet_var.size()>0) { const acdl_domaint::meet_irreduciblet dec_expr_nondet= nondet_var[rand() % nondet_var.size()]; // now search for nondet_vars that are not singletons acdl_domaint::varst sym1; find_symbols(dec_expr_nondet, sym1); for(int i=0;i<non_cond.size();i++) { acdl_domaint::varst sym2; find_symbols(non_cond[i], sym2); for(acdl_domaint::varst::iterator it1=sym2.begin(); it1!=sym2.end(); it1++) { bool is_in=sym1.find(*it1)!=sym1.end(); if(is_in) return non_cond[i]; } } } #endif // select non-cond decision variables acdl_domaint::meet_irreduciblet dec_expr_rand= non_cond[rand() % non_cond.size()]; #ifdef DEBUG std::cout << "[NON-COND DECISION] " << dec_expr_rand << std::endl; #endif unsigned status=domain.compare_val_lit(v, dec_expr_rand); if(status!=0) { // not conflicting decision=true; return dec_expr_rand; } else continue; } else { // select cond decision variables acdl_domaint::meet_irreduciblet dec_expr_rand= cond[rand() % cond.size()]; #ifdef DEBUG std::cout << "[COND DECISION] " << dec_expr_rand << std::endl; #endif unsigned status=domain.compare_val_lit(v, dec_expr_rand); if(status!=0) { // not conflicting decision=true; return dec_expr_rand; } else continue; } } // returns false if no decision in made // and the control reaches here return false_exprt(); }