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;
}
Beispiel #2
0
// Construct ZDD of sets containing exactly 1 occurrence of digit d in row r.
// For instance, if d = 3, r = 0:
//
//   1 === 2 === 3
//   3 ... 4a, --- 4b
//   4a === 5a === ... === 9a === ... === 11a === 12
//   4b === 5b === ... === 9b === ... === 11b === 13b
//   12 ... 13a, --- 13b
//   13a === ... === 20a === 21
//   13b === ... === 20b === 22b
// and so on until:
//   74a === 75 ... F, --- 76
//   74b === 76
//   76 === ... === 729 === T
//
// This ZDD has 9*2^720 members.
// When intersected with the one-digit-per-box set, the result has
// 9*8^8*9^72 members. (Pick 1 of 9 positions ford, leaving 8 possible choices
// forthe remaining 8 boxes in that row. The other 81 - 9 boxes can contain
// any single digitS.)
// The intersection forall d and a fixed r has 9!*9^72 members.
// The intersection forall r and a fixed d has 9^9*8^72 members.
void unique_digit_per_row(int d, int r) {
    zdd_push();
    // The order is determined by sorting by number, then by letter.
    int next = 81 * r + d;  // The next node involving the digit d.
    int v = 1;
    int state = 0;
    while (v <= 729) {
        if (v == next) {
            next += 9;
            state++;
            if (state == 1) {
                // The first split in the ZDD.
                zdd_add_node(v, 1, 2);
            } else if (state < 9) {
                // Fix previous node. We must not have a second occurrence of d.
                uint32_t n = zdd_last_node();
                zdd_set_hilo(n, n + 3);
                // If this is the first occurrence of d, we're on notice.
                zdd_add_node(v, 1, 2);
            } else {
                // If we never saw d, then branch to FALSE.
                // Otherwise reunite the branches.
                zdd_add_node(v, 0, 1);
                next = -1;
            }
        } else if (state == 0 || state == 9) {
            zdd_add_node(v, 1, 1);
        } else {
            zdd_add_node(v, 2, 2);
            zdd_add_node(v, 2, 2);
        }
        v++;
    }
    // Fix last nodes.
    uint32_t n = zdd_last_node();
    if (zdd_lo(n - 1) > n) zdd_set_lo(n - 1, 1);
    if (zdd_hi(n - 1) > n) zdd_set_hi(n - 1, 1);
    if (zdd_lo(n) > n) zdd_set_lo(n, 1);
    if (zdd_hi(n) > n) zdd_set_hi(n, 1);
}
Beispiel #3
0
// Construct ZDD of sets containing all elements in the given list.
// The list is terminated by -1.
void contains_all(int *list) {
    zdd_push();
    int v = 1;
    int *next = list;
    while (v <= 729) {
        if (v == *next) {
            next++;
            zdd_add_node(v, 0, 1);
        } else {
            zdd_add_node(v, 1, 1);
        }
        v++;
    }
    // Fix 729.
    uint32_t n = zdd_last_node();
    if (zdd_lo(n) > n) zdd_set_lo(n, 1);
    if (zdd_hi(n) > n) zdd_set_hi(n, 1);
}
static zddp minhit_nonsup_rec(zddp f, my_hash *h)
{
  if(f == zdd_bot()) return zdd_top();
  if(f == zdd_top()) return zdd_bot();

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

  zddp t  = zdd_union(zdd_lo(f), zdd_hi(f));
  ENSURE_TRUE_MSG(t != BDD_NULL, "ZDD operation failed");

  INC_RECDEPTH(recdepth);  
  zddp r0 = minhit_nonsup_rec(t, h);
  zddp tt = minhit_nonsup_rec(zdd_lo(f), h);
  DEC_RECDEPTH(recdepth);

  zddp r1 = nonsup(tt, r0);
  ENSURE_TRUE_MSG(r1 != BDD_NULL, "ZDD extra operation failed");
  r = zdd_node(zdd_itemval(f), r0, r1);
  ENSURE_TRUE_MSG(r  != BDD_NULL, "ZDD operation failed");

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