/*
 * Revision Control Information
 *
 * $Source$
 * $Author$
 * $Revision$
 * $Date$
 *
 */
/*
 *   set.c -- routines for maniuplating sets and set families
 */

/* LINTLIBRARY */

#include "espresso.h"

ABC_NAMESPACE_IMPL_START

static pset_family set_family_garbage = NULL;

static void intcpy(d, s, n)
register unsigned int *d, *s;
register long n;
{
    register int i;
    for(i = 0; i < n; i++) {
    *d++ = *s++;
    }
}


/* bit_index -- find first bit (from LSB) in a word (MSB=bit n, LSB=bit 0) */
int bit_index(a)
register unsigned int a;
{
    register int i;
    if (a == 0)
    return -1;
    for(i = 0; (a & 1) == 0; a >>= 1, i++)
    ;
    return i;
}


/* set_ord -- count number of elements in a set */
int set_ord(a)
register pset a;
{
    register int i, sum = 0;
    register unsigned int val;
    for(i = LOOP(a); i > 0; i--)
    if ((val = a[i]) != 0)
        sum += count_ones(val);
    return sum;
}

/* set_dist -- distance between two sets (# elements in common) */
int set_dist(a, b)
register pset a, b;
{
    register int i, sum = 0;
    register unsigned int val;
    for(i = LOOP(a); i > 0; i--)
    if ((val = a[i] & b[i]) != 0)
        sum += count_ones(val);
    return sum;
}

/* set_clear -- make "r" the empty set of "size" elements */
pset set_clear(r, size)
register pset r;
int size;
{
    register int i = LOOPINIT(size);
    *r = i; do r[i] = 0; while (--i > 0);
    return r;
}

/* set_fill -- make "r" the universal set of "size" elements */
pset set_fill(r, size)
register pset r;
register int size;
{
    register int i = LOOPINIT(size);
    *r = i;
    r[i] = ~ (unsigned) 0;
    r[i] >>= i * BPI - size;
    while (--i > 0)
    r[i] = ~ (unsigned) 0;
    return r;
}

/* set_copy -- copy set a into set r */
pset set_copy(r, a)
register pset r, a;
{
    register int i = LOOPCOPY(a);
    do r[i] = a[i]; while (--i >= 0);
    return r;
}

/* set_and -- compute intersection of sets "a" and "b" */
pset set_and(r, a, b)
register pset r, a, b;
{
    register int i = LOOP(a);
    PUTLOOP(r,i); do r[i] = a[i] & b[i]; while (--i > 0);
    return r;
}

/* set_or -- compute union of sets "a" and "b" */
pset set_or(r, a, b)
register pset r, a, b;
{
    register int i = LOOP(a);
    PUTLOOP(r,i); do r[i] = a[i] | b[i]; while (--i > 0);
    return r;
}

/* set_diff -- compute difference of sets "a" and "b" */
pset set_diff(r, a, b)
register pset r, a, b;
{
    register int i = LOOP(a);
    PUTLOOP(r,i); do r[i] = a[i] & ~b[i]; while (--i > 0);
    return r;
}

/* set_xor -- compute exclusive-or of sets "a" and "b" */
pset set_xor(r, a, b)
register pset r, a, b;
{
    register int i = LOOP(a);
#ifdef IBM_WATC
    PUTLOOP(r,i); do r[i] = (a[i]&~b[i]) | (~a[i]&b[i]); while (--i > 0);
#else
    PUTLOOP(r,i); do r[i] = a[i] ^ b[i]; while (--i > 0);
#endif
    return r;
}

/* set_merge -- compute "a" & "mask" | "b" & ~ "mask" */
pset set_merge(r, a, b, mask)
register pset r, a, b, mask;
{
    register int i = LOOP(a);
    PUTLOOP(r,i); do r[i] = (a[i]&mask[i]) | (b[i]&~mask[i]); while (--i > 0);
    return r;
}

/* set_andp -- compute intersection of sets "a" and "b" , TRUE if nonempty */
bool set_andp(r, a, b)
register pset r, a, b;
{
    register int i = LOOP(a);
    register unsigned int x = 0;
    PUTLOOP(r,i); do {r[i] = a[i] & b[i]; x |= r[i];} while (--i > 0);
    return x != 0;
}

