Пример #1
0
char *
btor_decimal_to_const_n (BtorMemMgr * mem, const char *str, int len)
{
  const char *end, *p;
  char *res, *tmp;

  assert (mem != NULL);
  assert (str != NULL);
  assert (len >= 0);

  res = btor_strdup (mem, "");

  end = str + len;
  for (p = str; p < end; p++)
    {
      tmp = btor_mult_unbounded_const (mem, res, "1010");       /* *10 */
      btor_delete_const (mem, res);
      res = tmp;

      tmp = btor_add_unbounded_const (mem, res, digit2const (*p));
      btor_delete_const (mem, res);
      res = tmp;
    }

  assert (strip_zeroes (res) == res);

  return res;
}
Пример #2
0
static char *
mul_const (BtorMemMgr * mm, const char *a, const char *b)
{
  char *result, *and, *add, *shift;
  int i, j, len;

  assert (mm != NULL);
  assert (a != NULL);
  assert (b != NULL);
  assert (strlen (a) == strlen (b));
  assert ((int) strlen (a) > 0);
  assert (is_valid_const_3vl (a));
  assert (is_valid_const_3vl (b));

  len = (int) strlen (a);
  result = btor_int_to_const (mm, 0, len);
  for (i = len - 1; i >= 0; i--)
    {
      BTOR_NEWN (mm, and, len + 1);
      for (j = 0; j < len; j++)
	and[j] = BTOR_AND_CONST_3VL (a[j], b[i]);
      and[len] = '\0';
      shift = btor_sll_n_bits_const (mm, and, len - 1 - i);
      add = add_const (mm, result, shift);
      btor_delete_const (mm, result);
      btor_delete_const (mm, and);
      btor_delete_const (mm, shift);
      result = add;
    }
  return result;
}
Пример #3
0
char *
btor_const_to_decimal (BtorMemMgr * mem, const char *c)
{
  char *res, *q, *tmp, *rem, ch;
  BtorCharStack stack;
  const char *p;
  int len;
  BTOR_INIT_STACK (stack);

  assert (mem != NULL);
  assert (c != NULL);
  assert (is_valid_const (c));

  res = btor_copy_const (mem, c);
  while (*res)
    {
      tmp = btor_udiv_unbounded_const (mem, res, "1010", &rem); /* / 10 */
      assert ((int) strlen (rem) <= 4);
      ch = 0;
      for (p = strip_zeroes (rem); *p; p++)
        {
          ch <<= 1;
          if (*p == '1')
            ch++;
        }
      assert (ch < 10);
      ch += '0';
      BTOR_PUSH_STACK (mem, stack, ch);
      btor_delete_const (mem, rem);
      btor_delete_const (mem, res);
      res = tmp;
    }
  btor_delete_const (mem, res);

  if (BTOR_EMPTY_STACK (stack))
    BTOR_PUSH_STACK (mem, stack, '0');

  len = BTOR_COUNT_STACK (stack);
  BTOR_NEWN (mem, res, len + 1);
  q = res;
  p = stack.top;
  while (p > stack.start)
    *q++ = *--p;
  assert (res + len == q);
  *q = 0;
  assert (len == (int) strlen (res));
  BTOR_RELEASE_STACK (mem, stack);
  return res;
}
Пример #4
0
static char *
srl_const (BtorMemMgr * mm, const char *a, const char *b)
{
  char *result, *temp;
  int i, len;

  assert (mm != NULL);
  assert (a != NULL);
  assert (b != NULL);
  assert ((int) strlen (a) > 1);
  assert (btor_is_power_of_2_util ((int) strlen (a)));
  assert (btor_log_2_util ((int) strlen (a)) == (int) strlen (b));
  assert (is_valid_const_3vl (a));
  assert (is_valid_const (b));

  len = (int) strlen (b);
  if (b[len - 1] == '1')
    result = btor_srl_n_bits_const (mm, a, 1);
  else
    result = btor_copy_const (mm, a);
  for (i = len - 2; i >= 0; i--)
    {
      temp = result;
      if (b[i] == '1')
        result = btor_srl_n_bits_const (mm, temp, 
	                                btor_pow_2_util (len - i - 1));
      else
        result = btor_copy_const (mm, temp);
      btor_delete_const (mm, temp);
    }
  return result;
}
Пример #5
0
static BtorNode *
parse_consth (BtorBTORParser * parser, int len)
{
  char * tmp, * extended;
  BtorNode *res;
  int ch, clen;

  if (parse_space (parser))
    return 0;

  assert (BTOR_EMPTY_STACK (parser->constant));

  while (!isspace (ch = btor_nextch_btor (parser)) && ch != EOF && ch != ';')
    {
      if (!isxdigit (ch))
	{
	   (void) btor_perr_btor (parser, "expected hexidecimal digit");
	   return 0;
	}

      BTOR_PUSH_STACK (parser->mem, parser->constant, ch);
    }

  btor_savech_btor (parser, ch);

  clen = BTOR_COUNT_STACK (parser->constant);
  BTOR_PUSH_STACK (parser->mem, parser->constant, 0);
  BTOR_RESET_STACK (parser->constant);

  tmp = btor_hex_to_const_n (parser->mem, parser->constant.start, clen);
  clen = (int) strlen (tmp);

  if (clen > len)
    {
      (void) btor_perr_btor (parser,
			  "hexadecimal constant '%s' exceeds bit width %d",
			  parser->constant.start, len);

      btor_freestr (parser->mem, tmp);
      return 0;
    }

  if (clen < len)
    {
      extended = btor_uext_const (parser->mem, tmp, len - clen);
      btor_delete_const (parser->mem, tmp);
      tmp = extended;
    }

  assert (len == (int) strlen (tmp));
  res = btor_const_exp (parser->btor, tmp);
  btor_freestr (parser->mem, tmp);

  assert (btor_get_exp_len (parser->btor, res) == len);

  return res;
}
Пример #6
0
char *
btor_add_unbounded_const (BtorMemMgr * mm, const char *a, const char *b)
{
  char *res, *r, c, x, y, s, *tmp;
  int alen, blen, rlen;
  const char *p, *q;

  assert (mm != NULL);
  assert (a != NULL);
  assert (b != NULL);
  assert (is_valid_const (a));
  assert (is_valid_const (b));

  a = strip_zeroes (a);
  b = strip_zeroes (b);

  if (!*a)
    return btor_strdup (mm, b);

  if (!*b)
    return btor_strdup (mm, a);

  alen = (int) strlen (a);
  blen = (int) strlen (b);
  rlen = (alen < blen) ? blen : alen;
  rlen++;

  BTOR_NEWN (mm, res, rlen + 1);

  p = a + alen;
  q = b + blen;

  c = '0';

  r = res + rlen;
  *r = 0;

  while (res < r)
    {
      x = (a < p) ? *--p : '0';
      y = (b < q) ? *--q : '0';
      s = x ^ y ^ c;
      c = (x & y) | (x & c) | (y & c);
      *--r = s;
    }

  p = strip_zeroes (res);
  if ((p != res))
    {
      tmp = btor_copy_const (mm, p);
      btor_delete_const (mm, res);
      res = tmp;
    }

  return res;
}
Пример #7
0
char *
btor_neg_const (BtorMemMgr * mm, const char *a)
{
  char *result, *not_a, *one;
  int len;

  assert (mm != NULL);
  assert (a != NULL);
  assert ((int) strlen (a) > 0);
  assert (is_valid_const (a));

  len = (int) strlen (a);
  not_a = btor_not_const (mm, a);
  one = btor_int_to_const (mm, 1, len);
  result = btor_add_const (mm, not_a, one);
  btor_delete_const (mm, not_a);
  btor_delete_const (mm, one);
  return result;
}
Пример #8
0
char *
btor_urem_const (BtorMemMgr * mm, const char *a, const char *b)
{
  char *quotient, *remainder;

  assert (mm != NULL);
  assert (a != NULL);
  assert (b != NULL);
  assert (strlen (a) == strlen (b));
  assert ((int) strlen (a) > 0);
  assert (is_valid_const (a));
  assert (is_valid_const (b));

  udiv_urem_const (mm, a, b, &quotient, &remainder);
  btor_delete_const (mm, quotient);
  return remainder;
}
Пример #9
0
char *
btor_urem_const_3vl (BtorMemMgr * mm, const char *a, const char *b)
{
  int i, len, skip_a, skip_b;
  char *quotient, *remainder;

  assert (mm != NULL);
  assert (a != NULL);
  assert (b != NULL);
  assert (strlen (a) == strlen (b));
  assert ((int) strlen (a) > 0);
  assert (is_valid_const_3vl (a));
  assert (is_valid_const_3vl (b));

  udiv_urem_const (mm, a, b, &quotient, &remainder);
  btor_delete_const (mm, quotient);

  /* optimization: b != 0 => a urem b <= a  /\ a urem b <= b,
   * this optimization is necessary, as the urem circuit 
   * does not propagate the known bits well */ 
  skip_a = 0;
  skip_b = 0;
  if (is_unequal_zero_3vl(mm, b) == '1')
    {
      len = (int) strlen (a);
      for (i = 0; i < len; i++)
        {
	  if (!skip_a && a[i] == '0')
	    remainder[i] = '0';
	  else if (!skip_b)
	    skip_a = 1;
	  else
	    break;

	  if (!skip_b && b[i] == '0')
	    remainder[i] = '0';
	  else if (!skip_a)
	    skip_b = 1;
	  else
	    break;
	}
    }

  return remainder;
}
Пример #10
0
char *
btor_srl_const_3vl (BtorMemMgr * mm, const char *a, const char *b)
{

  int min_shifts, max_shifts, len, found, i, j;
  char *result, *temp, cur;

  assert (mm != NULL);
  assert (a != NULL);
  assert (b != NULL);
  assert ((int) strlen (a) > 1);
  assert (btor_is_power_of_2_util ((int) strlen (a)));
  assert (btor_log_2_util ((int) strlen (a)) == (int) strlen (b));
  assert (is_valid_const_3vl (a));
  assert (is_valid_const_3vl (b));

  if (is_valid_const (b))
    result = srl_const (mm, a, b);
  else
    {
      len = (int) strlen (a);
      temp = btor_x_const_3vl (mm, len);
      compute_min_max_num_shifts (mm, b, &min_shifts, &max_shifts);
      result = btor_srl_n_bits_const (mm, temp, min_shifts);
      for (i = len - 1; i >= 0; i--)
        {
	  cur = a[i];
	  if (cur != 'x')
	    {
	      found = 0;
	      for (j = i - 1; j >= 0; j--)
		{
		  if (a[j] == cur)
		    found++;
		  else
		   break;
		}
	      if (found >= max_shifts)
		result[i] = cur;
	    }
	}
      btor_delete_const (mm, temp);
    }
  return result;
}
Пример #11
0
char *
btor_sub_const (BtorMemMgr * mm, const char *a, const char *b)
{
  char *result, *neg_b;
  int len;

  assert (mm != NULL);
  assert (a != NULL);
  assert (b != NULL);
  assert (strlen (a) == strlen (b));
  assert ((int) strlen (a) > 0);
  assert (is_valid_const (a));
  assert (is_valid_const (b));

  len = (int) strlen (a);
  neg_b = btor_neg_const (mm, b);
  result = btor_add_const (mm, a, neg_b);
  btor_delete_const (mm, neg_b);
  return result;
}
Пример #12
0
char *
btor_udiv_const_3vl (BtorMemMgr * mm, const char *a, const char *b)
{
#if 0
  int i, len;
#endif
  char *quotient, *remainder;

  assert (mm != NULL);
  assert (a != NULL);
  assert (b != NULL);
  assert (strlen (a) == strlen (b));
  assert ((int) strlen (a) > 0);
  assert (is_valid_const_3vl (a));
  assert (is_valid_const_3vl (b));

  udiv_urem_const (mm, a, b, &quotient, &remainder);
  btor_delete_const (mm, remainder);

/* it seems like this optimization is not necessary here,
 * as the division circuit propagates the known bits
 * quite well */
#if 0
  /* optimization: b != 0 => a udiv b <= a */
  if (is_unequal_zero_3vl(mm, b) == '1')
    {
      len = (int) strlen (a);
      for (i = 0; i < len; i++)
        {
	  if (a[i] == '0')
	    quotient[i] = '0';
	  else
	    break;
	}
    }
#endif

  return quotient;
}
Пример #13
0
static BtorNode *
parse_constd (BtorBTORParser * parser, int len)
{
  char ch, *tmp, * extended;
  BtorNode *res;
  int clen;

  if (parse_space (parser))
    return 0;

  assert (BTOR_EMPTY_STACK (parser->constant));

  ch = btor_nextch_btor (parser);
  if (!isdigit (ch))
    {
      (void) btor_perr_btor (parser, "expected digit");
      return 0;
    }

  BTOR_PUSH_STACK (parser->mem, parser->constant, ch);

  if (ch == '0')
    {
      ch = btor_nextch_btor (parser);

      if (isdigit (ch))
	{
	  (void) btor_perr_btor (parser, "digit after '0'");
	  return 0;
	}

      tmp = btor_strdup (parser->mem, "");
    }
  else
    {
      while (isdigit (ch = btor_nextch_btor (parser)))
	BTOR_PUSH_STACK (parser->mem, parser->constant, ch);

      clen = BTOR_COUNT_STACK (parser->constant);

      tmp = btor_decimal_to_const_n (parser->mem,
				     parser->constant.start, clen);
    }

  BTOR_PUSH_STACK (parser->mem, parser->constant, 0);
  BTOR_RESET_STACK (parser->constant);

  btor_savech_btor (parser, ch);

  clen = (int) strlen (tmp);
  if (clen > len)
    {
      (void) btor_perr_btor (parser,
			  "decimal constant '%s' exceeds bit width %d",
			  parser->constant.start, len);
      btor_freestr (parser->mem, tmp);
      return 0;
    }

  if (clen < len)
    {
      extended = btor_uext_const (parser->mem, tmp, len - clen);
      btor_delete_const (parser->mem, tmp);
      tmp = extended;
    }

  assert (len == (int) strlen (tmp));
  res = btor_const_exp (parser->btor, tmp);
  btor_delete_const (parser->mem, tmp);

  assert (btor_get_exp_len (parser->btor, res) == len);

  return res;
}
Пример #14
0
char *
btor_inverse_const (BtorMemMgr * mm, const char *c)
{
  char *a, *b, *y, *ly, *r, *q, *yq, *res, *ty;
  int len = strlen (c);

  assert (mm != NULL);
  assert (c != NULL);
  assert (len > 0);
  assert (c[len - 1] == '1');   /* odd */
  assert (is_valid_const (c));

  BTOR_NEWN (mm, a, len + 2);
  a[0] = '1';
  memset (a + 1, '0', len);
  a[len + 1] = 0;

  BTOR_NEWN (mm, b, len + 2);
  b[0] = '0';
  memcpy (b + 1, c, len);
  b[len + 1] = 0;

  y = btor_unsigned_to_const (mm, 1, len + 1);
  ly = btor_unsigned_to_const (mm, 0, len + 1);

  while (!btor_is_zero_const (b))
    {
      udiv_urem_const (mm, a, b, &q, &r);

      btor_delete_const (mm, a);

      a = b;
      b = r;

      ty = y;
      yq = btor_mul_const (mm, y, q);
      btor_delete_const (mm, q);

      y = btor_sub_const (mm, ly, yq);
      btor_delete_const (mm, yq);

      btor_delete_const (mm, ly);
      ly = ty;
    }

  res = btor_slice_const (mm, ly, len - 1, 0);

#ifndef NDEBUG
  assert (strlen (res) == strlen (c));
  ty = btor_mul_const (mm, c, res);
  assert (btor_is_one_const (ty));
  btor_delete_const (mm, ty);
#endif

  btor_delete_const (mm, ly);
  btor_delete_const (mm, y);
  btor_delete_const (mm, b);
  btor_delete_const (mm, a);

  return res;
}
Пример #15
0
char *
btor_udiv_unbounded_const (BtorMemMgr * mem,
                           const char *dividend, const char *divisor,
                           char **rem_ptr)
{
  char *quotient, *rest, *extended_divisor, *tmp;
  int delta, plen, qlen;
  const char *p, *q;

  assert (mem != NULL);
  assert (dividend != NULL);
  assert (divisor != NULL);
  assert (is_valid_const (dividend));
  assert (is_valid_const (divisor));

  dividend = strip_zeroes (dividend);
  divisor = strip_zeroes (divisor);

  for (p = dividend; *p && *p == '0'; p++)
    ;

  for (q = divisor; *q && *q == '0'; q++)
    ;

  assert (*q);                  /* in any case even if 'dividend == 0' */

  if (!*p || btor_cmp_const (p, q) < 0)
    {
      if (rem_ptr)
        *rem_ptr = btor_strdup (mem, p);        /* copy divident */

      return btor_strdup (mem, "");
    }

  plen = (int) strlen (p);
  qlen = (int) strlen (q);
  delta = plen - qlen;
  assert (delta >= 0);

  BTOR_NEWN (mem, extended_divisor, plen + 1);
  memset (extended_divisor, '0', delta);
  strcpy (extended_divisor + delta, divisor);

  udiv_urem_const (mem, dividend, extended_divisor, &quotient, &rest);

  btor_delete_const (mem, extended_divisor);

  tmp = btor_strdup (mem, strip_zeroes (quotient));
  btor_delete_const (mem, quotient);
  quotient = tmp;

  tmp = btor_strdup (mem, strip_zeroes (rest));
  btor_delete_const (mem, rest);
  rest = tmp;

  assert (btor_cmp_const (rest, divisor) < 0);
#ifndef NDEBUG
  {
    char *tmp1 = btor_mult_unbounded_const (mem, quotient, divisor);
    char *tmp2 = btor_add_unbounded_const (mem, tmp1, rest);
    assert (!btor_cmp_const (dividend, tmp2));
    btor_freestr (mem, tmp1);
    btor_freestr (mem, tmp2);
  }
#endif
  if (rem_ptr)
    *rem_ptr = rest;
  else
    btor_delete_const (mem, rest);

  return quotient;
}