src/misc/espresso/irred.c File Reference

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

Go to the source code of this file.

Functions

static void fcube_is_covered ()
static void ftautology ()
static bool ftaut_special_cases ()
pcover irredundant (pcover F, pcover D)
void mark_irredundant (pcover F, pcover D)
void irred_split_cover (pcover F, pcover D, pcover *E, pcover *Rt, pcover *Rp)
sm_matrixirred_derive_table (pcover D, pcover E, pcover Rp)
bool cube_is_covered (pcube *T, pcube c)
bool tautology (pcube *T)
bool taut_special_cases (pcube *T)
static void fcube_is_covered (pcube *T, pcube c, sm_matrix *table)
static void ftautology (pcube *T, sm_matrix *table)
static bool ftaut_special_cases (pcube *T, sm_matrix *table)

Variables

static int Rp_current

Function Documentation

bool cube_is_covered ( pcube *  T,
pcube  c 
)

Definition at line 204 of file irred.c.

00206 {
00207     return tautology(cofactor(T,c));
00208 }

static void fcube_is_covered ( pcube *  T,
pcube  c,
sm_matrix table 
) [static]

Definition at line 332 of file irred.c.

00335 {
00336     ftautology(cofactor(T,c), table);
00337 }

static void fcube_is_covered (  )  [static]
static bool ftaut_special_cases ( pcube *  T,
sm_matrix table 
) [static]

Definition at line 374 of file irred.c.

00377 {
00378     register pcube *T1, *Tsave, p, temp = cube.temp[0], ceil = cube.temp[1];
00379     int var, rownum;
00380 
00381     /* Check for a row of all 1's in the essential cubes */
00382     for(T1 = T+2; (p = *T1++) != 0; ) {
00383         if (! TESTP(p, REDUND)) {
00384             if (full_row(p, T[0])) {
00385                 /* subspace is covered by essentials -- no new rows for table */
00386                 free_cubelist(T);
00387                 return TRUE;
00388             }
00389         }
00390     }
00391 
00392     /* Collect column counts, determine unate variables, etc. */
00393 start:
00394     massive_count(T);
00395 
00396     /* If function is unate, find the rows of all 1's */
00397     if (cdata.vars_unate == cdata.vars_active) {
00398         /* find which nonessentials cover this subspace */
00399         rownum = table->last_row ? table->last_row->row_num+1 : 0;
00400         (void) sm_insert(table, rownum, Rp_current);
00401         for(T1 = T+2; (p = *T1++) != 0; ) {
00402             if (TESTP(p, REDUND)) {
00403                 /* See if a redundant cube covers this leaf */
00404                 if (full_row(p, T[0])) {
00405                     (void) sm_insert(table, rownum, (int) SIZE(p));
00406                 }
00407             }
00408         }
00409         free_cubelist(T);
00410         return TRUE;
00411 
00412     /* Perform unate reduction if there are any unate variables */
00413     } else if (cdata.vars_unate != 0) {
00414         /* Form a cube "ceil" with full variables in the unate variables */
00415         (void) set_copy(ceil, cube.emptyset);
00416         for(var = 0; var < cube.num_vars; var++) {
00417             if (cdata.is_unate[var]) {
00418                 INLINEset_or(ceil, ceil, cube.var_mask[var]);
00419             }
00420         }
00421 
00422         /* Save only those cubes that are "full" in all unate variables */
00423         for(Tsave = T1 = T+2; (p = *T1++) != 0; ) {
00424             if (setp_implies(ceil, set_or(temp, p, T[0]))) {
00425                 *Tsave++ = p;
00426             }
00427         }
00428         *Tsave++ = 0;
00429         T[1] = (pcube) Tsave;
00430 
00431         if (debug & TAUT) {
00432             printf("UNATE_REDUCTION: %d unate variables, reduced to %d\n",
00433                 cdata.vars_unate, CUBELISTSIZE(T));
00434         }
00435         goto start;
00436     }
00437 
00438     /* Not much we can do about it */
00439     return MAYBE;
00440 }

static bool ftaut_special_cases (  )  [static]
static void ftautology ( pcube *  T,
sm_matrix table 
) [static]

Definition at line 342 of file irred.c.

00345 {
00346     register pcube cl, cr;
00347     register int best;
00348     static int ftaut_level = 0;
00349 
00350     if (debug & TAUT) {
00351         debug_print(T, "FIND_TAUTOLOGY", ftaut_level++);
00352     }
00353 
00354     if (ftaut_special_cases(T, table) == MAYBE) {
00355         cl = new_cube();
00356         cr = new_cube();
00357         best = binate_split_select(T, cl, cr, TAUT);
00358 
00359         ftautology(scofactor(T, cl, best), table);
00360         ftautology(scofactor(T, cr, best), table);
00361 
00362         free_cubelist(T);
00363         free_cube(cl);
00364         free_cube(cr);
00365     }
00366 
00367     if (debug & TAUT) {
00368         (void) printf("exit FIND_TAUTOLOGY[%d]: table is %d by %d\n",
00369             --ftaut_level, table->nrows, table->ncols);
00370     }
00371 }

