/* Update the P to newP and they have the same cube sequence */ void Update_Partition(pcover newP, pcover P, pset x, pset q, int pos_q) { register pset r, tt=set_save(x), tmp=new_cube(); register int i, first_pos; /* The merge cube */ set_insert(tt, pos_q); /* Let the first variable of the merge cube is positive */ first_pos = Get_Var_Pos(tt, 0); if ((first_pos % 2) == 0) sf_addset(newP, set_save(tt)); else sf_addset(newP, Var_Phase_Inv(tt)); free_cube(tt); /* Add the other inputs sequently */ foreachi_set(P, i, r){ if (set_andp(tmp, r, x)) continue; if (set_andp(tmp, r, q)) continue; sf_addset(newP, r); } free_cube(tmp); }
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 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; }
void expand1_gasp(pset_family F, pset_family D, pset_family R, pset_family Foriginal, int c1index, pset_family *G) { register int c2index; register pset p, last, c2under; pset RAISE, FREESET, temp, *FD, c2essential; pset_family F1; if (debug & 0x0008) { printf("\nEXPAND1_GASP: \t%s\n", pc1(((F)->data + (F)->wsize * ( c1index)))); } RAISE = set_clear(((unsigned int *) malloc(sizeof(unsigned int) * ( ((cube.size) <= 32 ? 2 : (((((cube.size)-1) >> 5) + 1) + 1))))), cube.size); FREESET = set_clear(((unsigned int *) malloc(sizeof(unsigned int) * ( ((cube.size) <= 32 ? 2 : (((((cube.size)-1) >> 5) + 1) + 1))))), cube.size); temp = set_clear(((unsigned int *) malloc(sizeof(unsigned int) * ( ((cube.size) <= 32 ? 2 : (((((cube.size)-1) >> 5) + 1) + 1))))), cube.size); R->active_count = R->count; for( p=R->data, last= p+R->count*R->wsize; p< last; p+=R->wsize) { (p[0] |= ( 0x2000)); } F->active_count = F->count; for( c2under=F->data, c2index=0; c2index<F->count; c2under+=F->wsize, c2index++) { if (c1index == c2index || (c2under[0] & ( 0x8000))) { F->active_count--; (c2under[0] &= ~ ( 0x2000)); } else { (c2under[0] |= ( 0x2000)); } } (void) set_copy(RAISE, ((F)->data + (F)->wsize * ( c1index))); (void) set_diff(FREESET, cube.fullset, RAISE); essen_parts(R, F, RAISE, FREESET); essen_raising(R, RAISE, FREESET); for( c2under=F->data, c2index=0; c2index<F->count; c2under+=F->wsize, c2index++) { if ((c2under[0] & ( 0x2000))) { if (setp_implies(c2under, RAISE) || feasibly_covered(R, c2under, RAISE, temp)) { F1 = sf_save(Foriginal); (void) set_copy(((F1)->data + (F1)->wsize * ( c1index)), ((F)->data + (F)->wsize * ( c1index))); FD = cube2list(F1, D); c2essential = reduce_cube(FD, ((F1)->data + (F1)->wsize * ( c2index))); ((FD[0]) ? (free((char *) (FD[0])), (FD[0]) = 0) : 0); ((FD) ? (free((char *) (FD)), (FD) = 0) : 0);; sf_free(F1); if (feasibly_covered(R, c2essential, RAISE, temp)) { (void) set_or(temp, RAISE, c2essential); (temp[0] &= ~ ( 0x8000)); *G = sf_addset(*G, temp); } ((c2essential) ? (free((char *) (c2essential)), (c2essential) = 0) : 0); } } } ((RAISE) ? (free((char *) (RAISE)), (RAISE) = 0) : 0); ((FREESET) ? (free((char *) (FREESET)), (FREESET) = 0) : 0); ((temp) ? (free((char *) (temp)), (temp) = 0) : 0); }
/* Get the first group from P and add the remaining groups to M */ pset Get_First_Group(pcover P, pcover *M) { register pset result, q; register int i; result = set_save(GETSET(P, 0)); foreachi_set(P, i, q){ /* The be merged cube */ if (i == 0) continue; sf_addset(*M, q); } return result; }
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; } }
/* * Yes, I know this routine is a mess */ void read_cube(register FILE *fp, pPLA PLA) { register int var, i; pcube cf = cube.temp[0], cr = cube.temp[1], cd = cube.temp[2]; bool savef = FALSE, saved = FALSE, saver = FALSE; char token[256]; /* for kiss read hack */ int varx, first, last, offset; /* for kiss read hack */ set_clear(cf, cube.size); /* Loop and read binary variables */ for(var = 0; var < cube.num_binary_vars; var++) switch(getc(fp)) { case EOF: goto bad_char; case '\n': if (! line_length_error) fprintf(stderr, "product term(s) %s\n", "span more than one line (warning only)"); line_length_error = TRUE; lineno++; var--; break; case ' ': case '|': case '\t': var--; break; case '2': case '-': set_insert(cf, var*2+1); case '0': set_insert(cf, var*2); break; case '1': set_insert(cf, var*2+1); break; case '?': break; default: goto bad_char; } /* Loop for the all but one of the multiple-valued variables */ for(var = cube.num_binary_vars; var < cube.num_vars-1; var++) /* Read a symbolic multiple-valued variable */ if (cube.part_size[var] < 0) { (void) fscanf(fp, "%s", token); if (equal(token, "-") || equal(token, "ANY")) { if (kiss && var == cube.num_vars - 2) { /* leave it empty */ } else { /* make it full */ set_or(cf, cf, cube.var_mask[var]); } } else if (equal(token, "~")) { ; /* leave it empty ... (?) */ } else { if (kiss && var == cube.num_vars - 2) varx = var - 1, offset = ABS(cube.part_size[var-1]); else varx = var, offset = 0; /* Find the symbolic label in the label table */ first = cube.first_part[varx]; last = cube.last_part[varx]; for(i = first; i <= last; i++) if (PLA->label[i] == (char *) NULL) { PLA->label[i] = strdup(token); /* add new label */ set_insert(cf, i+offset); break; } else if (equal(PLA->label[i], token)) { set_insert(cf, i+offset); /* use column i */ break; } if (i > last) { fprintf(stderr, "declared size of variable %d (counting from variable 0) is too small\n", var); exit(-1); } } } else for(i = cube.first_part[var]; i <= cube.last_part[var]; i++) switch (getc(fp)) { case EOF: goto bad_char; case '\n': if (! line_length_error) fprintf(stderr, "product term(s) %s\n", "span more than one line (warning only)"); line_length_error = TRUE; lineno++; i--; break; case ' ': case '|': case '\t': i--; break; case '1': set_insert(cf, i); case '0': break; default: goto bad_char; } /* Loop for last multiple-valued variable */ if (kiss) { saver = savef = TRUE; (void) set_xor(cr, cf, cube.var_mask[cube.num_vars - 2]); } else set_copy(cr, cf); set_copy(cd, cf); for(i = cube.first_part[var]; i <= cube.last_part[var]; i++) switch (getc(fp)) { case EOF: goto bad_char; case '\n': if (! line_length_error) fprintf(stderr, "product term(s) %s\n", "span more than one line (warning only)"); line_length_error = TRUE; lineno++; i--; break; case ' ': case '|': case '\t': i--; break; case '4': case '1': if (PLA->pla_type & F_type) set_insert(cf, i), savef = TRUE; break; case '3': case '0': if (PLA->pla_type & R_type) set_insert(cr, i), saver = TRUE; break; case '2': case '-': if (PLA->pla_type & D_type) set_insert(cd, i), saved = TRUE; case '~': break; default: goto bad_char; } if (savef) PLA->F = sf_addset(PLA->F, cf); if (saved) PLA->D = sf_addset(PLA->D, cd); if (saver) PLA->R = sf_addset(PLA->R, cr); return; bad_char: fprintf(stderr, "(warning): input line #%d ignored\n", lineno); skip_line(fp, stdout, TRUE); return; }
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; } }