#include "espresso.h"
Go to the source code of this file.
Defines | |
#define | NEW |
Functions | |
pcover | expand (INOUT pcover F, IN pcover R, IN bool nonsparse) |
void | expand1 (pcover BB, pcover CC, pcube RAISE, pcube FREESET, pcube OVEREXPANDED_CUBE, pcube SUPER_CUBE, pcube INIT_LOWER, int *num_covered, pcube c) |
void | essen_parts (pcover BB, pcover CC, pcube RAISE, pcube FREESET) |
void | essen_raising (pcover BB, pcube RAISE, pcube FREESET) |
void | elim_lowering (pcover BB, pcover CC, pcube RAISE, pcube FREESET) |
int | most_frequent (pcover CC, pcube FREESET) |
void | setup_BB_CC (pcover BB, pcover CC) |
void | select_feasible (pcover BB, pcover CC, pcube RAISE, pcube FREESET, pcube SUPER_CUBE, int *num_covered) |
bool | feasibly_covered (pcover BB, pcube c, pcube RAISE, pcube new_lower) |
void | mincov (pcover BB, pcube RAISE, pcube FREESET) |
pcover | find_all_primes (pcover BB, pcube RAISE, pcube FREESET) |
pcover | all_primes (pcover F, pcover R) |
#define NEW |
pcover all_primes | ( | pcover | F, | |
pcover | R | |||
) |
Definition at line 664 of file expand.c.
00666 { 00667 register pcube last, p, RAISE, FREESET; 00668 pcover Fall_primes, B1; 00669 00670 FREESET = new_cube(); 00671 RAISE = new_cube(); 00672 Fall_primes = new_cover(F->count); 00673 00674 foreach_set(F, last, p) { 00675 if (TESTP(p, PRIME)) { 00676 Fall_primes = sf_addset(Fall_primes, p); 00677 } else { 00678 /* Setup for call to essential parts */ 00679 (void) set_copy(RAISE, p); 00680 (void) set_diff(FREESET, cube.fullset, RAISE); 00681 setup_BB_CC(R, /* CC */ (pcover) NULL); 00682 essen_parts(R, /* CC */ (pcover) NULL, RAISE, FREESET); 00683 00684 /* Find all of the primes, and add them to the prime set */ 00685 B1 = find_all_primes(R, RAISE, FREESET); 00686 Fall_primes = sf_append(Fall_primes, B1); 00687 } 00688 } 00689 00690 set_free(RAISE); 00691 set_free(FREESET); 00692 return Fall_primes; 00693 }
void elim_lowering | ( | pcover | BB, | |
pcover | CC, | |||
pcube | RAISE, | |||
pcube | FREESET | |||
) |
Definition at line 285 of file expand.c.
00288 { 00289 register pcube p, r = set_or(cube.temp[0], RAISE, FREESET); 00290 pcube last; 00291 00292 /* 00293 * Remove sets of BB which are orthogonal to future expansions 00294 */ 00295 foreach_active_set(BB, last, p) { 00296 #ifdef NO_INLINE 00297 if (! cdist0(p, r)) 00298 #else 00299 {register int w,lastw;register unsigned int x;if((lastw=cube.inword)!=-1){x=p[ 00300 lastw]&r[lastw];if(~(x|x>>1)&cube.inmask)goto false;for(w=1;w<lastw;w++){x=p[w] 00301 &r[w];if(~(x|x>>1)&DISJOINT)goto false;}}}{register int w,var,lastw;register 00302 pcube mask;for(var=cube.num_binary_vars;var<cube.num_vars;var++){mask=cube. 00303 var_mask[var];lastw=cube.last_word[var];for(w=cube.first_word[var];w<=lastw;w++) 00304 if(p[w]&r[w]&mask[w])goto nextvar;goto false;nextvar:;}}continue;false: 00305 #endif 00306 BB->active_count--, RESET(p, ACTIVE); 00307 } 00308 00309 00310 /* 00311 * Remove sets of CC which cannot be covered by future expansions 00312 */ 00313 if (CC != (pcover) NULL) { 00314 foreach_active_set(CC, last, p) { 00315 #ifdef NO_INLINE 00316 if (! setp_implies(p, r)) 00317 #else 00318 INLINEsetp_implies(p, r, /* when false => */ goto false1); 00319 /* when true => go to end of loop */ continue; 00320 false1: 00321 #endif 00322 CC->active_count--, RESET(p, ACTIVE); 00323 } 00324 } 00325 }
void essen_parts | ( | pcover | BB, | |
pcover | CC, | |||
pcube | RAISE, | |||
pcube | FREESET | |||
) |
Definition at line 207 of file expand.c.
00210 { 00211 register pcube p, r = RAISE; 00212 pcube lastp, xlower = cube.temp[0]; 00213 int dist; 00214 00215 (void) set_copy(xlower, cube.emptyset); 00216 00217 foreach_active_set(BB, lastp, p) { 00218 #ifdef NO_INLINE 00219 if ((dist = cdist01(p, r)) > 1) goto exit_if; 00220 #else 00221 {register int w,last;register unsigned int x;dist=0;if((last=cube.inword)!=-1) 00222 {x=p[last]&r[last];if(x=~(x|x>>1)&cube.inmask)if((dist=count_ones(x))>1)goto 00223 exit_if;for(w=1;w<last;w++){x=p[w]&r[w];if(x=~(x|x>>1)&DISJOINT)if(dist==1||( 00224 dist+=count_ones(x))>1)goto exit_if;}}}{register int w,var,last;register pcube 00225 mask;for(var=cube.num_binary_vars;var<cube.num_vars;var++){mask=cube.var_mask[ 00226 var];last=cube.last_word[var];for(w=cube.first_word[var];w<=last;w++)if(p[w]&r[ 00227 w]&mask[w])goto nextvar;if(++dist>1)goto exit_if;nextvar:;}} 00228 #endif 00229 if (dist == 0) { 00230 fatal("ON-set and OFF-set are not orthogonal"); 00231 } else { 00232 (void) force_lower(xlower, p, r); 00233 BB->active_count--; 00234 RESET(p, ACTIVE); 00235 } 00236 exit_if: ; 00237 } 00238 00239 if (! setp_empty(xlower)) { 00240 (void) set_diff(FREESET, FREESET, xlower);/* remove from free set */ 00241 elim_lowering(BB, CC, RAISE, FREESET); 00242 } 00243 00244 if (debug & EXPAND1) 00245 printf("ESSEN_PARTS:\tRAISE=%s FREESET=%s\n", pc1(RAISE), pc2(FREESET)); 00246 }
void essen_raising | ( | pcover | BB, | |
pcube | RAISE, | |||
pcube | FREESET | |||
) |
Definition at line 256 of file expand.c.
00259 { 00260 register pcube last, p, xraise = cube.temp[0]; 00261 00262 /* Form union of all cubes of BB, and then take complement wrt FREESET */ 00263 (void) set_copy(xraise, cube.emptyset); 00264 foreach_active_set(BB, last, p) 00265 INLINEset_or(xraise, xraise, p); 00266 (void) set_diff(xraise, FREESET, xraise); 00267 00268 (void) set_or(RAISE, RAISE, xraise); /* add to raising set */ 00269 (void) set_diff(FREESET, FREESET, xraise); /* remove from free set */ 00270 00271 if (debug & EXPAND1) 00272 printf("ESSEN_RAISING:\tRAISE=%s FREESET=%s\n", 00273 pc1(RAISE), pc2(FREESET)); 00274 }
pcover expand | ( | INOUT pcover | F, | |
IN pcover | R, | |||
IN bool | nonsparse | |||
) |
Definition at line 50 of file expand.c.
00054 { 00055 register pcube last, p; 00056 pcube RAISE, FREESET, INIT_LOWER, SUPER_CUBE, OVEREXPANDED_CUBE; 00057 int var, num_covered; 00058 bool change; 00059 00060 /* Order the cubes according to "chewing-away from the edges" of mini */ 00061 if (use_random_order) 00062 F = random_order(F); 00063 else 00064 F = mini_sort(F, ascend); 00065 00066 /* Allocate memory for variables needed by expand1() */ 00067 RAISE = new_cube(); 00068 FREESET = new_cube(); 00069 INIT_LOWER = new_cube(); 00070 SUPER_CUBE = new_cube(); 00071 OVEREXPANDED_CUBE = new_cube(); 00072 00073 /* Setup the initial lowering set (differs only for nonsparse) */ 00074 if (nonsparse) 00075 for(var = 0; var < cube.num_vars; var++) 00076 if (cube.sparse[var]) 00077 (void) set_or(INIT_LOWER, INIT_LOWER, cube.var_mask[var]); 00078 00079 /* Mark all cubes as not covered, and maybe essential */ 00080 foreach_set(F, last, p) { 00081 RESET(p, COVERED); 00082 RESET(p, NONESSEN); 00083 } 00084 00085 /* Try to expand each nonprime and noncovered cube */ 00086 foreach_set(F, last, p) { 00087 /* do not expand if PRIME or if covered by previous expansion */ 00088 if (! TESTP(p, PRIME) && ! TESTP(p, COVERED)) { 00089 00090 /* expand the cube p, result is RAISE */ 00091 expand1(R, F, RAISE, FREESET, OVEREXPANDED_CUBE, SUPER_CUBE, 00092 INIT_LOWER, &num_covered, p); 00093 if (debug & EXPAND) 00094 printf("EXPAND: %s (covered %d)\n", pc1(p), num_covered); 00095 (void) set_copy(p, RAISE); 00096 SET(p, PRIME); 00097 RESET(p, COVERED); /* not really necessary */ 00098 00099 /* See if we generated an inessential prime */ 00100 if (num_covered == 0 && ! setp_equal(p, OVEREXPANDED_CUBE)) { 00101 SET(p, NONESSEN); 00102 } 00103 } 00104 } 00105 00106 /* Delete any cubes of F which became covered during the expansion */ 00107 F->active_count = 0; 00108 change = FALSE; 00109 foreach_set(F, last, p) { 00110 if (TESTP(p, COVERED)) { 00111 RESET(p, ACTIVE); 00112 change = TRUE; 00113 } else { 00114 SET(p, ACTIVE); 00115 F->active_count++; 00116 } 00117 } 00118 if (change) 00119 F = sf_inactive(F); 00120 00121 free_cube(RAISE); 00122 free_cube(FREESET); 00123 free_cube(INIT_LOWER); 00124 free_cube(SUPER_CUBE); 00125 free_cube(OVEREXPANDED_CUBE); 00126 return F; 00127 }
void expand1 | ( | pcover | BB, | |
pcover | CC, | |||
pcube | RAISE, | |||
pcube | FREESET, | |||
pcube | OVEREXPANDED_CUBE, | |||
pcube | SUPER_CUBE, | |||
pcube | INIT_LOWER, | |||
int * | num_covered, | |||
pcube | c | |||
) |
Definition at line 132 of file expand.c.
00143 { 00144 int bestindex; 00145 00146 if (debug & EXPAND1) 00147 printf("\nEXPAND1: \t%s\n", pc1(c)); 00148 00149 /* initialize BB and CC */ 00150 SET(c, PRIME); /* don't try to cover ourself */ 00151 setup_BB_CC(BB, CC); 00152 00153 /* initialize count of # cubes covered, and the supercube of them */ 00154 *num_covered = 0; 00155 (void) set_copy(SUPER_CUBE, c); 00156 00157 /* Initialize the lowering, raising and unassigned sets */ 00158 (void) set_copy(RAISE, c); 00159 (void) set_diff(FREESET, cube.fullset, RAISE); 00160 00161 /* If some parts are forced into lowering set, remove them */ 00162 if (! setp_empty(INIT_LOWER)) { 00163 (void) set_diff(FREESET, FREESET, INIT_LOWER); 00164 elim_lowering(BB, CC, RAISE, FREESET); 00165 } 00166 00167 /* Determine what can be raised, and return the over-expanded cube */ 00168 essen_parts(BB, CC, RAISE, FREESET); 00169 (void) set_or(OVEREXPANDED_CUBE, RAISE, FREESET); 00170 00171 /* While there are still cubes which can be covered, cover them ! */ 00172 if (CC->active_count > 0) { 00173 select_feasible(BB, CC, RAISE, FREESET, SUPER_CUBE, num_covered); 00174 } 00175 00176 /* While there are still cubes covered by the overexpanded cube ... */ 00177 while (CC->active_count > 0) { 00178 bestindex = most_frequent(CC, FREESET); 00179 set_insert(RAISE, bestindex); 00180 set_remove(FREESET, bestindex); 00181 essen_parts(BB, CC, RAISE, FREESET); 00182 } 00183 00184 /* Finally, when all else fails, choose the largest possible prime */ 00185 /* We will loop only if we decide unravelling OFF-set is too expensive */ 00186 while (BB->active_count > 0) { 00187 mincov(BB, RAISE, FREESET); 00188 } 00189 00190 /* Raise any remaining free coordinates */ 00191 (void) set_or(RAISE, RAISE, FREESET); 00192 }
bool feasibly_covered | ( | pcover | BB, | |
pcube | c, | |||
pcube | RAISE, | |||
pcube | new_lower | |||
) |
Definition at line 516 of file expand.c.
00519 { 00520 register pcube p, r = set_or(cube.temp[0], RAISE, c); 00521 int dist; 00522 pcube lastp; 00523 00524 set_copy(new_lower, cube.emptyset); 00525 foreach_active_set(BB, lastp, p) { 00526 #ifdef NO_INLINE 00527 if ((dist = cdist01(p, r)) > 1) goto exit_if; 00528 #else 00529 {register int w,last;register unsigned int x;dist=0;if((last=cube.inword)!=-1) 00530 {x=p[last]&r[last];if(x=~(x|x>>1)&cube.inmask)if((dist=count_ones(x))>1)goto 00531 exit_if;for(w=1;w<last;w++){x=p[w]&r[w];if(x=~(x|x>>1)&DISJOINT)if(dist==1||( 00532 dist+=count_ones(x))>1)goto exit_if;}}}{register int w,var,last;register pcube 00533 mask;for(var=cube.num_binary_vars;var<cube.num_vars;var++){mask=cube.var_mask[ 00534 var];last=cube.last_word[var];for(w=cube.first_word[var];w<=last;w++)if(p[w]&r[ 00535 w]&mask[w])goto nextvar;if(++dist>1)goto exit_if;nextvar:;}} 00536 #endif 00537 if (dist == 0) 00538 return FALSE; 00539 else 00540 (void) force_lower(new_lower, p, r); 00541 exit_if: ; 00542 } 00543 return TRUE; 00544 }
pcover find_all_primes | ( | pcover | BB, | |
pcube | RAISE, | |||
pcube | FREESET | |||
) |
Definition at line 629 of file expand.c.
00632 { 00633 register pset last, p, plower; 00634 pset_family B, B1; 00635 00636 if (BB->active_count == 0) { 00637 B1 = new_cover(1); 00638 p = GETSET(B1, B1->count++); 00639 (void) set_copy(p, RAISE); 00640 SET(p, PRIME); 00641 } else { 00642 B = new_cover(BB->active_count); 00643 foreach_active_set(BB, last, p) { 00644 plower = set_copy(GETSET(B, B->count++), cube.emptyset); 00645 (void) force_lower(plower, p, RAISE); 00646 } 00647 B = sf_rev_contain(unravel(B, cube.num_binary_vars)); 00648 B1 = exact_minimum_cover(B); 00649 foreach_set(B1, last, p) { 00650 INLINEset_diff(p, FREESET, p); 00651 INLINEset_or(p, p, RAISE); 00652 SET(p, PRIME); 00653 } 00654 free_cover(B); 00655 } 00656 return B1; 00657 }
void mincov | ( | pcover | BB, | |
pcube | RAISE, | |||
pcube | FREESET | |||
) |
Definition at line 555 of file expand.c.
00558 { 00559 int expansion, nset, var, dist; 00560 pset_family B; 00561 register pcube xraise=cube.temp[0], xlower, p, last, plower; 00562 00563 #ifdef RANDOM_MINCOV 00564 #if defined(_POSIX_SOURCE) || defined(__SVR4) 00565 dist = rand() % set_ord(FREESET); 00566 #else 00567 dist = random() % set_ord(FREESET); 00568 #endif 00569 for(var = 0; var < cube.size && dist >= 0; var++) { 00570 if (is_in_set(FREESET, var)) { 00571 dist--; 00572 } 00573 } 00574 00575 set_insert(RAISE, var); 00576 set_remove(FREESET, var); 00577 (void) essen_parts(BB, /*CC*/ (pcover) NULL, RAISE, FREESET); 00578 #else 00579 00580 /* Create B which are those cubes which we must avoid intersecting */ 00581 B = new_cover(BB->active_count); 00582 foreach_active_set(BB, last, p) { 00583 plower = set_copy(GETSET(B, B->count++), cube.emptyset); 00584 (void) force_lower(plower, p, RAISE); 00585 } 00586 00587 /* Determine how many sets it will blow up into after the unravel */ 00588 nset = 0; 00589 foreach_set(B, last, p) { 00590 expansion = 1; 00591 for(var = cube.num_binary_vars; var < cube.num_vars; var++) { 00592 if ((dist=set_dist(p, cube.var_mask[var])) > 1) { 00593 expansion *= dist; 00594 if (expansion > 500) goto heuristic_mincov; 00595 } 00596 } 00597 nset += expansion; 00598 if (nset > 500) goto heuristic_mincov; 00599 } 00600 00601 B = unravel(B, cube.num_binary_vars); 00602 xlower = do_sm_minimum_cover(B); 00603 00604 /* Add any remaining free parts to the raising set */ 00605 (void) set_or(RAISE, RAISE, set_diff(xraise, FREESET, xlower)); 00606 (void) set_copy(FREESET, cube.emptyset); /* free set is empty */ 00607 BB->active_count = 0; /* BB satisfied */ 00608 if (debug & EXPAND1) { 00609 printf("MINCOV: \tRAISE=%s FREESET=%s\n", pc1(RAISE), pc2(FREESET)); 00610 } 00611 sf_free(B); 00612 set_free(xlower); 00613 return; 00614 00615 heuristic_mincov: 00616 sf_free(B); 00617 /* most_frequent will pick first free part */ 00618 set_insert(RAISE, most_frequent(/*CC*/ (pcover) NULL, FREESET)); 00619 (void) set_diff(FREESET, FREESET, RAISE); 00620 essen_parts(BB, /*CC*/ (pcover) NULL, RAISE, FREESET); 00621 return; 00622 #endif 00623 }
int most_frequent | ( | pcover | CC, | |
pcube | FREESET | |||
) |
Definition at line 335 of file expand.c.
00338 { 00339 register int i, best_part, best_count, *count; 00340 register pset p, last; 00341 00342 /* Count occurences of each variable */ 00343 count = ALLOC(int, cube.size); 00344 for(i = 0; i < cube.size; i++) 00345 count[i] = 0; 00346 if (CC != (pcover) NULL) 00347 foreach_active_set(CC, last, p) 00348 set_adjcnt(p, count, 1); 00349 00350 /* Now find which free part occurs most often */ 00351 best_count = best_part = -1; 00352 for(i = 0; i < cube.size; i++) 00353 if (is_in_set(FREESET,i) && count[i] > best_count) { 00354 best_part = i; 00355 best_count = count[i]; 00356 } 00357 FREE(count); 00358 00359 if (debug & EXPAND1) 00360 printf("MOST_FREQUENT:\tbest=%d FREESET=%s\n", best_part, pc2(FREESET)); 00361 return best_part; 00362 }
void select_feasible | ( | pcover | BB, | |
pcover | CC, | |||
pcube | RAISE, | |||
pcube | FREESET, | |||
pcube | SUPER_CUBE, | |||
int * | num_covered | |||
) |
Definition at line 401 of file expand.c.
00405 { 00406 register pcube p, last, bestfeas, *feas; 00407 register int i, j; 00408 pcube *feas_new_lower; 00409 int bestcount, bestsize, count, size, numfeas, lastfeas; 00410 pcover new_lower; 00411 00412 /* Start out with all cubes covered by the over-expanded cube as 00413 * the "possibly" feasibly-covered cubes (pfcc) 00414 */ 00415 feas = ALLOC(pcube, CC->active_count); 00416 numfeas = 0; 00417 foreach_active_set(CC, last, p) 00418 feas[numfeas++] = p; 00419 00420 /* Setup extra cubes to record parts forced low after a covering */ 00421 feas_new_lower = ALLOC(pcube, CC->active_count); 00422 new_lower = new_cover(numfeas); 00423 for(i = 0; i < numfeas; i++) 00424 feas_new_lower[i] = GETSET(new_lower, i); 00425 00426 00427 loop: 00428 /* Find the essentially raised parts -- this might cover some cubes 00429 for us, without having to find out if they are fcc or not 00430 */ 00431 essen_raising(BB, RAISE, FREESET); 00432 00433 /* Now check all "possibly" feasibly covered cubes to check feasibility */ 00434 lastfeas = numfeas; 00435 numfeas = 0; 00436 for(i = 0; i < lastfeas; i++) { 00437 p = feas[i]; 00438 00439 /* Check active because essen_parts might have removed it */ 00440 if (TESTP(p, ACTIVE)) { 00441 00442 /* See if the cube is already covered by RAISE -- 00443 * this can happen because of essen_raising() or because of 00444 * the previous "loop" 00445 */ 00446 if (setp_implies(p, RAISE)) { 00447 (*num_covered) += 1; 00448 (void) set_or(SUPER_CUBE, SUPER_CUBE, p); 00449 CC->active_count--; 00450 RESET(p, ACTIVE); 00451 SET(p, COVERED); 00452 /* otherwise, test if it is feasibly covered */ 00453 } else if (feasibly_covered(BB,p,RAISE,feas_new_lower[numfeas])) { 00454 feas[numfeas] = p; /* save the fcc */ 00455 numfeas++; 00456 } 00457 } 00458 } 00459 if (debug & EXPAND1) 00460 printf("SELECT_FEASIBLE: started with %d pfcc, ended with %d fcc\n", 00461 lastfeas, numfeas); 00462 00463 /* Exit here if there are no feasibly covered cubes */ 00464 if (numfeas == 0) { 00465 FREE(feas); 00466 FREE(feas_new_lower); 00467 free_cover(new_lower); 00468 return; 00469 } 00470 00471 /* Now find which is the best feasibly covered cube */ 00472 bestcount = 0; 00473 bestsize = 9999; 00474 for(i = 0; i < numfeas; i++) { 00475 size = set_dist(feas[i], FREESET); /* # of newly raised parts */ 00476 count = 0; /* # of other cubes which remain fcc after raising */ 00477 00478 #define NEW 00479 #ifdef NEW 00480 for(j = 0; j < numfeas; j++) 00481 if (setp_disjoint(feas_new_lower[i], feas[j])) 00482 count++; 00483 #else 00484 for(j = 0; j < numfeas; j++) 00485 if (setp_implies(feas[j], feas[i])) 00486 count++; 00487 #endif 00488 if (count > bestcount) { 00489 bestcount = count; 00490 bestfeas = feas[i]; 00491 bestsize = size; 00492 } else if (count == bestcount && size < bestsize) { 00493 bestfeas = feas[i]; 00494 bestsize = size; 00495 } 00496 } 00497 00498 /* Add the necessary parts to the raising set */ 00499 (void) set_or(RAISE, RAISE, bestfeas); 00500 (void) set_diff(FREESET, FREESET, RAISE); 00501 if (debug & EXPAND1) 00502 printf("FEASIBLE: \tRAISE=%s FREESET=%s\n", pc1(RAISE), pc2(FREESET)); 00503 essen_parts(BB, CC, RAISE, FREESET); 00504 goto loop; 00505 /* NOTREACHED */ 00506 }
void setup_BB_CC | ( | pcover | BB, | |
pcover | CC | |||
) |
Definition at line 372 of file expand.c.
00374 { 00375 register pcube p, last; 00376 00377 /* Create the block and cover set families */ 00378 BB->active_count = BB->count; 00379 foreach_set(BB, last, p) 00380 SET(p, ACTIVE); 00381 00382 if (CC != (pcover) NULL) { 00383 CC->active_count = CC->count; 00384 foreach_set(CC, last, p) 00385 if (TESTP(p, COVERED) || TESTP(p, PRIME)) 00386 CC->active_count--, RESET(p, ACTIVE); 00387 else 00388 SET(p, ACTIVE); 00389 } 00390 }