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