literalt prop_minimizet::constraint() { std::vector<objectivet> &entry=current->second; bvt or_clause; for(std::vector<objectivet>::iterator o_it=entry.begin(); o_it!=entry.end(); ++o_it) { if(!o_it->fixed) or_clause.push_back(!o_it->condition); } // This returns false if the clause is empty, // i.e., no further improvement possible. if(or_clause.empty()) return const_literal(false); else if(or_clause.size()==1) return or_clause.front(); else { or_exprt or_expr; forall_literals(it, or_clause) or_expr.copy_to_operands(literal_exprt(*it)); return prop_conv.convert(or_expr); } }
void satcheck_lingelingt::set_assumptions(const bvt &bv) { assumptions=bv; forall_literals(it, assumptions) assert(!it->is_constant()); }
bvt boolbvt::convert_array(const exprt &expr) { std::size_t width=boolbv_width(expr.type()); if(width==0) return conversion_failed(expr); if(expr.type().id()==ID_array) { assert(expr.has_operands()); const exprt::operandst &operands=expr.operands(); assert(!operands.empty()); std::size_t op_width=width/operands.size(); bvt bv; bv.reserve(width); forall_expr(it, operands) { const bvt &tmp=convert_bv(*it); if(tmp.size()!=op_width) throw "convert_array: unexpected operand width"; forall_literals(it2, tmp) bv.push_back(*it2); } return bv; }
propt::resultt satcheck_lingelingt::prop_solve() { assert(status!=ERROR); { std::string msg= i2string(_no_variables)+" variables, "+ i2string(clause_counter)+" clauses"; messaget::status(msg); } std::string msg; forall_literals(it, assumptions) lglassume(solver, it->dimacs()); const int res=lglsat(solver); if(res==10) { msg="SAT checker: negated claim is SATISFIABLE, i.e., does not hold"; messaget::status(msg); status=SAT; return P_SATISFIABLE; } else { assert(res==20); msg="SAT checker: negated claim is UNSATISFIABLE, i.e., holds"; messaget::status(msg); } status=UNSAT; return P_UNSATISFIABLE; }
propt::resultt satcheck_lingelingt::prop_solve() { assert(status!=ERROR); // We start counting at 1, thus there is one variable fewer. { std::string msg= std::to_string(no_variables()-1)+" variables, "+ std::to_string(clause_counter)+" clauses"; messaget::status() << msg << messaget::eom; } std::string msg; forall_literals(it, assumptions) lglassume(solver, it->dimacs()); const int res=lglsat(solver); if(res==10) { msg="SAT checker: instance is SATISFIABLE"; messaget::status() << msg << messaget::eom; status=SAT; return P_SATISFIABLE; } else { assert(res==20); msg="SAT checker: instance is UNSATISFIABLE"; messaget::status() << msg << messaget::eom; } status=UNSAT; return P_UNSATISFIABLE; }
literalt aig_prop_baset::lxor(const bvt &bv) { literalt literal=const_literal(false); forall_literals(it, bv) literal=lxor(*it, literal); return literal; }
literalt aig_prop_baset::lor(const bvt &bv) { literalt literal=const_literal(true); // Introduces N-1 extra nodes for N bits // See convert_node for where this overhead is removed forall_literals(it, bv) literal=land(neg(*it), literal); return neg(literal); }
literalt cvc_propt::lxor(const bvt &bv) { if(bv.empty()) return const_literal(false); if(bv.size()==1) return bv[0]; if(bv.size()==2) return lxor(bv[0], bv[1]); literalt literal=const_literal(false); forall_literals(it, bv) literal=lxor(*it, literal); return literal; }
void satcheck_precosatt::lcnf(const bvt &bv) { bvt new_bv; if(process_clause(bv, new_bv)) return; forall_literals(it, new_bv) solver->add(precosat_lit(*it)); solver->add(0); clause_counter++; }
void satcheck_lingelingt::lcnf(const bvt &bv) { bvt new_bv; if(process_clause(bv, new_bv)) return; forall_literals(it, new_bv) lgladd(solver, it->dimacs()); lgladd(solver, 0); clause_counter++; }
literalt smt1_propt::land(const bvt &bv) { out << std::endl; literalt l=new_variable(); out << ":assumption ; land" << std::endl; out << " (iff " << smt1_literal(l) << " (and"; forall_literals(it, bv) out << " " << smt1_literal(*it); out << "))" << std::endl; return l; }
literalt smt1_propt::lor(const bvt &bv) { out << "\n"; literalt l=new_variable(); out << ":assumption ; lor" << "\n"; out << " (iff " << smt1_literal(l) << " (or"; forall_literals(it, bv) out << " " << smt1_literal(*it); out << "))" << "\n"; return l; }
literalt smt1_propt::lxor(const bvt &bv) { if(bv.size()==0) return const_literal(false); if(bv.size()==1) return bv[0]; out << std::endl; literalt l=new_variable(); out << ":assumption ; lxor" << std::endl; out << " (iff " << smt1_literal(l) << " (xor"; forall_literals(it, bv) out << " " << smt1_literal(*it); out << "))" << std::endl; return l; }
bool boolbvt::type_conversion( const typet &src_type, const bvt &src, const typet &dest_type, bvt &dest) { bvtypet dest_bvtype=get_bvtype(dest_type); bvtypet src_bvtype=get_bvtype(src_type); if(src_bvtype==IS_C_BIT_FIELD) return type_conversion( c_bit_field_replacement_type(to_c_bit_field_type(src_type), ns), src, dest_type, dest); if(dest_bvtype==IS_C_BIT_FIELD) return type_conversion( src_type, src, c_bit_field_replacement_type(to_c_bit_field_type(dest_type), ns), dest); std::size_t src_width=src.size(); std::size_t dest_width=boolbv_width(dest_type); if(dest_width==0 || src_width==0) return true; dest.clear(); dest.reserve(dest_width); if(dest_type.id()==ID_complex) { if(src_type==dest_type.subtype()) { forall_literals(it, src) dest.push_back(*it); // pad with zeros for(std::size_t i=src.size(); i<dest_width; i++) dest.push_back(const_literal(false)); return false; } else if(src_type.id()==ID_complex) { // recursively do both halfs bvt lower, upper, lower_res, upper_res; lower.assign(src.begin(), src.begin()+src.size()/2); upper.assign(src.begin()+src.size()/2, src.end()); type_conversion(ns.follow(src_type.subtype()), lower, ns.follow(dest_type.subtype()), lower_res); type_conversion(ns.follow(src_type.subtype()), upper, ns.follow(dest_type.subtype()), upper_res); assert(lower_res.size()+upper_res.size()==dest_width); dest=lower_res; dest.insert(dest.end(), upper_res.begin(), upper_res.end()); return false; } } if(src_type.id()==ID_complex) { assert(dest_type.id()!=ID_complex); if(dest_type.id()==ID_signedbv || dest_type.id()==ID_unsignedbv || dest_type.id()==ID_floatbv || dest_type.id()==ID_fixedbv || dest_type.id()==ID_c_enum || dest_type.id()==ID_c_enum_tag || dest_type.id()==ID_bool) { // A cast from complex x to real T // is (T) __real__ x. bvt tmp_src(src); tmp_src.resize(src.size()/2); // cut off imag part return type_conversion(src_type.subtype(), tmp_src, dest_type, dest); } } switch(dest_bvtype) { case IS_RANGE: if(src_bvtype==IS_UNSIGNED || src_bvtype==IS_SIGNED || src_bvtype==IS_C_BOOL) { mp_integer dest_from=to_range_type(dest_type).get_from(); if(dest_from==0) { // do zero extension dest.resize(dest_width); for(std::size_t i=0; i<dest.size(); i++) dest[i]=(i<src.size()?src[i]:const_literal(false)); return false; } } else if(src_bvtype==IS_RANGE) // range to range { mp_integer src_from=to_range_type(src_type).get_from(); mp_integer dest_from=to_range_type(dest_type).get_from(); if(dest_from==src_from) { // do zero extension, if needed dest=bv_utils.zero_extension(src, dest_width); return false; } else { // need to do arithmetic: add src_from-dest_from mp_integer offset=src_from-dest_from; dest= bv_utils.add( bv_utils.zero_extension(src, dest_width), bv_utils.build_constant(offset, dest_width)); } return false; } break; case IS_FLOAT: // to float { float_utilst float_utils(prop); switch(src_bvtype) { case IS_FLOAT: // float to float // we don't have a rounding mode here, // which is why we refuse. break; case IS_SIGNED: // signed to float case IS_C_ENUM: float_utils.spec=to_floatbv_type(dest_type); dest=float_utils.from_signed_integer(src); return false; case IS_UNSIGNED: // unsigned to float case IS_C_BOOL: // _Bool to float float_utils.spec=to_floatbv_type(dest_type); dest=float_utils.from_unsigned_integer(src); return false; case IS_BV: assert(src_width==dest_width); dest=src; return false; default: if(src_type.id()==ID_bool) { // bool to float // build a one ieee_floatt f; f.spec=to_floatbv_type(dest_type); f.from_integer(1); dest=convert_bv(f.to_expr()); assert(src_width==1); Forall_literals(it, dest) *it=prop.land(*it, src[0]); return false; } } } break; case IS_FIXED: if(src_bvtype==IS_FIXED) { // fixed to fixed std::size_t dest_fraction_bits=to_fixedbv_type(dest_type).get_fraction_bits(), dest_int_bits=dest_width-dest_fraction_bits; std::size_t op_fraction_bits=to_fixedbv_type(src_type).get_fraction_bits(), op_int_bits=src_width-op_fraction_bits; dest.resize(dest_width); // i == position after dot // i == 0: first position after dot for(std::size_t i=0; i<dest_fraction_bits; i++) { // position in bv std::size_t p=dest_fraction_bits-i-1; if(i<op_fraction_bits) dest[p]=src[op_fraction_bits-i-1]; else dest[p]=const_literal(false); // zero padding } for(std::size_t i=0; i<dest_int_bits; i++) { // position in bv std::size_t p=dest_fraction_bits+i; assert(p<dest_width); if(i<op_int_bits) dest[p]=src[i+op_fraction_bits]; else dest[p]=src[src_width-1]; // sign extension } return false; } else if(src_bvtype==IS_BV) { assert(src_width==dest_width); dest=src; return false; } else if(src_bvtype==IS_UNSIGNED || src_bvtype==IS_SIGNED || src_bvtype==IS_C_BOOL || src_bvtype==IS_C_ENUM) { // integer to fixed std::size_t dest_fraction_bits= to_fixedbv_type(dest_type).get_fraction_bits(); for(std::size_t i=0; i<dest_fraction_bits; i++) dest.push_back(const_literal(false)); // zero padding for(std::size_t i=0; i<dest_width-dest_fraction_bits; i++) { literalt l; if(i<src_width) l=src[i]; else { if(src_bvtype==IS_SIGNED || src_bvtype==IS_C_ENUM) l=src[src_width-1]; // sign extension else l=const_literal(false); // zero extension } dest.push_back(l); } return false; } else if(src_type.id()==ID_bool) { // bool to fixed std::size_t fraction_bits= to_fixedbv_type(dest_type).get_fraction_bits(); assert(src_width==1); for(std::size_t i=0; i<dest_width; i++) { if(i==fraction_bits) dest.push_back(src[0]); else dest.push_back(const_literal(false)); } return false; } break; case IS_UNSIGNED: case IS_SIGNED: case IS_C_ENUM: switch(src_bvtype) { case IS_FLOAT: // float to integer // we don't have a rounding mode here, // which is why we refuse. break; case IS_FIXED: // fixed to integer { std::size_t op_fraction_bits= to_fixedbv_type(src_type).get_fraction_bits(); for(std::size_t i=0; i<dest_width; i++) { if(i<src_width-op_fraction_bits) dest.push_back(src[i+op_fraction_bits]); else { if(dest_bvtype==IS_SIGNED) dest.push_back(src[src_width-1]); // sign extension else dest.push_back(const_literal(false)); // zero extension } } // we might need to round up in case of negative numbers // e.g., (int)(-1.00001)==1 bvt fraction_bits_bv=src; fraction_bits_bv.resize(op_fraction_bits); literalt round_up= prop.land(prop.lor(fraction_bits_bv), src.back()); dest=bv_utils.incrementer(dest, round_up); return false; } case IS_UNSIGNED: // integer to integer case IS_SIGNED: case IS_C_ENUM: case IS_C_BOOL: { // We do sign extension for any source type // that is signed, independently of the // destination type. // E.g., ((short)(ulong)(short)-1)==-1 bool sign_extension= src_bvtype==IS_SIGNED || src_bvtype==IS_C_ENUM; for(std::size_t i=0; i<dest_width; i++) { if(i<src_width) dest.push_back(src[i]); else if(sign_extension) dest.push_back(src[src_width-1]); // sign extension else dest.push_back(const_literal(false)); } return false; } case IS_VERILOG_UNSIGNED: // verilog_unsignedbv to signed/unsigned/enum { for(std::size_t i=0; i<dest_width; i++) { std::size_t src_index=i*2; // we take every second bit if(src_index<src_width) dest.push_back(src[src_index]); else // always zero-extend dest.push_back(const_literal(false)); } return false; } break; case IS_VERILOG_SIGNED: // verilog_signedbv to signed/unsigned/enum { for(std::size_t i=0; i<dest_width; i++) { std::size_t src_index=i*2; // we take every second bit if(src_index<src_width) dest.push_back(src[src_index]); else // always sign-extend dest.push_back(src.back()); } return false; } break; default: if(src_type.id()==ID_bool) { // bool to integer assert(src_width==1); for(std::size_t i=0; i<dest_width; i++) { if(i==0) dest.push_back(src[0]); else dest.push_back(const_literal(false)); } return false; } } break; case IS_VERILOG_UNSIGNED: if(src_bvtype==IS_UNSIGNED || src_bvtype==IS_C_BOOL || src_type.id()==ID_bool) { for(std::size_t i=0, j=0; i<dest_width; i+=2, j++) { if(j<src_width) dest.push_back(src[j]); else dest.push_back(const_literal(false)); dest.push_back(const_literal(false)); } return false; } else if(src_bvtype==IS_SIGNED) { for(std::size_t i=0, j=0; i<dest_width; i+=2, j++) { if(j<src_width) dest.push_back(src[j]); else dest.push_back(src.back()); dest.push_back(const_literal(false)); } return false; } else if(src_bvtype==IS_VERILOG_UNSIGNED) { // verilog_unsignedbv to verilog_unsignedbv dest=src; if(dest_width<src_width) dest.resize(dest_width); else { dest=src; while(dest.size()<dest_width) { dest.push_back(const_literal(false)); dest.push_back(const_literal(false)); } } return false; } break; case IS_BV: assert(src_width==dest_width); dest=src; return false; case IS_C_BOOL: dest.resize(dest_width, const_literal(false)); if(src_bvtype==IS_FLOAT) { float_utilst float_utils(prop); float_utils.spec=to_floatbv_type(src_type); dest[0]=!float_utils.is_zero(src); } else if(src_bvtype==IS_C_BOOL) dest[0]=src[0]; else dest[0]=!bv_utils.is_zero(src); return false; default: if(dest_type.id()==ID_array) { if(src_width==dest_width) { dest=src; return false; } } else if(dest_type.id()==ID_struct) { const struct_typet &dest_struct = to_struct_type(dest_type); if(src_type.id()==ID_struct) { // we do subsets dest.resize(dest_width, const_literal(false)); const struct_typet &op_struct = to_struct_type(src_type); const struct_typet::componentst &dest_comp= dest_struct.components(); const struct_typet::componentst &op_comp= op_struct.components(); // build offset maps offset_mapt op_offsets, dest_offsets; build_offset_map(op_struct, op_offsets); build_offset_map(dest_struct, dest_offsets); // build name map typedef std::map<irep_idt, unsigned> op_mapt; op_mapt op_map; for(std::size_t i=0; i<op_comp.size(); i++) op_map[op_comp[i].get_name()]=i; // now gather required fields for(std::size_t i=0; i<dest_comp.size(); i++) { std::size_t offset=dest_offsets[i]; std::size_t comp_width=boolbv_width(dest_comp[i].type()); if(comp_width==0) continue; op_mapt::const_iterator it= op_map.find(dest_comp[i].get_name()); if(it==op_map.end()) { // not found // filling with free variables for(std::size_t j=0; j<comp_width; j++) dest[offset+j]=prop.new_variable(); } else { // found if(dest_comp[i].type()!=dest_comp[it->second].type()) { // filling with free variables for(std::size_t j=0; j<comp_width; j++) dest[offset+j]=prop.new_variable(); } else { std::size_t op_offset=op_offsets[it->second]; for(std::size_t j=0; j<comp_width; j++) dest[offset+j]=src[op_offset+j]; } } } return false; } } } return true; }