tvt satcheck_booleforce_baset::l_get(literalt a) const { assert(status==SAT); if(a.is_true()) return tvt(true); else if(a.is_false()) return tvt(false); tvt result; unsigned v=a.var_no(); assert(v<no_variables()); int r=booleforce_deref(v); if(r>0) result=tvt(true); else if(r<0) result=tvt(false); else result=tvt(tvt::tv_enumt::TV_UNKNOWN); if(a.sign()) result=!result; return result; }
tvt z3_propt::l_get(literalt a) const { tvt result=tvt(false); std::string literal; Z3_ast z3_literal; size_t found; if(a.is_true()) return tvt(true); else if(a.is_false()) return tvt(false); literal = "l"+i2string(a.var_no()); map_prop_varst::const_iterator cache_result=map_prop_vars.find(literal.c_str()); if(cache_result!=map_prop_vars.end()) { //std::cout << "Cache hit on " << cache_result->first << "\n"; z3_literal = cache_result->second; Z3_app app = Z3_to_app(z3_ctx, z3_literal); Z3_func_decl d = Z3_get_app_decl(z3_ctx, app); literal = Z3_func_decl_to_string(z3_ctx, d); found=literal.find("true"); if (found!=std::string::npos) result=tvt(true); else result=tvt(false); } if (a.sign()) result=!result; return result; }
tvt cvc_convt::l_get(literalt l) const { if(l.is_true()) return tvt(true); if(l.is_false()) return tvt(false); assert(l.var_no()<boolean_assignment.size()); return tvt(boolean_assignment[l.var_no()]^l.sign()); }
tvt smt1_propt::l_get(literalt literal) const { if(literal.is_true()) return tvt(true); if(literal.is_false()) return tvt(false); unsigned v=literal.var_no(); if(v>=assignment.size()) return tvt(tvt::TV_UNKNOWN); tvt r=assignment[v]; return literal.sign()?!r:r; }
void dplib_dect::read_assert(std::istream &in, std::string &line) { // strip ASSERT line=std::string(line, strlen("ASSERT "), std::string::npos); if(line=="") return; // bit-vector if(line[0]=='(') { // get identifier std::string::size_type pos= line.find(' '); std::string identifier=std::string(line, 1, pos-1); // get value if(!std::getline(in, line)) return; // skip spaces pos=0; while(pos<line.size() && line[pos]==' ') pos++; // get final ")" std::string::size_type pos2=line.rfind(')'); if(pos2==std::string::npos) return; std::string value=std::string(line, pos, pos2-pos); #if 0 std::cout << ">" << identifier << "< = >" << value << "<"; std::cout << std::endl; #endif } else { // boolean tvt value=tvt(true); if(has_prefix(line, "NOT ")) { line=std::string(line, strlen("NOT "), std::string::npos); value=tvt(false); } if(line=="") return; if(line[0]=='l') { unsigned number=unsafe_str2unsigned(line.c_str()+1); assert(number<dplib_prop.no_variables()); dplib_prop.assignment[number]=value; } } }
tvt invariant_sett::is_eq(std::pair<unsigned, unsigned> p) const { std::pair<unsigned, unsigned> s=p; std::swap(s.first, s.second); if(has_eq(p)) return tvt(true); if(has_ne(p) || has_ne(s)) return tvt(false); return tvt::unknown(); }
tvt qbf_squolem_coret::l_get(literalt a) const { if(a.is_true()) return tvt(tvt::TV_TRUE); else if(a.is_false()) return tvt(tvt::TV_FALSE); else if(squolem->modelIsTrue(a.var_no())) return tvt(tvt::TV_TRUE); else if(squolem->modelIsFalse(a.var_no()) || squolem->modelIsDontCare(a.var_no())) return tvt(tvt::TV_FALSE); else return tvt(tvt::TV_UNKNOWN); }
void smt1_propt::set_assignment(literalt literal, bool value) { if(literal.is_true() || literal.is_false()) return; unsigned v=literal.var_no(); assert(v<assignment.size()); assignment[v]=tvt(value); }
void fault_localizationt::localize_linear(lpointst &lpoints) { lpoints_valuet v; v.resize(lpoints.size()); for(size_t i=0; i<lpoints.size(); ++i) v[i]=tvt(tvt::tv_enumt::TV_UNKNOWN); for(size_t i=0; i<v.size(); ++i) { v[i]=tvt(tvt::tv_enumt::TV_TRUE); if(!check(lpoints, v)) update_scores(lpoints, v); v[i]=tvt(tvt::tv_enumt::TV_FALSE); if(!check(lpoints, v)) update_scores(lpoints, v); v[i]=tvt(tvt::tv_enumt::TV_UNKNOWN); } }
tvt satcheck_lingelingt::l_get(literalt a) const { if(a.is_constant()) return tvt(a.sign()); tvt result; if(a.var_no()>lglmaxvar(solver)) return tvt(tvt::TV_UNKNOWN); const int val=lglderef(solver, a.dimacs()); if(val>0) result=tvt(true); else if(val<0) result=tvt(false); else return tvt(tvt::TV_UNKNOWN); return result; }
tvt satcheck_precosatt::l_get(literalt a) const { if(a.is_constant()) return tvt(a.sign()); tvt result; if(a.var_no()>solver->getMaxVar()) return tvt(tvt::tv_enumt::TV_UNKNOWN); const int val=solver->val(precosat_lit(a)); if(val>0) result=tvt(true); else if(val<0) result=tvt(false); else return tvt(tvt::tv_enumt::TV_UNKNOWN); return result; }
tvt boolector_propt::l_get(literalt a) const { tvt result=tvt(false); std::string literal; BtorExp *boolector_literal; size_t found; if(a.is_true()) return tvt(true); else if(a.is_false()) return tvt(false); literal_cachet::const_iterator cache_result=literal_cache.find(a.var_no()); if(cache_result!=literal_cache.end()) boolector_literal = cache_result->second; else return tvt(tvt::TV_UNKNOWN); literal = boolector_bv_assignment(boolector_ctx, boolector_literal); found=literal.find("1"); if (found!=std::string::npos) result=tvt(true); else result=tvt(false); if (a.sign()) result=!result; return result; }
tvt satcheck_minisat1_baset::l_get(literalt a) const { if(a.is_true()) return tvt(true); else if(a.is_false()) return tvt(false); tvt result; assert(a.var_no()!=0); assert(a.var_no()<(unsigned)solver->model.size()); if(solver->model[a.var_no()]==l_True) result=tvt(true); else if(solver->model[a.var_no()]==l_False) result=tvt(false); else result=tvt(tvt::TV_UNKNOWN); if(a.sign()) result=!result; return result; }
tvt satcheck_smvsatt::l_get(literalt a) const { assert(status==SAT); if(a.is_true()) return tvt(true); else if(a.is_false()) return tvt(false); tvt result; unsigned v=a.var_no(); switch(sat_instance_value(satsolver, v)) { case 0: result=tvt(false); break; case 1: result=tvt(true); break; default: result=tvt(tvt::tv_enumt::TV_UNKNOWN); break; } if(a.sign()) result=!result; return result; }
void build_goto_trace( const symex_target_equationt &target, symex_target_equationt::SSA_stepst::const_iterator end_step, const prop_convt &prop_conv, const namespacet &ns, goto_tracet &goto_trace) { // We need to re-sort the steps according to their clock. // Furthermore, read-events need to occur before write // events with the same clock. typedef std::map<mp_integer, goto_tracet::stepst> time_mapt; time_mapt time_map; mp_integer current_time=0; for(symex_target_equationt::SSA_stepst::const_iterator it=target.SSA_steps.begin(); it!=end_step; it++) { const symex_target_equationt::SSA_stept &SSA_step=*it; if(prop_conv.l_get(SSA_step.guard_literal)!=tvt(true)) continue; if(it->is_constraint() || it->is_spawn()) continue; else if(it->is_atomic_begin()) { // for atomic sections the timing can only be determined once we see // a shared read or write (if there is none, the time will be // reverted to the time before entering the atomic section); we thus // use a temporary negative time slot to gather all events current_time*=-1; continue; } else if(it->is_shared_read() || it->is_shared_write() || it->is_atomic_end()) { mp_integer time_before=current_time; if(it->is_shared_read() || it->is_shared_write()) { // these are just used to get the time stamp exprt clock_value=prop_conv.get( symbol_exprt(partial_order_concurrencyt::rw_clock_id(it))); to_integer(clock_value, current_time); } else if(it->is_atomic_end() && current_time<0) current_time*=-1; assert(current_time>=0); // move any steps gathered in an atomic section if(time_before<0) { time_mapt::iterator entry= time_map.insert(std::make_pair( current_time, goto_tracet::stepst())).first; entry->second.splice(entry->second.end(), time_map[time_before]); time_map.erase(time_before); } continue; } // drop PHI and GUARD assignments altogether if(it->is_assignment() && (SSA_step.assignment_type==symex_target_equationt::PHI || SSA_step.assignment_type==symex_target_equationt::GUARD)) continue; goto_tracet::stepst &steps=time_map[current_time]; steps.push_back(goto_trace_stept()); goto_trace_stept &goto_trace_step=steps.back(); goto_trace_step.thread_nr=SSA_step.source.thread_nr; goto_trace_step.pc=SSA_step.source.pc; goto_trace_step.comment=SSA_step.comment; if(SSA_step.ssa_lhs.is_not_nil()) goto_trace_step.lhs_object=ssa_exprt(SSA_step.ssa_lhs.get_original_expr()); else goto_trace_step.lhs_object.make_nil(); goto_trace_step.type=SSA_step.type; goto_trace_step.hidden=SSA_step.hidden; goto_trace_step.format_string=SSA_step.format_string; goto_trace_step.io_id=SSA_step.io_id; goto_trace_step.formatted=SSA_step.formatted; goto_trace_step.identifier=SSA_step.identifier; goto_trace_step.assignment_type= (it->is_assignment()&& (SSA_step.assignment_type==symex_targett::VISIBLE_ACTUAL_PARAMETER || SSA_step.assignment_type==symex_targett::HIDDEN_ACTUAL_PARAMETER))? goto_trace_stept::ACTUAL_PARAMETER: goto_trace_stept::STATE; if(SSA_step.original_full_lhs.is_not_nil()) goto_trace_step.full_lhs= build_full_lhs_rec( prop_conv, ns, SSA_step.original_full_lhs, SSA_step.ssa_full_lhs); if(SSA_step.ssa_lhs.is_not_nil()) goto_trace_step.lhs_object_value=prop_conv.get(SSA_step.ssa_lhs); if(SSA_step.ssa_full_lhs.is_not_nil()) { goto_trace_step.full_lhs_value=prop_conv.get(SSA_step.ssa_full_lhs); simplify(goto_trace_step.full_lhs_value, ns); } for(const auto & j : SSA_step.converted_io_args) { if(j.is_constant() || j.id()==ID_string_constant) goto_trace_step.io_args.push_back(j); else { exprt tmp=prop_conv.get(j); goto_trace_step.io_args.push_back(tmp); } } if(SSA_step.is_assert() || SSA_step.is_assume() || SSA_step.is_goto()) { goto_trace_step.cond_expr=SSA_step.cond_expr; goto_trace_step.cond_value= prop_conv.l_get(SSA_step.cond_literal).is_true(); } } // Now assemble into a single goto_trace. // This expoits sorted-ness of the map. for(auto & t_it : time_map) goto_trace.steps.splice(goto_trace.steps.end(), t_it.second); // produce the step numbers unsigned step_nr=0; for(auto & s_it : goto_trace.steps) s_it.step_nr=++step_nr; }
tvt qbf_quantort::l_get(literalt a) const { assert(false); return tvt(tvt::TV_UNKNOWN); }
bool bv_minimizing_dect::minimize(const minimization_listt &symbols) { // unfortunately, only MiniSat supports this #if defined(SATCHECK_MINISAT) || defined(SATCHECK_MINISAT2) bvt constraints; for(minimization_listt::const_iterator l_it=symbols.begin(); l_it!=symbols.end(); l_it++) { unsigned result=0; const exprt &symbol = *l_it; status("Minimizing... "); // FIXME: be more gener[ous|al] here! assert(symbol.type().id()==ID_unsignedbv); unsigned width=boolbv_width(symbol.type()); for(unsigned i = width; i > 0; i--) { literalt lit; #if 0 std::cout << "SYMBOL: " << symbol << std::endl; #endif if(literal(symbol, i-1, lit)) continue; // there's no corresponding literal if(lit.is_constant()) continue; literalt nlit=satcheck.lnot(lit); constraints.push_back(nlit); if(satcheck.l_get(lit)==tvt(false)) continue; // call Minisat with constraints satcheck.set_assumptions(constraints); if(satcheck.prop_solve() == propt::P_UNSATISFIABLE) { // change constraint to 1 constraints.back().swap(lit); result |= 1 << (i-1); // make sure the model is reconstructed satcheck.set_assumptions(constraints); if(satcheck.prop_solve()==propt::P_UNSATISFIABLE) assert (false); // do not remove call to prop_solve!! } } status(symbol.get_string(ID_identifier)+" = "+i2string(result)); } return true; #else // we don't have it... return false; #endif }
void build_goto_trace( const symex_target_equationt &target, const prop_convt &prop_conv, const namespacet &ns, goto_tracet &goto_trace) { // We need to re-sort the steps according to their clock. // Furthermore, read-events need to occur before write // events with the same clock. typedef std::map<mp_integer, goto_tracet::stepst> time_mapt; time_mapt time_map; mp_integer current_time=0; for(symex_target_equationt::SSA_stepst::const_iterator it=target.SSA_steps.begin(); it!=target.SSA_steps.end(); it++) { const symex_target_equationt::SSA_stept &SSA_step=*it; if(prop_conv.l_get(SSA_step.guard_literal)!=tvt(true)) continue; if(it->is_constraint() || it->is_spawn()) continue; else if(it->is_atomic_begin()) { // for atomic sections the timing can only be determined once we see // a shared read or write (if there is none, the time will be // reverted to the time before entering the atomic section); we thus // use a temporary negative time slot to gather all events current_time*=-1; continue; } else if(it->is_shared_read() || it->is_shared_write() || it->is_atomic_end()) { mp_integer time_before=current_time; if(it->is_shared_read() || it->is_shared_write()) { // these are just used to get the time stamp exprt clock_value=prop_conv.get( symbol_exprt(partial_order_concurrencyt::rw_clock_id(it))); to_integer(clock_value, current_time); } else if(it->is_atomic_end() && current_time<0) current_time*=-1; assert(current_time>=0); // move any steps gathered in an atomic section if(time_before<0) { time_mapt::iterator entry= time_map.insert(std::make_pair( current_time, goto_tracet::stepst())).first; entry->second.splice(entry->second.end(), time_map[time_before]); time_map.erase(time_before); } continue; } // drop PHI and GUARD assignments altogether if(it->is_assignment() && (SSA_step.assignment_type==symex_target_equationt::PHI || SSA_step.assignment_type==symex_target_equationt::GUARD)) continue; goto_tracet::stepst &steps=time_map[current_time]; steps.push_back(goto_trace_stept()); goto_trace_stept &goto_trace_step=steps.back(); goto_trace_step.thread_nr=SSA_step.source.thread_nr; goto_trace_step.pc=SSA_step.source.pc; goto_trace_step.comment=SSA_step.comment; goto_trace_step.lhs_object=SSA_step.original_lhs_object; goto_trace_step.type=SSA_step.type; goto_trace_step.hidden=SSA_step.hidden; goto_trace_step.format_string=SSA_step.format_string; goto_trace_step.io_id=SSA_step.io_id; goto_trace_step.formatted=SSA_step.formatted; goto_trace_step.identifier=SSA_step.identifier; goto_trace_step.assignment_type= (SSA_step.assignment_type==symex_targett::VISIBLE_ACTUAL_PARAMETER || SSA_step.assignment_type==symex_targett::HIDDEN_ACTUAL_PARAMETER)? goto_trace_stept::ACTUAL_PARAMETER: goto_trace_stept::STATE; if(SSA_step.original_full_lhs.is_not_nil()) goto_trace_step.full_lhs= build_full_lhs_rec( prop_conv, ns, SSA_step.original_full_lhs, SSA_step.ssa_full_lhs); if(SSA_step.ssa_lhs.is_not_nil()) goto_trace_step.lhs_object_value=prop_conv.get(SSA_step.ssa_lhs); if(SSA_step.ssa_full_lhs.is_not_nil()) { goto_trace_step.full_lhs_value=prop_conv.get(SSA_step.ssa_full_lhs); simplify(goto_trace_step.full_lhs_value, ns); } for(std::list<exprt>::const_iterator j=SSA_step.converted_io_args.begin(); j!=SSA_step.converted_io_args.end(); j++) { const exprt &arg=*j; if(arg.is_constant() || arg.id()==ID_string_constant) goto_trace_step.io_args.push_back(arg); else { exprt tmp=prop_conv.get(arg); goto_trace_step.io_args.push_back(tmp); } } if(SSA_step.is_assert() || SSA_step.is_assume()) { goto_trace_step.cond_expr=SSA_step.cond_expr; goto_trace_step.cond_value= prop_conv.l_get(SSA_step.cond_literal).is_true(); } else if(SSA_step.is_location() && SSA_step.source.pc->is_goto()) { goto_trace_step.cond_expr=SSA_step.source.pc->guard; const bool backwards=SSA_step.source.pc->is_backwards_goto(); symex_target_equationt::SSA_stepst::const_iterator next=it; ++next; assert(next!=target.SSA_steps.end()); // goto was taken if backwards and next is enabled or forward // and next is not active; // there is an ambiguity here if a forward goto is to the next // instruction, which we simply ignore for now goto_trace_step.goto_taken= backwards== (prop_conv.l_get(next->guard_literal)==tvt(true)); } } // Now assemble into a single goto_trace. // This expoits sorted-ness of the map. for(time_mapt::iterator t_it=time_map.begin(); t_it!=time_map.end(); t_it++) { goto_trace.steps.splice(goto_trace.steps.end(), t_it->second); } // produce the step numbers unsigned step_nr=0; for(goto_tracet::stepst::iterator s_it=goto_trace.steps.begin(); s_it!=goto_trace.steps.end(); s_it++) s_it->step_nr=++step_nr; // Now delete anything after failed assertion for(goto_tracet::stepst::iterator s_it1=goto_trace.steps.begin(); s_it1!=goto_trace.steps.end(); s_it1++) if(s_it1->is_assert() && !s_it1->cond_value) { s_it1++; for(goto_tracet::stepst::iterator s_it2=s_it1; s_it2!=goto_trace.steps.end(); s_it2=goto_trace.steps.erase(s_it2)); break; } }
tvt satcheck_zcoret::l_get(literalt a) const { assert(false); return tvt(tvt::tv_enumt::TV_UNKNOWN); }
tvt qbf_qubet::l_get(literalt a) const { assert(false); return tvt(false); }
bool prop_convt::get_bool(const exprt &expr, tvt &value) const { // trivial cases if(expr.is_true()) { value=tvt(true); return false; } else if(expr.is_false()) { value=tvt(false); return false; } else if(expr.id()==ID_symbol) { symbolst::const_iterator result= symbols.find(to_symbol_expr(expr).get_identifier()); if(result==symbols.end()) return true; value=prop.l_get(result->second); return false; } // sub-expressions if(expr.id()==ID_not) { if(expr.type().id()==ID_bool && expr.operands().size()==1) { if(get_bool(expr.op0(), value)) return true; value=!value; return false; } } else if(expr.id()==ID_and || expr.id()==ID_or) { if(expr.type().id()==ID_bool && expr.operands().size()>=1) { value=tvt(expr.id()==ID_and); forall_operands(it, expr) { tvt tmp; if(get_bool(*it, tmp)) return true; if(expr.id()==ID_and) { if(tmp.is_false()) { value=tvt(false); return false; } value=value && tmp; } else // or { if(tmp.is_true()) { value=tvt(true); return false; } value=value || tmp; } } return false; }