/* * Revision Control Information * * $Source$ * $Author$ * $Revision$ * $Date$ * */ #include "espresso.h" ABC_NAMESPACE_IMPL_START static bool primes_consensus_special_cases(); static pcover primes_consensus_merge(); static pcover and_with_cofactor(); /* primes_consensus -- generate primes using consensus */ pcover primes_consensus(T) pcube *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 primes_consensus_special_cases(T, Tnew) pcube *T; /* will be disposed if answer is determined */ pcover *Tnew; /* 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); } *Tnew = A; set_free(ceil); 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) { *Tnew = sf_addset(new_cover(1), cube.fullset); free_cubelist(T); return TRUE; /* Check for unate cover */ } else if (cdata.vars_unate == cdata.vars_active) { A = cubeunlist(T); *Tnew = sf_contain(A); free_cubelist(T); return TRUE; /* Not much we can do about it */ } else { return MAYBE; } } static pcover primes_consensus_merge(Tl, Tr, cl, cr) pcover Tl, Tr; pcube cl, cr; { register pcube pl, pr, lastl, lastr, pt; pcover T, Tsave; Tl = and_with_cofactor(Tl, cl); Tr = and_with_cofactor(Tr, cr); T = sf_new(500, Tl->sf_size); pt = T->data; Tsave = sf_contain(sf_join(Tl, Tr)); foreach_set(Tl, lastl, pl) { foreach_set(Tr, lastr, pr) { if (cdist01(pl, pr) == 1) { consensus(pt, pl, pr); if (++T->count >= T->capacity) { Tsave = sf_union(Tsave, sf_contain(T)); T = sf_new(500, Tl->sf_size); pt = T->data; } else { pt += T->wsize; } } } } free_cover(Tl); free_cover(Tr); Tsave = sf_union(Tsave, sf_contain(T)); return Tsave; } static pcover and_with_cofactor(A, cof) pset_family A; register pset cof; { register pset last, p; foreach_set(A, last, p) { INLINEset_and(p, p, cof); if (cdist(p, cube.fullset) > 0) { RESET(p, ACTIVE); } else { SET(p, ACTIVE); } } return sf_inactive(A); } ABC_NAMESPACE_IMPL_END