static void ftautology (  )  [static]
sm_matrix* irred_derive_table ( pcover  D,
pcover  E,
pcover  Rp 
)

Definition at line 152 of file irred.c.

00154 {
00155     register pcube last, p, *list;
00156     sm_matrix *table;
00157     int size_last_dominance, i;
00158 
00159     /* Mark each cube in DE as not part of the redundant set */
00160     foreach_set(D, last, p) {
00161         RESET(p, REDUND);
00162     }
00163     foreach_set(E, last, p) {
00164         RESET(p, REDUND);
00165     }
00166 
00167     /* Mark each cube in Rp as partially redundant */
00168     foreach_set(Rp, last, p) {
00169         SET(p, REDUND);             /* belongs to redundant set */
00170     }
00171 
00172     /* For each cube in Rp, find ways to cover its minterms */
00173     list = cube3list(D, E, Rp);
00174     table = sm_alloc();
00175     size_last_dominance = 0;
00176     i = 0;
00177     foreach_set(Rp, last, p) {
00178         Rp_current = SIZE(p);
00179         fcube_is_covered(list, p, table);
00180         RESET(p, REDUND);       /* can now consider this cube redundant */
00181         if (debug & IRRED1) {
00182             (void) printf("IRRED1: %d of %d to-go=%d, table=%dx%d time=%s\n",
00183                 i, Rp->count, Rp->count - i,
00184                 table->nrows, table->ncols, print_time(ptime()));
00185         }
00186         /* try to keep memory limits down by reducing table as we go along */
00187         if (table->nrows - size_last_dominance > 1000) {
00188             (void) sm_row_dominance(table);
00189             size_last_dominance = table->nrows;
00190             if (debug & IRRED1) {
00191                 (void) printf("IRRED1: delete redundant rows, now %dx%d\n",
00192                     table->nrows, table->ncols);
00193             }
00194         }
00195         i++;
00196     }
00197     free_cubelist(list);
00198 
00199     return table;
00200 }

void irred_split_cover ( pcover  F,
pcover  D,
pcover *  E,
pcover *  Rt,
pcover *  Rp 
)

Definition at line 89 of file irred.c.

00092 {
00093     register pcube p, last;
00094     register int index;
00095     pcover R;
00096     pcube *FD, *ED;
00097 
00098     /* number the cubes of F -- these numbers track into E, Rp, Rt, etc. */
00099     index = 0;
00100     foreach_set(F, last, p) {
00101         PUTSIZE(p, index);
00102         index++;
00103     }
00104 
00105     *E = new_cover(10);
00106     *Rt = new_cover(10);
00107     *Rp = new_cover(10);
00108     R = new_cover(10);
00109 
00110     /* Split F into E and R */
00111     FD = cube2list(F, D);
00112     foreach_set(F, last, p) {
00113         if (cube_is_covered(FD, p)) {
00114             R = sf_addset(R, p);
00115         } else {
00116             *E = sf_addset(*E, p);
00117         }
00118         if (debug & IRRED1) {
00119             (void) printf("IRRED1: zr=%d ze=%d to-go=%d time=%s\n",
00120                 R->count, (*E)->count, F->count - (R->count + (*E)->count),
00121                 print_time(ptime()));
00122         }
00123     }
00124     free_cubelist(FD);
00125 
00126     /* Split R into Rt and Rp */
00127     ED = cube2list(*E, D);
00128     foreach_set(R, last, p) {
00129         if (cube_is_covered(ED, p)) {
00130             *Rt = sf_addset(*Rt, p);
00131         } else {
00132             *Rp = sf_addset(*Rp, p);
00133         }
00134         if (debug & IRRED1) {
00135             (void) printf("IRRED1: zr=%d zrt=%d to-go=%d time=%s\n",
00136                 (*Rp)->count, (*Rt)->count,
00137                 R->count - ((*Rp)->count +(*Rt)->count), print_time(ptime()));
00138         }
00139     }
00140     free_cubelist(ED);
00141 
00142     free_cover(R);
00143 }

pcover irredundant ( pcover  F,
pcover  D 
)

Definition at line 24 of file irred.c.

00026 {
00027     mark_irredundant(F, D);
00028     return sf_inactive(F);
00029 }

void mark_irredundant ( pcover  F,
pcover  D 
)

Definition at line 37 of file irred.c.

