Esempio n. 1
0
void
btor_dump_const_value_smt (Btor * btor,
                           const char * bits,
                           int base,
                           FILE * file)
{
  assert (btor);
  assert (bits);
  assert (base == BTOR_OUTPUT_BASE_BIN
          || base == BTOR_OUTPUT_BASE_DEC
          || base == BTOR_OUTPUT_BASE_HEX);

  char *val;
  const char *fmt;

  /* SMT-LIB v1.2 only supports decimal output */
  if (base == BTOR_OUTPUT_BASE_DEC)
    {
      val = btor_const_to_decimal (btor->mm, bits);
      fmt = "(_ bv%s %d)";
      fprintf (file, fmt, val, strlen (bits));
      btor_freestr (btor->mm, val);
    }
  else if (base == BTOR_OUTPUT_BASE_HEX && strlen (bits) % 4 == 0)
    {
      val = btor_const_to_hex (btor->mm, bits);
      fprintf (file, "#x%s", val);
      btor_freestr (btor->mm, val);
    }
  else
    {
      fprintf (file, "#b%s", bits);
    }
}
Esempio n. 2
0
static void
delete_smt_dump_context (BtorSMTDumpContext * sdc)
{
  BtorHashTableIterator it;

  btor_delete_ptr_hash_table (sdc->dump);
  btor_delete_ptr_hash_table (sdc->dumped);
  btor_delete_ptr_hash_table (sdc->boolean);
  btor_delete_ptr_hash_table (sdc->stores);
  btor_delete_ptr_hash_table (sdc->idtab);

  btor_init_node_hash_table_iterator (&it, sdc->roots);
  while (btor_has_next_node_hash_table_iterator (&it))
    btor_release_exp (sdc->btor, btor_next_node_hash_table_iterator (&it));
  btor_delete_ptr_hash_table (sdc->roots);

  btor_init_hash_table_iterator (&it, sdc->const_cache);
  while (btor_has_next_hash_table_iterator (&it))
    {
      assert (it.bucket->data.asStr);
      btor_freestr (sdc->btor->mm, it.bucket->data.asStr);
      btor_freestr (sdc->btor->mm, (char *) btor_next_hash_table_iterator (&it));
    }
  btor_delete_ptr_hash_table (sdc->const_cache);
  BTOR_DELETE (sdc->btor->mm, sdc);
}
Esempio n. 3
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;
}
Esempio n. 4
0
static void
btor_delete_btor_parser (BtorBTORParser * parser)
{
  BtorNode *e;
  int i;

  for (i = 0; i < BTOR_COUNT_STACK (parser->exps); i++)
    if ((e = parser->exps.start[i]))
      btor_release_exp (parser->btor, parser->exps.start[i]);

  BTOR_RELEASE_STACK (parser->mem, parser->exps);
  BTOR_RELEASE_STACK (parser->mem, parser->info);
  BTOR_RELEASE_STACK (parser->mem, parser->inputs);
  BTOR_RELEASE_STACK (parser->mem, parser->outputs);
  BTOR_RELEASE_STACK (parser->mem, parser->regs);
  BTOR_RELEASE_STACK (parser->mem, parser->nexts);

  BTOR_RELEASE_STACK (parser->mem, parser->op);
  BTOR_RELEASE_STACK (parser->mem, parser->constant);
  BTOR_RELEASE_STACK (parser->mem, parser->symbol);

  BTOR_DELETEN (parser->mem, parser->parsers, SIZE_PARSERS);
  BTOR_DELETEN (parser->mem, parser->ops, SIZE_PARSERS);

  btor_freestr (parser->mem, parser->error);
  BTOR_DELETE (parser->mem, parser);
}
Esempio n. 5
0
void
btor_delete_const (BtorMemMgr * mm, char *c)
{
  assert (mm != NULL);
  assert (c != NULL);
  assert (is_valid_const_3vl (c));

  btor_freestr (mm, c);
}
Esempio n. 6
0
static void
recursively_dump_exp_smt (BtorSMTDumpContext * sdc, BtorNode * exp,
                          int expect_bv, unsigned depth_limit)
{
  assert (sdc);
  assert (exp);
  assert (btor_find_in_ptr_hash_table (sdc->dump, BTOR_REAL_ADDR_NODE (exp)));

  unsigned depth;
  int pad, i, is_bool, add_space, zero_extend, expect_bool;
  BtorBitVector *bitsbv;
  char *bits;
  const char *op, *fmt;
  BtorNode *arg, *real_exp;
  BtorArgsIterator it;
  BtorNodePtrStack dump, args;
  BtorIntStack expect_bv_stack, expect_bool_stack, depth_stack;
  BtorIntStack add_space_stack, zero_extend_stack;
  BtorPtrHashTable *visited;
  BtorMemMgr *mm;

  mm = sdc->btor->mm;
  visited = btor_new_ptr_hash_table (mm, 0, 0);
  BTOR_INIT_STACK (args);
  BTOR_INIT_STACK (dump);
  BTOR_INIT_STACK (expect_bv_stack);
  BTOR_INIT_STACK (expect_bool_stack);
  BTOR_INIT_STACK (add_space_stack);
  BTOR_INIT_STACK (zero_extend_stack);
  BTOR_INIT_STACK (depth_stack);

  PUSH_DUMP_NODE (exp, expect_bv, 0, 0, 0, 0);
  while (!BTOR_EMPTY_STACK (dump))
    {
      assert (!BTOR_EMPTY_STACK (expect_bv_stack));
      assert (!BTOR_EMPTY_STACK (expect_bool_stack));
      assert (!BTOR_EMPTY_STACK (add_space_stack));
      assert (!BTOR_EMPTY_STACK (zero_extend_stack));
      assert (!BTOR_EMPTY_STACK (depth_stack));
      depth = BTOR_POP_STACK (depth_stack);
      exp = BTOR_POP_STACK (dump);
      expect_bv = BTOR_POP_STACK (expect_bv_stack);
      expect_bool = BTOR_POP_STACK (expect_bool_stack);
      add_space = BTOR_POP_STACK (add_space_stack);
      zero_extend = BTOR_POP_STACK (zero_extend_stack);
      real_exp = BTOR_REAL_ADDR_NODE (exp);
      is_bool = is_boolean (sdc, real_exp);
      assert (!expect_bv || !expect_bool);
      assert (!expect_bool || !expect_bv);

      /* open s-expression */
      if (!btor_find_in_ptr_hash_table (visited, real_exp))
        {
          if (add_space)
            fputc (' ', sdc->file);

          /* wrap node with zero_extend */
          if (zero_extend)
            {
              fmt = " ((_ zero_extend %d) ";
              fprintf (sdc->file, fmt, zero_extend);
            }

          /* always print constants */
          if (BTOR_IS_BV_CONST_NODE (real_exp))
            {
              if (exp == sdc->btor->true_exp && !expect_bv)
                fputs ("true", sdc->file);
              else if (exp == BTOR_INVERT_NODE (sdc->btor->true_exp)
                       && !expect_bv)
                fputs ("false", sdc->file);
              else if (BTOR_IS_INVERTED_NODE (exp))
                {
                  bitsbv = btor_not_bv (
                      sdc->btor->mm, btor_const_get_bits (real_exp));
                  bits = btor_bv_to_char_bv (sdc->btor->mm, bitsbv);
                  dump_const_value_aux_smt (sdc, bits);
                  btor_free_bv (sdc->btor->mm, bitsbv);
                  btor_freestr (sdc->btor->mm, bits);
                }
              else
                {
                  bits = btor_bv_to_char_bv (
                      sdc->btor->mm, btor_const_get_bits (real_exp));
                  dump_const_value_aux_smt (sdc, bits);
                  btor_freestr (sdc->btor->mm, bits);
                }

              /* close zero extend */
              if (zero_extend)
                fputc (')', sdc->file);
              continue;
            }

          /* wrap non-bool node and make it bool */
          if (expect_bool && !is_bool)
            {
              fputs ("(= ", sdc->file);
              dump_const_value_aux_smt (sdc, "1");
              fputc (' ', sdc->file);
            }

          /* wrap node with bvnot/not */
          if (BTOR_IS_INVERTED_NODE (exp))
            fputs (expect_bv || !is_bool ? "(bvnot " : "(not ", sdc->file);

          /* wrap bool node and make it a bit vector expression */
          if (is_bool && expect_bv)
            fputs ("(ite ", sdc->file);

          if (btor_find_in_ptr_hash_table (sdc->dumped, real_exp)
              || BTOR_IS_LAMBDA_NODE (real_exp)
              || BTOR_IS_UF_NODE (real_exp))
            {
#ifndef NDEBUG
              BtorPtrHashBucket *b;
              b = btor_find_in_ptr_hash_table (sdc->dump, real_exp);
              assert (b);
              /* functions and variables are declared separately */
              assert (BTOR_IS_LAMBDA_NODE (real_exp)
                      || BTOR_IS_UF_NODE (real_exp)
                      || BTOR_IS_BV_VAR_NODE (real_exp)
                      || BTOR_IS_PARAM_NODE (real_exp)
                      || b->data.asInt > 1);
#endif
              dump_smt_id (sdc, exp);
              goto CLOSE_WRAPPER;
            }

          if (depth_limit && depth >= depth_limit)
            {
              fprintf (sdc->file, "%s_%d", g_kind2smt[real_exp->kind],
                       real_exp->id);
              goto CLOSE_WRAPPER;
            }

          PUSH_DUMP_NODE (exp, expect_bv, expect_bool, 0, zero_extend, depth);
          btor_insert_in_ptr_hash_table (visited, real_exp);
          op = "";
          switch (real_exp->kind)
            {
              case BTOR_SLL_NODE:
              case BTOR_SRL_NODE:
                assert (!is_bool);
                op = real_exp->kind == BTOR_SRL_NODE ? "bvlshr" : "bvshl";
                assert (btor_get_exp_width (sdc->btor, real_exp) > 1);
                pad = btor_get_exp_width (sdc->btor, real_exp)
                      - btor_get_exp_width (sdc->btor, real_exp->e[1]);
                PUSH_DUMP_NODE (real_exp->e[1], 1, 0, 1, pad, depth + 1);
                PUSH_DUMP_NODE (real_exp->e[0], 1, 0, 1, 0, depth + 1);
                break;

              case BTOR_BCOND_NODE:
                op = "ite";
                PUSH_DUMP_NODE (real_exp->e[2], !is_bool, 0, 1, 0, depth + 1); 
                PUSH_DUMP_NODE (real_exp->e[1], !is_bool, 0, 1, 0, depth + 1); 
                PUSH_DUMP_NODE (real_exp->e[0], 0, 1, 1, 0, depth + 1); 
                break;

              case BTOR_APPLY_NODE:
                /* we need the arguments in reversed order */
                btor_init_args_iterator (&it, real_exp->e[1]);
                while (btor_has_next_args_iterator (&it))
                  {
                    arg = btor_next_args_iterator (&it);
                    BTOR_PUSH_STACK (mm, args, arg);
                  }
                while (!BTOR_EMPTY_STACK (args))
                  {
                    arg = BTOR_POP_STACK (args);
                    // TODO (ma): what about bool arguments/indices
                    PUSH_DUMP_NODE (arg, 1, 0, 1, 0, depth + 1);
                  }
                PUSH_DUMP_NODE (real_exp->e[0], 1, 0, 0, 0, depth + 1);
                break;

#if 0
              case BTOR_LAMBDA_NODE:
                extract_store (sdc, exp, &index, &value, &array);
                assert (index);
                assert (value);
                assert (array);
                fputs ("(store ", sdc->file);
                DUMP_EXP_SMT (array);
                fputc (' ', sdc->file);
                DUMP_EXP_SMT (index);
                fputc (' ', sdc->file);
                DUMP_EXP_SMT (value);
                fputc (')', sdc->file);
                break;
#endif

              default:
                expect_bv = 1;
                switch (real_exp->kind)
                  {
                    case BTOR_FEQ_NODE:
                    case BTOR_BEQ_NODE:
                      op = "=";
                      expect_bv = 1;
                      break;
                    case BTOR_ULT_NODE:
                      op = "bvult";
                      expect_bv = 1;
                      break;
                    case BTOR_SLICE_NODE:
                      assert (!is_bool);
                      op = "(_ extract ";
                      break;
                    case BTOR_AND_NODE:
                      op = is_bool ? "and" : "bvand";
                      expect_bv = !is_bool;
                      break;
                    case BTOR_ADD_NODE:
                      assert (!is_bool); op = "bvadd"; break;
                    case BTOR_MUL_NODE:
                      assert (!is_bool); op = "bvmul"; break;
                    case BTOR_UDIV_NODE:
                      assert (!is_bool); op = "bvudiv"; break;
                    case BTOR_UREM_NODE:
                      assert (!is_bool); op = "bvurem"; break;
                    case BTOR_CONCAT_NODE:
                      assert (!is_bool); op = "concat"; break;
                    default:
                      assert (0);
                      op = "unknown";
                  }
                if (BTOR_IS_AND_NODE (real_exp) && is_bool)
                  {
                    assert (BTOR_EMPTY_STACK (args));
                    get_children (sdc, exp, &args);
                    for (i = 0; i < BTOR_COUNT_STACK (args); i++)
                      {
                        arg = BTOR_PEEK_STACK (args, i);
                        PUSH_DUMP_NODE (arg, expect_bv, 0, 1, 0, depth + 1);
                      }
                    BTOR_RESET_STACK (args);
                  }
                else
                  for (i = real_exp->arity - 1; i >= 0; i--)
                    PUSH_DUMP_NODE (real_exp->e[i], expect_bv, 0, 1, 0,
                                    depth + 1);
            }

          /* open s-expression */
          assert (op);
          fprintf (sdc->file, "(%s", op);

          if (BTOR_IS_SLICE_NODE (real_exp))
            {
              fmt = "%d %d)";
              fprintf (sdc->file, fmt, btor_slice_get_upper (real_exp),
                       btor_slice_get_lower (real_exp));
            }
        }
      /* close s-expression */
      else
        {
          if (!btor_find_in_ptr_hash_table (sdc->dumped, real_exp))
            btor_insert_in_ptr_hash_table (sdc->dumped, real_exp);

          /* close s-expression */
          if (real_exp->arity > 0)
            fputc (')', sdc->file);

CLOSE_WRAPPER:
          /* close wrappers */

          /* wrap boolean expressions in bit vector expression */
          if (is_bool && expect_bv && !BTOR_IS_BV_CONST_NODE (real_exp))
            {
              fputc (' ', sdc->file);
              dump_const_value_aux_smt (sdc, "1");
              fputc (' ', sdc->file);
              dump_const_value_aux_smt (sdc, "0");
              fputc (')', sdc->file);
            }

          /* close bvnot for non-constants */
          if (BTOR_IS_INVERTED_NODE (exp) && !BTOR_IS_BV_CONST_NODE (real_exp))
            fputc (')', sdc->file);

          /* close bool wrapper */
          if (expect_bool && !is_boolean (sdc, real_exp))
            fputc (')', sdc->file);

          /* close zero extend wrapper */
          if (zero_extend)
            fputc (')', sdc->file);
        }
    }
  assert (BTOR_EMPTY_STACK (expect_bv_stack));
  BTOR_RELEASE_STACK (mm, args);
  BTOR_RELEASE_STACK (mm, dump);
  BTOR_RELEASE_STACK (mm, expect_bv_stack);
  BTOR_RELEASE_STACK (mm, expect_bool_stack);
  BTOR_RELEASE_STACK (mm, add_space_stack);
  BTOR_RELEASE_STACK (mm, zero_extend_stack);
  BTOR_RELEASE_STACK (mm, depth_stack);
  btor_delete_ptr_hash_table (visited);
}
Esempio n. 7
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;
}
Esempio n. 8
0
int
main (int argc, char ** argv)
{
  int i, j, verbosity, close_input, close_output, binary, merge;
  const char * input_name, * output_name;
  FILE * input_file, * output_file, * file;
  BtorAIG * aig, * tmp, * merged, ** p;
  BtorPtrHashTable * back_annotation;
  const char * parse_error;
  BtorPtrHashBucket *b;
  BtorParseResult model;
  BtorAIGVecMgr * avmgr;
  BtorAIGPtrStack regs;
  BtorAIGPtrStack nexts;
  BtorAIGPtrStack aigs;
  BtorParser * parser;
  BtorAIGMgr * amgr;
  BtorMemMgr * mem;
  BtorAIGVec * av;
  Btor * btor;

  verbosity = 0;
  close_input = 0;
  close_output = 0;
  binary = 0;
  merge = 0;
  input_name = "<stdin>";
  output_name = "<stdout>";
  input_file = stdin;
  output_file = stdout;

  for (i = 1; i < argc; i++)
    {
      if (!strcmp (argv[i], "-h"))
	{
	  printf ("usage: synthebor [-h][-v][-m][<input>[<output>]]\n");
	  exit (0);
	}
      else if (!strcmp (argv[i], "-v"))
	verbosity++;
      else if (!strcmp (argv[i], "-m"))
	merge = 1;
      else if (argv[i][0] == '-')
	die (1, "invalid command line option '%s'", argv[i]);
      else if (close_output)
	die (1, "too many files");
      else if (close_input)
	{
	  if (!strcmp (argv[i], input_name))
	    die (1, "input and output are the same");

	  if (!(file = fopen (argv[i], "w")))
	    die (1, "can not write '%s'", argv[i]);

	  output_file = file;
	  output_name = argv[i];
	  close_output = 1;
	}
      else if (!(file = fopen (argv[i], "r")))
	die (1, "can not read '%s'", argv[i]);
      else
	{
	  input_file = file;
	  input_name = argv[i];
	  close_input = 1;
	}
    }

  btor = btor_new_btor ();
  btor_set_verbosity_btor (btor, verbosity);
  btor_set_rewrite_level_btor (btor, 1);
  parser = btor_btor_parser_api ()->init (btor, verbosity);

  parse_error = btor_btor_parser_api()->parse (parser,
                                             input_file,
					     input_name,
					     &model);
  if (parse_error)
    die (0, parse_error);

  if (!model.noutputs)
    die (1, "no roots in '%s'", input_name);

  if (model.nregs && merge)
    die (1, "can not merge registers");

  mem = btor->mm;
  avmgr = btor->avmgr;
  amgr = btor_get_aig_mgr_aigvec_mgr (avmgr);

  back_annotation = btor_new_ptr_hash_table (mem, 0, 0);

  BTOR_INIT_STACK (regs);
  BTOR_INIT_STACK (nexts);

  for (i = 0; i < model.nregs; i++)
    {
      if (btor_is_array_exp (btor, model.regs[i]))
	die (1, "can not synthesize memories (yet)");

      av = btor_exp_to_aigvec (btor, model.regs[i], back_annotation);
      for (j = 0; j < av->len; j++)
	{
	  aig = btor_copy_aig (amgr, av->aigs[j]);
	  BTOR_PUSH_STACK (mem, regs, aig);
	}
      btor_release_delete_aigvec (avmgr, av);

      av = btor_exp_to_aigvec (btor, model.nexts[i], back_annotation);
      for (j = 0; j < av->len; j++)
	{
	  aig = btor_copy_aig (amgr, av->aigs[j]);
	  BTOR_PUSH_STACK (mem, nexts, aig);
	}
      btor_release_delete_aigvec (avmgr, av);
    }

  BTOR_INIT_STACK (aigs);
  merged = BTOR_AIG_TRUE;

  for (i = 0; i < model.noutputs; i++)
    {
      av = btor_exp_to_aigvec (btor, model.outputs[i], back_annotation);
      for (j = 0; j < av->len; j++)
	{
	  aig = av->aigs[j];

	  if (merge)
	    {
	      tmp = btor_and_aig (amgr, merged, aig);
	      btor_release_aig (amgr, merged);
	      merged = tmp;
	    }
	  else
	    {
	      aig = btor_copy_aig (amgr, aig);
	      BTOR_PUSH_STACK (mem, aigs, aig);
	    }
	}
      btor_release_delete_aigvec (avmgr, av);
    }

  if (merge)
    BTOR_PUSH_STACK (mem, aigs, merged);

#ifdef BTOR_HAVE_ISATTY
  if (close_output || !isatty (1))
    binary = 1;
#endif
  assert (BTOR_COUNT_STACK (regs) == BTOR_COUNT_STACK (nexts));
  btor_dump_aiger (amgr,
                  binary, output_file, 
		  BTOR_COUNT_STACK (aigs), aigs.start,
		  BTOR_COUNT_STACK (regs), regs.start, nexts.start,
		  back_annotation);

  for (p = aigs.start; p < aigs.top; p++)
    btor_release_aig (amgr, *p);
  BTOR_RELEASE_STACK (mem, aigs);

  for (p = regs.start; p < regs.top; p++)
    btor_release_aig (amgr, *p);
  BTOR_RELEASE_STACK (mem, regs);

  for (p = nexts.start; p < nexts.top; p++)
    btor_release_aig (amgr, *p);
  BTOR_RELEASE_STACK (mem, nexts);

  for (b = back_annotation->first; b; b = b->next)
    btor_freestr (mem, b->data.asStr);

  btor_delete_ptr_hash_table (back_annotation);

  btor_btor_parser_api()->reset (parser);
  btor_delete_btor (btor);

  if (close_input)
    fclose (input_file);

  if (close_output)
    fclose (output_file);

  return 0;
}
Esempio n. 9
0
char *
btor_sub_unbounded_const (BtorMemMgr * mem, const char *a, const char *b)
{
  char *res, *tmp, *r, c, x, y, s;
  int alen, blen, rlen;
  const char *p, *q;

  assert (mem != NULL);
  assert (a != NULL);
  assert (b != NULL);
  assert (is_valid_const (a));
  assert (is_valid_const (b));
  assert (btor_cmp_const (b, a) <= 0);

  a = strip_zeroes (a);
  b = strip_zeroes (b);
  if (!*b)
    return btor_strdup (mem, a);

  alen = (int) strlen (a);
  blen = (int) strlen (b);

  assert (alen >= blen);
  rlen = alen;

  BTOR_NEWN (mem, res, rlen + 1);

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

  c = '0';
  r = res + rlen;
  *r = 0;

  while (res < r)
    {
      assert (a < p);
      x = *--p;

      y = (b < q) ? *--q : '0';

      s = x ^ y ^ c;
      c = ((1 ^ x) & c) | ((1 ^ x) & y) | (y & c);

      *--r = s;
    }

  assert (c == '0');

#ifndef NDEBUG
  {
    tmp = btor_add_unbounded_const (mem, res, b);
    assert (!btor_cmp_const (tmp, a));
    btor_freestr (mem, tmp);
  }
#endif

  tmp = btor_strdup (mem, strip_zeroes (res));
  btor_freestr (mem, res);
  res = tmp;

  return res;
}
Esempio n. 10
0
char *
btor_hex_to_const_n (BtorMemMgr * mem, const char *str, int hlen)
{
  const char *p, *end;
  char *tmp, *res, *q;
  int len;

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

  len = 4 * hlen;
  BTOR_NEWN (mem, tmp, len + 1);
  q = tmp;

  end = str + hlen;
  for (p = str; p < end; p++)
    switch (*p)
      {
      case '0':
        *q++ = '0';
        *q++ = '0';
        *q++ = '0';
        *q++ = '0';
        break;
      case '1':
        *q++ = '0';
        *q++ = '0';
        *q++ = '0';
        *q++ = '1';
        break;
      case '2':
        *q++ = '0';
        *q++ = '0';
        *q++ = '1';
        *q++ = '0';
        break;
      case '3':
        *q++ = '0';
        *q++ = '0';
        *q++ = '1';
        *q++ = '1';
        break;
      case '4':
        *q++ = '0';
        *q++ = '1';
        *q++ = '0';
        *q++ = '0';
        break;
      case '5':
        *q++ = '0';
        *q++ = '1';
        *q++ = '0';
        *q++ = '1';
        break;
      case '6':
        *q++ = '0';
        *q++ = '1';
        *q++ = '1';
        *q++ = '0';
        break;
      case '7':
        *q++ = '0';
        *q++ = '1';
        *q++ = '1';
        *q++ = '1';
        break;
      case '8':
        *q++ = '1';
        *q++ = '0';
        *q++ = '0';
        *q++ = '0';
        break;
      case '9':
        *q++ = '1';
        *q++ = '0';
        *q++ = '0';
        *q++ = '1';
        break;
      case 'A':
      case 'a':
        *q++ = '1';
        *q++ = '0';
        *q++ = '1';
        *q++ = '0';
        break;
      case 'B':
      case 'b':
        *q++ = '1';
        *q++ = '0';
        *q++ = '1';
        *q++ = '1';
        break;
      case 'C':
      case 'c':
        *q++ = '1';
        *q++ = '1';
        *q++ = '0';
        *q++ = '0';
        break;
      case 'D':
      case 'd':
        *q++ = '1';
        *q++ = '1';
        *q++ = '0';
        *q++ = '1';
        break;
      case 'E':
      case 'e':
        *q++ = '1';
        *q++ = '1';
        *q++ = '1';
        *q++ = '0';
        break;
      case 'F':
      case 'f':
      default:
        assert (*p == 'f' || *p == 'F');
        *q++ = '1';
        *q++ = '1';
        *q++ = '1';
        *q++ = '1';
        break;
      }

  assert (tmp + len == q);
  *q++ = 0;

  res = btor_strdup (mem, strip_zeroes (tmp));
  btor_freestr (mem, tmp);

  return res;
}
Esempio n. 11
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;
}