/*
 * Revision Control Information
 *
 * $Source$
 * $Author$
 * $Revision$
 * $Date$
 *
 */
#include "espresso.h"

ABC_NAMESPACE_IMPL_START



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);
    }
}
ABC_NAMESPACE_IMPL_END