/* set_orp -- compute union of sets "a" and "b" , TRUE if nonempty */
bool set_orp(r, a, b)
register pset r, a, b;
{
    register int i = LOOP(a);
    register unsigned int x = 0;
    PUTLOOP(r,i); do {r[i] = a[i] | b[i]; x |= r[i];} while (--i > 0);
    return x != 0;
}

/* setp_empty -- check if the set "a" is empty */
bool setp_empty(a)
register pset a;
{
    register int i = LOOP(a);
    do if (a[i]) return FALSE; while (--i > 0);
    return TRUE;
}

/* setp_full -- check if the set "a" is the full set of "size" elements */
bool setp_full(a, size)
register pset a;
register int size;
{
    register int i = LOOP(a);
    register unsigned int test;
    test = ~ (unsigned) 0;
    test >>= i * BPI - size;
    if (a[i] != test)
    return FALSE;
    while (--i > 0)
    if (a[i] != (~(unsigned) 0))
        return FALSE;
    return TRUE;
}

/* setp_equal -- check if the set "a" equals set "b" */
bool setp_equal(a, b)
register pset a, b;
{
    register int i = LOOP(a);
    do if (a[i] != b[i]) return FALSE; while (--i > 0);
    return TRUE;
}

/* setp_disjoint -- check if intersection of "a" and "b" is empty */
bool setp_disjoint(a, b)
register pset a, b;
{
    register int i = LOOP(a);
    do if (a[i] & b[i]) return FALSE; while (--i > 0);
    return TRUE;
}

/* setp_implies -- check if "a" implies "b" ("b" contains "a") */
bool setp_implies(a, b)
register pset a, b;
{
    register int i = LOOP(a);
    do if (a[i] & ~b[i]) return FALSE; while (--i > 0);
    return TRUE;
}

/* sf_or -- form the "or" of all sets in a set family */
pset sf_or(A)
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;
}

/* sf_and -- form the "and" of all sets in a set family */
pset sf_and(A)
pset_family A;
{
    register pset and, last, p;

    and = set_fill(set_new(A->sf_size), A->sf_size);
    foreach_set(A, last, p)
    INLINEset_and(and, and, p);
    return and;
}

/* sf_active -- make all members of the set family active */
pset_family sf_active(A)
pset_family A;
{
    register pset p, last;
    foreach_set(A, last, p) {
    SET(p, ACTIVE);
    }
    A->active_count = A->count;
    return A;
}


/* sf_inactive -- remove all inactive cubes in a set family */
pset_family sf_inactive(A)
pset_family A;
{
    register pset p, last, pdest;

    pdest = A->data;
    foreach_set(A, last, p) {
    if (TESTP(p, ACTIVE)) {
        if (pdest != p) {
        INLINEset_copy(pdest, p);
        }
        pdest += A->wsize;
    } else {
        A->count--;
    }
    }
    return A;
}


/* sf_copy -- copy a set family */
pset_family sf_copy(R, A)
pset_family R, A;
{
    R->sf_size = A->sf_size;
    R->wsize = A->wsize;
/*R->capacity = A->count;*/
/*R->data = REALLOC(unsigned int, R->data, (long) R->capacity * R->wsize);*/
    R->count = A->count;
    R->active_count = A->active_count;
    intcpy(R->data, A->data, (long) A->wsize * A->count);
    return R;
}


/* sf_join -- join A and B into a single set_family */
pset_family sf_join(A, B)
pset_family A, B;
{
    pset_family R;
    long asize = A->count * A->wsize;
    long bsize = B->count * B->wsize;

    if (A->sf_size != B->sf_size) fatal("sf_join: sf_size mismatch");
    R = sf_new(A->count + B->count, A->sf_size);
    R->count = A->count + B->count;
    R->active_count = A->active_count + B->active_count;
    intcpy(R->data, A->data, asize);
    intcpy(R->data + asize, B->data, bsize);
    return R;
}


/* sf_append -- append the sets of B to the end of A, and dispose of B */
pset_family sf_append(A, B)
pset_family A, B;
{
    long asize = A->count * A->wsize;
    long bsize = B->count * B->wsize;

    if (A->sf_size != B->sf_size) fatal("sf_append: sf_size mismatch");
    A->capacity = A->count + B->count;
    A->data = REALLOC(unsigned int, A->data, (long) A->capacity * A->wsize);
    intcpy(A->data + asize, B->data, bsize);
    A->count += B->count;
    A->active_count += B->active_count;
    sf_free(B);
    return A;
}


