Exemplo n.º 1
0
/*
 * Expanded form for a product c * p
 * - c is a normalized bitvector constant
 * - p is a power product stored in a pp_buffer object
 * - n = bitsize of p
 * - the expansion is returned in a bvarith_buffer or bvarith64_buffer object
 * - the result is normalized
 */
void expand_bvpprod64(bvexp_table_t *table, bvarith64_buffer_t *buffer, pp_buffer_t *p, uint32_t n, uint64_t c) {
  bv_vartable_t *vtbl;
  bvmlist64_t *q;
  pp_buffer_t *aux;
  pprod_t *r;
  uint64_t a;
  uint32_t i, m, e, d;
  thvar_t x;

  assert(buffer->store == &table->store64 && buffer->ptbl == &table->pprods);

  bvarith64_buffer_prepare(buffer, n);
  bvarith64_buffer_set_one(buffer);
  aux = p;

  vtbl = table->vtbl;

  if (total_degree_test64(table, vtbl, p)) {
    /*
     * Expansion of c * x_1^d_1 ... x_n^ d_n:
     * - for a constant x_i, update c to c * a^d_i (where a = value of c)
     * - if x_i is expanded to q_i, update buffer to buffer * q_i ^ d_i
     * - otherwise, x_i^d_i is copied into the aux buffer
     */
    aux = &table->pp;
    pp_buffer_reset(aux);

    m = p->len;
    for (i=0; i<m; i++) {
      x = p->prod[i].var;
      d = p->prod[i].exp;
      if (bvvar_is_const64(vtbl, x)) {
        a = bvvar_val64(vtbl, x);
        c *= upower64(a, d);
      } else {
        q = bvexp_def64(table, x);
        if (q != NULL && mlist64_is_short(q, &e) && d * e <= BVEXP_DEGREE_LIMIT) {
          // replace x^d by q^d in buffer
          bvarith64_buffer_mul_mlist_power(buffer, q, d, &table->aux64);
        } else {
          // copy x^d into aux
          pp_buffer_mul_varexp(aux, x, d);
        }
      }
    }

    c = norm64(c, n);
    pp_buffer_normalize(aux);
  }

  /*
   * The result is c * aux * buffer
   */
  r = pprod_from_buffer(&table->pprods, aux);
  bvarith64_buffer_mul_mono(buffer, c, r);
  bvarith64_buffer_normalize(buffer);
}
Exemplo n.º 2
0
void expand_bvpprod(bvexp_table_t *table, bvarith_buffer_t *buffer, pp_buffer_t *p, uint32_t n, uint32_t *c) {
  bv_vartable_t *vtbl;
  bvmlist_t *q;
  pp_buffer_t *aux;
  pprod_t *r;
  uint32_t *a;
  uint32_t i, m, d, e, k;
  thvar_t x;


  assert(buffer->store == &table->store && buffer->ptbl == &table->pprods);

  bvarith_buffer_prepare(buffer, n);
  bvarith_buffer_set_one(buffer);
  aux = p;

  vtbl = table->vtbl;

  if (total_degree_test(table, vtbl, p)) {
    aux = &table->pp;
    pp_buffer_reset(aux);

    // make a copy of c in the internal bvconst buffer
    bvconstant_copy(&table->bvconst, n, c);
    c = table->bvconst.data;

    k = (n + 31) >> 5;
    m = p->len;
    for (i=0; i<m; i++) {
      x = p->prod[i].var;
      d = p->prod[i].exp;
      if (bvvar_is_const(vtbl, x)) {
        a = bvvar_val(vtbl, x);
        bvconst_mulpower(c, k, a, d);
      } else {
        q = bvexp_def(table, x);
        if (q != NULL && mlist_is_short(q, &e) && d * e <= BVEXP_DEGREE_LIMIT) {
          bvarith_buffer_mul_mlist_power(buffer, q, d, &table->aux);
        } else {
          pp_buffer_mul_varexp(aux, x, d);
        }
      }
    }

    // normalize
    bvconst_normalize(c, n);
    pp_buffer_normalize(aux);
  }

  /*
   * The result is c * aux * buffer
   */
  r = pprod_from_buffer(&table->pprods, aux);
  bvarith_buffer_mul_mono(buffer, c, r);
  bvarith_buffer_normalize(buffer);
}
Exemplo n.º 3
0
/*
 * Empty the table
 */
