bvt bv_utilst::shift(const bvt &src, const shiftt s, std::size_t dist) { bvt result; result.resize(src.size()); for(std::size_t i=0; i<src.size(); i++) { literalt l; switch(s) { case LEFT: l=(dist<=i?src[i-dist]:const_literal(false)); break; case ARIGHT: l=(i+dist<src.size()?src[i+dist]:src[src.size()-1]); // sign bit break; case LRIGHT: l=(i+dist<src.size()?src[i+dist]:const_literal(false)); break; default: assert(false); } result[i]=l; } return result; }
bvt float_utilst::sticky_right_shift( const bvt &op, const bvt &dist, literalt &sticky) { std::size_t d=1; bvt result=op; sticky=const_literal(false); for(std::size_t stage=0; stage<dist.size(); stage++) { if(dist[stage]!=const_literal(false)) { bvt tmp=bv_utils.shift(result, bv_utilst::LRIGHT, d); bvt lost_bits; if(d<=result.size()) lost_bits=bv_utils.extract(result, 0, d-1); else lost_bits=result; sticky=prop.lor( prop.land(dist[stage],prop.lor(lost_bits)), sticky); result=bv_utils.select(dist[stage], tmp, result); } d=d<<1; } return result; }
literalt cnft::land(const bvt &bv) { if(bv.size()==0) return const_literal(true); if(bv.size()==1) return bv[0]; if(bv.size()==2) return land(bv[0], bv[1]); forall_literals(it, bv) if(it->is_false()) return *it; if(is_all(bv, const_literal(true))) return const_literal(true); bvt new_bv; eliminate_duplicates(bv, new_bv); bvt lits(2); literalt literal=new_variable(); lits[1]=neg(literal); forall_literals(it, new_bv) { lits[0]=pos(*it); lcnf(lits); }
void bv_utilst::adder_no_overflow( bvt &sum, const bvt &op, bool subtract, representationt rep) { const bvt tmp_op=subtract?inverted(op):op; if(rep==SIGNED) { // an overflow occurs if the signs of the two operands are the same // and the sign of the sum is the opposite literalt old_sign=sum[sum.size()-1]; literalt sign_the_same= prop.lequal(sum[sum.size()-1], tmp_op[tmp_op.size()-1]); literalt carry; adder(sum, tmp_op, const_literal(subtract), carry); // result of addition in sum prop.l_set_to_false( prop.land(sign_the_same, prop.lxor(sum[sum.size()-1], old_sign))); } else if(rep==UNSIGNED) { literalt carry_out; adder(sum, tmp_op, const_literal(subtract), carry_out); prop.l_set_to(carry_out, subtract); } else assert(false); }
void boolbvt::convert_cond(const exprt &expr, bvt &bv) { const exprt::operandst &operands=expr.operands(); unsigned width=boolbv_width(expr.type()); if(width==0) return conversion_failed(expr, bv); bv.resize(width); // make it free variables Forall_literals(it, bv) *it=prop.new_variable(); if(operands.size()<2) throw "cond takes at least two operands"; if((operands.size()%2)!=0) throw "number of cond operands must be even"; if(prop.has_set_to()) { bool condition=true; literalt previous_cond=const_literal(false); literalt cond_literal=const_literal(false); forall_operands(it, expr) { if(condition) { cond_literal=convert(*it); cond_literal=prop.land(prop.lnot(previous_cond), cond_literal); previous_cond=prop.lor(previous_cond, cond_literal); } else { const bvt &op=convert_bv(*it); if(bv.size()!=op.size()) { std::cerr << "result size: " << bv.size() << std::endl << "operand: " << op.size() << std::endl << it->pretty() << std::endl; throw "size of value operand does not match"; } literalt value_literal=bv_utils.equal(bv, op); prop.l_set_to_true(prop.limplies(cond_literal, value_literal)); } condition=!condition; } }
literalt float_utilst::fraction_rounding_decision( const std::size_t dest_bits, const literalt sign, const bvt &fraction) { assert(dest_bits<fraction.size()); // we have too many fraction bits std::size_t extra_bits=fraction.size()-dest_bits; // more than two extra bits are superflus, and are // turned into a sticky bit literalt sticky_bit=const_literal(false); if(extra_bits>=2) { // We keep most-significant bits, and thus the tail is made // of least-significant bits. bvt tail=bv_utils.extract(fraction, 0, extra_bits-2); sticky_bit=prop.lor(tail); } // the rounding bit is the last extra bit assert(extra_bits>=1); literalt rounding_bit=fraction[extra_bits-1]; // we get one bit of the fraction for some rounding decisions literalt rounding_least=fraction[extra_bits]; // round-to-nearest (ties to even) literalt round_to_even= prop.land(rounding_bit, prop.lor(rounding_least, sticky_bit)); // round up literalt round_to_plus_inf= prop.land(!sign, prop.lor(rounding_bit, sticky_bit)); // round down literalt round_to_minus_inf= prop.land(sign, prop.lor(rounding_bit, sticky_bit)); // round to zero literalt round_to_zero= const_literal(false); // now select appropriate one return prop.lselect(rounding_mode_bits.round_to_even, round_to_even, prop.lselect(rounding_mode_bits.round_to_plus_inf, round_to_plus_inf, prop.lselect(rounding_mode_bits.round_to_minus_inf, round_to_minus_inf, prop.lselect(rounding_mode_bits.round_to_zero, round_to_zero, prop.new_variable())))); // otherwise non-det }
literalt z3_propt::lxor(literalt a, literalt b) { if(a==const_literal(false)) return b; if(b==const_literal(false)) return a; if(a==const_literal(true)) return lnot(b); if(b==const_literal(true)) return lnot(a); literalt o=new_variable(); lxor(a, b, o); return o; }
std::string cvc_propt::cvc_literal(literalt l) { if(l==const_literal(false)) return "FALSE"; else if(l==const_literal(true)) return "TRUE"; if(l.sign()) return "(NOT l"+i2string(l.var_no())+")"; return "l"+i2string(l.var_no()); }
bvt float_utilst::build_constant(const ieee_floatt &src) { unbiased_floatt result; result.sign=const_literal(src.get_sign()); result.NaN=const_literal(src.is_NaN()); result.infinity=const_literal(src.is_infinity()); result.exponent=bv_utils.build_constant(src.get_exponent(), spec.e); result.fraction=bv_utils.build_constant(src.get_fraction(), spec.f+1); return pack(bias(result)); }
std::string dplib_propt::dplib_literal(literalt l) { if(l==const_literal(false)) return "FALSE"; else if(l==const_literal(true)) return "TRUE"; if(l.sign()) return "(NOT l"+std::to_string(l.var_no())+")"; return "l"+std::to_string(l.var_no()); }
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; }
literalt z3_propt::lselect(literalt a, literalt b, literalt c) { // a?b:c = (a AND b) OR (/a AND c) if(a==const_literal(true)) return b; if(a==const_literal(false)) return c; if(b==c) return b; bvt bv; bv.reserve(2); bv.push_back(land(a, b)); bv.push_back(land(lnot(a), c)); return lor(bv); }
literalt z3_propt::lxor(const bvt &bv) { if(bv.size()==0) 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); for(unsigned i=0; i<bv.size(); i++) literal=lxor(bv[i], literal); return literal; }
void symex_target_equationt::convert_assertions( prop_convt &prop_conv) { // we find out if there is only _one_ assertion, // which allows for a simpler formula unsigned number_of_assertions=count_assertions(); if(number_of_assertions==0) return; if(number_of_assertions==1) { for(SSA_stepst::iterator it=SSA_steps.begin(); it!=SSA_steps.end(); it++) if(it->is_assert()) { prop_conv.set_to_false(it->cond_expr); it->cond_literal=const_literal(false); return; // prevent further assumptions! } else if(it->is_assume()) prop_conv.set_to_true(it->cond_expr); assert(false); // unreachable } bvt bv; bv.reserve(number_of_assertions); literalt assumption_literal=const_literal(true); for(SSA_stepst::iterator it=SSA_steps.begin(); it!=SSA_steps.end(); it++) if(it->is_assert()) { // do the expression literalt tmp_literal=prop_conv.convert(it->cond_expr); it->cond_literal=prop_conv.prop.limplies(assumption_literal, tmp_literal); bv.push_back(prop_conv.prop.lnot(it->cond_literal)); } else if(it->is_assume()) assumption_literal= prop_conv.prop.land(assumption_literal, it->cond_literal); if(!bv.empty()) prop_conv.prop.lcnf(bv); }
literalt aig_prop_baset::lxor(literalt a, literalt b) { if(a.is_false()) return b; if(b.is_false()) return a; if(a.is_true()) return neg(b); if(b.is_true()) return neg(a); if(a==b) return const_literal(false); if(a==neg(b)) return const_literal(true); // This produces up to three nodes! // See convert_node for where this overhead is removed return lor(land(a, neg(b)), land(neg(a), b)); }
std::string smt1_propt::smt1_literal(literalt l) { if(l==const_literal(false)) return "false"; else if(l==const_literal(true)) return "true"; std::string v="B"+i2string(l.var_no()); if(l.sign()) return "(not "+v+")"; return v; }
void cvc_convt::convert_literal(const literalt l) { if(l==const_literal(false)) out << "FALSE"; else if(l==const_literal(true)) out << "TRUE"; if(l.sign()) out << "(NOT "; out << "l" << l.var_no(); if(l.sign()) out << ")"; }
bvt float_utilst::pack(const biased_floatt &src) { assert(src.fraction.size()==spec.f); assert(src.exponent.size()==spec.e); bvt result; result.resize(spec.width()); // do sign // we make this 'false' for NaN result[result.size()-1]= prop.lselect(src.NaN, const_literal(false), src.sign); literalt infinity_or_NaN= prop.lor(src.NaN, src.infinity); // just copy fraction for(std::size_t i=0; i<spec.f; i++) result[i]=prop.land(src.fraction[i], !infinity_or_NaN); result[0]=prop.lor(result[0], src.NaN); // do exponent for(std::size_t i=0; i<spec.e; i++) result[i+spec.f]=prop.lor( src.exponent[i], infinity_or_NaN); return result; }
bvt bv_utilst::negate(const bvt &bv) { bvt result=inverted(bv); literalt carry_out; incrementer(result, const_literal(true), carry_out); return result; }
literalt cvc_propt::lxor(literalt a, literalt b) { if(a==const_literal(false)) return b; if(b==const_literal(false)) return a; if(a==const_literal(true)) return lnot(b); if(b==const_literal(true)) return lnot(a); out << "%% lxor" << std::endl; literalt o=def_cvc_literal(); out << cvc_literal(a) << " XOR " << cvc_literal(b) << ";" << std::endl << std::endl; return o; }
bvt float_utilst::abs(const bvt &src) { bvt result=src; assert(!src.empty()); result[result.size()-1]=const_literal(false); return result; }
literalt boolector_propt::lxor(literalt a, literalt b) { if(a==const_literal(false)) return b; if(b==const_literal(false)) return a; if(a==const_literal(true)) return lnot(b); if(b==const_literal(true)) return lnot(a); literalt l=new_variable(); BtorExp *result; result = boolector_xor(boolector_ctx, boolector_literal(a), boolector_literal(b)); boolector_assert(boolector_ctx, boolector_iff(boolector_ctx, boolector_literal(l), result)); return l; }
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); } }
literalt dplib_propt::lxor(literalt a, literalt b) { if(a==const_literal(false)) return b; if(b==const_literal(false)) return a; if(a==const_literal(true)) return !b; if(b==const_literal(true)) return !a; literalt o=def_dplib_literal(); out << "!(" << dplib_literal(a) << " <-> " << dplib_literal(b) << ");\n\n"; return o; }
void bv_utilst::adder_no_overflow(bvt &sum, const bvt &op) { literalt carry_out=const_literal(false); adder(sum, op, carry_out, carry_out); prop.l_set_to_false(carry_out); // enforce no overflow }
literalt cvc_propt::lselect(literalt a, literalt b, literalt c) { if(a==const_literal(true)) return b; if(a==const_literal(false)) return c; if(b==c) return b; out << "%% lselect" << std::endl; literalt o=def_cvc_literal(); out << "IF " << cvc_literal(a) << " THEN " << cvc_literal(b) << " ELSE " << cvc_literal(c) << " ENDIF;" << std::endl << std::endl; return o; }
BtorExp* boolector_propt::boolector_literal(literalt l) { BtorExp *literal_l; std::string literal_s; if(l==const_literal(false)) return boolector_false(boolector_ctx); else if(l==const_literal(true)) return boolector_true(boolector_ctx); literal_l = convert_literal(l.var_no()); if(l.sign()) return boolector_not(boolector_ctx, literal_l); return literal_l; }
void arrayst::add_array_Ackermann_constraints() { // this is quadratic! // iterate over arrays for(unsigned i=0; i<arrays.size(); i++) { const index_sett &index_set=index_map[arrays.find_number(i)]; // iterate over indices, 2x! for(index_sett::const_iterator i1=index_set.begin(); i1!=index_set.end(); i1++) for(index_sett::const_iterator i2=index_set.begin(); i2!=index_set.end(); i2++) if(i1!=i2) { // skip if both are constants if(i1->is_constant() && i2->is_constant()) continue; // index equality equality_exprt indices_equal(*i1, *i2); if(indices_equal.op0().type()!= indices_equal.op1().type()) { indices_equal.op1(). make_typecast(indices_equal.op0().type()); } literalt indices_equal_lit=convert(indices_equal); if(indices_equal_lit!=const_literal(false)) { index_exprt index_expr1; index_expr1.type()=ns.follow(arrays[i].type()).subtype(); index_expr1.array()=arrays[i]; index_expr1.index()=*i1; index_exprt index_expr2=index_expr1; index_expr2.index()=*i2; equality_exprt values_equal(index_expr1, index_expr2); bvt implication; implication.reserve(2); implication.push_back(prop.lnot(indices_equal_lit)); implication.push_back(convert(values_equal)); prop.lcnf(implication); } } } }
literalt aig_prop_baset::lxor(const bvt &bv) { literalt literal=const_literal(false); forall_literals(it, bv) literal=lxor(*it, literal); return literal; }
void boolbvt::convert_div(const exprt &expr, bvt &bv) { if(expr.type().id()!=ID_unsignedbv && expr.type().id()!=ID_signedbv && expr.type().id()!=ID_fixedbv) return conversion_failed(expr, bv); unsigned width=boolbv_width(expr.type()); if(width==0) return conversion_failed(expr, bv); if(expr.operands().size()!=2) throw "division takes two operands"; if(expr.op0().type().id()!=expr.type().id() || expr.op1().type().id()!=expr.type().id()) return conversion_failed(expr, bv); bvt op0=convert_bv(expr.op0()); bvt op1=convert_bv(expr.op1()); if(op0.size()!=width || op1.size()!=width) throw "convert_div: unexpected operand width"; bvt res, rem; if(expr.type().id()==ID_fixedbv) { unsigned fraction_bits= to_fixedbv_type(expr.type()).get_fraction_bits(); bvt zeros; zeros.resize(fraction_bits, const_literal(false)); // add fraction_bits least-significant bits op0.insert(op0.begin(), zeros.begin(), zeros.end()); op1=bv_utils.sign_extension(op1, op1.size()+fraction_bits); bv_utils.divider(op0, op1, res, rem, bv_utilst::SIGNED); // cut it down again res.resize(width); } else { bv_utilst::representationt rep= expr.type().id()==ID_signedbv?bv_utilst::SIGNED: bv_utilst::UNSIGNED; bv_utils.divider(op0, op1, res, rem, rep); } bv=res; }