Example #1
0
void boolbvt::convert_with(
  const typet &type,
  const exprt &op1,
  const exprt &op2,
  const bvt &prev_bv,
  bvt &next_bv)
{
  // we only do that on arrays, bitvectors, structs, and unions

  next_bv.resize(prev_bv.size());

  if(type.id()==ID_array)
    return convert_with_array(to_array_type(type), op1, op2, prev_bv, next_bv);
  else if(type.id()==ID_bv ||
          type.id()==ID_unsignedbv ||
          type.id()==ID_signedbv)
    return convert_with_bv(type, op1, op2, prev_bv, next_bv);
  else if(type.id()==ID_struct)
    return convert_with_struct(to_struct_type(type), op1, op2, prev_bv, next_bv);
  else if(type.id()==ID_union)
    return convert_with_union(to_union_type(type), op1, op2, prev_bv, next_bv);
  else if(type.id()==ID_symbol)
    return convert_with(ns.follow(type), op1, op2, prev_bv, next_bv);

  error().source_location=type.source_location();
  error() << "unexpected with type: " << type.id();
  throw 0;
}
Example #2
0
void boolbvt::convert_with_bv(
  const typet &type,
  const exprt &op1,
  const exprt &op2,
  const bvt &prev_bv,
  bvt &next_bv)
{
  literalt l=convert(op2);

  mp_integer op1_value;
  if(!to_integer(op1, op1_value))
  {
    next_bv=prev_bv;

    if(op1_value<next_bv.size())
      next_bv[integer2size_t(op1_value)]=l;

    return;
  }

  typet counter_type=op1.type();

  for(std::size_t i=0; i<prev_bv.size(); i++)
  {
    exprt counter=from_integer(i, counter_type);

    literalt eq_lit=convert(equal_exprt(op1, counter));

    next_bv[i]=prop.lselect(eq_lit, l, prev_bv[i]);
  }
}
void convert(const bvt &bv, vec<Lit> &dest)
{
  dest.growTo(bv.size());
  
  for(unsigned i=0; i<bv.size(); i++)
    dest[i]=Lit(bv[i].var_no(), bv[i].sign());
}
Example #4
0
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);
}
Example #5
0
void cvc_propt::lcnf(const bvt &bv)
{
  if(bv.empty()) return;
  bvt new_bv;

  std::set<literalt> s;

  new_bv.reserve(bv.size());

  for(bvt::const_iterator it=bv.begin(); it!=bv.end(); it++)
  {
    if(s.insert(*it).second)
      new_bv.push_back(*it);

    if(s.find(lnot(*it))!=s.end())
      return; // clause satisfied

    assert(it->var_no()<_no_variables);
  }

  assert(!new_bv.empty());

  out << "%% lcnf" << std::endl;
  out << "ASSERT ";

  for(bvt::const_iterator it=new_bv.begin(); it!=new_bv.end(); it++)
  {
    if(it!=new_bv.begin()) out << " OR ";
    out << cvc_literal(*it);
  }

  out << ";" << std::endl << std::endl;
}
Example #6
0
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;
}
Example #7
0
void boolbv_mapt::get_literals(
  const irep_idt &identifier,
  const typet &type,
  const unsigned width,
  bvt &literals)
{
  map_entryt &map_entry=get_map_entry(identifier, type);

  assert(literals.size()==width);
  Forall_literals(it, literals)
  {
    literalt &l=*it;
    const unsigned bit=it-literals.begin();

    assert(bit<map_entry.literal_map.size());
    map_bitt &mb=map_entry.literal_map[bit];

    if(mb.is_set)
    {
      l=mb.l;
      continue;
    }

    l=prop.new_variable();

    mb.is_set=true;
    mb.l=l;

    #ifdef DEBUG
    std::cout << "NEW: " << identifier << ":" << bit
              << "=" << l << std::endl;
    #endif
  }
Example #8
0
void dplib_propt::lcnf(const bvt &bv)
{
  if(bv.empty())
    return;
  bvt new_bv;

  std::set<literalt> s;

  new_bv.reserve(bv.size());

  for(bvt::const_iterator it=bv.begin(); it!=bv.end(); it++)
  {
    if(s.insert(*it).second)
      new_bv.push_back(*it);

    if(s.find(!*it)!=s.end())
      return; // clause satisfied

    assert(it->var_no()<=_no_variables);
  }

  assert(!new_bv.empty());

  out << "// lcnf\n";
  out << "AXIOM ";

  for(bvt::const_iterator it=new_bv.begin(); it!=new_bv.end(); it++)
  {
    if(it!=new_bv.begin())
      out << " | ";
    out << dplib_literal(*it);
  }

  out << ";\n\n";
}
Example #9
0
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);
  }
