src/misc/espresso/unate.c File Reference

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

Go to the source code of this file.

Defines

#define MAGIC   500

Functions

static pset_family abs_covered ()
static pset_family abs_covered_many ()
static int abs_select_restricted ()
pcover map_cover_to_unate (pcube *T)
pcover map_unate_to_cover (pset_family A)
pset_family unate_compl (pset_family A)
pset_family unate_complement (pset_family A)
pset_family exact_minimum_cover (IN pset_family T)
pset_family unate_intersect (pset_family A, pset_family B, bool largest_only)
static pset_family abs_covered (pset_family A, int pick)
static pset_family abs_covered_many (pset_family A, pset pick_set)
static int abs_select_restricted (pset_family A, pset restrict)

Define Documentation

#define MAGIC   500

Definition at line 300 of file unate.c.


Function Documentation

static pset_family abs_covered ( pset_family  A,
int  pick 
) [static]

Definition at line 368 of file unate.c.

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 }

static pset_family abs_covered (  )  [static]
static pset_family abs_covered_many ( pset_family  A,
pset  pick_set 
) [static]

Definition at line 392 of file unate.c.

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 }

static pset_family abs_covered_many (  )  [static]
static int abs_select_restricted ( pset_family  A,
pset  restrict 
) [static]

Definition at line 417 of file unate.c.

00420 {
00421     register int i, best_var, best_count, *count;
00422 
00423     /* Sum the elements in these columns */
00424     count = sf_count_restricted(A, restrict);
00425 
00426     /* Find which variable has maximum weight */
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 }

static int abs_select_restricted (  )  [static]
pset_family exact_minimum_cover ( IN pset_family  T  ) 

Definition at line 223 of file unate.c.

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];                /* 32 suffices for 2 ** 32 cubes ! */
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     /* A simple heuristic ordering */
00242     T = lex_sort(sf_save(T));
00243 
00244     /* Push a full set on the stack to get things started */
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         /* "unstack" the set into a family */
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         /* Pop the stack and perform (leveled) intersections */
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);         /* this is the copy of T we made ... */
00291     return temp;
00292 }

pcover map_cover_to_unate ( pcube *  T  ) 

Definition at line 20 of file unate.c.

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             /* Copy a column from T to A */
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 }

pcover map_unate_to_cover ( pset_family  A  ) 

Definition at line 61 of file unate.c.

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     /* Find the unate variables */
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     /* Loop for each set of A */
00083     pB = B->data;
00084     foreach_set(A, last, p) {
00085 
00086         /* Initialize this set of B */
00087         INLINEset_fill(pB, cube.size);
00088 
00089         /* Now loop for the unate variables; if the part is in A,
00090          * then this variable of B should be a single 1 in the unate
00091          * part.
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 }

pset_family unate_compl ( pset_family  A  ) 

Definition at line 114 of file unate.c.

00116 {
00117     register pset p, last;
00118 
00119     /* Make sure A is single-cube containment minimal */
00120 /*    A = sf_rev_contain(A);*/
00121 
00122     foreach_set(A, last, p) {
00123         PUTSIZE(p, set_ord(p));
00124     }
00125 
00126     /* Recursively find the complement */
00127     A = unate_complement(A);
00128 
00129     /* Now, we can guarantee a minimal result by containing the result */
00130     A = sf_rev_contain(A);
00131     return A;
00132 }

pset_family unate_complement ( pset_family  A  ) 

Definition at line 138 of file unate.c.

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     /* Check for no sets in the matrix -- complement is the universe */
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     /* Check for a single set in the maxtrix -- compute de Morgan complement */
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         /* Select splitting variable as the variable which belongs to a set
00167          * of the smallest size, and which has greatest column count
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         /* Check for no data (shouldn't happen ?) */
00181         if (min_set_ord == 0) {
00182             A->count = 0;
00183             Abar = A;
00184 
00185         /* Check for "essential" columns */
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         /* else, recur as usual */
00194         } else {
00195             max_i = abs_select_restricted(A, restrict);
00196 
00197             /* Select those rows of A which are not covered by max_i,
00198              * recursively find all minimal covers of these rows, and
00199              * then add back in max_i
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             /* Now recur on A with all zero's on column max_i */
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 }

pset_family unate_intersect ( pset_family  A,
pset_family  B,
bool  largest_only 
)

Definition at line 302 of file unate.c.

00305 {
00306     register pset pi, pj, lasti, lastj, pt;
00307     pset_family T, Tsave;
00308     bool save;
00309     int maxord, ord;
00310 
00311     /* How large should each temporary result cover be ? */
00312     T = sf_new(MAGIC, A->sf_size);
00313     Tsave = NULL;
00314     maxord = 0;
00315     pt = T->data;
00316 
00317     /* Form pairwise intersection of each set of A with each cube of B */
00318     foreach_set(A, lasti, pi) {
00319 
00320         foreach_set(B, lastj, pj) {
00321 
00322             save = set_andp(pt, pi, pj);
00323 
00324             /* Check if we want the largest only */
00325             if (save && largest_only) {
00326                 if ((ord = set_ord(pt)) > maxord) {
00327                     /* discard Tsave and T */
00328                     if (Tsave != NULL) {
00329                         sf_free(Tsave);
00330                         Tsave = NULL;
00331                     }
00332                     pt = T->data;
00333                     T->count = 0;
00334                     /* Re-create pt (which was just thrown away) */
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     /* Contain the final result and merge it into Tsave */
00357     T = sf_contain(T);
00358     Tsave = (Tsave == NULL) ? T : sf_union(Tsave, T);
00359 
00360     return Tsave;
00361 }


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