#include "espresso.h"
ABC_NAMESPACE_IMPL_START
pcover essential(Fp, Dp)
IN pcover *Fp, *Dp;
{
register pcube last, p;
pcover E, F = *Fp, D = *Dp;
(void) sf_active(F);
E = new_cover(10);
foreach_set(F, last, p) {
if (! TESTP(p, NONESSEN)) {
if (TESTP(p, RELESSEN)) {
if (essen_cube(F, D, p)) {
if (debug & ESSEN)
printf("ESSENTIAL: %s\n", pc1(p));
E = sf_addset(E, p);
RESET(p, ACTIVE);
F->active_count--;
}
}
}
}
*Fp = sf_inactive(F);
*Dp = sf_join(D, E);
sf_free(D);
return E;
}
bool essen_cube(F, D, c)
IN pcover F, D;
IN pcube c;
{
pcover H, FD;
pcube *H1;
bool essen;
FD = sf_join(F, D);
H = cb_consensus(FD, c);
free_cover(FD);
H1 = cube2list(H, D);
essen = ! cube_is_covered(H1, c);
free_cubelist(H1);
free_cover(H);
return essen;
}
pcover cb_consensus(T, c)
register pcover T;
register pcube c;
{
register pcube temp, last, p;
register pcover R;
R = new_cover(T->count*2);
temp = new_cube();
foreach_set(T, last, p) {
if (p != c) {
switch (cdist01(p, c)) {
case 0:
R = cb_consensus_dist0(R, p, c);
break;
case 1:
consensus(temp, p, c);
R = sf_addset(R, temp);
break;
}
}
}
set_free(temp);
return R;
}
pcover cb_consensus_dist0(R, p, c)
pcover R;
register pcube p, c;
{
int var;
bool got_one;
register pcube temp, mask;
register pcube p_diff_c=cube.temp[0], p_and_c=cube.temp[1];
if (setp_implies(p, c)) {
return R;
}
temp = new_cube();
got_one = FALSE;
INLINEset_diff(p_diff_c, p, c);
INLINEset_and(p_and_c, p, c);
for(var = cube.num_binary_vars; var < cube.num_vars; var++) {
mask = cube.var_mask[var];
if (! setp_disjoint(p_diff_c, mask)) {
INLINEset_merge(temp, c, p_and_c, mask);
R = sf_addset(R, temp);
got_one = TRUE;
}
}
if (! got_one && cube.num_binary_vars > 0) {
INLINEset_and(temp, p, c);
R = sf_addset(R, temp);
}
set_free(temp);
return R;
}
ABC_NAMESPACE_IMPL_END