/* * verify -- check that all minterms of F are contained in (Fold u Dold) * and that all minterms of Fold are contained in (F u Dold). */ bool verify(pset_family F, pset_family Fold, pset_family Dold) { pcube p, last, *FD; bool verify_error = FALSE; /* Make sure the function didn't grow too large */ FD = cube2list(Fold, Dold); foreach_set(F, last, p) if (! cube_is_covered(FD, p)) { printf("some minterm in F is not covered by Fold u Dold\n"); verify_error = TRUE; if (verbose_debug) printf("%s\n", pc1(p)); else break; } free_cubelist(FD); /* Make sure minimized function covers the original function */ FD = cube2list(F, Dold); foreach_set(Fold, last, p) if (! cube_is_covered(FD, p)) { printf("some minterm in Fold is not covered by F u Dold\n"); verify_error = TRUE; if (verbose_debug) printf("%s\n", pc1(p)); else break; } free_cubelist(FD); return verify_error; }
static bool primes_consensus_special_cases(pset *T, pset_family *Tnew) /* will be disposed if answer is determined */ /* returned only if answer determined */ { register pcube *T1, p, ceil, cof=T[0]; pcube last; pcover A; /* Check for no cubes in the cover */ if (T[2] == NULL) { *Tnew = new_cover(0); free_cubelist(T); return TRUE; } /* Check for only a single cube in the cover */ if (T[3] == NULL) { *Tnew = sf_addset(new_cover(1), set_or(cof, cof, T[2])); free_cubelist(T); return TRUE; } /* Check for a row of all 1's (implies function is a tautology) */ for(T1 = T+2; (p = *T1++) != NULL; ) { if (full_row(p, cof)) { *Tnew = sf_addset(new_cover(1), cube.fullset); free_cubelist(T); return TRUE; } } /* Check for a column of all 0's which can be factored out */ ceil = set_save(cof); for(T1 = T+2; (p = *T1++) != NULL; ) { INLINEset_or(ceil, ceil, p); } if (! setp_equal(ceil, cube.fullset)) { p = new_cube(); (void) set_diff(p, cube.fullset, ceil); (void) set_or(cof, cof, p); free_cube(p); A = primes_consensus(T); foreach_set(A, last, p) { INLINEset_and(p, p, ceil); }
int check_equiv(pset_family f1, pset_family f2) { register pcube *f1list, *f2list; register pcube p, last; f1list = cube1list(f1); foreach_set(f2, last, p) { if (! cube_is_covered(f1list, p)) { return FALSE; } } free_cubelist(f1list); f2list = cube1list(f2); foreach_set(f1, last, p) { if (! cube_is_covered(f2list, p)) { return FALSE; } } free_cubelist(f2list); return TRUE; }
/* complement -- compute the complement of T */ pcover complement(pset *T) /* T will be disposed of */ { register pcube cl, cr; register int best; pcover Tbar, Tl, Tr; int lifting; static int compl_level = 0; if (debug & COMPL) debug_print(T, "COMPLEMENT", compl_level++); T = compl_special_cases(T, &Tbar); if (T != NULL){ /* Allocate space for the partition cubes */ cl = new_cube(); cr = new_cube(); best = binate_split_select(T, cl, cr, COMPL); /* Complement the left and right halves */ Tl = complement(scofactor(T, cl, best)); Tr = complement(scofactor(T, cr, best)); if (Tr->count*Tl->count > (Tr->count+Tl->count)*CUBELISTSIZE(T)) { lifting = USE_COMPL_LIFT_ONSET; } else { lifting = USE_COMPL_LIFT; } Tbar = compl_merge(T, Tl, Tr, cl, cr, best, lifting); free_cube(cl); free_cube(cr); free_cubelist(T); } if (debug & COMPL) debug1_print(Tbar, "exit COMPLEMENT", --compl_level); return Tbar; }
// complement -- compute the complement of T set_family_t * complement(set **T) { set *cl, *cr; int best; set_family_t *Tbar, *Tl, *Tr; int lifting; static int compl_level = 0; if (debug & COMPL) debug_print(T, "COMPLEMENT", compl_level++); if (compl_special_cases(T, &Tbar) == MAYBE) { // Allocate space for the partition cubes cl = set_new(CUBE.size); cr = set_new(CUBE.size); best = binate_split_select(T, cl, cr, COMPL); // Complement the left and right halves Tl = complement(scofactor(T, cl, best)); Tr = complement(scofactor(T, cr, best)); if (Tr->count*Tl->count > (Tr->count+Tl->count)*CUBELISTSIZE(T)) { lifting = USE_COMPL_LIFT_ONSET; } else { lifting = USE_COMPL_LIFT; } Tbar = compl_merge(T, Tl, Tr, cl, cr, best, lifting); set_free(cl); set_free(cr); free_cubelist(T); } if (debug & COMPL) debug1_print(Tbar, "exit COMPLEMENT", --compl_level); return Tbar; }
/* primes_consensus -- generate primes using consensus */ pcover primes_consensus(pset *T) /* T will be disposed of */ { register pcube cl, cr; register int best; pcover Tnew, Tl, Tr; if (primes_consensus_special_cases(T, &Tnew) == MAYBE) { cl = new_cube(); cr = new_cube(); best = binate_split_select(T, cl, cr, COMPL); Tl = primes_consensus(scofactor(T, cl, best)); Tr = primes_consensus(scofactor(T, cr, best)); Tnew = primes_consensus_merge(Tl, Tr, cl, cr); free_cube(cl); free_cube(cr); free_cubelist(T); } return Tnew; }
static bool compl_special_cases(pset *T, pset_family *Tbar) /* will be disposed if answer is determined */ /* returned only if answer determined */ { register pcube *T1, p, ceil, cof=T[0]; pcover A, ceil_compl; /* Check for no cubes in the cover */ if (T[2] == NULL) { *Tbar = sf_addset(new_cover(1), cube.fullset); free_cubelist(T); return TRUE; } /* Check for only a single cube in the cover */ if (T[3] == NULL) { *Tbar = compl_cube(set_or(cof, cof, T[2])); free_cubelist(T); return TRUE; } /* Check for a row of all 1's (implies complement is null) */ for(T1 = T+2; (p = *T1++) != NULL; ) { if (full_row(p, cof)) { *Tbar = new_cover(0); free_cubelist(T); return TRUE; } } /* Check for a column of all 0's which can be factored out */ ceil = set_save(cof); for(T1 = T+2; (p = *T1++) != NULL; ) { INLINEset_or(ceil, ceil, p); } if (! setp_equal(ceil, cube.fullset)) { ceil_compl = compl_cube(ceil); (void) set_or(cof, cof, set_diff(ceil, cube.fullset, ceil)); set_free(ceil); *Tbar = sf_append(complement(T), ceil_compl); return TRUE; } set_free(ceil); /* Collect column counts, determine unate variables, etc. */ massive_count(T); /* If single active variable not factored out above, then tautology ! */ if (cdata.vars_active == 1) { *Tbar = new_cover(0); free_cubelist(T); return TRUE; /* Check for unate cover */ } else if (cdata.vars_unate == cdata.vars_active) { A = map_cover_to_unate(T); free_cubelist(T); A = unate_compl(A); *Tbar = map_unate_to_cover(A); sf_free(A); return TRUE; /* Not much we can do about it */ } else { return MAYBE; } }
static bool compl_special_cases(set **T, set_family_t **Tbar) { set **T1, *p, *ceil, *cof=T[0]; set_family_t *A, *ceil_compl; // Check for no cubes in the cover if (T[2] == NULL) { *Tbar = sf_addset(sf_new(1, CUBE.size), CUBE.fullset); free_cubelist(T); return TRUE; } // Check for only a single cube in the cover if (T[3] == NULL) { *Tbar = compl_cube(set_or(cof, cof, T[2])); free_cubelist(T); return TRUE; } // Check for a row of all 1's (implies complement is null) for (T1 = T+2; (p = *T1++) != NULL; ) { if (full_row(p, cof)) { *Tbar = sf_new(0, CUBE.size); free_cubelist(T); return TRUE; } } // Check for a column of all 0's which can be factored out ceil = set_save(cof); for (T1 = T+2; (p = *T1++) != NULL; ) { set_or(ceil, ceil, p); } if (! setp_equal(ceil, CUBE.fullset)) { ceil_compl = compl_cube(ceil); set_or(cof, cof, set_diff(ceil, CUBE.fullset, ceil)); set_free(ceil); *Tbar = sf_append(complement(T), ceil_compl); return TRUE; } set_free(ceil); // Collect column counts, determine unate variables, etc. massive_count(T); // If single active variable not factored out above, then tautology! if (CDATA.vars_active == 1) { *Tbar = sf_new(0, CUBE.size); free_cubelist(T); return TRUE; // Check for unate cover } else if (CDATA.vars_unate == CDATA.vars_active) { A = map_cover_to_unate(T); free_cubelist(T); A = unate_compl(A); *Tbar = map_unate_to_cover(A); sf_free(A); return TRUE; // Not much we can do about it } else { return MAYBE; } }