pcover reduce(pset_family F, pset_family D) { register pcube last, p, cunder, *FD; /* Order the cubes */ if (use_random_order) F = random_order(F); else { F = toggle ? sort_reduce(F) : mini_sort(F, (qsort_compare_func) descend); toggle = ! toggle; } /* Try to reduce each cube */ FD = cube2list(F, D); foreach_set(F, last, p) { cunder = reduce_cube(FD, p); /* reduce the cube */ if (setp_equal(cunder, p)) { /* see if it actually did */ SET(p, ACTIVE); /* cube remains active */ SET(p, PRIME); /* cube remains prime ? */ } else { if (debug & REDUCE) { printf("REDUCE: %s to %s %s\n", pc1(p), pc2(cunder), print_time(ptime())); } set_copy(p, cunder); /* save reduced version */ RESET(p, PRIME); /* cube is no longer prime */ if (setp_empty(cunder)) RESET(p, ACTIVE); /* if null, kill the cube */ else SET(p, ACTIVE); /* cube is active */ } free_cube(cunder); }
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); }
/* Try to expand each nonprime and noncovered cube */ foreach_set(F, last, p) { /* do not expand if PRIME or if covered by previous expansion */ if (! TESTP(p, PRIME) && ! TESTP(p, COVERED)) { /* expand the cube p, result is RAISE */ expand1(R, F, RAISE, FREESET, OVEREXPANDED_CUBE, SUPER_CUBE, INIT_LOWER, &num_covered, p); if (debug & EXPAND) printf("EXPAND: %s (covered %d)\n", pc1(p), num_covered); (void) set_copy(p, RAISE); SET(p, PRIME); RESET(p, COVERED); /* not really necessary */ /* See if we generated an inessential prime */ if (num_covered == 0 && ! setp_equal(p, OVEREXPANDED_CUBE)) { SET(p, NONESSEN); } } }
static pset_family reduce_gasp(pset_family F, pset_family D) { pset p, last, cunder, *FD; pset_family G; G = sf_new(F->count, cube.size); FD = cube2list(F, D); for( p=F->data, last= p+F->count*F->wsize; p< last; p+=F->wsize) { cunder = reduce_cube(FD, p); if (setp_empty(cunder)) { fatal("empty reduction in reduce_gasp, shouldn't happen"); } else if (setp_equal(cunder, p)) { (cunder[0] |= ( 0x8000)); G = sf_addset(G, p); } else { (cunder[0] &= ~ ( 0x8000)); G = sf_addset(G, cunder); } if (debug & 0x0010) { printf("REDUCE_GASP: %s reduced to %s\n", pc1(p), pc2(cunder)); } ((cunder) ? (free((char *) (cunder)), (cunder) = 0) : 0); } ((FD[0]) ? (free((char *) (FD[0])), (FD[0]) = 0) : 0); ((FD) ? (free((char *) (FD)), (FD) = 0) : 0);; return G; }
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; } }