src/misc/espresso/cvrm.c File Reference

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

Go to the source code of this file.

Functions

static void cb_unravel (IN register pcube c, IN int start, IN int end, IN pcube startbase, INOUT pcover B1)
pcover unravel_range (IN pcover B, IN int start, IN int end)
pcover unravel (IN pcover B, IN int start)
pcover lex_sort (pcover T)
pcover size_sort (pcover T)
pcover mini_sort (pcover F, int(*compare)())
pcover sort_reduce (IN pcover T)
pcover random_order (pcover F)
int cubelist_partition (pcube *T, pcube **A, pcube **B, unsigned int comp_debug)
pcover cof_output (pcover T, int i)
pcover uncof_output (pcover T, int i)
 foreach_output_function (pPLA PLA, int(*func)(), int(*func1)())
void so_espresso (pPLA PLA, int strategy)
void so_both_espresso (pPLA PLA, int strategy)
int so_do_espresso (pPLA PLA, int i)
int so_do_exact (pPLA PLA, int i)
int so_save (pPLA PLA, int i)
int so_both_do_espresso (pPLA PLA, int i)
int so_both_do_exact (pPLA PLA, int i)
int so_both_save (pPLA PLA, int i)

Variables

static pcover Fmin
static pcube phase

Function Documentation

static void cb_unravel ( IN register pcube  c,
IN int  start,
IN int  end,
IN pcube  startbase,
INOUT pcover  B1 
) [static]

Definition at line 21 of file cvrm.c.

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     /* Determine how many cubes it will blow up into, and create a mask
00032         for those parts that have only a single coordinate
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     /* Add the unravelled sets starting at the last element of B1 */
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 }

pcover cof_output ( pcover  T,
int  i 
)

Definition at line 309 of file cvrm.c.

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 }

int cubelist_partition ( pcube *  T,
pcube **  A,
pcube **  B,
unsigned int  comp_debug 
)

Definition at line 231 of file cvrm.c.

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     /* Mark all cubes -- covered cubes belong to the partition */
00244     for(T1 = T+2; (p = *T1++) != NULL; ) {
00245         RESET(p, COVERED);
00246     }
00247 
00248     /*
00249      *  Extract a partition from the cubelist T; start with the first cube as a
00250      *  seed, and then pull in all cubes which share a variable with the seed;
00251      *  iterate until no new cubes are brought into the partition.
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         /* Allocate and setup the cubelist's for the two partitions */
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         /* Loop over the cubes in T and distribute to A and B */
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         /* Stuff needed at the end of the cubelist's */
00297         *A1++ = NULL;
00298         (*A)[1] = (pcube) A1;
00299         *B1++ = NULL;
00300         (*B)[1] = (pcube) B1;
00301     }
00302 
00303     return numcube - count;
00304 }

foreach_output_function ( pPLA  PLA,
int (*)()  func,
int (*)()  func1 
)

Definition at line 360 of file cvrm.c.

00364 {
00365     pPLA PLA1;
00366     int i;
00367 
00368     /* Loop for each output function */
00369     for(i = 0; i < cube.part_size[cube.output]; i++) {
00370 
00371         /* cofactor on the output part */
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         /* Call a routine to do something with the cover */
00378         if ((*func)(PLA1, i) == 0) {
00379             free_PLA(PLA1);
00380             return;
00381         }
00382 
00383         /* intersect with the particular output part again */
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         /* Call a routine to do something with the final result */
00389         if ((*func1)(PLA1, i) == 0) {
00390             free_PLA(PLA1);
00391             return;
00392         }
00393 
00394         /* Cleanup for next go-around */
00395         free_PLA(PLA1);
00396         
00397 
00398     }
00399 }

pcover lex_sort ( pcover  T  ) 

Definition at line 118 of file cvrm.c.

00120 {
00121     pcover T1 = sf_unlist(sf_sort(T, lex_order), T->count, T->sf_size);
00122     free_cover(T);
00123     return T1;
00124 }