Example #10
0
void boolbvt::convert_replication(const exprt &expr, bvt &bv)
{
  unsigned width=boolbv_width(expr.type());
  
  if(width==0)
    return conversion_failed(expr, bv);

  if(expr.operands().size()!=2)
    throw "replication takes two operands";

  mp_integer times;
  if(to_integer(expr.op0(), times))
    throw "replication takes constant as first parameter";
  const unsigned u_times=integer2unsigned(times);

  const bvt &op=convert_bv(expr.op1());

  unsigned offset=0;
  bv.resize(width);

  for(unsigned i=0; i<u_times; i++)
  {
    if(op.size()+offset>width)
      throw "replication operand width too big";

    for(unsigned i=0; i<op.size(); i++)
      bv[i+offset]=op[i];

    offset+=op.size();
  }    

  if(offset!=bv.size())
    throw "replication operand width too small";
}
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;
    }
  }
Example #12
0
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
}
Example #13
0
void z3_propt::eliminate_duplicates(const bvt &bv, bvt &dest)
{
  std::set<literalt> s;

  dest.reserve(bv.size());

  for(bvt::const_iterator it=bv.begin(); it!=bv.end(); it++)
  {
    if(s.insert(*it).second)
      dest.push_back(*it);
  }
}
Example #14
0
bvt bv_utilst::select(literalt s, const bvt &a, const bvt &b)
{
  assert(a.size()==b.size());

  bvt result;

  result.resize(a.size());
  for(std::size_t i=0; i<result.size(); i++)
    result[i]=prop.lselect(s, a[i], b[i]);

  return result;
}
Example #15
0
void float_utilst::set_rounding_mode(const bvt &src)
{
  bvt round_to_even=bv_utils.build_constant(ieee_floatt::ROUND_TO_EVEN, src.size());
  bvt round_to_plus_inf=bv_utils.build_constant(ieee_floatt::ROUND_TO_PLUS_INF, src.size());
  bvt round_to_minus_inf=bv_utils.build_constant(ieee_floatt::ROUND_TO_MINUS_INF, src.size());
  bvt round_to_zero=bv_utils.build_constant(ieee_floatt::ROUND_TO_ZERO, src.size());

  rounding_mode_bits.round_to_even=bv_utils.equal(src, round_to_even);
  rounding_mode_bits.round_to_plus_inf=bv_utils.equal(src, round_to_plus_inf);
  rounding_mode_bits.round_to_minus_inf=bv_utils.equal(src, round_to_minus_inf);
  rounding_mode_bits.round_to_zero=bv_utils.equal(src, round_to_zero);
}
Example #16
0
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;
}
Example #17
0
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;
}
Example #18
0
bvt bv_utilst::extract(const bvt &a, std::size_t first, std::size_t last)
{
  // preconditions
  assert(first<a.size());
  assert(last<a.size());
  assert(first<=last);

  bvt result=a;
  result.resize(last+1);
  if(first!=0) result.erase(result.begin(), result.begin()+first);

  assert(result.size()==last-first+1);
  return result;
}
Example #19
0
bvt bv_utilst::add_sub(const bvt &op0, const bvt &op1, bool subtract)
{
  assert(op0.size()==op1.size());

  literalt carry_in=const_literal(subtract);
  literalt carry_out;

  bvt result=op0;
  bvt tmp_op1=subtract?inverted(op1):op1;

  adder(result, tmp_op1, carry_in, carry_out);

  return result;
}
Example #20
0
bvt bv_utilst::concatenate(const bvt &a, const bvt &b) const
{
  bvt result;

  result.resize(a.size()+b.size());

  for(std::size_t i=0; i<a.size(); i++)
    result[i]=a[i];

  for(std::size_t i=0; i<b.size(); i++)
    result[i+a.size()]=b[i];

  return result;
}
Example #21
0
literalt bv_utilst::carry_out(
  const bvt &op0,
  const bvt &op1,
  literalt carry_in)
{
  assert(op0.size()==op1.size());

  literalt carry_out=carry_in;

  for(std::size_t i=0; i<op0.size(); i++)
    carry_out=carry(op0[i], op1[i], carry_out);

  return carry_out;
}
Example #22
0
void bv_utilst::adder(
  bvt &sum,
  const bvt &op,
  literalt carry_in,
  literalt &carry_out)
{
  assert(sum.size()==op.size());

  carry_out=carry_in;

  for(std::size_t i=0; i<sum.size(); i++)
  {
    sum[i] = full_adder(sum[i], op[i], carry_out, carry_out);
  }
}
void boolbvt::convert_concatenation(const exprt &expr, bvt &bv)
{
  unsigned width=boolbv_width(expr.type());
  
  if(width==0)
    return conversion_failed(expr, bv);
    
  const exprt::operandst &operands=expr.operands();

  if(operands.size()==0)
    throw "concatenation takes at least one operand";

  unsigned offset=width;
  bv.resize(width);

  forall_expr(it, operands)
  {
    const bvt &op=convert_bv(*it);

    if(op.size()>offset)
      throw "concatenation operand width too big";

    offset-=op.size();

    for(unsigned i=0; i<op.size(); i++)
      bv[offset+i]=op[i];
  }    

  if(offset!=0)
    throw "concatenation operand width too small";
}
Example #24
0
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;
}
Example #25
0
void boolbvt::convert_with_union(
  const union_typet &type,
  const exprt &op1,
  const exprt &op2,
  const bvt &prev_bv,
  bvt &next_bv)
{
  next_bv=prev_bv;

  const bvt &op2_bv=convert_bv(op2);

  if(next_bv.size()<op2_bv.size())
  {
    error().source_location=type.source_location();
    error() << "convert_with_union: unexpected operand op2 width" << eom;
    throw 0;
  }

  if(config.ansi_c.endianness==configt::ansi_ct::endiannesst::IS_LITTLE_ENDIAN)
  {
    for(std::size_t i=0; i<op2_bv.size(); i++)
      next_bv[i]=op2_bv[i];
  }
  else
  {
    assert(config.ansi_c.endianness==configt::ansi_ct::endiannesst::IS_BIG_ENDIAN);

    endianness_mapt map_u(type, false, ns);
    endianness_mapt map_op2(op2.type(), false, ns);

    for(std::size_t i=0; i<op2_bv.size(); i++)
      next_bv[map_u.map_bit(i)]=op2_bv[map_op2.map_bit(i)];
  }
}
Example #26
0
mp_integer boolbvt::get_value(
    const bvt &bv,
    std::size_t offset,
    std::size_t width)
{
    mp_integer value=0;
    mp_integer weight=1;

    for(std::size_t bit_nr=offset; bit_nr<offset+width; bit_nr++)
    {
        assert(bit_nr<bv.size());
        switch(prop.l_get(bv[bit_nr]).get_value())
        {
        case tvt::tv_enumt::TV_FALSE:
            break;
        case tvt::tv_enumt::TV_TRUE:
            value+=weight;
            break;
        case tvt::tv_enumt::TV_UNKNOWN:
            break;
        default:
            assert(false);
        }

        weight*=2;
    }

    return value;
}
Example #27
0
bvt float_utilst::abs(const bvt &src)
{
  bvt result=src;
  assert(!src.empty());
  result[result.size()-1]=const_literal(false);
  return result;
}
Example #28
0
float_utilst::unbiased_floatt float_utilst::unpack(const bvt &src)
{
  assert(src.size()==spec.width());

  unbiased_floatt result;

  result.sign=sign_bit(src);

  result.fraction=get_fraction(src);
  result.fraction.push_back(is_normal(src)); // add hidden bit

  result.exponent=get_exponent(src);
  assert(result.exponent.size()==spec.e);

  // unbias the exponent
  literalt denormal=bv_utils.is_zero(result.exponent);

  result.exponent=
    bv_utils.select(denormal,
      bv_utils.build_constant(-spec.bias()+1, spec.e),
      sub_bias(result.exponent));

  result.infinity=is_infinity(src);
  result.zero=is_zero(src);
  result.NaN=is_NaN(src);

  return result;
}
Example #29
0
void boolbvt::convert_constant(const constant_exprt &expr, bvt &bv)
{
  unsigned width=boolbv_width(expr.type());
  
  if(width==0)
    return conversion_failed(expr, bv);

  bv.resize(width);
  
  const typet &expr_type=expr.type();
  
  if(expr_type.id()==ID_array)
  {
    unsigned op_width=width/expr.operands().size();
    unsigned offset=0;

    forall_operands(it, expr)
    {
      const bvt &tmp=convert_bv(*it);

      if(tmp.size()!=op_width)
        throw "convert_constant: unexpected operand width";

      for(unsigned j=0; j<op_width; j++)
        bv[offset+j]=tmp[j];

      offset+=op_width;
    }   
    
    return;
  }
Example #30
0
bvt float_utilst::from_unsigned_integer(const bvt &src)
{
  unbiased_floatt result;

  result.fraction=src;

  // build an exponent (unbiased) -- this is signed!
  result.exponent=
    bv_utils.build_constant(
      src.size()-1,
      address_bits(src.size()-1).to_long()+1);

  result.sign=const_literal(false);

  return rounder(result);
}