#include "espresso.h"
Go to the source code of this file.
Defines | |
#define | USE_COMPL_LIFT 0 |
#define | USE_COMPL_LIFT_ONSET 1 |
#define | USE_COMPL_LIFT_ONSET_COMPLEX 2 |
#define | NO_LIFTING 3 |
Functions | |
static bool | compl_special_cases () |
static pcover | compl_merge () |
static void | compl_d1merge () |
static pcover | compl_cube () |
static void | compl_lift () |
static void | compl_lift_onset () |
static void | compl_lift_onset_complex () |
static bool | simp_comp_special_cases () |
static bool | simplify_special_cases () |
pcover | complement (pcube *T) |
static bool | compl_special_cases (pcube *T, pcover *Tbar) |
static pcover | compl_merge (pcube *T1, pcover L, pcover R, pcube cl, pcube cr, int var, int lifting) |
static void | compl_lift (pcube *A1, pcube *B1, pcube bcube, int var) |
static void | compl_lift_onset (pcube *A1, pcover T, pcube bcube, int var) |
static void | compl_lift_onset_complex (pcube *A1, pcover T, int var) |
static void | compl_d1merge (pcube *L1, pcube *R1) |
static pcover | compl_cube (pcube p) |
void | simp_comp (pcube *T, pcover *Tnew, pcover *Tbar) |
static bool | simp_comp_special_cases (pcube *T, pcover *Tnew, pcover *Tbar) |
pcover | simplify (pcube *T) |
static bool | simplify_special_cases (pcube *T, pcover *Tnew) |
static pcover compl_cube | ( | pcube | p | ) | [static] |
Definition at line 397 of file compl.c.
00399 { 00400 register pcube diff=cube.temp[7], pdest, mask, full=cube.fullset; 00401 int var; 00402 pcover R; 00403 00404 /* Allocate worst-case size cover (to avoid checking overflow) */ 00405 R = new_cover(cube.num_vars); 00406 00407 /* Compute bit-wise complement of the cube */ 00408 INLINEset_diff(diff, full, p); 00409 00410 for(var = 0; var < cube.num_vars; var++) { 00411 mask = cube.var_mask[var]; 00412 /* If the bit-wise complement is not empty in var ... */ 00413 if (! setp_disjoint(diff, mask)) { 00414 pdest = GETSET(R, R->count++); 00415 INLINEset_merge(pdest, diff, full, mask); 00416 } 00417 } 00418 return R; 00419 }
static pcover compl_cube | ( | ) | [static] |
static void compl_d1merge | ( | pcube * | L1, | |
pcube * | R1 | |||
) | [static] |
Definition at line 373 of file compl.c.
00375 { 00376 register pcube pl, pr; 00377 00378 /* Find equal cubes between the two cofactors */ 00379 for(pl = *L1, pr = *R1; (pl != NULL) && (pr != NULL); ) 00380 switch (d1_order(L1, R1)) { 00381 case 1: 00382 pr = *(++R1); break; /* advance right pointer */ 00383 case -1: 00384 pl = *(++L1); break; /* advance left pointer */ 00385 case 0: 00386 RESET(pr, ACTIVE); 00387 INLINEset_or(pl, pl, pr); 00388 pr = *(++R1); 00389 default: 00390 ; 00391 } 00392 }
static void compl_d1merge | ( | ) | [static] |
static void compl_lift | ( | pcube * | A1, | |
pcube * | B1, | |||
pcube | bcube, | |||
int | var | |||
) | [static] |
Definition at line 263 of file compl.c.
00266 { 00267 register pcube a, b, *B2, lift=cube.temp[4], liftor=cube.temp[5]; 00268 pcube mask = cube.var_mask[var]; 00269 00270 (void) set_and(liftor, bcube, mask); 00271 00272 /* for each cube in the first array ... */ 00273 for(; (a = *A1++) != NULL; ) { 00274 if (TESTP(a, ACTIVE)) { 00275 00276 /* create a lift of this cube in the merging coord */ 00277 (void) set_merge(lift, bcube, a, mask); 00278 00279 /* for each cube in the second array */ 00280 for(B2 = B1; (b = *B2++) != NULL; ) { 00281 INLINEsetp_implies(lift, b, /* when_false => */ continue); 00282 /* when_true => fall through to next statement */ 00283 00284 /* cube of A1 was contained by some cube of B1, so raise */ 00285 INLINEset_or(a, a, liftor); 00286 break; 00287 } 00288 } 00289 } 00290 }
static void compl_lift | ( | ) | [static] |
static void compl_lift_onset | ( | pcube * | A1, | |
pcover | T, | |||
pcube | bcube, | |||
int | var | |||
) | [static] |
Definition at line 300 of file compl.c.
00305 { 00306 register pcube a, last, p, lift=cube.temp[4], mask=cube.var_mask[var]; 00307 00308 /* for each active cube from one branch of the complement */ 00309 for(; (a = *A1++) != NULL; ) { 00310 if (TESTP(a, ACTIVE)) { 00311 00312 /* create a lift of this cube in the merging coord */ 00313 INLINEset_and(lift, bcube, mask); /* isolate parts to raise */ 00314 INLINEset_or(lift, a, lift); /* raise these parts in a */ 00315 00316 /* for each cube in the ON-set, check for intersection */ 00317 foreach_set(T, last, p) { 00318 if (cdist0(p, lift)) { 00319 goto nolift; 00320 } 00321 } 00322 INLINEset_copy(a, lift); /* save the raising */ 00323 SET(a, ACTIVE); 00324 nolift : ; 00325 } 00326 } 00327 }
static void compl_lift_onset | ( | ) | [static] |
static void compl_lift_onset_complex | ( | pcube * | A1, | |
pcover | T, | |||
int | var | |||
) | [static] |
Definition at line 335 of file compl.c.
00339 { 00340 register int dist; 00341 register pcube last, p, a, xlower; 00342 00343 /* for each cube in the complement */ 00344 xlower = new_cube(); 00345 for(; (a = *A1++) != NULL; ) { 00346 00347 if (TESTP(a, ACTIVE)) { 00348 00349 /* Find which parts of the splitting variable are forced low */ 00350 INLINEset_clear(xlower, cube.size); 00351 foreach_set(T, last, p) { 00352 if ((dist = cdist01(p, a)) < 2) { 00353 if (dist == 0) { 00354 fatal("compl: ON-set and OFF-set are not orthogonal"); 00355 } else { 00356 (void) force_lower(xlower, p, a); 00357 } 00358 } 00359 } 00360 00361 (void) set_diff(xlower, cube.var_mask[var], xlower); 00362 (void) set_or(a, a, xlower); 00363 free_cube(xlower); 00364 } 00365 } 00366 }
static void compl_lift_onset_complex | ( | ) | [static] |
static pcover compl_merge | ( | pcube * | T1, | |
pcover | L, | |||
pcover | R, | |||
pcube | cl, | |||
pcube | cr, | |||
int | var, | |||
int | lifting | |||
) | [static] |
Definition at line 169 of file compl.c.
00175 { 00176 register pcube p, last, pt; 00177 pcover T, Tbar; 00178 pcube *L1, *R1; 00179 00180 if (debug & COMPL) { 00181 (void) printf("compl_merge: left %d, right %d\n", L->count, R->count); 00182 (void) printf("%s (cl)\n%s (cr)\nLeft is\n", pc1(cl), pc2(cr)); 00183 cprint(L); 00184 (void) printf("Right is\n"); 00185 cprint(R); 00186 } 00187 00188 /* Intersect each cube with the cofactored cube */ 00189 foreach_set(L, last, p) { 00190 INLINEset_and(p, p, cl); 00191 SET(p, ACTIVE); 00192 } 00193 foreach_set(R, last, p) { 00194 INLINEset_and(p, p, cr); 00195 SET(p, ACTIVE); 00196 } 00197 00198 /* Sort the arrays for a distance-1 merge */ 00199 (void) set_copy(cube.temp[0], cube.var_mask[var]); 00200 qsort((char *) (L1 = sf_list(L)), L->count, sizeof(pset), (int (*)()) d1_order); 00201 qsort((char *) (R1 = sf_list(R)), R->count, sizeof(pset), (int (*)()) d1_order); 00202 00203 /* Perform distance-1 merge */ 00204 compl_d1merge(L1, R1); 00205 00206 /* Perform lifting */ 00207 switch(lifting) { 00208 case USE_COMPL_LIFT_ONSET: 00209 T = cubeunlist(T1); 00210 compl_lift_onset(L1, T, cr, var); 00211 compl_lift_onset(R1, T, cl, var); 00212 free_cover(T); 00213 break; 00214 case USE_COMPL_LIFT_ONSET_COMPLEX: 00215 T = cubeunlist(T1); 00216 compl_lift_onset_complex(L1, T, var); 00217 compl_lift_onset_complex(R1, T, var); 00218 free_cover(T); 00219 break; 00220 case USE_COMPL_LIFT: 00221 compl_lift(L1, R1, cr, var); 00222 compl_lift(R1, L1, cl, var); 00223 break; 00224 case NO_LIFTING: 00225 break; 00226 default: 00227 ; 00228 } 00229 FREE(L1); 00230 FREE(R1); 00231 00232 /* Re-create the merged cover */ 00233 Tbar = new_cover(L->count + R->count); 00234 pt = Tbar->data; 00235 foreach_set(L, last, p) { 00236 INLINEset_copy(pt, p); 00237 Tbar->count++; 00238 pt += Tbar->wsize; 00239 } 00240 foreach_active_set(R, last, p) { 00241 INLINEset_copy(pt, p); 00242 Tbar->count++; 00243 pt += Tbar->wsize; 00244 } 00245 00246 if (debug & COMPL) { 00247 (void) printf("Result %d\n", Tbar->count); 00248 if (verbose_debug) 00249 cprint(Tbar); 00250 } 00251 00252 free_cover(L); 00253 free_cover(R); 00254 return Tbar; 00255 }
static pcover compl_merge | ( | ) | [static] |
static bool compl_special_cases | ( | pcube * | T, | |
pcover * | Tbar | |||
) | [static] |
Definition at line 86 of file compl.c.
00089 { 00090 register pcube *T1, p, ceil, cof=T[0]; 00091 pcover A, ceil_compl; 00092 00093 /* Check for no cubes in the cover */ 00094 if (T[2] == NULL) { 00095 *Tbar = sf_addset(new_cover(1), cube.fullset); 00096 free_cubelist(T); 00097 return TRUE; 00098 } 00099 00100 /* Check for only a single cube in the cover */ 00101 if (T[3] == NULL) { 00102 *Tbar = compl_cube(set_or(cof, cof, T[2])); 00103 free_cubelist(T); 00104 return TRUE; 00105 } 00106 00107 /* Check for a row of all 1's (implies complement is null) */ 00108 for(T1 = T+2; (p = *T1++) != NULL; ) { 00109 if (full_row(p, cof)) { 00110 *Tbar = new_cover(0); 00111 free_cubelist(T); 00112 return TRUE; 00113 } 00114 } 00115 00116 /* Check for a column of all 0's which can be factored out */ 00117 ceil = set_save(cof); 00118 for(T1 = T+2; (p = *T1++) != NULL; ) { 00119 INLINEset_or(ceil, ceil, p); 00120 } 00121 if (! setp_equal(ceil, cube.fullset)) { 00122 ceil_compl = compl_cube(ceil); 00123 (void) set_or(cof, cof, set_diff(ceil, cube.fullset, ceil)); 00124 set_free(ceil); 00125 *Tbar = sf_append(complement(T), ceil_compl); 00126 return TRUE; 00127 } 00128 set_free(ceil); 00129 00130 /* Collect column counts, determine unate variables, etc. */ 00131 massive_count(T); 00132 00133 /* If single active variable not factored out above, then tautology ! */ 00134 if (cdata.vars_active == 1) { 00135 *Tbar = new_cover(0); 00136 free_cubelist(T); 00137 return TRUE; 00138 00139 /* Check for unate cover */ 00140 } else if (cdata.vars_unate == cdata.vars_active) { 00141 A = map_cover_to_unate(T); 00142 free_cubelist(T); 00143 A = unate_compl(A); 00144 *Tbar = map_unate_to_cover(A); 00145 sf_free(A); 00146 return TRUE; 00147 00148 /* Not much we can do about it */ 00149 } else { 00150 return MAYBE; 00151 } 00152 }
static bool compl_special_cases | ( | ) | [static] |
pcover complement | ( | pcube * | T | ) |
Definition at line 46 of file compl.c.
00048 { 00049 register pcube cl, cr; 00050 register int best; 00051 pcover Tbar, Tl, Tr; 00052 int lifting; 00053 static int compl_level = 0; 00054 00055 if (debug & COMPL) 00056 debug_print(T, "COMPLEMENT", compl_level++); 00057 00058 if (compl_special_cases(T, &Tbar) == MAYBE) { 00059 00060 /* Allocate space for the partition cubes */ 00061 cl = new_cube(); 00062 cr = new_cube(); 00063 best = binate_split_select(T, cl, cr, COMPL); 00064 00065 /* Complement the left and right halves */ 00066 Tl = complement(scofactor(T, cl, best)); 00067 Tr = complement(scofactor(T, cr, best)); 00068 00069 if (Tr->count*Tl->count > (Tr->count+Tl->count)*CUBELISTSIZE(T)) { 00070 lifting = USE_COMPL_LIFT_ONSET; 00071 } else { 00072 lifting = USE_COMPL_LIFT; 00073 } 00074 Tbar = compl_merge(T, Tl, Tr, cl, cr, best, lifting); 00075 00076 free_cube(cl); 00077 free_cube(cr); 00078 free_cubelist(T); 00079 } 00080 00081 if (debug & COMPL) 00082 debug1_print(Tbar, "exit COMPLEMENT", --compl_level); 00083 return Tbar; 00084 }
void simp_comp | ( | pcube * | T, | |
pcover * | Tnew, | |||
pcover * | Tbar | |||
) |
Definition at line 422 of file compl.c.
00426 { 00427 register pcube cl, cr; 00428 register int best; 00429 pcover Tl, Tr, Tlbar, Trbar; 00430 int lifting; 00431 static int simplify_level = 0; 00432 00433 if (debug & COMPL) 00434 debug_print(T, "SIMPCOMP", simplify_level++); 00435 00436 if (simp_comp_special_cases(T, Tnew, Tbar) == MAYBE) { 00437 00438 /* Allocate space for the partition cubes */ 00439 cl = new_cube(); 00440 cr = new_cube(); 00441 best = binate_split_select(T, cl, cr, COMPL); 00442 00443 /* Complement the left and right halves */ 00444 simp_comp(scofactor(T, cl, best), &Tl, &Tlbar); 00445 simp_comp(scofactor(T, cr, best), &Tr, &Trbar); 00446 00447 lifting = USE_COMPL_LIFT; 00448 *Tnew = compl_merge(T, Tl, Tr, cl, cr, best, lifting); 00449 00450 lifting = USE_COMPL_LIFT; 00451 *Tbar = compl_merge(T, Tlbar, Trbar, cl, cr, best, lifting); 00452 00453 /* All of this work for nothing ? Let's hope not ... */ 00454 if ((*Tnew)->count > CUBELISTSIZE(T)) { 00455 sf_free(*Tnew); 00456 *Tnew = cubeunlist(T); 00457 } 00458 00459 free_cube(cl); 00460 free_cube(cr); 00461 free_cubelist(T); 00462 } 00463 00464 if (debug & COMPL) { 00465 debug1_print(*Tnew, "exit SIMPCOMP (new)", simplify_level); 00466 debug1_print(*Tbar, "exit SIMPCOMP (compl)", simplify_level); 00467 simplify_level--; 00468 } 00469 }
static bool simp_comp_special_cases | ( | pcube * | T, | |
pcover * | Tnew, | |||
pcover * | Tbar | |||
) | [static] |
Definition at line 471 of file compl.c.
00475 { 00476 register pcube *T1, p, ceil, cof=T[0]; 00477 pcube last; 00478 pcover A; 00479 00480 /* Check for no cubes in the cover (function is empty) */ 00481 if (T[2] == NULL) { 00482 *Tnew = new_cover(1); 00483 *Tbar = sf_addset(new_cover(1), cube.fullset); 00484 free_cubelist(T); 00485 return TRUE; 00486 } 00487 00488 /* Check for only a single cube in the cover */ 00489 if (T[3] == NULL) { 00490 (void) set_or(cof, cof, T[2]); 00491 *Tnew = sf_addset(new_cover(1), cof); 00492 *Tbar = compl_cube(cof); 00493 free_cubelist(T); 00494 return TRUE; 00495 } 00496 00497 /* Check for a row of all 1's (function is a tautology) */ 00498 for(T1 = T+2; (p = *T1++) != NULL; ) { 00499 if (full_row(p, cof)) { 00500 *Tnew = sf_addset(new_cover(1), cube.fullset); 00501 *Tbar = new_cover(1); 00502 free_cubelist(T); 00503 return TRUE; 00504 } 00505 } 00506 00507 /* Check for a column of all 0's which can be factored out */ 00508 ceil = set_save(cof); 00509 for(T1 = T+2; (p = *T1++) != NULL; ) { 00510 INLINEset_or(ceil, ceil, p); 00511 } 00512 if (! setp_equal(ceil, cube.fullset)) { 00513 p = new_cube(); 00514 (void) set_diff(p, cube.fullset, ceil); 00515 (void) set_or(cof, cof, p); 00516 set_free(p); 00517 simp_comp(T, Tnew, Tbar); 00518 00519 /* Adjust the ON-set */ 00520 A = *Tnew; 00521 foreach_set(A, last, p) { 00522 INLINEset_and(p, p, ceil); 00523 } 00524 00525 /* Compute the new complement */ 00526 *Tbar = sf_append(*Tbar, compl_cube(ceil)); 00527 set_free(ceil); 00528 return TRUE; 00529 } 00530 set_free(ceil); 00531 00532 /* Collect column counts, determine unate variables, etc. */ 00533 massive_count(T); 00534 00535 /* If single active variable not factored out above, then tautology ! */ 00536 if (cdata.vars_active == 1) { 00537 *Tnew = sf_addset(new_cover(1), cube.fullset); 00538 *Tbar = new_cover(1); 00539 free_cubelist(T); 00540 return TRUE; 00541 00542 /* Check for unate cover */ 00543 } else if (cdata.vars_unate == cdata.vars_active) { 00544 /* Make the cover minimum by single-cube containment */ 00545 A = cubeunlist(T); 00546 *Tnew = sf_contain(A); 00547 00548 /* Now form a minimum representation of the complement */ 00549 A = map_cover_to_unate(T); 00550 A = unate_compl(A); 00551 *Tbar = map_unate_to_cover(A); 00552 sf_free(A); 00553 free_cubelist(T); 00554 return TRUE; 00555 00556 /* Not much we can do about it */ 00557 } else { 00558 return MAYBE; 00559 } 00560 }
static bool simp_comp_special_cases | ( | ) | [static] |
pcover simplify | ( | pcube * | T | ) |
Definition at line 563 of file compl.c.
00565 { 00566 register pcube cl, cr; 00567 register int best; 00568 pcover Tbar, Tl, Tr; 00569 int lifting; 00570 static int simplify_level = 0; 00571 00572 if (debug & COMPL) { 00573 debug_print(T, "SIMPLIFY", simplify_level++); 00574 } 00575 00576 if (simplify_special_cases(T, &Tbar) == MAYBE) { 00577 00578 /* Allocate space for the partition cubes */ 00579 cl = new_cube(); 00580 cr = new_cube(); 00581 00582 best = binate_split_select(T, cl, cr, COMPL); 00583 00584 /* Complement the left and right halves */ 00585 Tl = simplify(scofactor(T, cl, best)); 00586 Tr = simplify(scofactor(T, cr, best)); 00587 00588 lifting = USE_COMPL_LIFT; 00589 Tbar = compl_merge(T, Tl, Tr, cl, cr, best, lifting); 00590 00591 /* All of this work for nothing ? Let's hope not ... */ 00592 if (Tbar->count > CUBELISTSIZE(T)) { 00593 sf_free(Tbar); 00594 Tbar = cubeunlist(T); 00595 } 00596 00597 free_cube(cl); 00598 free_cube(cr); 00599 free_cubelist(T); 00600 } 00601 00602 if (debug & COMPL) { 00603 debug1_print(Tbar, "exit SIMPLIFY", --simplify_level); 00604 } 00605 return Tbar; 00606 }
static bool simplify_special_cases | ( | pcube * | T, | |
pcover * | Tnew | |||
) | [static] |
Definition at line 608 of file compl.c.
00611 { 00612 register pcube *T1, p, ceil, cof=T[0]; 00613 pcube last; 00614 pcover A; 00615 00616 /* Check for no cubes in the cover */ 00617 if (T[2] == NULL) { 00618 *Tnew = new_cover(0); 00619 free_cubelist(T); 00620 return TRUE; 00621 } 00622 00623 /* Check for only a single cube in the cover */ 00624 if (T[3] == NULL) { 00625 *Tnew = sf_addset(new_cover(1), set_or(cof, cof, T[2])); 00626 free_cubelist(T); 00627 return TRUE; 00628 } 00629 00630 /* Check for a row of all 1's (implies function is a tautology) */ 00631 for(T1 = T+2; (p = *T1++) != NULL; ) { 00632 if (full_row(p, cof)) { 00633 *Tnew = sf_addset(new_cover(1), cube.fullset); 00634 free_cubelist(T); 00635 return TRUE; 00636 } 00637 } 00638 00639 /* Check for a column of all 0's which can be factored out */ 00640 ceil = set_save(cof); 00641 for(T1 = T+2; (p = *T1++) != NULL; ) { 00642 INLINEset_or(ceil, ceil, p); 00643 } 00644 if (! setp_equal(ceil, cube.fullset)) { 00645 p = new_cube(); 00646 (void) set_diff(p, cube.fullset, ceil); 00647 (void) set_or(cof, cof, p); 00648 free_cube(p); 00649 00650 A = simplify(T); 00651 foreach_set(A, last, p) { 00652 INLINEset_and(p, p, ceil); 00653 } 00654 *Tnew = A; 00655 set_free(ceil); 00656 return TRUE; 00657 } 00658 set_free(ceil); 00659 00660 /* Collect column counts, determine unate variables, etc. */ 00661 massive_count(T); 00662 00663 /* If single active variable not factored out above, then tautology ! */ 00664 if (cdata.vars_active == 1) { 00665 *Tnew = sf_addset(new_cover(1), cube.fullset); 00666 free_cubelist(T); 00667 return TRUE; 00668 00669 /* Check for unate cover */ 00670 } else if (cdata.vars_unate == cdata.vars_active) { 00671 A = cubeunlist(T); 00672 *Tnew = sf_contain(A); 00673 free_cubelist(T); 00674 return TRUE; 00675 00676 /* Not much we can do about it */ 00677 } else { 00678 return MAYBE; 00679 } 00680 }
static bool simplify_special_cases | ( | ) | [static] |