00039 {
00040     pcover E, Rt, Rp;
00041     pset p, p1, last;
00042     sm_matrix *table;
00043     sm_row *cover;
00044     sm_element *pe;
00045 
00046     /* extract a minimum cover */
00047     irred_split_cover(F, D, &E, &Rt, &Rp);
00048     table = irred_derive_table(D, E, Rp);
00049     cover = sm_minimum_cover(table, NIL(int), /* heuristic */ 1, /* debug */ 0);
00050 
00051     /* mark the cubes for the result */
00052     foreach_set(F, last, p) {
00053         RESET(p, ACTIVE);
00054         RESET(p, RELESSEN);
00055     }
00056     foreach_set(E, last, p) {
00057         p1 = GETSET(F, SIZE(p));
00058         assert(setp_equal(p1, p));
00059         SET(p1, ACTIVE);
00060         SET(p1, RELESSEN);              /* for essen(), mark as rel. ess. */
00061     }
00062     sm_foreach_row_element(cover, pe) {
00063         p1 = GETSET(F, pe->col_num);
00064         SET(p1, ACTIVE);
00065     }
00066 
00067     if (debug & IRRED) {
00068         printf("# IRRED: F=%d E=%d R=%d Rt=%d Rp=%d Rc=%d Final=%d Bound=%d\n",
00069             F->count, E->count, Rt->count+Rp->count, Rt->count, Rp->count,
00070             cover->length, E->count + cover->length, 0);
00071     }
00072 
00073     free_cover(E);
00074     free_cover(Rt);
00075     free_cover(Rp);
00076     sm_free(table);
00077     sm_row_free(cover);
00078 }

bool taut_special_cases ( pcube *  T  ) 

Definition at line 247 of file irred.c.

00249 {
00250     register pcube *T1, *Tsave, p, ceil=cube.temp[0], temp=cube.temp[1];
00251     pcube *A, *B;
00252     int var;
00253 
00254     /* Check for a row of all 1's which implies tautology */
00255     for(T1 = T+2; (p = *T1++) != NULL; ) {
00256         if (full_row(p, T[0])) {
00257             free_cubelist(T);
00258             return TRUE;
00259         }
00260     }
00261 
00262     /* Check for a column of all 0's which implies no tautology */
00263 start:
00264     INLINEset_copy(ceil, T[0]);
00265     for(T1 = T+2; (p = *T1++) != NULL; ) {
00266         INLINEset_or(ceil, ceil, p);
00267     }
00268     if (! setp_equal(ceil, cube.fullset)) {
00269         free_cubelist(T);
00270         return FALSE;
00271     }
00272 
00273     /* Collect column counts, determine unate variables, etc. */
00274     massive_count(T);
00275 
00276     /* If function is unate (and no row of all 1's), then no tautology */
00277     if (cdata.vars_unate == cdata.vars_active) {
00278         free_cubelist(T);
00279         return FALSE;
00280 
00281     /* If active in a single variable (and no column of 0's) then tautology */
00282     } else if (cdata.vars_active == 1) {
00283         free_cubelist(T);
00284         return TRUE;
00285 
00286     /* Check for unate variables, and reduce cover if there are any */
00287     } else if (cdata.vars_unate != 0) {
00288         /* Form a cube "ceil" with full variables in the unate variables */
00289         (void) set_copy(ceil, cube.emptyset);
00290         for(var = 0; var < cube.num_vars; var++) {
00291             if (cdata.is_unate[var]) {
00292                 INLINEset_or(ceil, ceil, cube.var_mask[var]);
00293             }
00294         }
00295 
00296         /* Save only those cubes that are "full" in all unate variables */
00297         for(Tsave = T1 = T+2; (p = *T1++) != 0; ) {
00298             if (setp_implies(ceil, set_or(temp, p, T[0]))) {
00299                 *Tsave++ = p;
00300             }
00301         }
00302         *Tsave++ = NULL;
00303         T[1] = (pcube) Tsave;
00304 
00305         if (debug & TAUT) {
00306             printf("UNATE_REDUCTION: %d unate variables, reduced to %d\n",
00307                 cdata.vars_unate, CUBELISTSIZE(T));
00308         }
00309         goto start;
00310 
00311     /* Check for component reduction */
00312     } else if (cdata.var_zeros[cdata.best] < CUBELISTSIZE(T) / 2) {
00313         if (cubelist_partition(T, &A, &B, debug & TAUT) == 0) {
00314             return MAYBE;
00315         } else {
00316             free_cubelist(T);
00317             if (tautology(A)) {
00318                 free_cubelist(B);
00319                 return TRUE;
00320             } else {
00321                 return tautology(B);
00322             }
00323         }
00324     }
00325 
00326     /* We tried as hard as we could, but must recurse from here on */
00327     return MAYBE;
00328 }

bool tautology ( pcube *  T  ) 

Definition at line 214 of file irred.c.

00216 {
00217     register pcube cl, cr;
00218     register int best, result;
00219     static int taut_level = 0;
00220 
00221     if (debug & TAUT) {
00222         debug_print(T, "TAUTOLOGY", taut_level++);
00223     }
00224 
00225     if ((result = taut_special_cases(T)) == MAYBE) {
00226         cl = new_cube();
00227         cr = new_cube();
00228         best = binate_split_select(T, cl, cr, TAUT);
00229         result = tautology(scofactor(T, cl, best)) &&
00230                  tautology(scofactor(T, cr, best));
00231         free_cubelist(T);
00232         free_cube(cl);
00233         free_cube(cr);
00234     }
00235 
00236     if (debug & TAUT) {
00237         printf("exit TAUTOLOGY[%d]: %s\n", --taut_level, print_bool(result));
00238     }
00239     return result;
00240 }


Variable Documentation

int Rp_current [static]

Definition at line 17 of file irred.c.


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