Exemplo n.º 1
0
/* pattern: lower <= j <= upper && range_cond ? j : a[j] */
static inline BtorNode *
create_pattern_itoi (Btor * btor,
                     BtorNode * lower,
                     BtorNode * upper,
                     BtorNode * array,
                     BtorBitVector * offset)
{
  assert (lower);
  assert (upper);
  assert (BTOR_REAL_ADDR_NODE (lower)->kind
          == BTOR_REAL_ADDR_NODE (upper)->kind);
  assert (BTOR_IS_BV_CONST_NODE (BTOR_REAL_ADDR_NODE (lower))
          || BTOR_IS_ADD_NODE (BTOR_REAL_ADDR_NODE (lower)));
  assert (BTOR_REAL_ADDR_NODE (lower)->sort_id
          == BTOR_REAL_ADDR_NODE (upper)->sort_id);
  assert (btor_get_codomain_fun_sort (
            &btor->sorts_unique_table, array->sort_id) ==
          BTOR_REAL_ADDR_NODE (lower)->sort_id);
  assert (offset);

  BtorNode *res, *param, *ite, *read, *cond;

  param = btor_param_exp (btor, btor_get_exp_width (btor, lower), 0);
  read = btor_read_exp (btor, array, param);
  cond = create_range (btor, lower, upper, param, offset);;
  ite = btor_cond_exp (btor, cond, param, read);
  res = btor_lambda_exp (btor, param, ite);

  btor_release_exp (btor, param);
  btor_release_exp (btor, read);
  btor_release_exp (btor, cond);
  btor_release_exp (btor, ite);

  return res;
}
Exemplo n.º 2
0
static BtorNode *
parse_redunary (BtorBTORParser * parser, int len, Unary f)
{
  BtorNode *tmp, *res;

  (void) len;
  assert (len == 1);

  if (parse_space (parser))
    return 0;

  if (!(tmp = parse_exp (parser, 0, 0)))
    return 0;

  if (btor_get_exp_len (parser->btor, tmp) == 1)
    {
      (void) btor_perr_btor (parser,
			  "argument of reduction operation of width 1");
      btor_release_exp (parser->btor, tmp);
      return 0;
    }

  res = f (parser->btor, tmp);
  btor_release_exp (parser->btor, tmp);
  assert (btor_get_exp_len (parser->btor, res) == 1);

  return res;
}
Exemplo n.º 3
0
static BtorNode *
parse_binary (BtorBTORParser * parser, int len, Binary f)
{
  BtorNode *l, *r, *res;

  assert (len);

  if (parse_space (parser))
    return 0;

  if (!(l = parse_exp (parser, len, 0)))
    return 0;

  if (parse_space (parser))
    {
    RELEASE_L_AND_RETURN_ERROR:
      btor_release_exp (parser->btor, l);
      return 0;
    }

  if (!(r = parse_exp (parser, len, 0)))
    goto RELEASE_L_AND_RETURN_ERROR;

  res = f (parser->btor, l, r);
  btor_release_exp (parser->btor, r);
  btor_release_exp (parser->btor, l);
  assert (btor_get_exp_len (parser->btor, res) == len);

  return res;
}
Exemplo n.º 4
0
static BtorNode *
parse_read (BtorBTORParser * parser, int len)
{
  BtorNode *array, *idx, *res;
  int idxlen;

  if (parse_space (parser))
    return 0;

  if (!(array = parse_array_exp (parser, len)))
    return 0;

  if (parse_space (parser))
    {
RELEASE_ARRAY_AND_RETURN_ERROR:
      btor_release_exp (parser->btor, array);
      return 0;
    }

  idxlen = btor_get_index_exp_len (parser->btor, array);
  if (!(idx = parse_exp (parser, idxlen, 0)))
    goto RELEASE_ARRAY_AND_RETURN_ERROR;

  res = btor_read_exp (parser->btor, array, idx);
  btor_release_exp (parser->btor, idx);
  btor_release_exp (parser->btor, array);

  return res;
}
Exemplo n.º 5
0
static BtorNode *
parse_slice (BtorBTORParser * parser, int len)
{
  int arglen, upper, lower, delta;
  BtorNode *res, *arg;

  if (parse_space (parser))
    return 0;

  if (!(arg = parse_exp (parser, 0, 0)))
    return 0;

  if (parse_space (parser))
    {
    RELEASE_ARG_AND_RETURN_ERROR:
      btor_release_exp (parser->btor, arg);
      return 0;
    }

  arglen = btor_get_exp_len (parser->btor, arg);

  if (parse_non_negative_int (parser, &upper))
    goto RELEASE_ARG_AND_RETURN_ERROR;

  if (upper >= arglen)
    {
      (void) btor_perr_btor (parser, "upper index '%d' >= argument width '%d",
			  upper, arglen);
      goto RELEASE_ARG_AND_RETURN_ERROR;
    }

  if (parse_space (parser))
    goto RELEASE_ARG_AND_RETURN_ERROR;

  if (parse_non_negative_int (parser, &lower))
    goto RELEASE_ARG_AND_RETURN_ERROR;

  if (upper < lower)
    {
      (void) btor_perr_btor (parser,
			  "upper index '%d' smaller than lower index '%d'",
			  upper, lower);
      goto RELEASE_ARG_AND_RETURN_ERROR;
    }

  delta = upper - lower + 1;
  if (delta != len)
    {
      (void) btor_perr_btor (parser,
			  "slice width '%d' not equal to expected width '%d'",
			  delta, len);
      goto RELEASE_ARG_AND_RETURN_ERROR;
    }

  res = btor_slice_exp (parser->btor, arg, upper, lower);
  btor_release_exp (parser->btor, arg);

  return res;
}
Exemplo n.º 6
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);
}
Exemplo n.º 7
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);
}
Exemplo n.º 8
0
static BtorNode *
parse_write (BtorBTORParser * parser, int len)
{
  BtorNode *array, *idx, *val, *res;
  int idxlen, vallen;

  if (parse_space (parser))
    return 0;

  if (parse_positive_int (parser, &idxlen))
    return 0;

  if (parse_space (parser))
    return 0;

  if (!(array = parse_array_exp (parser, len)))
    return 0;

  if (parse_space (parser))
    {
RELEASE_ARRAY_AND_RETURN_ERROR:
      btor_release_exp (parser->btor, array);
      return 0;
    }

  if (!(idx = parse_exp (parser, idxlen, 0)))
    goto RELEASE_ARRAY_AND_RETURN_ERROR;

  if (parse_space (parser))
    {
RELEASE_ARRAY_AND_IDX_AND_RETURN_ERROR:
      btor_release_exp (parser->btor, idx);
      goto RELEASE_ARRAY_AND_RETURN_ERROR;
    }

  vallen = btor_get_exp_len (parser->btor, array);
  if (!(val = parse_exp (parser, vallen, 0)))
    goto RELEASE_ARRAY_AND_IDX_AND_RETURN_ERROR;

  res = btor_write_exp (parser->btor, array, idx, val);

  btor_release_exp (parser->btor, array);
  btor_release_exp (parser->btor, idx);
  btor_release_exp (parser->btor, val);

  return res;
}
Exemplo n.º 9
0
void
btor_delete_param_cache_tuple (Btor * btor, BtorParamCacheTuple * t)
{
  assert (btor);
  assert (t);
  
  int i;

  btor_release_exp (btor, t->exp);
  if (t->args)
    {
      for (i = 0; i < t->num_args; i++)
        btor_release_exp (btor, t->args[i]);
      BTOR_DELETEN (btor->mm, t->args, t->num_args);
    }
  BTOR_DELETE (btor->mm, t);
}
Exemplo n.º 10
0
static BtorNode *
parse_logical (BtorBTORParser * parser, int len, Binary f)
{
  BtorNode * l, * r, * res;

  if (len != 1)
    {
      (void) btor_perr_btor (parser, "logical operator bit width '%d'", len);
      return 0;
    }

  if (parse_space (parser))
    return 0;

  if (!(l = parse_exp (parser, 0, 0)))
    return 0;

  if (btor_get_exp_len (parser->btor, l) != 1)
    {
BIT_WIDTH_ERROR_RELEASE_L_AND_RETURN:
      (void) btor_perr_btor (parser, "expected argument of bit width '1'");
RELEASE_L_AND_RETURN_ERROR:
      btor_release_exp (parser->btor, l);
      return 0;
    }

  if (parse_space (parser))
    goto RELEASE_L_AND_RETURN_ERROR;

  if (!(r = parse_exp (parser, 0, 0)))
    goto RELEASE_L_AND_RETURN_ERROR;

  if (btor_get_exp_len (parser->btor, r) != 1)
    {
      btor_release_exp (parser->btor, r);
      goto BIT_WIDTH_ERROR_RELEASE_L_AND_RETURN;
    }

  res = f (parser->btor, l, r);
  btor_release_exp (parser->btor, r);
  btor_release_exp (parser->btor, l);
  assert (btor_get_exp_len (parser->btor, res) == 1);

  return res;
}
Exemplo n.º 11
0
void
boolector_release (Btor * btor, BtorNode * exp)
{
  BTOR_ABORT_ARG_NULL_BOOLECTOR (btor);
  BTOR_ABORT_ARG_NULL_BOOLECTOR (exp);
  BTOR_ABORT_REFS_NOT_POS_BOOLECTOR (exp);
  btor->external_refs--;
  btor_release_exp (btor, exp);
}
Exemplo n.º 12
0
static BtorNode *
parse_concat (BtorBTORParser * parser, int len)
{
  BtorNode *l, *r, *res;
  int llen, rlen;

  if (parse_space (parser))
    return 0;

  if (!(l = parse_exp (parser, 0, 0)))
    return 0;

  if (parse_space (parser))
    {
    RELEASE_L_AND_RETURN_ERROR:
      btor_release_exp (parser->btor, l);
      return 0;
    }

  if (!(r = parse_exp (parser, 0, 0)))
    goto RELEASE_L_AND_RETURN_ERROR;

  llen = btor_get_exp_len (parser->btor, l);
  rlen = btor_get_exp_len (parser->btor, r);

  if (llen + rlen != len)
    {
      (void)
	btor_perr_btor (parser,
		     "operands widths %d and %d do not add up to %d",
		     llen, rlen, len);

      btor_release_exp (parser->btor, r);
      btor_release_exp (parser->btor, l);
      return 0;
    }

  res = btor_concat_exp (parser->btor, l, r);
  btor_release_exp (parser->btor, r);
  btor_release_exp (parser->btor, l);
  assert (btor_get_exp_len (parser->btor, res) == len);

  return res;
}
Exemplo n.º 13
0
void
btor_delete_node_map (BtorNodeMap * map)
{
  assert (map);

  BtorHashTableIterator it;
  BtorNode *cur;
  
  btor_init_node_hash_table_iterator (&it, map->table);
  while (btor_has_next_node_hash_table_iterator (&it))
    {
      btor_release_exp (BTOR_REAL_ADDR_NODE (
                          (BtorNode *) it.bucket->data.asPtr)->btor, 
                        it.bucket->data.asPtr);
      cur = btor_next_node_hash_table_iterator (&it);
      btor_release_exp (BTOR_REAL_ADDR_NODE (cur)->btor, cur);
    }
  btor_delete_ptr_hash_table (map->table);
  BTOR_DELETE (map->btor->mm, map);
}
Exemplo n.º 14
0
inline static bool
is_itoip1_pattern (BtorNode * index, BtorNode * value)
{
  bool res;
  BtorNode *inc;

  inc = btor_inc_exp (BTOR_REAL_ADDR_NODE (index)->btor, index);
  res = inc == value;
  btor_release_exp (BTOR_REAL_ADDR_NODE (index)->btor, inc); 
  return res;
}
Exemplo n.º 15
0
static BtorNode *
parse_ext (BtorBTORParser * parser, int len, Extend f)
{
  BtorNode *res, *arg;
  int alen, elen;

  if (parse_space (parser))
    return 0;

  if (!(arg = parse_exp (parser, 0, 0)))
    return 0;

  alen = btor_get_exp_len (parser->btor, arg);

  if (parse_space (parser))
    {
    RELEASE_ARG_AND_RETURN_ERROR:
      btor_release_exp (parser->btor, arg);
      return 0;
    }

  if (parse_non_negative_int (parser, &elen))
    goto RELEASE_ARG_AND_RETURN_ERROR;

  if (alen + elen != len)
    {
      (void)
	btor_perr_btor (parser,
		     "argument length of %d plus %d does not match %d",
		     alen, elen, len);
      goto RELEASE_ARG_AND_RETURN_ERROR;
    }

  res = f (parser->btor, arg, elen);
  assert (btor_get_exp_len (parser->btor, res) == len);
  btor_release_exp (parser->btor, arg);

  return res;
}
Exemplo n.º 16
0
static BtorNode *
parse_cond (BtorBTORParser * parser, int len)
{
  BtorNode *c, *t, *e, *res;

  if (parse_space (parser))
    return 0;

  if (!(c = parse_exp (parser, 1, 0)))
    return 0;

  if (parse_space (parser))
    {
    RELEASE_C_AND_RETURN_ERROR:
      btor_release_exp (parser->btor, c);
      return 0;
    }

  if (!(t = parse_exp (parser, len, 0)))
    goto RELEASE_C_AND_RETURN_ERROR;

  if (parse_space (parser))
    {
    RELEASE_C_AND_T_AND_RETURN_ERROR:
      btor_release_exp (parser->btor, t);
      goto RELEASE_C_AND_RETURN_ERROR;
    }

  if (!(e = parse_exp (parser, len, 0)))
    goto RELEASE_C_AND_T_AND_RETURN_ERROR;

  res = btor_cond_exp (parser->btor, c, t, e);
  btor_release_exp (parser->btor, e);
  btor_release_exp (parser->btor, t);
  btor_release_exp (parser->btor, c);

  return res;
}
Exemplo n.º 17
0
static BtorNode *
parse_shift (BtorBTORParser * parser, int len, Shift f)
{
  BtorNode *l, *r, *res;
  int rlen;

  for (rlen = 1; rlen <= 30 && len != (1 << rlen); rlen++)
    ;

  if (len != (1 << rlen))
    {
      (void) btor_perr_btor (parser, "length %d is not a power of two", len);
      return 0;
    }

  if (parse_space (parser))
    return 0;

  if (!(l = parse_exp (parser, len, 0)))
    return 0;

  if (parse_space (parser))
    {
    RELEASE_L_AND_RETURN_ERROR:
      btor_release_exp (parser->btor, l);
      return 0;
    }

  if (!(r = parse_exp (parser, rlen, 0)))
    goto RELEASE_L_AND_RETURN_ERROR;

  res = f (parser->btor, l, r);
  btor_release_exp (parser->btor, r);
  btor_release_exp (parser->btor, l);
  assert (btor_get_exp_len (parser->btor, res) == len);

  return res;
}
Exemplo n.º 18
0
static BtorNode *
parse_acond (BtorBTORParser * parser, int len)
{
  BtorNode *c, *t, *e, *res;
  int idxlen;

  if (parse_space (parser))
    return 0;

  if (parse_positive_int (parser, &idxlen))
    return 0;

  if (parse_space (parser))
    return 0;

  if (!(c = parse_exp (parser, 1, 0)))
    return 0;

  if (parse_space (parser))
    {
    RELEASE_C_AND_RETURN_ERROR:
      btor_release_exp (parser->btor, c);
      return 0;
    }

  if (!(t = parse_array_exp (parser, len)))
    goto RELEASE_C_AND_RETURN_ERROR;

  if (idxlen != btor_get_index_exp_len (parser->btor, t))
    {
      (void) btor_perr_btor (parser,
			     "mismatch of index bit width of 'then' array");
    RELEASE_C_AND_T_AND_RETURN_ERROR:
      btor_release_exp (parser->btor, t);
      goto RELEASE_C_AND_RETURN_ERROR;
    }

  if (parse_space (parser))
    goto RELEASE_C_AND_T_AND_RETURN_ERROR;

  if (!(e = parse_array_exp (parser, len)))
    goto RELEASE_C_AND_T_AND_RETURN_ERROR;

  if (idxlen != btor_get_index_exp_len (parser->btor, e))
    {
      (void) btor_perr_btor (parser,
			     "mismatch of index bit width of 'else' array");
      btor_release_exp (parser->btor, e);
      goto RELEASE_C_AND_T_AND_RETURN_ERROR;
    }

  res = btor_cond_exp (parser->btor, c, t, e);
  btor_release_exp (parser->btor, e);
  btor_release_exp (parser->btor, t);
  btor_release_exp (parser->btor, c);

  return res;
}
Exemplo n.º 19
0
static void
dump_smt_aux (Btor * btor, FILE * file, BtorNode ** roots, int nroots)
{
  assert (btor);
  assert (file);
  assert (!btor->options.incremental.val);
//  assert (!btor->options.model_gen.val);

  int i, ret;
  BtorNode *temp, *tmp_roots[nroots];
  BtorHashTableIterator it;
  BtorSMTDumpContext *sdc;

  for (i = 0; i < nroots; i++)
    tmp_roots[i] = roots[i];

  sdc = new_smt_dump_context (btor, file);

  if (nroots)
    {
      for (i = 0; i < nroots; i++)
        add_root_to_smt_dump_context (sdc, tmp_roots[i]);
    }
  else
    {
      ret = btor_simplify (btor);

      if (ret == BTOR_UNKNOWN)
        {
          btor_init_node_hash_table_iterator (&it, btor->unsynthesized_constraints);
          btor_queue_node_hash_table_iterator (&it, btor->synthesized_constraints);
          btor_queue_node_hash_table_iterator (&it, btor->embedded_constraints);
          while (btor_has_next_node_hash_table_iterator (&it))
            add_root_to_smt_dump_context (sdc,
                btor_next_node_hash_table_iterator (&it));
        }
      else
        {
          assert (ret == BTOR_SAT || ret == BTOR_UNSAT);
          temp = (ret == BTOR_SAT) ? btor_true_exp (btor)
                                   : btor_false_exp (btor);
          add_root_to_smt_dump_context (sdc, temp);
          btor_release_exp (btor, temp);
        }
    }

  dump_smt (sdc);
  delete_smt_dump_context (sdc);
}
Exemplo n.º 20
0
static BtorNode *
parse_array_exp (BtorBTORParser * parser, int len)
{
  BtorNode * res;

  res = parse_exp (parser, len, 1);
  if (!res)
    return 0;

  if (btor_is_array_exp (parser->btor, res))
    return res;

  (void) btor_perr_btor (parser, "expected array expression");
  btor_release_exp (parser->btor, res);

  return 0;
}
Exemplo n.º 21
0
static BtorNode *
parse_unary (BtorBTORParser * parser, int len, Unary f)
{
  BtorNode *tmp, *res;

  assert (len);
  if (parse_space (parser))
    return 0;

  if (!(tmp = parse_exp (parser, len, 0)))
    return 0;

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

  return res;
}
Exemplo n.º 22
0
static inline BtorNode *
create_pattern_cpy (Btor * btor,
                    BtorNode * lower,
                    BtorNode * upper,
                    BtorNode * src_array,
                    BtorNode * dst_array,
                    BtorNode * src_addr,
                    BtorNode * dst_addr,
                    BtorBitVector * offset)
{
  assert (!BTOR_IS_INVERTED_NODE (lower));
  assert (!BTOR_IS_INVERTED_NODE (upper));
  assert (BTOR_IS_ADD_NODE (lower));
  assert (BTOR_IS_ADD_NODE (upper));

  BtorNode *res, *param, *ite, *read, *cond, *read_src, *add, *sub;

  param = btor_param_exp (btor, btor_get_exp_width (btor, lower), 0);
  read = btor_read_exp (btor, dst_array, param);
  cond = create_range (btor, lower, upper, param, offset);

  sub = btor_sub_exp (btor, param, dst_addr);
  add = btor_add_exp (btor, src_addr, sub);
  read_src = btor_read_exp (btor, src_array, add);
  ite = btor_cond_exp (btor, cond, read_src, read);
  res = btor_lambda_exp (btor, param, ite);

  btor_release_exp (btor, param);
  btor_release_exp (btor, read);
  btor_release_exp (btor, cond);
  btor_release_exp (btor, sub);
  btor_release_exp (btor, add);
  btor_release_exp (btor, read_src);
  btor_release_exp (btor, ite);
  return res;
}
Exemplo n.º 23
0
BtorNode *
btor_non_recursive_extended_substitute_node (
  Btor * btor,
  BtorNodeMap * map,
  void * state,
  BtorNodeMapper mapper,
  BtorNodeReleaser release,
  BtorNode * root)
{
  BtorNodePtrStack working_stack, marked_stack;
  BtorNode * res, * node, * mapped;
  BtorMemMgr * mm;
  int i;

  if (map->simplify)
    root = btor_simplify_exp (BTOR_REAL_ADDR_NODE (root)->btor, root);

  mm  = btor->mm;

  BTOR_INIT_STACK (working_stack);
  BTOR_INIT_STACK (marked_stack);
  BTOR_PUSH_STACK (mm, working_stack, root);
  
  while (!BTOR_EMPTY_STACK (working_stack))
    {
      node = BTOR_POP_STACK (working_stack);
      node = BTOR_REAL_ADDR_NODE (node);
      assert (node->kind != BTOR_PROXY_NODE);
      if (btor_mapped_node (map, node))
        continue;
      if (node->mark == 2)
        continue;
      mapped = mapper (btor, state, node);
      if (mapped)
        {
          btor_map_node (map, node, mapped);
          release (btor, mapped);
        }
      else
      if (!node->mark)
        {
          node->mark = 1;
          BTOR_PUSH_STACK (mm, working_stack, node);
          BTOR_PUSH_STACK (mm, marked_stack, node);
          for (i = node->arity - 1; i >= 0; i--)
            BTOR_PUSH_STACK (mm, working_stack, node->e[i]);
        }
      else
        {
          mapped = btor_map_node_internal (btor, map, node);
          btor_map_node (map, node, mapped);
          btor_release_exp (btor, mapped);
          assert (node->mark == 1);
          node->mark = 2;
        }
    }
  BTOR_RELEASE_STACK (mm, working_stack);
  while (!BTOR_EMPTY_STACK (marked_stack))
    {
      node = BTOR_POP_STACK (marked_stack);
      assert (node->mark == 2);
      node->mark = 0;
    }
  BTOR_RELEASE_STACK (mm, marked_stack);
  res = btor_mapped_node (map, root);
  assert (res);
  return res;
}
Exemplo n.º 24
0
void
btor_eliminate_applies (Btor * btor)
{
  assert (btor);

  int num_applies, num_applies_total = 0, round;
  double start, delta;
  BtorPtrHashTable *apps;
  BtorNode *app, *fun;
  BtorNodeIterator it;
  BtorHashTableIterator h_it;
  BtorMemMgr *mm;

  if (btor->lambdas->count == 0)
    return;

  start = btor_time_stamp ();

  mm = btor->mm;
  round = 1;

  /* NOTE: in some cases substitute_and_rebuild creates applies that can be
   * beta-reduced. this can happen when parameterized applies become not
   * parameterized. hence, we beta-reduce applies until fix point.
   */
  do
    {
      apps = btor_new_ptr_hash_table (mm,
                                      (BtorHashPtr) btor_hash_exp_by_id,
                                      (BtorCmpPtr) btor_compare_exp_by_id);

      /* collect function applications */
      btor_init_node_hash_table_iterator (&h_it, btor->lambdas);
      while (btor_has_next_node_hash_table_iterator (&h_it))
        {
          fun = btor_next_node_hash_table_iterator (&h_it);

          btor_init_apply_parent_iterator (&it, fun);
          while (btor_has_next_apply_parent_iterator (&it))
            {
              app = btor_next_apply_parent_iterator (&it);

              if (btor_find_in_ptr_hash_table (apps, app))
                continue;

              if (app->parameterized)
                continue;

              btor_insert_in_ptr_hash_table (apps, btor_copy_exp (btor, app));
            }
        }

      num_applies = apps->count;
      num_applies_total += num_applies;
      BTOR_MSG (btor->msg, 1, "eliminate %d applications in round %d",
                num_applies, round);

      btor_substitute_and_rebuild (btor, apps, -1);

      btor_init_node_hash_table_iterator (&h_it, apps);
      while (btor_has_next_node_hash_table_iterator (&h_it))
        btor_release_exp (btor, btor_next_node_hash_table_iterator (&h_it));
      btor_delete_ptr_hash_table (apps);
      round++;
    }
  while (num_applies > 0);

#ifndef NDEBUG
  btor_init_node_hash_table_iterator (&h_it, btor->lambdas);
  while (btor_has_next_node_hash_table_iterator (&h_it))
    {
      fun = btor_next_node_hash_table_iterator (&h_it);

      btor_init_apply_parent_iterator (&it, fun);
      while (btor_has_next_apply_parent_iterator (&it))
        {
          app = btor_next_apply_parent_iterator (&it);
          assert (app->parameterized);
        }
    }
#endif

  delta = btor_time_stamp () - start;
  btor->time.betareduce += delta;
  BTOR_MSG (btor->msg, 1, "eliminated %d function applications in %.1f seconds",
            num_applies_total, delta);
  assert (btor_check_all_hash_tables_proxy_free_dbg (btor));
  assert (btor_check_all_hash_tables_simp_free_dbg (btor));
  assert (btor_check_unique_table_children_proxy_free_dbg (btor));
}
Exemplo n.º 25
0
static unsigned 
extract_lambdas (Btor * btor, BtorPtrHashTable * map_value_index,
                 BtorPtrHashTable * map_lambda_base)
{
  assert (btor);
  assert (map_value_index);
  assert (map_lambda_base);

  bool is_top_eq;
  BtorBitVector *inc;
  unsigned i_range, i_index, i_value, i_inc;
  BtorNode *subst, *base, *tmp, *array, *value, *lower, *upper; 
  BtorNode *src_array, *src_addr, *dst_addr;
  BtorHashTableIterator it, iit;
  BtorPtrHashTable *t, *index_value_map;
  BtorPtrHashBucket *b;
  BtorNodePtrStack ranges, indices, values, indices_itoi, indices_itoip1;
  BtorNodePtrStack indices_cpy, indices_rem, *stack;
  BtorBitVectorPtrStack increments;
  BtorMemMgr *mm;

  /* statistics */
  unsigned num_total = 0, num_writes = 0;
  unsigned num_set = 0, num_set_inc = 0, num_set_itoi = 0, num_set_itoip1 = 0;
  unsigned num_cpy = 0, size_set = 0, size_set_inc = 0, size_set_itoi = 0;
  unsigned size_set_itoip1 = 0, size_cpy = 0;

  mm = btor->mm;
  BTOR_INIT_STACK (ranges);
  BTOR_INIT_STACK (indices);
  BTOR_INIT_STACK (increments);
  BTOR_INIT_STACK (values);
  BTOR_INIT_STACK (indices_itoi);
  BTOR_INIT_STACK (indices_itoip1);
  BTOR_INIT_STACK (indices_cpy);
  BTOR_INIT_STACK (indices_rem);
  btor_init_node_hash_table_iterator (&it, map_value_index);
  while (btor_has_next_node_hash_table_iterator (&it))
    {
      t = it.bucket->data.asPtr;
      array = btor_next_node_hash_table_iterator (&it);
      assert (t);

      /* find memset patterns, the remaining unused indices are pushed onto
       * stack 'indices' */
      btor_init_node_hash_table_iterator (&iit, t);
      while (btor_has_next_node_hash_table_iterator (&iit))
        {
          stack = iit.bucket->data.asPtr;
          value = btor_next_node_hash_table_iterator (&iit);
          assert (stack);
          find_ranges (btor, stack, &ranges, &increments, &indices,
                       &num_set, &num_set_inc, &size_set, &size_set_inc);
          BTOR_RELEASE_STACK (mm, *stack);
          BTOR_DELETE (mm, stack);
          BTOR_PUSH_STACK (mm, ranges, 0);
          BTOR_PUSH_STACK (mm, indices, 0);
          BTOR_PUSH_STACK (mm, values, value);
          assert (BTOR_COUNT_STACK (ranges) - BTOR_COUNT_STACK (values) > 0
                  || BTOR_COUNT_STACK (indices) -
                         BTOR_COUNT_STACK (values) > 0);
          assert ((BTOR_COUNT_STACK (ranges) -
                       BTOR_COUNT_STACK (values)) % 2 == 0);
          assert ((BTOR_COUNT_STACK (ranges) -
                       BTOR_COUNT_STACK (values)) / 2 ==
                           BTOR_COUNT_STACK (increments)); 
        }

      /* choose base array for patterns/writes:
       *  1) write chains: base array of the write chains
       *  2) top eqs: a new UF symbol */
      if ((b = btor_find_in_ptr_hash_table (map_lambda_base, array)))
        {
          assert (BTOR_IS_LAMBDA_NODE (array));
          b = btor_find_in_ptr_hash_table (map_lambda_base, array);
          assert (b);
          subst = btor_copy_exp (btor, b->data.asPtr);
          is_top_eq = false;
        }
      else
        {
          assert (BTOR_IS_UF_ARRAY_NODE (array));
          subst = btor_array_exp (btor,
                                  btor_get_fun_exp_width (btor, array),
                                  btor_get_index_exp_width (btor, array),
                                  0);

          is_top_eq = true;
        }

      index_value_map = btor_new_ptr_hash_table (mm, 0, 0);
      base = subst;
      i_range = i_index = i_inc = 0;
      for (i_value = 0; i_value < BTOR_COUNT_STACK (values); i_value++)
        {
          value = BTOR_PEEK_STACK (values, i_value);

          /* create memset regions */
          for (; i_range < BTOR_COUNT_STACK (ranges) - 1; i_range += 2)
            {
              lower = BTOR_PEEK_STACK (ranges, i_range);
              /* next value */
              if (!lower)
                {
                  i_range++;
                  break;
                }
              upper = BTOR_PEEK_STACK (ranges, i_range + 1);
              assert (i_inc < BTOR_COUNT_STACK (increments));
              inc = BTOR_PEEK_STACK (increments, i_inc);
              tmp = create_pattern_memset (btor, lower, upper, value, subst,
                                           inc);
              tmp->is_array = 1;
              btor_release_exp (btor, subst);
              subst = tmp;
              btor_free_bv (mm, inc);
              i_inc++;
            }

          /* find patterns that are dependent on the current index */
          for (; i_index < BTOR_COUNT_STACK (indices); i_index++)
            {
              lower = BTOR_PEEK_STACK (indices, i_index);
              /* next value */
              if (!lower)
                {
                  i_index++;
                  break;
                }
              assert (!btor_find_in_ptr_hash_table (index_value_map,
                                                    lower));
              /* save index value pairs for later */
              btor_insert_in_ptr_hash_table (index_value_map,
                                             lower)->data.asPtr = value;

              /* pattern 1: index -> index */
              if (is_itoi_pattern (lower, value))
                BTOR_PUSH_STACK (mm, indices_itoi, lower);
              /* pattern 2: index -> index + 1 */
              else if (is_itoip1_pattern (lower, value))
                BTOR_PUSH_STACK (mm, indices_itoip1, lower);
              /* pattern 3: memcopy pattern */
              else if (is_cpy_pattern (lower, value))
                BTOR_PUSH_STACK (mm, indices_cpy, lower);
              else /* no pattern found */
                BTOR_PUSH_STACK (mm, indices_rem, lower);
            }
        }

      /* pattern: index -> index */
      BTOR_RESET_STACK (ranges);
      BTOR_RESET_STACK (increments);
      find_ranges (btor, &indices_itoi, &ranges, &increments, &indices_rem,
                   &num_set_itoi, 0, &size_set_itoi, 0);
      if (!BTOR_EMPTY_STACK (ranges))
        {
          assert (BTOR_COUNT_STACK (ranges) % 2 == 0);
          for (i_range = 0, i_inc = 0;
               i_range < BTOR_COUNT_STACK (ranges) - 1;
               i_range += 2, i_inc++)
            {
              lower = BTOR_PEEK_STACK (ranges, i_range);
              upper = BTOR_PEEK_STACK (ranges, i_range + 1);
              assert (i_inc < BTOR_COUNT_STACK (increments));
              inc = BTOR_PEEK_STACK (increments, i_inc);
              tmp = create_pattern_itoi (btor, lower, upper, subst, inc);
              tmp->is_array = 1;
              btor_release_exp (btor, subst);
              subst = tmp;
              btor_free_bv (mm, inc);
            }
        }

      /* pattern: index -> index + 1 */
      BTOR_RESET_STACK (ranges);
      BTOR_RESET_STACK (increments);
      find_ranges (btor, &indices_itoip1, &ranges, &increments, &indices_rem,
                   &num_set_itoip1, 0, &size_set_itoip1, 0);
      if (!BTOR_EMPTY_STACK (ranges))
        {
          assert (BTOR_COUNT_STACK (ranges) % 2 == 0);
          for (i_range = 0, i_inc = 0;
               i_range < BTOR_COUNT_STACK (ranges) - 1;
               i_range += 2, i_inc++)
            {
              lower = BTOR_PEEK_STACK (ranges, i_range);
              upper = BTOR_PEEK_STACK (ranges, i_range + 1);
              assert (i_inc < BTOR_COUNT_STACK (increments));
              inc = BTOR_PEEK_STACK (increments, i_inc);
              tmp = create_pattern_itoip1 (btor, lower, upper, subst, inc);
              tmp->is_array = 1;
              btor_release_exp (btor, subst);
              subst = tmp;
              btor_free_bv (mm, inc);
            }
        }

      /* pattern: memcopy */
      BTOR_RESET_STACK (ranges);
      BTOR_RESET_STACK (increments);
      find_ranges (btor, &indices_cpy, &ranges, &increments, &indices_rem,
                   &num_cpy, 0, &size_cpy, 0);
      if (!BTOR_EMPTY_STACK (ranges))
        {
          assert (base == subst);
          assert (BTOR_COUNT_STACK (ranges) % 2 == 0);
          for (i_range = 0, i_inc = 0;
               i_range < BTOR_COUNT_STACK (ranges) - 1;
               i_range += 2, i_inc++)
            {
              lower = BTOR_PEEK_STACK (ranges, i_range);
              upper = BTOR_PEEK_STACK (ranges, i_range + 1);
              assert (i_inc < BTOR_COUNT_STACK (increments));
              inc = BTOR_PEEK_STACK (increments, i_inc);
              b = btor_find_in_ptr_hash_table (index_value_map, lower);
              value = b->data.asPtr; 
              extract_cpy_src_dst_info (lower, value,
                                        &src_array, &src_addr, &dst_addr, 0);
              /* 'subst' == destination array */
              tmp = create_pattern_cpy (btor, lower, upper,
                                        src_array, subst,
                                        src_addr, dst_addr, inc);
              tmp->is_array = 1;
              btor_release_exp (btor, subst);
              subst = tmp;
              btor_free_bv (mm, inc);
            }
        }

      num_total = num_set + num_set_inc + num_set_itoi + num_set_itoip1 +
                  num_cpy;

      /* we can skip creating writes if we did not find any pattern in a write
       * chain, and thus can leave the write chain as-is.
       * for the top equality case we always have to create writes since we
       * convert top level equalities to writes. */
      if (is_top_eq || num_total > 0)
        {
          /* no pattern found for indices in 'indices_rem'. create writes */
          for (i_index = 0; i_index < BTOR_COUNT_STACK (indices_rem); i_index++)
            {
              lower = BTOR_PEEK_STACK (indices_rem, i_index);
              b = btor_find_in_ptr_hash_table (index_value_map, lower);
              assert (b);
              value = b->data.asPtr;
              tmp = btor_write_exp (btor, subst, lower, value);
              btor_release_exp (btor, subst);
              subst = tmp;
              num_writes++;
            }
        }

      assert ((is_top_eq || num_total > 0) || base == subst);
      if (base != subst)
        btor_insert_substitution (btor, array, subst, 0);
      btor_release_exp (btor, subst);

      btor_delete_ptr_hash_table (index_value_map);
      btor_delete_ptr_hash_table (t);
      BTOR_RESET_STACK (ranges);
      BTOR_RESET_STACK (indices);
      BTOR_RESET_STACK (values);
      BTOR_RESET_STACK (increments);
      BTOR_RESET_STACK (indices_itoi);
      BTOR_RESET_STACK (indices_itoip1);
      BTOR_RESET_STACK (indices_cpy);
      BTOR_RESET_STACK (indices_rem);
    }
  BTOR_RELEASE_STACK (mm, ranges);
  BTOR_RELEASE_STACK (mm, indices);
  BTOR_RELEASE_STACK (mm, values);
  BTOR_RELEASE_STACK (mm, increments);
  BTOR_RELEASE_STACK (mm, indices_itoi);
  BTOR_RELEASE_STACK (mm, indices_itoip1);
  BTOR_RELEASE_STACK (mm, indices_cpy);
  BTOR_RELEASE_STACK (mm, indices_rem);

  BTOR_MSG (btor->msg, 1,
            "set: %u (%u), "
            "set_inc: %u (%u), "
            "set_itoi: %u (%u), "
            "set_itoip1: %u (%u), "
            "cpy: %u (%u)",
            num_set, size_set,
            num_set_inc, size_set_inc,
            num_set_itoi, size_set_itoi,
            num_set_itoip1, size_set_itoip1,
            num_cpy, size_cpy);
  return num_total;
}
Exemplo n.º 26
0
/*
 *
 * 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;
}
Exemplo n.º 27
0
static BtorNode *
parse_anext (BtorBTORParser * parser, int len)
{
  int idx, current_idx_len, idx_len;
  BtorNode * current, * next;
  Info info;

  if (parse_space (parser))
    return 0;

  if (parse_positive_int (parser, &idx_len))
    return 0;

  if (parse_space (parser))
    return 0;

  if (parse_positive_int (parser, &idx))
    return 0;

  if (idx >= BTOR_COUNT_STACK (parser->exps) ||
      !(current = parser->exps.start[idx]))
    {
      (void) btor_perr_btor (parser, "invalid next index %d", idx);
      return 0;
    }

  info = parser->info.start[idx];
  if (!info.array)
    {
      (void) btor_perr_btor (parser, "next index %d is not an array", idx);
      return 0;
    }

  if (info.next)
    {
      (void) btor_perr_btor (parser, "next index %d already used", idx);
      return 0;
    }

  if (parse_space (parser))
    return 0;

  assert (btor_is_array_exp (parser->btor, current));
  if (!(next = parse_array_exp (parser, len)))
    return 0;

  current_idx_len = btor_get_index_exp_len (parser->btor, current);
  if (idx_len != current_idx_len)
    {
      btor_release_exp (parser->btor, next);
      (void) btor_perr_btor (parser,
			  "arrays with different index width %d and %d",
			  current_idx_len, idx_len);
      return 0;
    }

  BTOR_PUSH_STACK (parser->mem, parser->regs, current);
  BTOR_PUSH_STACK (parser->mem, parser->nexts, next);
  parser->info.start[idx].next = 1;

  return next;
}
Exemplo n.º 28
0
static BtorNode *
parse_compare_and_overflow (BtorBTORParser * parser,
			    int len, Binary f, int can_be_array)
{
  BtorNode *l, *r, *res;
  int llen, rlen;

  if (len != 1)
    {
      (void) btor_perr_btor (parser,
			  "comparison or overflow operator returns %d bits",
			  len);
      return 0;
    }

  if (parse_space (parser))
    return 0;

  if (!(l = parse_exp (parser, 0, can_be_array)))
    return 0;

  if (parse_space (parser))
    {
    RELEASE_L_AND_RETURN_ERROR:
      btor_release_exp (parser->btor, l);
      return 0;
    }

  if (!(r = parse_exp (parser, 0, can_be_array)))
    goto RELEASE_L_AND_RETURN_ERROR;

  llen = btor_get_exp_len (parser->btor, l);
  rlen = btor_get_exp_len (parser->btor, r);

  if (llen != rlen)
    {
      (void)
	btor_perr_btor (parser,
		     "operands have different bit width %d and %d",
		     llen, rlen);
RELEASE_L_AND_R_AND_RETURN_ZERO:
      btor_release_exp (parser->btor, r);
      btor_release_exp (parser->btor, l);
      return 0;
    }

  if (can_be_array)
    {
      if (btor_is_array_exp (parser->btor, l) &&
	  !btor_is_array_exp (parser->btor, r))
	{
	  (void) btor_perr_btor (parser,
				 "first operand is array and second not");
	  goto RELEASE_L_AND_R_AND_RETURN_ZERO;
	}

      if (!btor_is_array_exp (parser->btor, l) &&
	  btor_is_array_exp (parser->btor, r))
	{
	  (void) btor_perr_btor (parser,
				 "second operand is array and first not");
	  goto RELEASE_L_AND_R_AND_RETURN_ZERO;
	}

      if (btor_is_array_exp (parser->btor, l) &&
	  btor_is_array_exp (parser->btor, r))
	{
	  llen = btor_get_index_exp_len (parser->btor, l);
	  rlen = btor_get_index_exp_len (parser->btor, r);

	  if (llen != rlen)
	    {
	      (void) btor_perr_btor (
		       parser,
		       "array operands have different index width %d and %d",
		       llen, rlen);
	      goto RELEASE_L_AND_R_AND_RETURN_ZERO;
	    }
	}
    }

  res = f (parser->btor, l, r);

  btor_release_exp (parser->btor, r);
  btor_release_exp (parser->btor, l);

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

  return res;
}