/* sf_new -- allocate "num" sets of "size" elements each */
pset_family sf_new(num, size)
int num, size;
{
    pset_family A;
    if (set_family_garbage == NULL) {
    A = ALLOC(set_family_t, 1);
    } else {
    A = set_family_garbage;
    set_family_garbage = A->next;
    }
    A->sf_size = size;
    A->wsize = SET_SIZE(size);
    A->capacity = num;
    A->data = ALLOC(unsigned int, (long) A->capacity * A->wsize);
    A->count = 0;
    A->active_count = 0;
    return A;
}


/* sf_save -- create a duplicate copy of a set family */
pset_family sf_save(A)
register pset_family A;
{
    return sf_copy(sf_new(A->count, A->sf_size), A);
}


/* sf_free -- free the storage allocated for a set family */
void sf_free(A)
pset_family A;
{
    FREE(A->data);
    A->next = set_family_garbage;
    set_family_garbage = A;
}


/* sf_cleanup -- free all of the set families from the garbage list */
void sf_cleanup()
{
    register pset_family p, pnext;
    for(p = set_family_garbage; p != (pset_family) NULL; p = pnext) {
    pnext = p->next;
    FREE(p);
    }
    set_family_garbage = (pset_family) NULL;
}


/* sf_addset -- add a set to the end of a set family */
pset_family sf_addset(A, s)
pset_family A;
pset s;
{
    register pset p;

    if (A->count >= A->capacity) {
    A->capacity = A->capacity + A->capacity/2 + 1;
    A->data = REALLOC(unsigned int, A->data, (long) A->capacity * A->wsize);
    }
    p = GETSET(A, A->count++);
    INLINEset_copy(p, s);
    return A;
}

/* sf_delset -- delete a set from a set family */
void sf_delset(A, i)
pset_family A;
int i;
{   (void) set_copy(GETSET(A,i), GETSET(A, --A->count));}

/* sf_print -- print a set_family as a set (list the element numbers) */
void sf_print(A)
pset_family A;
{
    char *ps1();
    register pset p;
    register int i;
    foreachi_set(A, i, p)
    printf("A[%d] = %s\n", i, ps1(p));
}

/* sf_bm_print -- print a set_family as a bit-matrix */
void sf_bm_print(A)
pset_family A;
{
    char *pbv1();
    register pset p;
    register int i;
    foreachi_set(A, i, p)
    printf("[%4d] %s\n", i, pbv1(p, A->sf_size));
}


/* sf_write -- output a set family in an unintelligable manner */
void sf_write(fp, A)
FILE *fp;
pset_family A;
{
    register pset p, last;
    (void) fprintf(fp, "%d %d\n", A->count, A->sf_size);
    foreach_set(A, last, p)
    set_write(fp, p);
    (void) fflush(fp);
}


/* sf_read -- read a set family written by sf_write */
pset_family sf_read(fp)
FILE *fp;
{
    int i, j;
    register pset p, last;
    pset_family A;

    (void) fscanf(fp, "%d %d\n", &i, &j);
    A = sf_new(i, j);
    A->count = i;
    foreach_set(A, last, p) {
    (void) fscanf(fp, "%x", p);
    for(j = 1; j <= LOOP(p); j++)
        (void) fscanf(fp, "%x", p+j);
    }
    return A;
}


/* set_write -- output a set in an unintelligable manner */
void set_write(fp, a)
register FILE *fp;
register pset a;
{
    register int n = LOOP(a), j;

    for(j = 0; j <= n; j++) {
    (void) fprintf(fp, "%x ", a[j]);
    if ((j+1) % 8 == 0 && j != n)
        (void) fprintf(fp, "\n\t");
    }
    (void) fprintf(fp, "\n");
}


