2008-01-31 05:01:00 +01:00
|
|
|
|
/*
|
|
|
|
|
|
* Revision Control Information
|
|
|
|
|
|
*
|
|
|
|
|
|
* $Source$
|
|
|
|
|
|
* $Author$
|
|
|
|
|
|
* $Revision$
|
|
|
|
|
|
* $Date$
|
|
|
|
|
|
*
|
|
|
|
|
|
*/
|
|
|
|
|
|
#include "espresso.h"
|
|
|
|
|
|
|
2010-11-01 09:35:04 +01:00
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-01-31 05:01:00 +01:00
|
|
|
|
|
|
|
|
|
|
static void dump_irredundant();
|
|
|
|
|
|
static pcover do_minimize();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* minimize_exact -- main entry point for exact minimization
|
|
|
|
|
|
*
|
|
|
|
|
|
* Global flags which affect this routine are:
|
|
|
|
|
|
*
|
|
|
|
|
|
* debug
|
|
|
|
|
|
* skip_make_sparse
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
pcover
|
|
|
|
|
|
minimize_exact(F, D, R, exact_cover)
|
|
|
|
|
|
pcover F, D, R;
|
|
|
|
|
|
int exact_cover;
|
|
|
|
|
|
{
|
|
|
|
|
|
return do_minimize(F, D, R, exact_cover, /*weighted*/ 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pcover
|
|
|
|
|
|
minimize_exact_literals(F, D, R, exact_cover)
|
|
|
|
|
|
pcover F, D, R;
|
|
|
|
|
|
int exact_cover;
|
|
|
|
|
|
{
|
|
|
|
|
|
return do_minimize(F, D, R, exact_cover, /*weighted*/ 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static pcover
|
|
|
|
|
|
do_minimize(F, D, R, exact_cover, weighted)
|
|
|
|
|
|
pcover F, D, R;
|
|
|
|
|
|
int exact_cover;
|
|
|
|
|
|
int weighted;
|
|
|
|
|
|
{
|
|
|
|
|
|
pcover newF, E, Rt, Rp;
|
|
|
|
|
|
pset p, last;
|
|
|
|
|
|
int heur, level, *weights, i;
|
|
|
|
|
|
sm_matrix *table;
|
|
|
|
|
|
sm_row *cover;
|
|
|
|
|
|
sm_element *pe;
|
|
|
|
|
|
int debug_save = debug;
|
|
|
|
|
|
|
|
|
|
|
|
if (debug & EXACT) {
|
|
|
|
|
|
debug |= (IRRED | MINCOV);
|
|
|
|
|
|
}
|
|
|
|
|
|
#if defined(sun) || defined(bsd4_2) /* hack ... */
|
|
|
|
|
|
if (debug & MINCOV) {
|
|
|
|
|
|
setlinebuf(stdout);
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
level = (debug & MINCOV) ? 4 : 0;
|
|
|
|
|
|
heur = ! exact_cover;
|
|
|
|
|
|
|
|
|
|
|
|
/* Generate all prime implicants */
|
|
|
|
|
|
EXEC(F = primes_consensus(cube2list(F, D)), "PRIMES ", F);
|
|
|
|
|
|
|
|
|
|
|
|
/* Setup the prime implicant table */
|
|
|
|
|
|
EXEC(irred_split_cover(F, D, &E, &Rt, &Rp), "ESSENTIALS ", E);
|
|
|
|
|
|
EXEC(table = irred_derive_table(D, E, Rp), "PI-TABLE ", Rp);
|
|
|
|
|
|
|
|
|
|
|
|
/* Solve either a weighted or nonweighted covering problem */
|
|
|
|
|
|
if (weighted) {
|
|
|
|
|
|
/* correct only for all 2-valued variables */
|
|
|
|
|
|
weights = ALLOC(int, F->count);
|
|
|
|
|
|
foreach_set(Rp, last, p) {
|
|
|
|
|
|
weights[SIZE(p)] = cube.size - set_ord(p);
|
|
|
|
|
|
/* We have added the 0's in the output part instead of the 1's.
|
|
|
|
|
|
This loop corrects the literal count. */
|
|
|
|
|
|
for (i = cube.first_part[cube.output];
|
|
|
|
|
|
i <= cube.last_part[cube.output]; i++) {
|
|
|
|
|
|
is_in_set(p, i) ? weights[SIZE(p)]++ : weights[SIZE(p)]--;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
weights = NIL(int);
|
|
|
|
|
|
}
|
|
|
|
|
|
EXEC(cover=sm_minimum_cover(table,weights,heur,level), "MINCOV ", F);
|
|
|
|
|
|
if (weights != 0) {
|
|
|
|
|
|
FREE(weights);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (debug & EXACT) {
|
|
|
|
|
|
dump_irredundant(E, Rt, Rp, table);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Form the result cover */
|
|
|
|
|
|
newF = new_cover(100);
|
|
|
|
|
|
foreach_set(E, last, p) {
|
|
|
|
|
|
newF = sf_addset(newF, p);
|
|
|
|
|
|
}
|
|
|
|
|
|
sm_foreach_row_element(cover, pe) {
|
|
|
|
|
|
newF = sf_addset(newF, GETSET(F, pe->col_num));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
free_cover(E);
|
|
|
|
|
|
free_cover(Rt);
|
|
|
|
|
|
free_cover(Rp);
|
|
|
|
|
|
sm_free(table);
|
|
|
|
|
|
sm_row_free(cover);
|
|
|
|
|
|
free_cover(F);
|
|
|
|
|
|
|
|
|
|
|
|
/* Attempt to make the results more sparse */
|
|
|
|
|
|
debug &= ~ (IRRED | SHARP | MINCOV);
|
|
|
|
|
|
if (! skip_make_sparse && R != 0) {
|
|
|
|
|
|
newF = make_sparse(newF, D, R);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
debug = debug_save;
|
|
|
|
|
|
return newF;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
dump_irredundant(E, Rt, Rp, table)
|
|
|
|
|
|
pcover E, Rt, Rp;
|
|
|
|
|
|
sm_matrix *table;
|
|
|
|
|
|
{
|
|
|
|
|
|
FILE *fp_pi_table, *fp_primes;
|
|
|
|
|
|
pPLA PLA;
|
|
|
|
|
|
pset last, p;
|
|
|
|
|
|
char *file;
|
|
|
|
|
|
|
|
|
|
|
|
if (filename == 0 || strcmp(filename, "(stdin)") == 0) {
|
|
|
|
|
|
fp_pi_table = fp_primes = stdout;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
file = ALLOC(char, strlen(filename)+20);
|
|
|
|
|
|
(void) sprintf(file, "%s.primes", filename);
|
|
|
|
|
|
if ((fp_primes = fopen(file, "w")) == NULL) {
|
|
|
|
|
|
(void) fprintf(stderr, "espresso: Unable to open %s\n", file);
|
|
|
|
|
|
fp_primes = stdout;
|
|
|
|
|
|
}
|
|
|
|
|
|
(void) sprintf(file, "%s.pi", filename);
|
|
|
|
|
|
if ((fp_pi_table = fopen(file, "w")) == NULL) {
|
|
|
|
|
|
(void) fprintf(stderr, "espresso: Unable to open %s\n", file);
|
|
|
|
|
|
fp_pi_table = stdout;
|
|
|
|
|
|
}
|
|
|
|
|
|
FREE(file);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PLA = new_PLA();
|
|
|
|
|
|
PLA_labels(PLA);
|
|
|
|
|
|
|
|
|
|
|
|
fpr_header(fp_primes, PLA, F_type);
|
|
|
|
|
|
free_PLA(PLA);
|
|
|
|
|
|
|
|
|
|
|
|
(void) fprintf(fp_primes, "# Essential primes are\n");
|
|
|
|
|
|
foreach_set(E, last, p) {
|
|
|
|
|
|
(void) fprintf(fp_primes, "%s\n", pc1(p));
|
|
|
|
|
|
}
|
|
|
|
|
|
(void) fprintf(fp_primes, "# Totally redundant primes are\n");
|
|
|
|
|
|
foreach_set(Rt, last, p) {
|
|
|
|
|
|
(void) fprintf(fp_primes, "%s\n", pc1(p));
|
|
|
|
|
|
}
|
|
|
|
|
|
(void) fprintf(fp_primes, "# Partially redundant primes are\n");
|
|
|
|
|
|
foreach_set(Rp, last, p) {
|
|
|
|
|
|
(void) fprintf(fp_primes, "%s\n", pc1(p));
|
|
|
|
|
|
}
|
|
|
|
|
|
if (fp_primes != stdout) {
|
|
|
|
|
|
(void) fclose(fp_primes);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sm_write(fp_pi_table, table);
|
|
|
|
|
|
if (fp_pi_table != stdout) {
|
|
|
|
|
|
(void) fclose(fp_pi_table);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2010-11-01 09:35:04 +01:00
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|
|
|
|
|