static bddp hit_z2b_rec(zddp f, my_hash *h)
{
  if(f == zdd_top()) return bdd_bot();
  if(f == zdd_bot()) return bdd_top();

  bddp r;
  if(ht_search((uintptr_t)f, (uintptr_t*)&r, h)) return r;

  INC_RECDEPTH(recdepth);  
  bddp r0 = hit_z2b_rec(zdd_lo(f), h);
  bddp r1 = hit_z2b_rec(zdd_hi(f), h);
  DEC_RECDEPTH(recdepth);

  bddp t = bdd_node(zdd_itemval(f), r1, bdd_top());
  ENSURE_TRUE_MSG(t != BDD_NULL, "BDD operation failed");
  r = bdd_and(r0, t);
  ENSURE_TRUE_MSG(r != BDD_NULL, "BDD operation failed");

  ht_insert((uintptr_t)f, (uintptr_t)r, h);

#ifdef SIZE_LOG
  const uintmax_t insize  = zdd_size(f);
  const uintmax_t outsize = bdd_size(r);
  fprintf(sizelog, "%ju\t%ju\n", insize, outsize);
  if(maxsize < outsize) maxsize = outsize;
#endif /*SIZE_LOG*/

  return r;
}
Exemple #2
0
void zdd_count(mpz_ptr z) {
  uint32_t r = zdd_root(), s = zdd_size();
  mpz_ptr *count = malloc(sizeof(*count) * s);
  for(int i = 0; i < s; i++) count[i] = NULL;
  // Count elements in ZDD rooted at node n.
  mpz_ptr get_count(uint32_t n) {
    if (count[n]) return count[n];
    count[n] = malloc(sizeof(mpz_t));
    mpz_init(count[n]);
    if (n <= 1) {
      mpz_set_ui(count[n], n);
      return count[n];
    }
    uint32_t x = pool[n]->lo;
    uint32_t y = pool[n]->hi;
    x = 1 >= x ? x : x - r + 2;
    y = 1 >= y ? y : y - r + 2;
    mpz_add(count[n], get_count(x), get_count(y));
    return count[n];
  }
  r = 1 >= r ? r : 2;
  mpz_set(z, get_count(r));
  for(int i = 0; i < s; i++) {
    if (count[i]) {
      mpz_clear(count[i]);
      free(count[i]);
    }
  }
}
Exemple #3
0
// Compute 0, 1, 2 power sums of sizes of sets.
void zdd_count_2(restrict mpz_ptr z0,
                 restrict mpz_ptr z1,
		 restrict mpz_ptr z2) {
  uint32_t r = zdd_root(), s = zdd_size();
  restrict mpz_ptr *t0 = malloc(sizeof(*t0) * s);
  restrict mpz_ptr *t1 = malloc(sizeof(*t1) * s);
  restrict mpz_ptr *t2 = malloc(sizeof(*t2) * s);
  for(int i = 0; i < s; i++) t0[i] = NULL;
  // Count elements in ZDD rooted at node n.
  // Along with t1 size of solutions.
  mpz_ptr recurse(uint32_t n) {
    if (t0[n]) return t0[n];
    t0[n] = malloc(sizeof(mpz_t));
    mpz_init(t0[n]);
    t1[n] = malloc(sizeof(mpz_t));
    mpz_init(t1[n]);
    t2[n] = malloc(sizeof(mpz_t));
    mpz_init(t2[n]);
    if (n <= 1) {
      // t0[1] should be 1.
      mpz_set_ui(t0[n], n);
      // t1[n], t2[n] should be zero.
      // Another reason why 0^0 = 1.
      return t0[n];
    }
    uint32_t x = pool[n]->lo;
    uint32_t y = pool[n]->hi;
    x = 1 >= x ? x : x - r + 2;
    y = 1 >= y ? y : y - r + 2;
    mpz_add(t0[n], recurse(x), recurse(y));
    mpz_add(t1[n], t1[x], t1[y]);
    mpz_add(t1[n], t1[n], t0[y]);
    mpz_add(t2[n], t2[x], t2[y]);
    mpz_addmul_ui(t2[n], t1[y], 2);
    mpz_add(t2[n], t2[n], t0[y]);
    return t0[n];
  }

  r = 1 >= r ? r : 2;
  mpz_set(z0, recurse(r));
  mpz_set(z1, t1[r]);
  mpz_set(z2, t2[r]);
  for(int i = 0; i < s; i++) {
    if (t0[i]) {
      mpz_clear(t0[i]);
      free(t0[i]);
      mpz_clear(t1[i]);
      free(t1[i]);
      mpz_clear(t2[i]);
      free(t2[i]);
    }
  }
}
Exemple #4
0
void zdd_count_1(restrict mpz_ptr z0, restrict mpz_ptr z1) {
  uint32_t r = zdd_root(), s = zdd_size();
  restrict mpz_ptr *count = malloc(sizeof(*count) * s);
  restrict mpz_ptr *total = malloc(sizeof(*total) * s);
  for(int i = 0; i < s; i++) count[i] = NULL;
  // Count elements in ZDD rooted at node n.
  // Along with total size of solutions.
  mpz_ptr get_count(uint32_t n) {
    if (count[n]) return count[n];
    count[n] = malloc(sizeof(mpz_t));
    mpz_init(count[n]);
    total[n] = malloc(sizeof(mpz_t));
    mpz_init(total[n]);
    if (n <= 1) {
      mpz_set_ui(count[n], n);
      // total[n] should be zero.
      return count[n];
    }
    uint32_t x = pool[n]->lo;
    uint32_t y = pool[n]->hi;
    x = 1 >= x ? x : x - r + 2;
    y = 1 >= y ? y : y - r + 2;
    mpz_add(count[n], get_count(x), get_count(y));
    mpz_add(total[n], total[x], total[y]);
    mpz_add(total[n], total[n], count[y]);
    return count[n];
  }

  r = 1 >= r ? r : 2;
  mpz_set(z0, get_count(r));
  mpz_set(z1, total[r]);
  for(int i = 0; i < s; i++) {
    if (count[i]) {
      mpz_clear(count[i]);
      free(count[i]);
      mpz_clear(total[i]);
      free(total[i]);
    }
  }
}