/* sf_bm_read -- read a set family written by sf_bm_print (almost) */
pset_family sf_bm_read(fp)
FILE *fp;
{
    int i, j, rows, cols;
    register pset pdest;
    pset_family A;

    (void) fscanf(fp, "%d %d\n", &rows, &cols);
    A = sf_new(rows, cols);
    for(i = 0; i < rows; i++) {
    pdest = GETSET(A, A->count++);
    (void) set_clear(pdest, A->sf_size);
    for(j = 0; j < cols; j++) {
        switch(getc(fp)) {
        case '0':
            break;
        case '1':
            set_insert(pdest, j);
            break;
        default:
            fatal("Error reading set family");
        }
    }
    if (getc(fp) != '\n') {
        fatal("Error reading set family (at end of line)");
    }
    }
    return A;
}



/* ps1 -- convert a set into a printable string */
#define largest_string 120
static char s1[largest_string];
char *ps1(a)
register pset a;
{
    register int i, num, l, len = 0, n = NELEM(a);
    char temp[20];
    bool first = TRUE;

    s1[len++] = '[';
    for(i = 0; i < n; i++)
    if (is_in_set(a,i)) {
        if (! first)
        s1[len++] = ',';
        first = FALSE; num = i;
        /* Generate digits (reverse order) */
        l = 0; do temp[l++] = num % 10 + '0'; while ((num /= 10) > 0);
        /* Copy them back in correct order */
        do s1[len++] = temp[--l]; while (l > 0);
        if (len > largest_string-15) {
        s1[len++] = '.'; s1[len++] = '.'; s1[len++] = '.';
        break;
        }
    }

    s1[len++] = ']';
    s1[len++] = '\0';
    return s1;
}

/* pbv1 -- print bit-vector */
char *pbv1(s, n)
pset s;
int n;
{
    register int i;
    for(i = 0; i < n; i++)
    s1[i] = is_in_set(s,i) ? '1' : '0';
    s1[n] = '\0';
    return s1;
}


/* set_adjcnt -- adjust the counts for a set by "weight" */
void
set_adjcnt(a, count, weight)
register pset a;
register int *count, weight;
{
    register int i, base;
    register unsigned int val;

    for(i = LOOP(a); i > 0; ) {
    for(val = a[i], base = --i << LOGBPI; val != 0; base++, val >>= 1) {
        if (val & 1) {
        count[base] += weight;
        }
    }
    }
}



/* sf_count -- perform a column sum over a set family */
int *sf_count(A)
pset_family A;
{
    register pset p, last;
    register int i, base, *count;
    register unsigned int val;

    count = ALLOC(int, A->sf_size);
    for(i = A->sf_size - 1; i >= 0; i--) {
    count[i] = 0;
    }

    foreach_set(A, last, p) {
    for(i = LOOP(p); i > 0; ) {
        for(val = p[i], base = --i << LOGBPI; val != 0; base++, val >>= 1) {
        if (val & 1) {
            count[base]++;
        }
        }
    }
    }
    return count;
}


/* sf_count_restricted -- perform a column sum over a set family, restricting
 * to only the columns which are in r; also, the columns are weighted by the
 * number of elements which are in each row
 */
int *sf_count_restricted(A, r)
pset_family A;
register pset r;
{
    register pset p;
    register int i, base, *count;
    register unsigned int val;
    int weight;
    pset last;

    count = ALLOC(int, A->sf_size);
    for(i = A->sf_size - 1; i >= 0; i--) {
    count[i] = 0;
    }

    /* Loop for each set */
    foreach_set(A, last, p) {
    weight = 1024 / (set_ord(p) - 1);
    for(i = LOOP(p); i > 0; ) {
        for(val=p[i]&r[i], base= --i<<LOGBPI; val!=0; base++, val >>= 1) {
        if (val & 1) {
            count[base] += weight;
        }
        }
    }
    }
    return count;
}


/*
 *  sf_delc -- delete columns first ... last of A
 */
pset_family sf_delc(A, first, last)
pset_family A;
int first, last;
{
    return sf_delcol(A, first, last-first + 1);
}


/*
 *  sf_addcol -- add columns to a set family; includes a quick check to see
 *  if there is already enough room (and hence, can avoid copying)
 */
pset_family sf_addcol(A, firstcol, n)
pset_family A;
int firstcol, n;
{
    int maxsize;

    /* Check if adding columns at the end ... */
    if (firstcol == A->sf_size) {
    /* If so, check if there is already enough room */
    maxsize = BPI * LOOPINIT(A->sf_size);
    if ((A->sf_size + n) <= maxsize) {
        A->sf_size += n;
        return A;
    }
    }
    return sf_delcol(A, firstcol, -n);
}

