src/misc/espresso/compl.c File Reference

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

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)

Define Documentation

#define NO_LIFTING   3

Definition at line 32 of file compl.c.

#define USE_COMPL_LIFT   0

Definition at line 29 of file compl.c.

#define USE_COMPL_LIFT_ONSET   1

Definition at line 30 of file compl.c.

#define USE_COMPL_LIFT_ONSET_COMPLEX   2

Definition at line 31 of file compl.c.


Function Documentation

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]

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