std::string get_prog_var_name(const symbol_tablet &st, const goto_programt::targett &decl) { const irep_idt &base_id=st.lookup(get_affected_variable(*decl)).base_name; std::string base_name(id2string(base_id)); return base_name+=PROG_SUFFIX; }
void link_result_var(const symbol_tablet &st, goto_functionst &gf, const size_t num_user_vars, const size_t max_solution_size, goto_programt::targett pos) { goto_programt &body=get_entry_body(gf); const size_t num_temps=max_solution_size - 1; pos=link_temp_vars(st, body, --pos, num_temps, num_user_vars); ++pos; set_rops_reference(st, body, pos, get_affected_variable(*pos), num_temps); }
void safety_learn_configt::process(const size_t max_solution_size) { constraint_varst ce_vars; get_invariant_constraint_vars(ce_vars, original_program); const typet type(invariant_meta_type()); // XXX: Currently single data type const exprt zero(gen_zero(type)); counterexamplet dummy_ce; dummy_ce.x.push_back(counterexamplet::assignmentst()); counterexamplet::assignmentst &x=dummy_ce.x.front(); for (const symbol_exprt &var : ce_vars) x.insert(std::make_pair(var.get_identifier(), zero)); // TODO: Implement for multiple loops (change constraint, instrumentation) const safety_programt &prog=original_program; const invariant_programt::const_invariant_loopst loops=prog.get_loops(); assert(!loops.empty()); // XXX: We might have to handle skolem choices explicitly at some point for (const goto_programt::targett &skolem_choice : loops.front()->skolem_choices) x.insert(std::make_pair(get_affected_variable(*skolem_choice), zero)); counterexamplet::assignmentst &x0=dummy_ce.x0; for (const goto_programt::targett &x0_choice : original_program.x0_choices) x0.insert(std::make_pair(get_affected_variable(*x0_choice), zero)); counterexamplest empty(1, dummy_ce); process(empty, max_solution_size); }
void assume_renondet_inputs_valid(jsa_programt &prog) { if (prog.counterexample_locations.empty()) return; const symbol_tablet &st=prog.st; goto_programt &body=get_entry_body(prog.gf); for (const goto_programt::targett &pos : prog.inductive_step_renondets) { const irep_idt &id=get_affected_variable(*pos); const symbol_exprt lhs(st.lookup(id).symbol_expr()); const typet &type=lhs.type(); if (is_jsa_heap(type)) assume_valid_heap(st, body, pos, address_of_exprt(lhs)); } }
void safety_add_learned_counterexamples(safety_programt &prog, const safety_goto_cest &ces, constraint_factoryt constraint) { if (ces.empty()) return; // TODO: Implement for multiple loops (change constraint, instrumentation) counterexamplest x0s; std::transform(ces.begin(), ces.end(), std::back_inserter(x0s), [](const safety_goto_cet &ce) { return ce.x0;}); counterexamplest first_loop_only; std::transform(ces.begin(), ces.end(), std::back_inserter(first_loop_only), [](const safety_goto_cet &ce) { assert(!ce.x.empty()); return ce.x.front();}); const std::string x0_pre(X0_CHOICE_PREFIX); const std::string x_pre(X_CHOICE_PREFIX); invariant_declare_x_choice_arrays(prog, x0s, x0_pre); invariant_declare_x_choice_arrays(prog, first_loop_only, x_pre); const size_t sz=ces.size(); const goto_programt::targett loop_end=invariant_add_ce_loop(prog, sz, false); positional_assign(prog, prog.x0_choices, first_loop_only, x0_pre); for (const goto_programt::targett x0 : prog.x0_choices) { const irep_idt &id=get_affected_variable(*x0); const counterexamplet &ce_template=x0s.front(); const counterexamplet::const_iterator it=ce_template.find(id); assert(ce_template.end() != it); counterexamplet tmp; tmp.insert(std::make_pair(id, it->second)); invariant_assign_ce_values(prog, tmp, x0s.size(), x0_pre, x0, false); } goto_programt::targett pos=prog.get_loops().front()->meta_variables.Ix; const size_t first_loop_sz=first_loop_only.size(); invariant_assign_ce_values(prog, first_loop_only.front(), first_loop_sz, x_pre, pos, false); invariant_add_constraint(prog, constraint, loop_end); }
void safety_fitness_configt::set_test_case(const counterexamplet &ce) { if (quantifiers.empty()) return; goto_functionst &gf=program.gf; // TODO: Implement for multiple loops (change constraint, instrumentation) const counterexamplet::assignmentst &ass=ce.x.back(); typedef counterexamplet::assignmentst counterexamplet; for (goto_programt::targett quantifier : quantifiers) { const irep_idt &var=get_affected_variable(*quantifier); const counterexamplet::const_iterator it=ass.find(var); if (ass.end() == it) continue; symbol_tablet &st=program.st; if (program_contains_ce) { goto_programt::targett assignment=quantifier; erase_target(get_entry_body(gf).instructions, ++assignment); } invariant_assign_user_variable(st, gf, quantifier, var, it->second); } gf.update(); program_contains_ce=true; }
bool is_nondet(goto_programt::const_targett target, goto_programt::const_targett end) { const goto_programt::instructiont &instr=*target; switch (instr.type) { case goto_program_instruction_typet::DECL: { goto_programt::const_targett next=std::next(target); if (next == end) return true; if (goto_program_instruction_typet::FUNCTION_CALL == next->type) { if (to_code_function_call(next->code).lhs().is_not_nil()) return false; else ++next; } const goto_programt::instructiont next_instr=*next; if (goto_program_instruction_typet::ASSIGN != next_instr.type) return true; const irep_idt id(get_affected_variable(instr)); if (id != get_affected_variable(next_instr)) return true; return contains(to_code_assign(next_instr.code).rhs(), id); } case goto_program_instruction_typet::ASSIGN: { const exprt &rhs=to_code_assign(instr.code).rhs(); if (ID_side_effect != rhs.id()) return false; return ID_nondet == to_side_effect_expr(rhs).get_statement(); } case goto_program_instruction_typet::FUNCTION_CALL: { const code_function_callt &call=to_code_function_call(instr.code); if (call.lhs().is_not_nil()) return false; } default: return false; } }