void reset_bvexp_table(bvexp_table_t *table) {
  bvexp_table_remove_vars(table, 0);

  /*
   * The two aux buffers must be deleted first since their content may become
   * invalid pointers afer the reset_objstore calls. Just calling
   * bvarith..._prepare is not enough as it keeps the end_marker in
   * table->aux/table->aux64.
   */
  delete_bvarith_buffer(&table->aux);
  delete_bvarith64_buffer(&table->aux64);
  pp_buffer_reset(&table->pp);

  reset_objstore(&table->store);
  reset_objstore(&table->store64);
  reset_pprod_table(&table->pprods);

  // Recreate the buffers aux and aux64
  init_bvarith_buffer(&table->aux, &table->pprods, &table->store);
  init_bvarith64_buffer(&table->aux64, &table->pprods, &table->store64);
}
Exemplo n.º 4
0
int main() {
  pprod_t *p1, *p2;
  uint32_t i, j;
  int32_t cmp;

  p[0] = empty_pp;
  p[1] = var_pp(0);
  p[2] = var_pp(1);
  p[3] = var_pp(0x3fffffff);

  init_pp_buffer(&buffer, 0);
  p[4] = pp_buffer_getprod(&buffer);  // empty

  pp_buffer_reset(&buffer);
  pp_buffer_mul_var(&buffer, 0);
  p[5] = pp_buffer_getprod(&buffer); // x_0

  pp_buffer_reset(&buffer);
  pp_buffer_mul_var(&buffer, 0);
  pp_buffer_mul_var(&buffer, 1);
  pp_buffer_mul_var(&buffer, 0);
  p[6] = pp_buffer_getprod(&buffer);  // x_0^2 x_1

  pp_buffer_reset(&buffer);
  pp_buffer_mul_varexp(&buffer, 1, 2);
  pp_buffer_mul_varexp(&buffer, 4, 3);
  p[7] = pp_buffer_getprod(&buffer);  // x_1^2 x_4^3

  pp_buffer_set_varexp(&buffer, 3, 2);
  pp_buffer_mul_varexp(&buffer, 1, 4);
  p[8] = pp_buffer_getprod(&buffer);   // x_3^2 x_1^4

  pp_buffer_set_pprod(&buffer, p[7]);
  pp_buffer_mul_pprod(&buffer, p[1]);
  pp_buffer_mul_pprod(&buffer, p[8]);
  p[9] = pp_buffer_getprod(&buffer);

  for (i=0; i<NUM_PRODS; i++) {
    printf("p[%"PRIu32"] =  ", i);
    print_pprod(stdout, p[i]);
    printf(" total degree = %"PRIu32"\n", pprod_degree(p[i]));
    for (j=0; j<5; j++) {
      printf(" degree of x_%"PRIu32" = %"PRIu32"\n", j, pprod_var_degree(p[i], j));
    }
    printf("----\n");
  }
  printf("\n");

  for (i=0; i<NUM_PRODS; i++) {
    p1 = p[i];
    for (j=0; j<NUM_PRODS; j++) {
      p2 = p[j];
      printf("p1: ");
      print_pprod0(stdout, p1);
      printf("p2: ");
      print_pprod0(stdout, p2);
      if (pprod_equal(p1, p2)) {
	printf("equal products\n");
      }
      if (pprod_divides(p1, p2)) {
	printf("p1 divides p2\n");
      }
      if (pprod_divisor(&buffer, p1, p2)) {
	printf("p2/p1: ");
	print_pp_buffer0(stdout, &buffer);
      }
      if (pprod_divides(p2, p1)) {
	printf("p2 divides p1\n");
      }
      if (pprod_divisor(&buffer, p2, p1)) {
	printf("p1/p2: ");
	print_pp_buffer0(stdout, &buffer);
      }
      cmp = pprod_lex_cmp(p1, p2);
      if (cmp < 0) {
	printf("p1 < p2 in lex order\n");
      } else if (cmp > 0) {
	printf("p1 > p2 in lex order\n");
      } else {
	printf("p1 = p2 in lex order\n");
      }
      if (pprod_precedes(p1, p2)) {
	printf("p1 < p2 in deglex ordering\n");
      }
      if (pprod_precedes(p2, p1)) {
	printf("p2 < p1 in deglex ordering\n");
      }
      printf("----\n");
    }
  }


  for (i=0; i<10; i++) {
    free_pprod(p[i]);
  }

  delete_pp_buffer(&buffer);

  return 0;
}