bool to_integer(const exprt &expr, mp_integer &int_value) { if(!expr.is_constant()) return true; const std::string &value = expr.value().as_string(); const irep_idt &type_id = expr.type().id(); if(type_id == "pointer") { if(value == "NULL") { int_value = 0; return false; } } else if(type_id == "c_enum" || type_id == "symbol") { int_value = string2integer(value); return false; } else if(type_id == "unsignedbv") { int_value = binary2integer(value, false); return false; } else if(type_id == "signedbv") { int_value = binary2integer(value, true); return false; } return true; }
bool polynomial_acceleratort::fit_const(goto_programt::instructionst &body, exprt &target, polynomialt &poly) { return false; scratch_programt program(symbol_table); program.append(body); program.add_instruction(ASSERT)->guard = equal_exprt(target, not_exprt(target)); try { if (program.check_sat(false)) { #ifdef DEBUG std::cout << "Fitting constant, eval'd to: " << expr2c(program.eval(target), ns) << std::endl; #endif constant_exprt val = to_constant_expr(program.eval(target)); mp_integer mp = binary2integer(val.get_value().c_str(), true); monomialt mon; monomialt::termt term; term.var = from_integer(1, target.type()); term.exp = 1; mon.terms.push_back(term); mon.coeff = mp.to_long(); poly.monomials.push_back(mon); return true; } } catch (std::string s) { std::cout << "Error in fitting polynomial SAT check: " << s << std::endl; } catch (const char *s) { std::cout << "Error in fitting polynomial SAT check: " << s << std::endl; } return false; }
exprt boolbvt::bv_get_rec( const bvt &bv, const std::vector<bool> &unknown, std::size_t offset, const typet &type) const { if(type.id()==ID_symbol) return bv_get_rec(bv, unknown, offset, ns.follow(type)); std::size_t width=boolbv_width(type); assert(bv.size()==unknown.size()); assert(bv.size()>=offset+width); if(type.id()==ID_bool) { if(!unknown[offset]) { switch(prop.l_get(bv[offset]).get_value()) { case tvt::tv_enumt::TV_FALSE: return false_exprt(); case tvt::tv_enumt::TV_TRUE: return true_exprt(); default: return false_exprt(); // default } } return nil_exprt(); } bvtypet bvtype=get_bvtype(type); if(bvtype==IS_UNKNOWN) { if(type.id()==ID_array) { const typet &subtype=type.subtype(); std::size_t sub_width=boolbv_width(subtype); if(sub_width!=0) { exprt::operandst op; op.reserve(width/sub_width); for(std::size_t new_offset=0; new_offset<width; new_offset+=sub_width) { op.push_back( bv_get_rec(bv, unknown, offset+new_offset, subtype)); } exprt dest=exprt(ID_array, type); dest.operands().swap(op); return dest; } } else if(type.id()==ID_struct_tag) { return bv_get_rec(bv, unknown, offset, ns.follow_tag(to_struct_tag_type(type))); } else if(type.id()==ID_union_tag) { return bv_get_rec(bv, unknown, offset, ns.follow_tag(to_union_tag_type(type))); } else if(type.id()==ID_struct) { const struct_typet &struct_type=to_struct_type(type); const struct_typet::componentst &components=struct_type.components(); std::size_t new_offset=0; exprt::operandst op; op.reserve(components.size()); for(struct_typet::componentst::const_iterator it=components.begin(); it!=components.end(); it++) { const typet &subtype=ns.follow(it->type()); op.push_back(nil_exprt()); std::size_t sub_width=boolbv_width(subtype); if(sub_width!=0) { op.back()=bv_get_rec(bv, unknown, offset+new_offset, subtype); new_offset+=sub_width; } } struct_exprt dest(type); dest.operands().swap(op); return dest; } else if(type.id()==ID_union) { const union_typet &union_type=to_union_type(type); const union_typet::componentst &components=union_type.components(); assert(!components.empty()); // Any idea that's better than just returning the first component? std::size_t component_nr=0; union_exprt value(union_type); value.set_component_name( components[component_nr].get_name()); const typet &subtype=components[component_nr].type(); value.op()=bv_get_rec(bv, unknown, offset, subtype); return value; } else if(type.id()==ID_vector) { const typet &subtype=ns.follow(type.subtype()); std::size_t sub_width=boolbv_width(subtype); if(sub_width!=0 && width%sub_width==0) { std::size_t size=width/sub_width; exprt value(ID_vector, type); value.operands().resize(size); for(std::size_t i=0; i<size; i++) value.operands()[i]= bv_get_rec(bv, unknown, i*sub_width, subtype); return value; } } else if(type.id()==ID_complex) { const typet &subtype=ns.follow(type.subtype()); std::size_t sub_width=boolbv_width(subtype); if(sub_width!=0 && width==sub_width*2) { exprt value(ID_complex, type); value.operands().resize(2); value.op0()=bv_get_rec(bv, unknown, 0*sub_width, subtype); value.op1()=bv_get_rec(bv, unknown, 1*sub_width, subtype); return value; } } } std::string value; for(std::size_t bit_nr=offset; bit_nr<offset+width; bit_nr++) { char ch; if(unknown[bit_nr]) ch='0'; else switch(prop.l_get(bv[bit_nr]).get_value()) { case tvt::tv_enumt::TV_FALSE: ch='0'; break; case tvt::tv_enumt::TV_TRUE: ch='1'; break; case tvt::tv_enumt::TV_UNKNOWN: ch='0'; break; default: assert(false); } value=ch+value; } switch(bvtype) { case IS_UNKNOWN: if(type.id()==ID_string) { mp_integer int_value=binary2integer(value, false); irep_idt s; if(int_value>=string_numbering.size()) s=irep_idt(); else s=string_numbering[int_value.to_long()]; return constant_exprt(s, type); } break; case IS_RANGE: { mp_integer int_value=binary2integer(value, false); mp_integer from=string2integer(type.get_string(ID_from)); constant_exprt value_expr(type); value_expr.set_value(integer2string(int_value+from)); return value_expr; } break; default: case IS_C_ENUM: constant_exprt value_expr(type); value_expr.set_value(value); return value_expr; } return nil_exprt(); }
void fixedbvt::from_expr(const constant_exprt &expr) { spec=to_fixedbv_type(expr.type()); v=binary2integer(id2string(expr.get_value()), true); }
void bv_arithmetict::from_expr(const exprt &expr) { assert(expr.is_constant()); spec=expr.type(); value=binary2integer(expr.get_string(ID_value), spec.is_signed); }
void ieee_floatt::from_expr(const constant_exprt &expr) { spec=ieee_float_spect(to_floatbv_type(expr.type())); unpack(binary2integer(id2string(expr.get_value()), false)); }
void ieee_floatt::from_expr(const exprt &expr) { assert(expr.is_constant()); spec=to_floatbv_type(expr.type()); unpack(binary2integer(expr.get_string(ID_value), false)); }
void rw_sett::read_write_rec( const exprt &expr, bool r, bool w, const std::string &suffix, const guardt &guard) { if(expr.id()=="symbol" && !expr.has_operands()) { const symbol_exprt &symbol_expr=to_symbol_expr(expr); const symbolt *symbol; if(!ns.lookup(symbol_expr.get_identifier(), symbol)) { if(!symbol->static_lifetime /*&& expr.type().id()=="pointer"*/) { return; // ignore for now } if(symbol->name=="c::__ESBMC_alloc" || symbol->name=="c::__ESBMC_alloc_size" || symbol->name=="c::stdin" || symbol->name=="c::stdout" || symbol->name=="c::stderr" || symbol->name=="c::sys_nerr") { return; // ignore for now } } irep_idt object=id2string(symbol_expr.get_identifier())+suffix; entryt &entry=entries[object]; entry.object=object; entry.r=entry.r || r; entry.w=entry.w || w; entry.guard = migrate_expr_back(guard.as_expr()); } else if(expr.id()=="member") { assert(expr.operands().size()==1); const std::string &component_name=expr.component_name().as_string(); read_write_rec(expr.op0(), r, w, "."+component_name+suffix, guard); } else if(expr.id()=="index") { // we don't distinguish the array elements for now assert(expr.operands().size()==2); std::string tmp; tmp = integer2string(binary2integer(expr.op1().value().as_string(), true),10); read_write_rec(expr.op0(), r, w, "["+suffix+tmp+"]", guard); read(expr.op1(), guard); } else if(expr.id()=="dereference") { assert(expr.operands().size()==1); read(expr.op0(), guard); exprt tmp(expr.op0()); expr2tc tmp_expr; migrate_expr(tmp, tmp_expr); dereference(target, tmp_expr, ns, value_sets); tmp = migrate_expr_back(tmp_expr); read_write_rec(tmp, r, w, suffix, guard); } else if(expr.is_address_of() || expr.id()=="implicit_address_of") { assert(expr.operands().size()==1); } else if(expr.id()=="if") { assert(expr.operands().size()==3); read(expr.op0(), guard); guardt true_guard(guard); expr2tc tmp_expr; migrate_expr(expr.op0(), tmp_expr); true_guard.add(tmp_expr); read_write_rec(expr.op1(), r, w, suffix, true_guard); guardt false_guard(guard); migrate_expr(gen_not(expr.op0()), tmp_expr); false_guard.add(tmp_expr); read_write_rec(expr.op2(), r, w, suffix, false_guard); } else { forall_operands(it, expr) read_write_rec(*it, r, w, suffix, guard); } }