00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "espresso.h"
00015
00016 static pset_family abs_covered();
00017 static pset_family abs_covered_many();
00018 static int abs_select_restricted();
00019
00020 pcover map_cover_to_unate(T)
00021 pcube *T;
00022 {
00023 register unsigned int word_test, word_set, bit_test, bit_set;
00024 register pcube p, pA;
00025 pset_family A;
00026 pcube *T1;
00027 int ncol, i;
00028
00029 A = sf_new(CUBELISTSIZE(T), cdata.vars_unate);
00030 A->count = CUBELISTSIZE(T);
00031 foreachi_set(A, i, p) {
00032 (void) set_clear(p, A->sf_size);
00033 }
00034 ncol = 0;
00035
00036 for(i = 0; i < cube.size; i++) {
00037 if (cdata.part_zeros[i] > 0) {
00038 assert(ncol <= cdata.vars_unate);
00039
00040
00041 word_test = WHICH_WORD(i);
00042 bit_test = 1 << WHICH_BIT(i);
00043 word_set = WHICH_WORD(ncol);
00044 bit_set = 1 << WHICH_BIT(ncol);
00045
00046 pA = A->data;
00047 for(T1 = T+2; (p = *T1++) != 0; ) {
00048 if ((p[word_test] & bit_test) == 0) {
00049 pA[word_set] |= bit_set;
00050 }
00051 pA += A->wsize;
00052 }
00053
00054 ncol++;
00055 }
00056 }
00057
00058 return A;
00059 }
00060
00061 pcover map_unate_to_cover(A)
00062 pset_family A;
00063 {
00064 register int i, ncol, lp;
00065 register pcube p, pB;
00066 int var, nunate, *unate;
00067 pcube last;
00068 pset_family B;
00069
00070 B = sf_new(A->count, cube.size);
00071 B->count = A->count;
00072
00073
00074 unate = ALLOC(int, cube.num_vars);
00075 nunate = 0;
00076 for(var = 0; var < cube.num_vars; var++) {
00077 if (cdata.is_unate[var]) {
00078 unate[nunate++] = var;
00079 }
00080 }
00081
00082
00083 pB = B->data;
00084 foreach_set(A, last, p) {
00085
00086
00087 INLINEset_fill(pB, cube.size);
00088
00089
00090
00091
00092
00093 for(ncol = 0; ncol < nunate; ncol++) {
00094 if (is_in_set(p, ncol)) {
00095 lp = cube.last_part[unate[ncol]];
00096 for(i = cube.first_part[unate[ncol]]; i <= lp; i++) {
00097 if (cdata.part_zeros[i] == 0) {
00098 set_remove(pB, i);
00099 }
00100 }
00101 }
00102 }
00103 pB += B->wsize;
00104 }
00105
00106 FREE(unate);
00107 return B;
00108 }
00109
00110
00111
00112
00113
00114 pset_family unate_compl(A)
00115 pset_family A;
00116 {
00117 register pset p, last;
00118
00119
00120
00121
00122 foreach_set(A, last, p) {
00123 PUTSIZE(p, set_ord(p));
00124 }
00125
00126
00127 A = unate_complement(A);
00128
00129
00130 A = sf_rev_contain(A);
00131 return A;
00132 }
00133
00134
00135
00136
00137
00138 pset_family unate_complement(A)
00139 pset_family A;
00140 {
00141 pset_family Abar;
00142 register pset p, p1, restrict;
00143 register int i;
00144 int max_i, min_set_ord, j;
00145
00146
00147 if (A->count == 0) {
00148 sf_free(A);
00149 Abar = sf_new(1, A->sf_size);
00150 (void) set_clear(GETSET(Abar, Abar->count++), A->sf_size);
00151
00152
00153 } else if (A->count == 1) {
00154 p = A->data;
00155 Abar = sf_new(A->sf_size, A->sf_size);
00156 for(i = 0; i < A->sf_size; i++) {
00157 if (is_in_set(p, i)) {
00158 p1 = set_clear(GETSET(Abar, Abar->count++), A->sf_size);
00159 set_insert(p1, i);
00160 }
00161 }
00162 sf_free(A);
00163
00164 } else {
00165
00166
00167
00168
00169 restrict = set_new(A->sf_size);
00170 min_set_ord = A->sf_size + 1;
00171 foreachi_set(A, i, p) {
00172 if (SIZE(p) < min_set_ord) {
00173 set_copy(restrict, p);
00174 min_set_ord = SIZE(p);
00175 } else if (SIZE(p) == min_set_ord) {
00176 set_or(restrict, restrict, p);
00177 }
00178 }
00179
00180
00181 if (min_set_ord == 0) {
00182 A->count = 0;
00183 Abar = A;
00184
00185
00186 } else if (min_set_ord == 1) {
00187 Abar = unate_complement(abs_covered_many(A, restrict));
00188 sf_free(A);
00189 foreachi_set(Abar, i, p) {
00190 set_or(p, p, restrict);
00191 }
00192
00193
00194 } else {
00195 max_i = abs_select_restricted(A, restrict);
00196
00197
00198
00199
00200
00201 Abar = unate_complement(abs_covered(A, max_i));
00202 foreachi_set(Abar, i, p) {
00203 set_insert(p, max_i);
00204 }
00205
00206
00207 foreachi_set(A, i, p) {
00208 if (is_in_set(p, max_i)) {
00209 set_remove(p, max_i);
00210 j = SIZE(p) - 1;
00211 PUTSIZE(p, j);
00212 }
00213 }
00214
00215 Abar = sf_append(Abar, unate_complement(A));
00216 }
00217 set_free(restrict);
00218 }
00219
00220 return Abar;
00221 }
00222
00223 pset_family exact_minimum_cover(T)
00224 IN pset_family T;
00225 {
00226 register pset p, last, p1;
00227 register int i, n;
00228 int lev, lvl;
00229 pset nlast;
00230 pset_family temp;
00231 long start = ptime();
00232 struct {
00233 pset_family sf;
00234 int level;
00235 } stack[32];
00236
00237 if (T->count <= 0)
00238 return sf_new(1, T->sf_size);
00239 for(n = T->count, lev = 0; n != 0; n >>= 1, lev++) ;
00240
00241
00242 T = lex_sort(sf_save(T));
00243
00244
00245 n = 1;
00246 stack[0].sf = sf_new(1, T->sf_size);
00247 stack[0].level = lev;
00248 set_fill(GETSET(stack[0].sf, stack[0].sf->count++), T->sf_size);
00249
00250 nlast = GETSET(T, T->count - 1);
00251 foreach_set(T, last, p) {
00252
00253
00254 temp = sf_new(set_ord(p), T->sf_size);
00255 for(i = 0; i < T->sf_size; i++)
00256 if (is_in_set(p, i)) {
00257 p1 = set_fill(GETSET(temp, temp->count++), T->sf_size);
00258 set_remove(p1, i);
00259 }
00260 stack[n].sf = temp;
00261 stack[n++].level = lev;
00262
00263
00264 while (n > 1 && (stack[n-1].level==stack[n-2].level || p == nlast)) {
00265 temp = unate_intersect(stack[n-1].sf, stack[n-2].sf, FALSE);
00266 lvl = MIN(stack[n-1].level, stack[n-2].level) - 1;
00267 if (debug & MINCOV && lvl < 10) {
00268 printf("# EXACT_MINCOV[%d]: %4d = %4d x %4d, time = %s\n",
00269 lvl, temp->count, stack[n-1].sf->count,
00270 stack[n-2].sf->count, print_time(ptime() - start));
00271 (void) fflush(stdout);
00272 }
00273 sf_free(stack[n-2].sf);
00274 sf_free(stack[n-1].sf);
00275 stack[n-2].sf = temp;
00276 stack[n-2].level = lvl;
00277 n--;
00278 }
00279 }
00280
00281 temp = stack[0].sf;
00282 p1 = set_fill(set_new(T->sf_size), T->sf_size);
00283 foreach_set(temp, last, p)
00284 INLINEset_diff(p, p1, p);
00285 set_free(p1);
00286 if (debug & MINCOV1) {
00287 printf("MINCOV: family of all minimal coverings is\n");
00288 sf_print(temp);
00289 }
00290 sf_free(T);
00291 return temp;
00292 }
00293
00294
00295
00296
00297
00298
00299
00300 #define MAGIC 500
00301
00302 pset_family unate_intersect(A, B, largest_only)
00303 pset_family A, B;
00304 bool largest_only;
00305 {
00306 register pset pi, pj, lasti, lastj, pt;
00307 pset_family T, Tsave;
00308 bool save;
00309 int maxord, ord;
00310
00311
00312 T = sf_new(MAGIC, A->sf_size);
00313 Tsave = NULL;
00314 maxord = 0;
00315 pt = T->data;
00316
00317
00318 foreach_set(A, lasti, pi) {
00319
00320 foreach_set(B, lastj, pj) {
00321
00322 save = set_andp(pt, pi, pj);
00323
00324
00325 if (save && largest_only) {
00326 if ((ord = set_ord(pt)) > maxord) {
00327
00328 if (Tsave != NULL) {
00329 sf_free(Tsave);
00330 Tsave = NULL;
00331 }
00332 pt = T->data;
00333 T->count = 0;
00334
00335 (void) set_and(pt, pi, pj);
00336 maxord = ord;
00337 } else if (ord < maxord) {
00338 save = FALSE;
00339 }
00340 }
00341
00342 if (save) {
00343 if (++T->count >= T->capacity) {
00344 T = sf_contain(T);
00345 Tsave = (Tsave == NULL) ? T : sf_union(Tsave, T);
00346 T = sf_new(MAGIC, A->sf_size);
00347 pt = T->data;
00348 } else {
00349 pt += T->wsize;
00350 }
00351 }
00352 }
00353 }
00354
00355
00356
00357 T = sf_contain(T);
00358 Tsave = (Tsave == NULL) ? T : sf_union(Tsave, T);
00359
00360 return Tsave;
00361 }
00362
00363
00364
00365
00366
00367 static pset_family
00368 abs_covered(A, pick)
00369 pset_family A;
00370 register int pick;
00371 {
00372 register pset last, p, pdest;
00373 register pset_family Aprime;
00374
00375 Aprime = sf_new(A->count, A->sf_size);
00376 pdest = Aprime->data;
00377 foreach_set(A, last, p)
00378 if (! is_in_set(p, pick)) {
00379 INLINEset_copy(pdest, p);
00380 Aprime->count++;
00381 pdest += Aprime->wsize;
00382 }
00383 return Aprime;
00384 }
00385
00386
00387
00388
00389
00390
00391 static pset_family
00392 abs_covered_many(A, pick_set)
00393 pset_family A;
00394 register pset pick_set;
00395 {
00396 register pset last, p, pdest;
00397 register pset_family Aprime;
00398
00399 Aprime = sf_new(A->count, A->sf_size);
00400 pdest = Aprime->data;
00401 foreach_set(A, last, p)
00402 if (setp_disjoint(p, pick_set)) {
00403 INLINEset_copy(pdest, p);
00404 Aprime->count++;
00405 pdest += Aprime->wsize;
00406 }
00407 return Aprime;
00408 }
00409
00410
00411
00412
00413
00414
00415
00416 static int
00417 abs_select_restricted(A, restrict)
00418 pset_family A;
00419 pset restrict;
00420 {
00421 register int i, best_var, best_count, *count;
00422
00423
00424 count = sf_count_restricted(A, restrict);
00425
00426
00427 best_var = -1;
00428 best_count = 0;
00429 for(i = 0; i < A->sf_size; i++) {
00430 if (count[i] > best_count) {
00431 best_var = i;
00432 best_count = count[i];
00433 }
00434 }
00435 FREE(count);
00436
00437 if (best_var == -1)
00438 fatal("abs_select_restricted: should not have best_var == -1");
00439
00440 return best_var;
00441 }