00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "espresso.h"
00019
00020
00021 static void cb_unravel(c, start, end, startbase, B1)
00022 IN register pcube c;
00023 IN int start, end;
00024 IN pcube startbase;
00025 INOUT pcover B1;
00026 {
00027 pcube base = cube.temp[0], p, last;
00028 int expansion, place, skip, var, size, offset;
00029 register int i, j, k, n;
00030
00031
00032
00033
00034 expansion = 1;
00035 (void) set_copy(base, startbase);
00036 for(var = start; var <= end; var++) {
00037 if ((size = set_dist(c, cube.var_mask[var])) < 2) {
00038 (void) set_or(base, base, cube.var_mask[var]);
00039 } else {
00040 expansion *= size;
00041 }
00042 }
00043 (void) set_and(base, c, base);
00044
00045
00046 offset = B1->count;
00047 B1->count += expansion;
00048 foreach_remaining_set(B1, last, GETSET(B1, offset-1), p) {
00049 INLINEset_copy(p, base);
00050 }
00051
00052 place = expansion;
00053 for(var = start; var <= end; var++) {
00054 if ((size = set_dist(c, cube.var_mask[var])) > 1) {
00055 skip = place;
00056 place = place / size;
00057 n = 0;
00058 for(i = cube.first_part[var]; i <= cube.last_part[var]; i++) {
00059 if (is_in_set(c, i)) {
00060 for(j = n; j < expansion; j += skip) {
00061 for(k = 0; k < place; k++) {
00062 p = GETSET(B1, j+k+offset);
00063 (void) set_insert(p, i);
00064 }
00065 }
00066 n += place;
00067 }
00068 }
00069 }
00070 }
00071 }
00072
00073
00074 pcover unravel_range(B, start, end)
00075 IN pcover B;
00076 IN int start, end;
00077 {
00078 pcover B1;
00079 int var, total_size, expansion, size;
00080 register pcube p, last, startbase = cube.temp[1];
00081
00082
00083 (void) set_copy(startbase, cube.emptyset);
00084 for(var = 0; var < start; var++)
00085 (void) set_or(startbase, startbase, cube.var_mask[var]);
00086 for(var = end+1; var < cube.num_vars; var++)
00087 (void) set_or(startbase, startbase, cube.var_mask[var]);
00088
00089
00090 total_size = 0;
00091 foreach_set(B, last, p) {
00092 expansion = 1;
00093 for(var = start; var <= end; var++)
00094 if ((size = set_dist(p, cube.var_mask[var])) >= 2)
00095 if ((expansion *= size) > 1000000)
00096 fatal("unreasonable expansion in unravel");
00097 total_size += expansion;
00098 }
00099
00100
00101 B1 = new_cover(total_size);
00102 foreach_set(B, last, p) {
00103 cb_unravel(p, start, end, startbase, B1);
00104 }
00105 free_cover(B);
00106 return B1;
00107 }
00108
00109
00110 pcover unravel(B, start)
00111 IN pcover B;
00112 IN int start;
00113 {
00114 return unravel_range(B, start, cube.num_vars-1);
00115 }
00116
00117
00118 pcover lex_sort(T)
00119 pcover T;
00120 {
00121 pcover T1 = sf_unlist(sf_sort(T, lex_order), T->count, T->sf_size);
00122 free_cover(T);
00123 return T1;
00124 }
00125
00126
00127
00128 pcover size_sort(T)
00129 pcover T;
00130 {
00131 pcover T1 = sf_unlist(sf_sort(T, descend), T->count, T->sf_size);
00132 free_cover(T);
00133 return T1;
00134 }
00135
00136
00137
00138 pcover mini_sort(F, compare)
00139 pcover F;
00140 int (*compare)();
00141 {
00142 register int *count, cnt, n = cube.size, i;
00143 register pcube p, last;
00144 pcover F_sorted;
00145 pcube *F1;
00146
00147
00148 count = sf_count(F);
00149
00150
00151 foreach_set(F, last, p) {
00152 cnt = 0;
00153 for(i = 0; i < n; i++)
00154 if (is_in_set(p, i))
00155 cnt += count[i];
00156 PUTSIZE(p, cnt);
00157 }
00158 FREE(count);
00159
00160
00161 qsort((char *) (F1 = sf_list(F)), F->count, sizeof(pcube), compare);
00162 F_sorted = sf_unlist(F1, F->count, F->sf_size);
00163 free_cover(F);
00164
00165 return F_sorted;
00166 }
00167
00168
00169
00170 pcover sort_reduce(T)
00171 IN pcover T;
00172 {
00173 register pcube p, last, largest = NULL;
00174 register int bestsize = -1, size, n = cube.num_vars;
00175 pcover T_sorted;
00176 pcube *T1;
00177
00178 if (T->count == 0)
00179 return T;
00180
00181
00182 foreach_set(T, last, p)
00183 if ((size = set_ord(p)) > bestsize)
00184 largest = p, bestsize = size;
00185
00186 foreach_set(T, last, p)
00187 PUTSIZE(p, ((n - cdist(largest,p)) << 7) + MIN(set_ord(p),127));
00188
00189 qsort((char *) (T1 = sf_list(T)), T->count, sizeof(pcube), (int (*)()) descend);
00190 T_sorted = sf_unlist(T1, T->count, T->sf_size);
00191 free_cover(T);
00192
00193 return T_sorted;
00194 }
00195
00196 pcover random_order(F)
00197 register pcover F;
00198 {
00199 pset temp;
00200 register int i, k;
00201 #ifdef RANDOM
00202 long random();
00203 #endif
00204
00205 temp = set_new(F->sf_size);
00206 for(i = F->count - 1; i > 0; i--) {
00207
00208 #ifdef RANDOM
00209 k = random() % i;
00210 #else
00211
00212
00213
00214 k = (i*23 + 997) % i;
00215 #endif
00216
00217 (void) set_copy(temp, GETSET(F, k));
00218 (void) set_copy(GETSET(F, k), GETSET(F, i));
00219 (void) set_copy(GETSET(F, i), temp);
00220 }
00221 set_free(temp);
00222 return F;
00223 }
00224
00225
00226
00227
00228
00229
00230
00231 int cubelist_partition(T, A, B, comp_debug)
00232 pcube *T;
00233 pcube **A, **B;
00234 unsigned int comp_debug;
00235 {
00236 register pcube *T1, p, seed, cof;
00237 pcube *A1, *B1;
00238 bool change;
00239 int count, numcube;
00240
00241 numcube = CUBELISTSIZE(T);
00242
00243
00244 for(T1 = T+2; (p = *T1++) != NULL; ) {
00245 RESET(p, COVERED);
00246 }
00247
00248
00249
00250
00251
00252
00253 seed = set_save(T[2]);
00254 cof = T[0];
00255 SET(T[2], COVERED);
00256 count = 1;
00257
00258 do {
00259 change = FALSE;
00260 for(T1 = T+2; (p = *T1++) != NULL; ) {
00261 if (! TESTP(p, COVERED) && ccommon(p, seed, cof)) {
00262 INLINEset_and(seed, seed, p);
00263 SET(p, COVERED);
00264 change = TRUE;
00265 count++;
00266 }
00267
00268 }
00269 } while (change);
00270
00271 set_free(seed);
00272
00273 if (comp_debug) {
00274 (void) printf("COMPONENT_REDUCTION: split into %d %d\n",
00275 count, numcube - count);
00276 }
00277
00278 if (count != numcube) {
00279
00280 *A = A1 = ALLOC(pcube, numcube+3);
00281 *B = B1 = ALLOC(pcube, numcube+3);
00282 (*A)[0] = set_save(T[0]);
00283 (*B)[0] = set_save(T[0]);
00284 A1 = *A + 2;
00285 B1 = *B + 2;
00286
00287
00288 for(T1 = T+2; (p = *T1++) != NULL; ) {
00289 if (TESTP(p, COVERED)) {
00290 *A1++ = p;
00291 } else {
00292 *B1++ = p;
00293 }
00294 }
00295
00296
00297 *A1++ = NULL;
00298 (*A)[1] = (pcube) A1;
00299 *B1++ = NULL;
00300 (*B)[1] = (pcube) B1;
00301 }
00302
00303 return numcube - count;
00304 }
00305
00306
00307
00308
00309 pcover cof_output(T, i)
00310 pcover T;
00311 register int i;
00312 {
00313 pcover T1;
00314 register pcube p, last, pdest, mask;
00315
00316 mask = cube.var_mask[cube.output];
00317 T1 = new_cover(T->count);
00318 foreach_set(T, last, p) {
00319 if (is_in_set(p, i)) {
00320 pdest = GETSET(T1, T1->count++);
00321 INLINEset_or(pdest, p, mask);
00322 RESET(pdest, PRIME);
00323 }
00324 }
00325 return T1;
00326 }
00327
00328
00329
00330
00331
00332 pcover uncof_output(T, i)
00333 pcover T;
00334 int i;
00335 {
00336 register pcube p, last, mask;
00337
00338 if (T == NULL) {
00339 return T;
00340 }
00341
00342 mask = cube.var_mask[cube.output];
00343 foreach_set(T, last, p) {
00344 INLINEset_diff(p, p, mask);
00345 set_insert(p, i);
00346 }
00347 return T;
00348 }
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 foreach_output_function(PLA, func, func1)
00361 pPLA PLA;
00362 int (*func)();
00363 int (*func1)();
00364 {
00365 pPLA PLA1;
00366 int i;
00367
00368
00369 for(i = 0; i < cube.part_size[cube.output]; i++) {
00370
00371
00372 PLA1 = new_PLA();
00373 PLA1->F = cof_output(PLA->F, i + cube.first_part[cube.output]);
00374 PLA1->R = cof_output(PLA->R, i + cube.first_part[cube.output]);
00375 PLA1->D = cof_output(PLA->D, i + cube.first_part[cube.output]);
00376
00377
00378 if ((*func)(PLA1, i) == 0) {
00379 free_PLA(PLA1);
00380 return;
00381 }
00382
00383
00384 PLA1->F = uncof_output(PLA1->F, i + cube.first_part[cube.output]);
00385 PLA1->R = uncof_output(PLA1->R, i + cube.first_part[cube.output]);
00386 PLA1->D = uncof_output(PLA1->D, i + cube.first_part[cube.output]);
00387
00388
00389 if ((*func1)(PLA1, i) == 0) {
00390 free_PLA(PLA1);
00391 return;
00392 }
00393
00394
00395 free_PLA(PLA1);
00396
00397
00398 }
00399 }
00400
00401 static pcover Fmin;
00402 static pcube phase;
00403
00404
00405
00406
00407 void so_espresso(PLA, strategy)
00408 pPLA PLA;
00409 int strategy;
00410 {
00411 Fmin = new_cover(PLA->F->count);
00412 if (strategy == 0) {
00413 foreach_output_function(PLA, so_do_espresso, so_save);
00414 } else {
00415 foreach_output_function(PLA, so_do_exact, so_save);
00416 }
00417 sf_free(PLA->F);
00418 PLA->F = Fmin;
00419 }
00420
00421
00422
00423
00424
00425
00426 void so_both_espresso(PLA, strategy)
00427 pPLA PLA;
00428 int strategy;
00429 {
00430 phase = set_save(cube.fullset);
00431 Fmin = new_cover(PLA->F->count);
00432 if (strategy == 0) {
00433 foreach_output_function(PLA, so_both_do_espresso, so_both_save);
00434 } else {
00435 foreach_output_function(PLA, so_both_do_exact, so_both_save);
00436 }
00437 sf_free(PLA->F);
00438 PLA->F = Fmin;
00439 PLA->phase = phase;
00440 }
00441
00442
00443 int so_do_espresso(PLA, i)
00444 pPLA PLA;
00445 int i;
00446 {
00447 char word[32];
00448
00449
00450 skip_make_sparse = 1;
00451 (void) sprintf(word, "ESPRESSO-POS(%d)", i);
00452 EXEC_S(PLA->F = espresso(PLA->F, PLA->D, PLA->R), word, PLA->F);
00453 return 1;
00454 }
00455
00456
00457 int so_do_exact(PLA, i)
00458 pPLA PLA;
00459 int i;
00460 {
00461 char word[32];
00462
00463
00464 skip_make_sparse = 1;
00465 (void) sprintf(word, "EXACT-POS(%d)", i);
00466 EXEC_S(PLA->F = minimize_exact(PLA->F, PLA->D, PLA->R, 1), word, PLA->F);
00467 return 1;
00468 }
00469
00470
00471
00472 int so_save(PLA, i)
00473 pPLA PLA;
00474 int i;
00475 {
00476 Fmin = sf_append(Fmin, PLA->F);
00477 PLA->F = NULL;
00478 return 1;
00479 }
00480
00481
00482 int so_both_do_espresso(PLA, i)
00483 pPLA PLA;
00484 int i;
00485 {
00486 char word[32];
00487
00488
00489 (void) sprintf(word, "ESPRESSO-POS(%d)", i);
00490 skip_make_sparse = 1;
00491 EXEC_S(PLA->F = espresso(PLA->F, PLA->D, PLA->R), word, PLA->F);
00492
00493
00494 (void) sprintf(word, "ESPRESSO-NEG(%d)", i);
00495 skip_make_sparse = 1;
00496 EXEC_S(PLA->R = espresso(PLA->R, PLA->D, PLA->F), word, PLA->R);
00497
00498 return 1;
00499 }
00500
00501
00502 int so_both_do_exact(PLA, i)
00503 pPLA PLA;
00504 int i;
00505 {
00506 char word[32];
00507
00508
00509 (void) sprintf(word, "EXACT-POS(%d)", i);
00510 skip_make_sparse = 1;
00511 EXEC_S(PLA->F = minimize_exact(PLA->F, PLA->D, PLA->R, 1), word, PLA->F);
00512
00513
00514 (void) sprintf(word, "EXACT-NEG(%d)", i);
00515 skip_make_sparse = 1;
00516 EXEC_S(PLA->R = minimize_exact(PLA->R, PLA->D, PLA->F, 1), word, PLA->R);
00517
00518 return 1;
00519 }
00520
00521
00522 int so_both_save(PLA, i)
00523 pPLA PLA;
00524 int i;
00525 {
00526 if (PLA->F->count > PLA->R->count) {
00527 sf_free(PLA->F);
00528 PLA->F = PLA->R;
00529 PLA->R = NULL;
00530 i += cube.first_part[cube.output];
00531 set_remove(phase, i);
00532 } else {
00533 sf_free(PLA->R);
00534 PLA->R = NULL;
00535 }
00536 Fmin = sf_append(Fmin, PLA->F);
00537 PLA->F = NULL;
00538 return 1;
00539 }