pcover mini_sort ( pcover  F,
int (*)()  compare 
)

Definition at line 138 of file cvrm.c.

00141 {
00142     register int *count, cnt, n = cube.size, i;
00143     register pcube p, last;
00144     pcover F_sorted;
00145     pcube *F1;
00146 
00147     /* Perform a column sum over the set family */
00148     count = sf_count(F);
00149 
00150     /* weight is "inner product of the cube and the column sums" */
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     /* use qsort to sort the array */
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 }

pcover random_order ( pcover  F  ) 

Definition at line 196 of file cvrm.c.

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         /* Choose a random number between 0 and i */
00208 #ifdef RANDOM
00209         k = random() % i;
00210 #else
00211         /* this is not meant to be really used; just provides an easy
00212            "out" if random() and srandom() aren't around
00213         */
00214         k = (i*23 + 997) % i;
00215 #endif
00216         /* swap sets i and k */
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 }

pcover size_sort ( pcover  T  ) 

Definition at line 128 of file cvrm.c.

00130 {
00131     pcover T1 = sf_unlist(sf_sort(T, descend), T->count, T->sf_size);
00132     free_cover(T);
00133     return T1;
00134 }

int so_both_do_espresso ( pPLA  PLA,
int  i 
)

Definition at line 482 of file cvrm.c.

00485 {
00486     char word[32];
00487 
00488     /* minimize the single-output function (on-set) */
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     /* minimize the single-output function (off-set) */
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 }

int so_both_do_exact ( pPLA  PLA,
int  i 
)

Definition at line 502 of file cvrm.c.

00505 {
00506     char word[32];
00507 
00508     /* minimize the single-output function (on-set) */
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     /* minimize the single-output function (off-set) */
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 }

void so_both_espresso ( pPLA  PLA,
int  strategy 
)

Definition at line 426 of file cvrm.c.

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 }

int so_both_save ( pPLA  PLA,
int  i 
)

Definition at line 522 of file cvrm.c.

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 }

int so_do_espresso ( pPLA  PLA,
int  i 
)

Definition at line 443 of file cvrm.c.

00446 {
00447     char word[32];
00448 
00449     /* minimize the single-output function (on-set) */
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 }

int so_do_exact ( pPLA  PLA,
int  i 
)

Definition at line 457 of file cvrm.c.

00460 {
00461     char word[32];
00462 
00463     /* minimize the single-output function (on-set) */
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 }

void so_espresso ( pPLA  PLA,
int  strategy 
)

Definition at line 407 of file cvrm.c.

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 }

int so_save ( pPLA  PLA,
int  i 
)

Definition at line 472 of file cvrm.c.

00475 {
00476     Fmin = sf_append(Fmin, PLA->F);     /* disposes of PLA->F */
00477     PLA->F = NULL;
00478     return 1;
00479 }

pcover sort_reduce ( IN pcover  T  ) 

Definition at line 170 of file cvrm.c.

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     /* find largest cube */
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 }

pcover uncof_output ( pcover  T,
int  i 
)

Definition at line 332 of file cvrm.c.

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 }

pcover unravel ( IN pcover  B,
IN int  start 
)

Definition at line 110 of file cvrm.c.

00113 {
00114     return unravel_range(B, start, cube.num_vars-1);
00115 }

pcover unravel_range ( IN pcover  B,
IN int  start,
IN int  end 
)

Definition at line 74 of file cvrm.c.

00077 {
00078     pcover B1;
00079     int var, total_size, expansion, size;
00080     register pcube p, last, startbase = cube.temp[1];
00081 
00082     /* Create the starting base for those variables not being unravelled */
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     /* Determine how many cubes it will blow up into */
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     /* We can now allocate a cover of exactly the correct size */
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 }


Variable Documentation

pcover Fmin [static]

Definition at line 401 of file cvrm.c.

pcube phase [static]

Definition at line 402 of file cvrm.c.


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