#include "espresso.h"
ABC_NAMESPACE_IMPL_START
pset_family sf_contain(A)
INOUT pset_family A;
{
int cnt;
pset *A1;
pset_family R;
A1 = sf_sort(A, descend);
cnt = rm_equal(A1, descend);
cnt = rm_contain(A1);
R = sf_unlist(A1, cnt, A->sf_size);
sf_free(A);
return R;
}
pset_family sf_rev_contain(A)
INOUT pset_family A;
{
int cnt;
pset *A1;
pset_family R;
A1 = sf_sort(A, ascend);
cnt = rm_equal(A1, ascend);
cnt = rm_rev_contain(A1);
R = sf_unlist(A1, cnt, A->sf_size);
sf_free(A);
return R;
}
pset_family sf_ind_contain(A, row_indices)
INOUT pset_family A;
INOUT int *row_indices;
{
int cnt;
pset *A1;
pset_family R;
A1 = sf_sort(A, descend);
cnt = rm_equal(A1, descend);
cnt = rm_contain(A1);
R = sf_ind_unlist(A1, cnt, A->sf_size, row_indices, A->data);
sf_free(A);
return R;
}
pset_family sf_dupl(A)
INOUT pset_family A;
{
register int cnt;
register pset *A1;
pset_family R;
A1 = sf_sort(A, descend);
cnt = rm_equal(A1, descend);
R = sf_unlist(A1, cnt, A->sf_size);
sf_free(A);
return R;
}
pset_family sf_union(A, B)
INOUT pset_family A, B;
{
int cnt;
pset_family R;
pset *A1 = sf_list(A), *B1 = sf_list(B), *E1;
E1 = ALLOC(pset, MAX(A->count, B->count) + 1);
cnt = rm2_equal(A1, B1, E1, descend);
cnt += rm2_contain(A1, B1) + rm2_contain(B1, A1);
R = sf_merge(A1, B1, E1, cnt, A->sf_size);
sf_free(A); sf_free(B);
return R;
}
pset_family dist_merge(A, mask)
INOUT pset_family A;
IN pset mask;
{
pset *A1;
int cnt;
pset_family R;
(void) set_copy(cube.temp[0], mask);
A1 = sf_sort(A, d1_order);
cnt = d1_rm_equal(A1, d1_order);
R = sf_unlist(A1, cnt, A->sf_size);
sf_free(A);
return R;
}
pset_family d1merge(A, var)
INOUT pset_family A;
IN int var;
{
return dist_merge(A, cube.var_mask[var]);
}
int d1_rm_equal(A1, compare)
register pset *A1;
int (*compare)();
{
register int i, j, dest;
dest = 0;
if (A1[0] != (pcube) NULL) {
for(i = 0, j = 1; A1[j] != (pcube) NULL; j++)
if ( (*compare)(&A1[i], &A1[j]) == 0) {
(void) set_or(A1[i], A1[i], A1[j]);
} else {
A1[dest++] = A1[i];
i = j;
}
A1[dest++] = A1[i];
}
A1[dest] = (pcube) NULL;
return dest;
}
int rm_equal(A1, compare)
INOUT pset *A1;
IN int (*compare)();
{
register pset *p, *pdest = A1;
if (*A1 != NULL) {
for(p = A1+1; *p != NULL; p++)
if ((*compare)(p, p-1) != 0)
*pdest++ = *(p-1);
*pdest++ = *(p-1);
*pdest = NULL;
}
return pdest - A1;
}
int rm_contain(A1)
INOUT pset *A1;
{
register pset *pa, *pb;
register pset *pcheck = NULL; register pset a, b;
pset *pdest = A1;
int last_size = -1;
for(pa = A1; (a = *pa++) != NULL; ) {
if (SIZE(a) != last_size)
last_size = SIZE(a), pcheck = pdest;
for(pb = A1; pb != pcheck; ) {
b = *pb++;
INLINEsetp_implies(a, b, continue);
goto lnext1;
}
*pdest++ = a;
lnext1: ;
}
*pdest = NULL;
return pdest - A1;
}
int rm_rev_contain(A1)
INOUT pset *A1;
{
register pset *pa, *pb;
register pset *pcheck = NULL; register pset a, b;
pset *pdest = A1;
int last_size = -1;
for(pa = A1; (a = *pa++) != NULL; ) {
if (SIZE(a) != last_size)
last_size = SIZE(a), pcheck = pdest;
for(pb = A1; pb != pcheck; ) {
b = *pb++;
INLINEsetp_implies(b, a, continue);
goto lnext1;
}
*pdest++ = a;
lnext1: ;
}
*pdest = NULL;
return pdest - A1;
}
int rm2_equal(A1, B1, E1, compare)
INOUT register pset *A1, *B1;
OUT pset *E1;
IN int (*compare)();
{
register pset *pda = A1, *pdb = B1, *pde = E1;
for(; *A1 != NULL && *B1 != NULL; )
switch((*compare)(A1, B1)) {
case -1:
*pda++ = *A1++; break;
case 0:
*pde++ = *A1++; B1++; break;
case 1:
*pdb++ = *B1++; break;
}
while (*A1 != NULL)
*pda++ = *A1++;
while (*B1 != NULL)
*pdb++ = *B1++;
*pda = *pdb = *pde = NULL;
return pde - E1;
}
int rm2_contain(A1, B1)
INOUT pset *A1;
IN pset *B1;
{
register pset *pa, *pb, a, b, *pdest = A1;
for(pa = A1; (a = *pa++) != NULL; ) {
for(pb = B1; (b = *pb++) != NULL && SIZE(b) > SIZE(a); ) {
INLINEsetp_implies(a, b, continue);
goto lnext1;
}
*pdest++ = a;
lnext1: ;
}
*pdest = NULL;
return pdest - A1;
}
pset *sf_sort(A, compare)
IN pset_family A;
IN int (*compare)();
{
register pset p, last, *pdest, *A1;
pdest = A1 = ALLOC(pset, A->count + 1);
foreach_set(A, last, p) {
PUTSIZE(p, set_ord(p));
*pdest++ = p;
}
*pdest = NULL;
qsort((char *) A1, (size_t)A->count, sizeof(pset), compare);
return A1;
}
pset *sf_list(A)
IN register pset_family A;
{
register pset p, last, *pdest, *A1;
pdest = A1 = ALLOC(pset, A->count + 1);
foreach_set(A, last, p)
*pdest++ = p;
*pdest = NULL;
return A1;
}
pset_family sf_unlist(A1, totcnt, size)
IN pset *A1;
IN int totcnt, size;
{
register pset pr, p, *pa;
pset_family R = sf_new(totcnt, size);
R->count = totcnt;
for(pr = R->data, pa = A1; (p = *pa++) != NULL; pr += R->wsize)
INLINEset_copy(pr, p);
FREE(A1);
return R;
}
pset_family sf_ind_unlist(A1, totcnt, size, row_indices, pfirst)
IN pset *A1;
IN int totcnt, size;
INOUT int *row_indices;
IN register pset pfirst;
{
register pset pr, p, *pa;
register int i, *new_row_indices;
pset_family R = sf_new(totcnt, size);
R->count = totcnt;
new_row_indices = ALLOC(int, totcnt);
for(pr = R->data, pa = A1, i=0; (p = *pa++) != NULL; pr += R->wsize, i++) {
INLINEset_copy(pr, p);
new_row_indices[i] = row_indices[(p - pfirst)/R->wsize];
}
for(i = 0; i < totcnt; i++)
row_indices[i] = new_row_indices[i];
FREE(new_row_indices);
FREE(A1);
return R;
}
pset_family sf_merge(A1, B1, E1, totcnt, size)
INOUT pset *A1, *B1, *E1;
IN int totcnt, size;
{
register pset pr, ps, *pmin, *pmid, *pmax;
pset_family R;
pset *temp[3], *swap;
int i, j, n;
R = sf_new(totcnt, size);
R->count = totcnt;
pr = R->data;
n = 3; temp[0] = A1; temp[1] = B1; temp[2] = E1;
for(i = 0; i < n-1; i++)
for(j = i+1; j < n; j++)
if (desc1(*temp[i], *temp[j]) > 0) {
swap = temp[j];
temp[j] = temp[i];
temp[i] = swap;
}
pmin = temp[0]; pmid = temp[1]; pmax = temp[2];
while (*pmin != (pset) NULL) {
ps = *pmin++;
INLINEset_copy(pr, ps);
pr += R->wsize;
if (desc1(*pmin, *pmax) > 0) {
swap = pmax; pmax = pmin; pmin = pmid; pmid = swap;
} else if (desc1(*pmin, *pmid) > 0) {
swap = pmin; pmin = pmid; pmid = swap;
}
}
FREE(A1);
FREE(B1);
FREE(E1);
return R;
}
ABC_NAMESPACE_IMPL_END