#include "espresso.h"
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) |
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 }