Exemple #1
0
BtorNode *
boolector_ulte (Btor * btor, BtorNode * e0, BtorNode * e1)
{
  BTOR_ABORT_ARG_NULL_BOOLECTOR (btor);
  BTOR_ABORT_ARG_NULL_BOOLECTOR (e0);
  BTOR_ABORT_ARG_NULL_BOOLECTOR (e1);
  BTOR_ABORT_REFS_NOT_POS_BOOLECTOR (e0);
  BTOR_ABORT_REFS_NOT_POS_BOOLECTOR (e1);
  e0 = btor_pointer_chase_simplified_exp (btor, e0);
  e1 = btor_pointer_chase_simplified_exp (btor, e1);
  BTOR_ABORT_ARRAY_BOOLECTOR (e0);
  BTOR_ABORT_ARRAY_BOOLECTOR (e1);
  BTOR_ABORT_NE_BW (e0, e1);
  btor->external_refs++;
  return btor_ulte_exp (btor, e0, e1);
}
/*
 *
 * diff: d
 * l,....,u
 * l <= i && i <= u && (u - i) % d == 0
 *
 * optimization if d is power of two
 *   l <= i && i <= u && (u - i) & (d - 1) = 0
 *   
 *   l <= i && i <= u && (u - i)[bits(d) - 1 - 1: 0] = 0
 *   
 *   d: 1
 *   l <= i && i <= u 
 *   
 *   d: 2
 *   l <= i && i <= u && (u - i)[0:0] = 0
 *   
 *   d: 4
 *   l <= i && i <= u && (u - i)[1:0] = 0
 *   
 *   d: 8
 *   l <= i && i <= u && (u - i)[2:0] = 0
*/
static inline BtorNode *
create_range (Btor * btor,
              BtorNode * lower,
              BtorNode * upper,
              BtorNode * param,
              BtorBitVector * offset)
{
  assert (lower);
  assert (upper);
  assert (param);
  assert (BTOR_IS_REGULAR_NODE (param));
  assert (BTOR_IS_PARAM_NODE (param));
  assert (BTOR_IS_BV_CONST_NODE (BTOR_REAL_ADDR_NODE (lower))
          || BTOR_IS_ADD_NODE (BTOR_REAL_ADDR_NODE (lower)));
  assert (BTOR_IS_BV_CONST_NODE (BTOR_REAL_ADDR_NODE (upper))
          || BTOR_IS_ADD_NODE (BTOR_REAL_ADDR_NODE (upper)));
  assert (BTOR_REAL_ADDR_NODE (lower)->sort_id
          == BTOR_REAL_ADDR_NODE (upper)->sort_id);
  assert (offset);

  int pos;
  BtorNode *res, *le0, *le1, *and, *off, *sub, *rem, *eq, *zero, *slice;

  le0 = btor_ulte_exp (btor, lower, param);
  le1 = btor_ulte_exp (btor, param, upper);
  and = btor_and_exp (btor, le0, le1);

  /* increment by one */
  if (btor_is_one_bv (offset))
    res = btor_copy_exp (btor, and);
  /* increment by power of two */
  else if ((pos = btor_is_power_of_two_bv (offset)) > -1)
    {
      assert (pos > 0);
      sub = btor_sub_exp (btor, upper, param);
      slice = btor_slice_exp (btor, sub, pos - 1, 0);
      zero = btor_zero_exp (btor, btor_get_exp_width (btor, slice));
      eq = btor_eq_exp (btor, slice, zero);
      res = btor_and_exp (btor, and, eq);

      btor_release_exp (btor, zero);
      btor_release_exp (btor, slice);
      btor_release_exp (btor, sub);
      btor_release_exp (btor, eq);
    }
  /* increment by some arbitrary value */
  else
    {
      zero = btor_zero_exp (btor, btor_get_exp_width (btor, lower));
      off = btor_const_exp (btor, offset);
      assert (BTOR_REAL_ADDR_NODE (off)->sort_id
              == BTOR_REAL_ADDR_NODE (lower)->sort_id);
      sub = btor_sub_exp (btor, upper, param);
      rem = btor_urem_exp (btor, sub, off);
      eq = btor_eq_exp (btor, rem, zero); 
      res = btor_and_exp (btor, and, eq);

      btor_release_exp (btor, zero);
      btor_release_exp (btor, off);
      btor_release_exp (btor, sub);
      btor_release_exp (btor, rem);
      btor_release_exp (btor, eq);
    }
  btor_release_exp (btor, le0);
  btor_release_exp (btor, le1);
  btor_release_exp (btor, and);
  return res;
}