/* cube_setup -- assume that the fields "num_vars", "num_binary_vars", and part_size[num_binary_vars .. num_vars-1] are setup, and initialize the rest of cube and cdata. If a part_size is < 0, then the field size is abs(part_size) and the field read from the input is symbolic. */ void cube_setup() { register int i, var; register pcube p; if (cube.num_binary_vars < 0 || cube.num_vars < cube.num_binary_vars) fatal("cube size is silly, error in .i/.o or .mv"); cube.num_mv_vars = cube.num_vars - cube.num_binary_vars; cube.output = cube.num_mv_vars > 0 ? cube.num_vars - 1 : -1; cube.size = 0; cube.first_part = ALLOC(int, cube.num_vars); cube.last_part = ALLOC(int, cube.num_vars); cube.first_word = ALLOC(int, cube.num_vars); cube.last_word = ALLOC(int, cube.num_vars); for(var = 0; var < cube.num_vars; var++) { if (var < cube.num_binary_vars) cube.part_size[var] = 2; cube.first_part[var] = cube.size; cube.first_word[var] = WHICH_WORD(cube.size); cube.size += ABS(cube.part_size[var]); cube.last_part[var] = cube.size - 1; cube.last_word[var] = WHICH_WORD(cube.size - 1); } cube.var_mask = ALLOC(pset, cube.num_vars); cube.sparse = ALLOC(int, cube.num_vars); cube.binary_mask = new_cube(); cube.mv_mask = new_cube(); for(var = 0; var < cube.num_vars; var++) { p = cube.var_mask[var] = new_cube(); for(i = cube.first_part[var]; i <= cube.last_part[var]; i++) set_insert(p, i); if (var < cube.num_binary_vars) { INLINEset_or(cube.binary_mask, cube.binary_mask, p); cube.sparse[var] = 0; } else { INLINEset_or(cube.mv_mask, cube.mv_mask, p); cube.sparse[var] = 1; } } if (cube.num_binary_vars == 0) cube.inword = -1; else { cube.inword = cube.last_word[cube.num_binary_vars - 1]; cube.inmask = cube.binary_mask[cube.inword] & DISJOINT; } cube.temp = ALLOC(pset, CUBE_TEMP); for(i = 0; i < CUBE_TEMP; i++) cube.temp[i] = new_cube(); cube.fullset = set_fill(new_cube(), cube.size); cube.emptyset = new_cube(); cdata.part_zeros = ALLOC(int, cube.size); cdata.var_zeros = ALLOC(int, cube.num_vars); cdata.parts_active = ALLOC(int, cube.num_vars); cdata.is_unate = ALLOC(int, cube.num_vars); }
/* sf_or -- form the "or" of all sets in a set family */ pset sf_or(pset_family A) { register pset or, last, p; or = set_new(A->sf_size); foreach_set(A, last, p) INLINEset_or(or, or, p); return or; }
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); }
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; } }
ABC_NAMESPACE_IMPL_START /* cube_setup -- assume that the fields "num_vars", "num_binary_vars", and part_size[num_binary_vars .. num_vars-1] are setup, and initialize the rest of cube and cdata. If a part_size is < 0, then the field size is abs(part_size) and the field read from the input is symbolic. */ void cube_setup() { register int i, var; register pcube p; if (cube.num_binary_vars < 0 || cube.num_vars < cube.num_binary_vars) fatal("cube size is silly, error in .i/.o or .mv"); cube.num_mv_vars = cube.num_vars - cube.num_binary_vars; cube.output = cube.num_mv_vars > 0 ? cube.num_vars - 1 : -1; cube.size = 0; cube.first_part = ALLOC(int, cube.num_vars); cube.last_part = ALLOC(int, cube.num_vars); cube.first_word = ALLOC(int, cube.num_vars); cube.last_word = ALLOC(int, cube.num_vars); for(var = 0; var < cube.num_vars; var++) { if (var < cube.num_binary_vars) cube.part_size[var] = 2; cube.first_part[var] = cube.size; cube.first_word[var] = WHICH_WORD(cube.size); cube.size += ABS(cube.part_size[var]); cube.last_part[var] = cube.size - 1; cube.last_word[var] = WHICH_WORD(cube.size - 1); } cube.var_mask = ALLOC(pset, cube.num_vars); cube.sparse = ALLOC(int, cube.num_vars); cube.binary_mask = new_cube(); cube.mv_mask = new_cube(); for(var = 0; var < cube.num_vars; var++) { p = cube.var_mask[var] = new_cube(); for(i = cube.first_part[var]; i <= cube.last_part[var]; i++) set_insert(p, i); if (var < cube.num_binary_vars) { INLINEset_or(cube.binary_mask, cube.binary_mask, p); cube.sparse[var] = 0; } else { INLINEset_or(cube.mv_mask, cube.mv_mask, p); cube.sparse[var] = 1; } } if (cube.num_binary_vars == 0) cube.inword = -1; else { cube.inword = cube.last_word[cube.num_binary_vars - 1]; cube.inmask = cube.binary_mask[cube.inword] & DISJOINT; } cube.temp = ALLOC(pset, CUBE_TEMP); for(i = 0; i < CUBE_TEMP; i++) cube.temp[i] = new_cube(); cube.fullset = set_fill(new_cube(), cube.size); cube.emptyset = new_cube(); cdata.part_zeros = ALLOC(int, cube.size); cdata.var_zeros = ALLOC(int, cube.num_vars); cdata.parts_active = ALLOC(int, cube.num_vars); cdata.is_unate = ALLOC(int, cube.num_vars); }