src/misc/espresso/expand.c File Reference

#include "espresso.h"
Include dependency graph for expand.c:

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 Documentation

#define NEW

Function Documentation

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 }


Generated on Tue Jan 5 12:19:11 2010 for abc70930 by  doxygen 1.6.1