/*
 * sf_delcol -- add/delete columns to/from a set family
 *
 *  if n > 0 then n columns starting from firstcol are deleted if n < 0
 *  then n blank columns are inserted starting at firstcol
 *      (i.e., the first new column number is firstcol)
 *
 *  This is done by copying columns in the array which is a relatively
 *  slow operation.
 */
pset_family sf_delcol(A, firstcol, n)
pset_family A;
register int firstcol, n;
{
    register pset p, last, pdest;
    register int i;
    pset_family B;

    B = sf_new(A->count, A->sf_size - n);
    foreach_set(A, last, p) {
    pdest = GETSET(B, B->count++);
    INLINEset_clear(pdest, B->sf_size);
    for(i = 0; i < firstcol; i++)
        if (is_in_set(p, i))
        set_insert(pdest, i);
    for(i = n > 0 ? firstcol + n : firstcol; i < A->sf_size; i++)
        if (is_in_set(p, i))
        set_insert(pdest, i - n);
    }
    sf_free(A);
    return B;
}


/*
 *  sf_copy_col -- copy column "srccol" from "src" to column "dstcol" of "dst"
 */
pset_family sf_copy_col(dst, dstcol, src, srccol)
pset_family dst, src;
int dstcol, srccol;
{
    register pset last, p, pdest;
    register int word_test, word_set;
    unsigned int bit_set, bit_test;

    /* CHEAT! form these constants outside the loop */
    word_test = WHICH_WORD(srccol);
    bit_test = 1 << WHICH_BIT(srccol);
    word_set = WHICH_WORD(dstcol);
    bit_set = 1 << WHICH_BIT(dstcol);

    pdest = dst->data;
    foreach_set(src, last, p) {
    if ((p[word_test] & bit_test) != 0)
        pdest[word_set] |= bit_set;
/*
 *  equivalent code for this is ...
 *    if (is_in_set(p, srccol)) set_insert(pdest, destcol);
 */
    pdest += dst->wsize;
    }
    return dst;
}



/*
 *  sf_compress -- delete columns from a matrix
 */
pset_family sf_compress(A, c)
pset_family A;            /* will be freed */
register pset c;
{
    register pset p;
    register int i, bcol;
    pset_family B;

    /* create a clean set family for the result */
    B = sf_new(A->count, set_ord(c));
    for(i = 0; i < A->count; i++) {
    p = GETSET(B, B->count++);
    INLINEset_clear(p, B->sf_size);
    }

    /* copy each column of A which has a 1 in c */
    bcol = 0;
    for(i = 0; i < A->sf_size; i++) {
    if (is_in_set(c, i)) {
        (void) sf_copy_col(B, bcol++, A, i);
    }
    }
    sf_free(A);
    return B;
}



/*
 *  sf_transpose -- transpose a bit matrix
 *
 *  There are trickier ways of doing this, but this works.
 */
pset_family sf_transpose(A)
pset_family A;
{
    pset_family B;
    register pset p;
    register int i, j;

    B = sf_new(A->sf_size, A->count);
    B->count = A->sf_size;
    foreachi_set(B, i, p) {
    INLINEset_clear(p, B->sf_size);
    }
    foreachi_set(A, i, p) {
    for(j = 0; j < A->sf_size; j++) {
        if (is_in_set(p, j)) {
        set_insert(GETSET(B, j), i);
        }
    }
    }
    sf_free(A);
    return B;
}


/*
 *   sf_permute -- permute the columns of a set_family
 *
 *   permute is an array of integers containing column numbers of A which
 *   are to be retained.
 */
pset_family sf_permute(A, permute, npermute)
pset_family A;
register int *permute, npermute;
{
    pset_family B;
    register pset p, last, pdest;
    register int j;

    B = sf_new(A->count, npermute);
    B->count = A->count;
    foreach_set(B, last, p)
    INLINEset_clear(p, npermute);

    pdest = B->data;
    foreach_set(A, last, p) {
    for(j = 0; j < npermute; j++)
        if (is_in_set(p, permute[j]))
        set_insert(pdest, j);
    pdest += B->wsize;
    }
    sf_free(A);
    return B;
}
ABC_NAMESPACE_IMPL_END

