/*
 * Add t to buffer b
 * - t must be defined in table and be a bitvector term of same bitsize as b
 * - b->ptbl must be the same as table->pprods
 */
void bvarith_buffer_add_term(bvarith_buffer_t *b, term_table_t *table, term_t t) {
  pprod_t **v;
  bvpoly_t *p;
  int32_t i;

  assert(b->ptbl == table->pprods);
  assert(pos_term(t) && good_term(table, t) && is_bitvector_term(table, t) &&
         term_bitsize(table, t) == b->bitsize);

  i = index_of(t);
  switch (table->kind[i]) {
  case POWER_PRODUCT:
    bvarith_buffer_add_pp(b, pprod_for_idx(table, i));
    break;

  case BV_CONSTANT:
    bvarith_buffer_add_const(b, bvconst_for_idx(table, i)->data);
    break;

  case BV_POLY:
    p = bvpoly_for_idx(table, i);
    v = pprods_for_bvpoly(table, p);
    bvarith_buffer_add_bvpoly(b, p, v);
    term_table_reset_pbuffer(table);
    break;

  default:
    bvarith_buffer_add_var(b, t);
    break;
  }
}
/*
 * Multiply b by t^d
 * - t must be an arithmetic term
 * - p->ptbl and table->pprods must be equal
 */
void bvarith_buffer_mul_term_power(bvarith_buffer_t *b, term_table_t *table, term_t t, uint32_t d) {
  bvarith_buffer_t aux;
  bvconstant_t c;
  bvpoly_t *p;
  pprod_t **v;
  pprod_t *r;
  int32_t i;

  assert(b->ptbl == table->pprods);
  assert(pos_term(t) && good_term(table, t) && is_bitvector_term(table, t) &&
         term_bitsize(table, t) == b->bitsize);

  i = index_of(t);
  switch (table->kind[i]) {
  case POWER_PRODUCT:
    r = pprod_exp(b->ptbl, pprod_for_idx(table, i), d); // r = t^d
    bvarith_buffer_mul_pp(b, r);
    break;

  case BV_CONSTANT:
    init_bvconstant(&c);
    bvconstant_copy64(&c, b->bitsize, 1); // c := 1
    bvconst_mulpower(c.data, b->width, bvconst_for_idx(table, i)->data, d); // c := t^d
    bvarith_buffer_mul_const(b, c.data);
    delete_bvconstant(&c);
    break;

  case BV_POLY:
    p = bvpoly_for_idx(table, i);
    v = pprods_for_bvpoly(table, p);
    init_bvarith_buffer(&aux, b->ptbl, b->store);
    bvarith_buffer_mul_bvpoly_power(b, p, v, d, &aux);
    delete_bvarith_buffer(&aux);
    term_table_reset_pbuffer(table);
    break;

  default:
    r = pprod_varexp(b->ptbl, t, d);
    bvarith_buffer_mul_pp(b, r);
    break;
  }
}
/*
 * Add a * t to b
 * - t must be defined in table and be a bitvector term of same bitsize as b
 * - a must be have the same bitsize as b (as many words a b->width)
 * - b->ptbl must be the same as table->pprods
 */
void bvarith_buffer_add_const_times_term(bvarith_buffer_t *b, term_table_t *table, uint32_t *a, term_t t) {
  bvconstant_t c;
  pprod_t **v;
  bvpoly_t *p;
  int32_t i;

  assert(b->ptbl == table->pprods);
  assert(pos_term(t) && good_term(table, t) && is_bitvector_term(table, t) &&
         term_bitsize(table, t) == b->bitsize);

  i = index_of(t);
  switch (table->kind[i]) {
  case POWER_PRODUCT:
    bvarith_buffer_add_mono(b, a, pprod_for_idx(table, i));
    break;

  case BV_CONSTANT:
    init_bvconstant(&c);
    bvconstant_copy(&c, b->bitsize, bvconst_for_idx(table, i)->data);
    bvconst_mul(c.data, b->width, a);
    bvarith_buffer_add_const(b, c.data);
    delete_bvconstant(&c);
    break;

  case BV_POLY:
    p = bvpoly_for_idx(table, i);
    v = pprods_for_bvpoly(table, p);
    bvarith_buffer_add_const_times_bvpoly(b, p, v, a);
    term_table_reset_pbuffer(table);
    break;

  default:
    bvarith_buffer_add_varmono(b, a, t);
    break;
  }
}
Exemple #4
0
/*
 * Check whether t occurs in v
 * - t must be a free root
 * - v must be a valid term
 */
static bool bfs_occurs_check(intern_tbl_t *tbl, term_t t, term_t v) {
  term_table_t *terms;
  int_queue_t *queue;
  int_hset_t *cache;
  int32_t x;
  bool found;

  assert(intern_tbl_root_is_free(tbl, t));
  assert(is_pos_term(t) && term_kind(tbl->terms, t) == UNINTERPRETED_TERM);

  terms = tbl->terms;
  queue = intern_tbl_get_queue(tbl);
  cache = intern_tbl_get_cache(tbl);

  assert(int_queue_is_empty(queue) && int_hset_is_empty(cache));

  bfs_visit_term(tbl, v);
  found = false;

  do {
    x = int_queue_pop(queue);

    switch (kind_for_idx(terms, x)) {
    case CONSTANT_TERM:
    case ARITH_CONSTANT:
    case BV64_CONSTANT:
    case BV_CONSTANT:
    case VARIABLE:
      break;

    case UNINTERPRETED_TERM:
      if (x == index_of(t)) {
        // found a cycle
        found = true;
        goto done;
      }
      break;

    case ARITH_EQ_ATOM:
    case ARITH_GE_ATOM:
      bfs_visit_term(tbl, integer_value_for_idx(terms, x));
      break;

    case ITE_TERM:
    case ITE_SPECIAL:
    case APP_TERM:
    case UPDATE_TERM:
    case TUPLE_TERM:
    case EQ_TERM:
    case DISTINCT_TERM:
    case FORALL_TERM:
    case LAMBDA_TERM:
    case OR_TERM:
    case XOR_TERM:
    case ARITH_BINEQ_ATOM:
    case BV_ARRAY:
    case BV_DIV:
    case BV_REM:
    case BV_SDIV:
    case BV_SREM:
    case BV_SMOD:
    case BV_SHL:
    case BV_LSHR:
    case BV_ASHR:
    case BV_EQ_ATOM:
    case BV_GE_ATOM:
    case BV_SGE_ATOM:
      bfs_visit_composite(tbl, composite_for_idx(terms, x));
      break;

    case BIT_TERM:
    case SELECT_TERM:
      bfs_visit_term(tbl, select_for_idx(terms, x)->arg);
      break;

    case POWER_PRODUCT:
      bfs_visit_pprod(tbl, pprod_for_idx(terms, x));
      break;

    case ARITH_POLY:
      bfs_visit_poly(tbl, polynomial_for_idx(terms, x));
      break;

    case BV64_POLY:
      bfs_visit_bvpoly64(tbl, bvpoly64_for_idx(terms, x));
      break;

    case BV_POLY:
      bfs_visit_bvpoly(tbl, bvpoly_for_idx(terms, x));
      break;

    default:
      assert(false);
      abort();
      break;
    }

  } while (! int_queue_is_empty(queue));

 done:
  int_hset_reset(cache);
  int_queue_reset(queue);

  return found;
}