33#define REFINE_BY_SIM_1 0
34#define REFINE_BY_SIM_2 0
35#define BACKTRACK_BY_SAT 1
36#define SELECT_DYNAMICALLY 0
43#define CLAUSE_DECAY 0.9
199static int *ints(
int n) {
return ABC_ALLOC(
int, n); }
200static int *zeros(
int n) {
return ABC_CALLOC(
int, n); }
201static char *bits(
int n) {
return ABC_CALLOC(
char, n); }
203static char * getVertexName(
Abc_Ntk_t *pNtk,
int v);
205static int ifInputVectorsAreConsistent(
struct saucy * s,
int * leftVec,
int * rightVec);
206static int ifOutputVectorsAreConsistent(
struct saucy * s,
int * leftVec,
int * rightVec);
216static void reduceDB(
struct saucy * s);
220print_automorphism_ntk(FILE *f,
int n,
const int *gamma,
int nsupp,
const int *support,
char * marks,
Abc_Ntk_t * pNtk)
225 for (i = 0; i < nsupp; ++i) {
229 if (marks[k])
continue;
233 fprintf(f,
"(%s", getVertexName(pNtk, k));
236 for (j = gamma[k]; j != k; j = gamma[j]) {
238 fprintf(f,
" %s", getVertexName(pNtk, j));
247 for (i = 0; i < nsupp; ++i) {
248 marks[support[i]] = 0;
255print_automorphism_ntk2(FILE *f,
int n,
const int *gamma,
int nsupp,
const int *support,
char * marks,
Abc_Ntk_t * pNtk)
260 for (i = 0; i < nsupp; ++i) {
264 if (marks[k])
continue;
268 fprintf(f,
"%d", k-1);
271 for (j = gamma[k]; j != k; j = gamma[j]) {
273 fprintf(f,
" %d ", j-1);
281 for (i = 0; i < nsupp; ++i) {
282 marks[support[i]] = 0;
289print_automorphism_quiet(FILE *f,
int n,
const int *gamma,
int nsupp,
const int *support,
char * marks,
Abc_Ntk_t * pNtk)
295array_find_min(
const int *a,
int n)
297 const int *start = a, *end = a + n, *min = a;
299 if (*a < *min) min = a;
305swap(
int *a,
int x,
int y)
313sift_up(
int *a,
int k)
329sift_down(
int *a,
int n)
333 if (k < n && a[k] < a[k+1]) ++k;
346heap_sort(
int *a,
int n)
349 for (i = 1; i < n; ++i) {
360insertion_sort(
int *a,
int n)
363 for (i = 1; i < n; ++i) {
365 for (j = i; j > 0 && a[j-1] > k; --j) {
373partition(
int *a,
int n,
int m)
377 while (a[f] <= m) ++f;
378 do --b;
while (m <= a[b]);
400median(
int a,
int b,
int c)
403 if (b <= c)
return b;
404 if (a <= c)
return c;
408 if (a <= c)
return a;
409 if (b <= c)
return c;
415introsort_loop(
int *a,
int n,
int lim)
424 p = partition(a, n, median(a[0], a[n/2], a[n-1]));
425 introsort_loop(a +
p, n -
p, lim);
431introsort(
int *a,
int n)
433 introsort_loop(a, n, 2 * log_base2(n));
434 insertion_sort(a, n);
438do_find_min(
struct coloring *c,
int t)
440 return array_find_min(c->
lab + t, c->
clen[t] + 1) + t;
444find_min(
struct saucy *s,
int t)
446 return do_find_min(&s->
right, t);
457swap_labels(
struct coloring *c,
int a,
int b)
460 set_label(c, a, c->
lab[b]);
461 set_label(c, b, tmp);
468 int cb = cf + c->
clen[cf];
472 swap_labels(c, cb - offset, c->
unlab[k]);
484 if (c->
clen[cf]) move_to_back(s, c, k);
493 if (c->
clen[cf] && !s->
ccount[k]++) move_to_back(s, c, k);
497check_mapping(
struct saucy *s,
const int *adj,
const int *edg,
int k)
502 for (i = adj[k]; i != adj[k+1]; ++i) {
508 for (i = adj[gk]; ret && i != adj[gk+1]; ++i) {
509 ret = s->
stuff[edg[i]];
513 for (i = adj[k]; i != adj[k+1]; ++i) {
524 int nins = Abc_NtkPiNum(s->
pNtk);
528 for (i = 0; i < nins; i++) {
544 bumpActivity(s, cex);
549is_undirected_automorphism(
struct saucy *s)
553 for (i = 0; i < s->
ndiffs; ++i) {
555 if (!check_mapping(s, s->
adj, s->
edg, j))
return 0;
564 add_conterexample(s, cex);
567 add_conterexample(s, cex);
578is_directed_automorphism(
struct saucy *s)
582 for (i = 0; i < s->
ndiffs; ++i) {
584 if (!check_mapping(s, s->
adj, s->
edg, j))
return 0;
585 if (!check_mapping(s, s->
dadj, s->
dedg, j))
return 0;
603fix_fronts(
struct coloring *c,
int cf,
int ff)
605 int i, end = cf + c->
clen[cf];
606 for (i = ff; i <= end; ++i) {
612array_indirect_sort(
int *a,
const int *b,
int n)
619 do { h = 3 * h + 1; }
while (h < j);
622 for (i = h; i < n; ++i) {
624 for (j = i; b[a[j-h]] > b[k]; ) {
626 if ((j -= h) < h)
break;
635at_terminal(
struct saucy *s)
641add_diffnon(
struct saucy *s,
int k)
651remove_diffnon(
struct saucy *s,
int k)
665add_diff(
struct saucy *s,
int k)
675is_a_pair(
struct saucy *s,
int k)
681in_cell_range(
struct coloring *c,
int ff,
int cf)
683 int cb = cf + c->
clen[cf];
684 return cf <= ff && ff <= cb;
688add_pair(
struct saucy *s,
int k)
697eat_pair(
struct saucy *s,
int k)
707pick_all_the_pairs(
struct saucy *s)
710 for (i = 0; i < s->
npairs; ++i) {
717clear_undiffnons(
struct saucy *s)
726fix_diff_singleton(
struct saucy *s,
int cf)
729 int l = s->left.lab[cf];
739 remove_diffnon(s, r);
747 if (in_cell_range(&s->
right, s->left.unlab[r], rcfl)) {
752 else if (is_a_pair(s, r)) {
759fix_diff_subtract(
struct saucy *s,
int cf,
const int *a,
const int *b)
765 for (i = cf; i <= cb; ++i) {
770 for (i = cf; i <= cb; ++i) {
772 if (!s->
stuff[k]) add_diff(s, k);
776 for (i = cf; i <= cb; ++i) {
782fix_diffs(
struct saucy *s,
int cf,
int ff)
787 fix_diff_singleton(s, cf);
788 fix_diff_singleton(s, ff);
793 fix_diff_subtract(s, min, s->left.lab, s->
right.
lab);
794 fix_diff_subtract(s, min, s->
right.
lab, s->left.lab);
799split_color(
struct coloring *c,
int cf,
int ff)
805 cb = cf + c->
clen[cf];
806 c->
clen[cf] = fb - cf;
807 c->
clen[ff] = cb - ff;
810 fix_fronts(c, ff, ff);
814split_common(
struct saucy *s,
struct coloring *c,
int cf,
int ff)
816 split_color(c, cf, ff);
820 add_induce(s, c, ff);
823 add_induce(s, c, cf);
828split_left(
struct saucy *s,
struct coloring *c,
int cf,
int ff)
836 split_common(s, c, cf, ff);
843split_init(
struct saucy *s,
struct coloring *c,
int cf,
int ff)
845 split_left(s, c, cf, ff);
864split_other(
struct saucy *s,
struct coloring *c,
int cf,
int ff)
876 split_common(s, c, cf, ff);
879 fix_diffs(s, cf, ff);
891 for(i = 0; i < n; i += (left->clen[i]+1)) {
892 for(j = 0; j < (left->clen[i]+1); j++) {
893 if (fNames) printf(
"%s ", getVertexName(pNtk, left->lab[i+j]));
894 else printf(
"%d ", left->lab[i+j]);
896 if((i+left->clen[i]+1) < n) printf(
"|");
905 if (right == NULL)
return 1;
908 for(i = 0; i < n; i += (right->clen[i]+1)) {
909 for(j = 0; j < (right->clen[i]+1); j++) {
910 if (fNames) printf(
"%s ", getVertexName(pNtk, right->lab[i+j]));
911 else printf(
"%d ", right->lab[i+j]);
913 if((i+right->clen[i]+1) < n) printf(
"|");
940 for (i = 0; ret && i < s->
csize; ++i) {
942 ret = refine(s, c, cf);
946 for (i = 0; i < s->
csize; ++i) {
955maybe_split(
struct saucy *s,
struct coloring *c,
int cf,
int ff)
957 return cf == ff ? 1 : s->
split(s, c, cf, ff);
964 return maybe_split(s, c, cf, cf + zcnt);
969 const int *adj,
const int *edg,
int cf)
971 int i, k = c->
lab[cf];
974 for (i = adj[k]; i != adj[k+1]; ++i) {
975 data_mark(s, c, edg[i]);
979 return refine_cell(s, c, ref_single_cell);
983ref_singleton_directed(
struct saucy *s,
struct coloring *c,
int cf)
985 return ref_singleton(s, c, s->
adj, s->
edg, cf)
986 && ref_singleton(s, c, s->
dadj, s->
dedg, cf);
990ref_singleton_undirected(
struct saucy *s,
struct coloring *c,
int cf)
992 return ref_singleton(s, c, s->
adj, s->
edg, cf);
996ref_nonsingle_cell(
struct saucy *s,
struct coloring *c,
int cf)
998 int cnt, i, cb, nzf, ff, fb, bmin, bmax;
1001 cb = cf + c->
clen[cf];
1007 s->
count[ff] = bmin = bmax = cnt;
1011 while (++ff <= cb) {
1015 while (bmin > cnt) s->
bucket[--bmin] = 0;
1016 while (bmax < cnt) s->
bucket[++bmax] = 0;
1024 if (bmin == bmax && cf == nzf)
return 1;
1028 for (i = bmin; i <= bmax; ++i, ff = fb) {
1029 if (!s->
bucket[i])
continue;
1035 for (i = nzf; i <= cb; ++i) {
1038 for (i = nzf; i <= cb; ++i) {
1039 set_label(c, i, s->
junk[i]);
1043 for (i = bmax; i > bmin; --i) {
1045 if (ff && !s->
split(s, c, cf, ff))
return 0;
1049 return maybe_split(s, c, cf, s->
bucket[bmin]);
1054 const int *adj,
const int *edg,
int cf)
1057 const int cb = cf + c->
clen[cf];
1058 const int size = cb - cf + 1;
1062 return ref_singleton(s, c, adj, edg, cf);
1067 for (i = 0; i <
size; ++i) {
1069 for (j = adj[k]; j != adj[k+1]; ++j) {
1070 data_count(s, c, edg[j]);
1075 ret = refine_cell(s, c, ref_nonsingle_cell);
1078 for (i = cf; i <= cb; ++i) {
1080 for (j = adj[k]; j != adj[k+1]; ++j) {
1089ref_nonsingle_directed(
struct saucy *s,
struct coloring *c,
int cf)
1091 return ref_nonsingle(s, c, s->
adj, s->
edg, cf)
1092 && ref_nonsingle(s, c, s->
dadj, s->
dedg, cf);
1096ref_nonsingle_undirected(
struct saucy *s,
struct coloring *c,
int cf)
1098 return ref_nonsingle(s, c, s->
adj, s->
edg, cf);
1102clear_refine(
struct saucy *s)
1105 for (i = 0; i < s->
nninduce; ++i) {
1108 for (i = 0; i < s->
nsinduce; ++i) {
1123 if (at_terminal(s)) {
1154 return refine(s, c);
1158backtrackBysatCounterExamples(
struct saucy *s,
struct coloring *c)
1164 if (c == &s->left)
return 1;
1171 if (flag[j])
continue;
1174 res = ifInputVectorsAreConsistent(s, cex1->
inVec, cex2->
inVec);
1180 if (res == -1)
break;
1181 if (res == 0)
continue;
1184 bumpActivity(s, cex1);
1185 bumpActivity(s, cex2);
1192 if (Abc_NtkPoNum(s->
pNtk) == 1)
continue;
1194 if (!ifOutputVectorsAreConsistent(s, cex1->
outVec, cex2->
outVec)) {
1195 bumpActivity(s, cex1);
1196 bumpActivity(s, cex2);
1213 int allOutputsAreDistinguished;
1216 if (Abc_NtkPoNum(s->
pNtk) == 1)
return 1;
1221 allOutputsAreDistinguished = 1;
1222 for (j = 0; j < Abc_NtkPoNum(s->
pNtk); j++) {
1224 allOutputsAreDistinguished = 0;
1228 if (allOutputsAreDistinguished)
break;
1230 randVec = assignRandomBitsToCells(s->
pNtk, c);
1231 g = buildSim1Graph(s->
pNtk, c, randVec, s->
iDep, s->
oDep);
1239 for (j = 0; j < s->
n; j += c->
clen[j]+1)
1240 add_induce(s, c, j);
1246 for (j = 0; j < s->
n; j += c->
clen[j]+1)
1247 add_induce(s, c, j);
1248 refineByDepGraph(s, c);
1251 Vec_IntFree(randVec);
1267 int allOutputsAreDistinguished;
1270 if (Abc_NtkPoNum(s->
pNtk) == 1)
return 1;
1275 allOutputsAreDistinguished = 1;
1276 for (j = 0; j < Abc_NtkPoNum(s->
pNtk); j++) {
1278 allOutputsAreDistinguished = 0;
1282 if (allOutputsAreDistinguished)
break;
1284 randVec = assignRandomBitsToCells(s->
pNtk, c);
1285 g = buildSim1Graph(s->
pNtk, c, randVec, s->
iDep, s->
oDep);
1293 for (j = 0; j < s->
n; j += c->
clen[j]+1)
1294 add_induce(s, c, j);
1302 for (j = 0; j < s->
n; j += c->
clen[j]+1)
1303 add_induce(s, c, j);
1304 refineByDepGraph(s, c);
1307 Vec_IntFree(randVec);
1329 g = buildSim1Graph(s->
pNtk, c, randVec, s->
iDep, s->
oDep);
1341 for (j = 0; j < s->
n; j += c->
clen[j]+1)
1342 add_induce(s, c, j);
1352 for (j = 0; j < s->
n; j += c->
clen[j]+1)
1353 add_induce(s, c, j);
1354 ret = refineByDepGraph(s, c);
1376 randVec = assignRandomBitsToCells(s->
pNtk, c);
1385 for (j = 0; j < s->
n; j += c->
clen[j]+1)
1386 add_induce(s, c, j);
1392 for (j = 0; j < s->
n; j += c->
clen[j]+1)
1393 add_induce(s, c, j);
1394 refineByDepGraph(s, c);
1397 Vec_IntFree(randVec);
1416 randVec = assignRandomBitsToCells(s->
pNtk, c);
1425 for (j = 0; j < s->
n; j += c->
clen[j]+1)
1426 add_induce(s, c, j);
1434 for (j = 0; j < s->
n; j += c->
clen[j]+1)
1435 add_induce(s, c, j);
1436 refineByDepGraph(s, c);
1439 Vec_IntFree(randVec);
1473 for (j = 0; j < s->
n; j += c->
clen[j]+1)
1474 add_induce(s, c, j);
1484 for (j = 0; j < s->
n; j += c->
clen[j]+1)
1485 add_induce(s, c, j);
1486 ret = refineByDepGraph(s, c);
1503check_OPP_only_has_swaps(
struct saucy *s,
struct coloring *c)
1506 Vec_Int_t * left_cfront, * right_cfront;
1511 left_cfront = Vec_IntAlloc (1);
1512 right_cfront = Vec_IntAlloc (1);
1514 for (cell = 0; cell < s->
n; cell += (s->left.clen[cell]+1)) {
1515 for (j = cell; j <= (cell+s->left.clen[cell]); j++) {
1516 Vec_IntPush(left_cfront, s->left.cfront[s->
right.
lab[j]]);
1517 Vec_IntPush(right_cfront, s->
right.
cfront[s->left.lab[j]]);
1519 Vec_IntSortUnsigned(left_cfront);
1520 Vec_IntSortUnsigned(right_cfront);
1521 for (j = 0; j < Vec_IntSize(left_cfront); j++) {
1522 if (Vec_IntEntry(left_cfront, j) != Vec_IntEntry(right_cfront, j)) {
1523 Vec_IntFree(left_cfront);
1524 Vec_IntFree(right_cfront);
1528 Vec_IntClear(left_cfront);
1529 Vec_IntClear(right_cfront);
1532 Vec_IntFree(left_cfront);
1533 Vec_IntFree(right_cfront);
1539check_OPP_for_Boolean_matching(
struct saucy *s,
struct coloring *c)
1542 int countN1Left, countN2Left;
1543 int countN1Right, countN2Right;
1549 for (cell = 0; cell < s->
n; cell += (s->
right.
clen[cell]+1)) {
1550 countN1Left = countN2Left = countN1Right = countN2Right = 0;
1552 for (j = cell; j <= (cell+s->
right.
clen[cell]); j++) {
1554 name = getVertexName(s->
pNtk, s->left.lab[j]);
1574 if (countN1Left != countN2Right || countN2Left != countN1Right)
1582double_check_OPP_isomorphism(
struct saucy *s,
struct coloring * c)
1585 int i, j, v, sum1, sum2, xor1, xor2;
1593 for (j = s->
adj[v]; j < s->
adj[v+1]; j++) {
1599 for (j = s->
adj[v]; j < s->
adj[v+1]; j++) {
1600 sum2 += s->left.cfront[s->
edg[j]];
1601 xor2 ^= s->left.cfront[s->
edg[j]];
1603 if ((sum1 != sum2) || (xor1 != xor2))
1607 for (j = s->
adj[v]; j < s->
adj[v+1]; j++) {
1613 for (j = s->
adj[v]; j < s->
adj[v+1]; j++) {
1614 sum2 += s->left.cfront[s->
edg[j]];
1615 xor2 ^= s->left.cfront[s->
edg[j]];
1617 if ((sum1 != sum2) || (xor1 != xor2))
1627 int back = target + c->
clen[target];
1633 swap_labels(c, min, back);
1639 s->
split(s, c, target, back);
1643 if (!refineByDepGraph(s, c))
return 0;
1647 if (s->
fBooleanMatching && !check_OPP_for_Boolean_matching(s, c))
return 0;
1656 if (s->
fBooleanMatching && !check_OPP_for_Boolean_matching(s, c))
return 0;
1658 if (s->
fLookForSwaps && !check_OPP_only_has_swaps(s, c))
return 0;
1660 if (!double_check_OPP_isomorphism(s, c))
return 0;
1666select_smallest_max_connected_cell(
struct saucy *s,
int start,
int end)
1668 int smallest_cell = -1, cell;
1669 int smallest_cell_size = s->
n;
1670 int max_connections = -1;
1671 int * connection_list = zeros(s->
n);
1674 while( !s->left.clen[cell] ) cell++;
1675 while( cell < end ) {
1676 if (s->left.clen[cell] <= smallest_cell_size) {
1677 int i, connections = 0;;
1678 for (i = s->
depAdj[s->left.lab[cell]]; i < s->depAdj[s->left.lab[cell]+1]; i++) {
1679 if (!connection_list[s->
depEdg[i]]) {
1681 connection_list[s->
depEdg[i]] = 1;
1684 if ((s->left.clen[cell] < smallest_cell_size) || (connections > max_connections)) {
1685 smallest_cell_size = s->left.clen[cell];
1686 max_connections = connections;
1687 smallest_cell = cell;
1689 for (i = s->
depAdj[s->left.lab[cell]]; i < s->depAdj[s->left.lab[cell]+1]; i++)
1690 connection_list[s->
depEdg[i]] = 0;
1696 return smallest_cell;
1700descend_leftmost(
struct saucy *s)
1706 while (!at_terminal(s)) {
1709 target = min = select_smallest_max_connected_cell(s, s->
nextnon[-1], Abc_NtkPoNum(s->
pNtk));
1711 target = min = select_smallest_max_connected_cell(s, Abc_NtkPoNum(s->
pNtk), s->
n);
1713 printf(
"%s->%s\n", getVertexName(s->
pNtk, s->left.lab[min]), getVertexName(s->
pNtk, s->left.lab[min]));
1717 if (!
descend(s, &s->left, target, min))
return 0;
1730zeta_fixed(
struct saucy *s)
1736select_dynamically(
struct saucy *s,
int *target,
int *lmin,
int *rmin)
1739 const int *clen = s->left.clen;
1748 for (i = 0; i < s->
npairs; ++i) {
1751 *lmin = s->left.unlab[s->
right.
lab[s->left.unlab[k]]];
1755 && in_cell_range(&s->left, *lmin, *target)
1756 && in_cell_range(&s->
right, *rmin, *target))
1775 for (i = 0; i < s->
n; i += (clen[i]+1)) {
1776 if (!clen[i])
continue;
1777 *rmin = *lmin = *target = i;
1778 if (s->
right.
cfront[s->left.lab[*lmin]] == *target)
1788select_statically(
struct saucy *s,
int *target,
int *lmin,
int *rmin)
1792 *target = *rmin = s->left.cfront[s->
splitvar[s->
lev]];
1795 for (i = *rmin; i <= (*rmin + s->
right.
clen[*target]); i++)
1796 if (s->
right.
lab[*rmin] == s->left.lab[*lmin]) {
1803descend_left(
struct saucy *s)
1805 int target, lmin, rmin;
1811 while (!at_terminal(s) ) {
1818 printf(
"in level %d: %s->%s\n", s->
lev, getVertexName(s->
pNtk, s->left.lab[lmin]), getVertexName(s->
pNtk, s->
right.
lab[rmin]));
1824 s->
split = split_left;
1829 descend(s, &s->left, target, lmin);
1831 s->
split = split_other;
1848find_representative(
int k,
int *theta)
1853 for (rep = k; rep != theta[rep]; rep = theta[rep]);
1856 while (theta[k] != rep) {
1857 tmp = theta[k]; theta[k] = rep; k = tmp;
1863update_theta(
struct saucy *s)
1865 int i, k, x, y, tmp;
1867 for (i = 0; i < s->
ndiffs; ++i) {
1869 x = find_representative(k, s->
theta);
1870 y = find_representative(s->
gamma[k], s->
theta);
1889theta_prune(
struct saucy *s)
1892 int label, rep, irep;
1897 rep = find_representative(label, s->
theta);
1898 if (rep == label && rep != irep) {
1906orbit_prune(
struct saucy *s)
1908 int i, label, fixed, min = -1;
1914 fixed = cell[
size-1];
1917 for (i = 0; i <
size-1; ++i) {
1921 if (label <= fixed)
continue;
1924 if (min != -1 && label > cell[min])
continue;
1934note_anctar_reps(
struct saucy *s)
1936 int i, j, k, m, f, rep, tmp;
1954 for (m = k; m != j; m = s->
thnext[m]) {
1972multiply_index(
struct saucy *s,
int k)
1981backtrack_leftmost(
struct saucy *s)
1983 int rep = find_representative(s->
indmin, s->
theta);
1984 int repsize = s->
thsize[rep];
1987 pick_all_the_pairs(s);
1988 clear_undiffnons(s);
1992 min = theta_prune(s);
1996 multiply_index(s, repsize);
2003backtrack_other(
struct saucy *s)
2011 pick_all_the_pairs(s);
2013 clear_undiffnons(s);
2018 min = find_min(s, cf);
2020 min = orbit_prune(s);
2027 min = orbit_prune(s);
2028 if (min != -1 && s->
right.
lab[min + cf] == spec) {
2029 swap_labels(&s->
right, min + cf, cb);
2030 min = orbit_prune(s);
2037rewind_coloring(
struct saucy *s,
struct coloring *c,
int lev)
2039 int i, cf, ff, splits = s->
splitlev[lev];
2040 for (i = s->
nsplits - 1; i >= splits; --i) {
2044 fix_fronts(c, cf, ff);
2049rewind_simulation_vectors(
struct saucy *s,
int lev)
2062do_backtrack(
struct saucy *s)
2067 rewind_coloring(s, &s->
right, s->
lev);
2084 s->
indmin = s->left.lab[cb];
2086 note_anctar_reps(s);
2091 ? backtrack_leftmost(s)
2092 : backtrack_other(s);
2096backtrack_loop(
struct saucy *s)
2102 min = do_backtrack(s);
2103 if (min != -1)
return min + s->
start[s->
lev];
2109backtrack(
struct saucy *s)
2113 min = backtrack_loop(s);
2116 rewind_coloring(s, &s->left, s->
lev+1);
2119 rewind_simulation_vectors(s, s->
lev+1);
2125backtrack_bad(
struct saucy *s)
2129 min = backtrack_loop(s);
2131 int oldLev = s->
lev;
2132 while (!backtrackBysatCounterExamples(s, &s->
right)) {
2133 min = backtrack_loop(s);
2136 printf(
"Backtrack by SAT from level %d to %d\n", oldLev, 0);
2141 if (s->
lev < oldLev)
2142 printf(
"Backtrack by SAT from level %d to %d\n", oldLev, s->
lev);
2146 rewind_coloring(s, &s->left, s->
lev+1);
2149 rewind_simulation_vectors(s, s->
lev+1);
2159 int numouts = Abc_NtkPoNum(s->
pNtk);
2164 for (i = 0; i < s->
n; ++i) {
2197prepare_permutation(
struct saucy *s)
2200 for (i = 0; i < s->
ndiffs; ++i) {
2202 s->
unsupp[i] = s->left.lab[k];
2213 int numouts = Abc_NtkPoNum(s->
pNtk);
2218 for (i = 0; i < s->
n; ++i) {
2236unprepare_permutation(
struct saucy *s)
2240 for (i = 0; i < s->
ndiffs; ++i) {
2246do_search(
struct saucy *s)
2250 unprepare_permutation(s);
2271 && descend_left(s)) {
2274 prepare_permutation(s);
2282 unprepare_permutation(s);
2286 unprepare_permutation(s);
2292 min = backtrack_bad(s);
2294 printf(
"BAD NODE\n");
2328 g = buildDepGraph(pNtk, s->
iDep, s->
oDep);
2359 for (i = 0; i < s->
n; ++i) {
2364 for (i = 0; i < s->
n; ++i) {
2369 for (i = 0; i < s->
n; ++i) {
2374 for (i = 0; i < s->
n; ++i) {
2380 for (i = 0; i < s->
n; ++i) {
2385 for (i = 0; i < s->
n; ++i) {
2400 for (i = 0; i < s->
n; ++i) {
2402 if (max < colors[i]) max = colors[i];
2407 s->left.clen[0] = s->
ccount[0] - 1;
2408 for (i = 0; i < max; ++i) {
2414 for (i = 0; i < s->
n; ++i) {
2415 set_label(&s->left, --s->
ccount[colors[i]], i);
2419 for (i = 0; i <= max; ++i) {
2424 for (i = 0; i < s->
n; i += s->left.clen[i]+1) {
2425 add_induce(s, &s->left, i);
2426 fix_fronts(&s->left, i, i);
2430 for (i = 0, j = -1; i < s->
n; i += s->left.clen[i] + 1) {
2431 if (!s->left.clen[i])
continue;
2442 s->
split = split_init;
2447 printf(
"Initial Refine by Dependency graph ... ");
2448 refineByDepGraph(s, &s->left);
2452 printf(
"Initial Refine by Simulation ... ");
2457 printf(
"done!\n\t--------------------\n");
2462 descend_leftmost(s);
2463 s->
split = split_other;
2485 while (do_search(s));
2541 for (i = 0; i < Abc_NtkPiNum(s->
pNtk); i++) {
2542 Vec_IntFree( s->
iDep[i] );
2543 Vec_IntFree( s->
obs[i] );
2546 for (i = 0; i < Abc_NtkPoNum(s->
pNtk); i++) {
2547 Vec_IntFree( s->
oDep[i] );
2548 Vec_IntFree( s->
ctrl[i] );
2579 int numouts = Abc_NtkPoNum(
pNtk);
2580 int numins = Abc_NtkPiNum(
pNtk);
2581 int n = numins + numouts;
2583 if (s == NULL)
return NULL;
2588 s->left.cfront = zeros(
n);
2589 s->left.clen = ints(
n);
2605 s->left.lab = ints(
n);
2606 s->left.unlab = ints(
n);
2635 for(i = 0; i < numins; i++) {
2636 s->
iDep[i] = Vec_IntAlloc( 1 );
2637 s->
obs[i] = Vec_IntAlloc( 1 );
2639 for(i = 0; i < numouts; i++) {
2640 s->
oDep[i] = Vec_IntAlloc( 1 );
2641 s->
ctrl[i] = Vec_IntAlloc( 1 );
2650 s->
pModel = ints( numins );
2678 fprintf(f,
"group size = %fe%d\n",
2682 fprintf(f,
"generators = %d\n",
stats.
gens);
2686 fprintf(f,
"bad nodes = %d\n",
stats.
bads);
2698 int numouts = Abc_NtkPoNum(
pNtk);
2719 for(i = 0; i < Abc_NtkPiNum(
pNtk); i++)
2720 vNodes[i] = Vec_PtrAlloc(50);
2725 Abc_NtkIncrementTravId(
pNtk );
2726 Abc_NodeSetTravIdCurrent( pObj );
2727 pObj = Abc_ObjFanout0Ntk(pObj);
2742 for(i = 0; i < Abc_NtkPoNum(
pNtk); i++) {
2743 char * seg = (
char *)vSuppFun->pArray[i];
2745 for(j = 0; j < Abc_NtkPiNum(
pNtk); j+=8) {
2746 if(((*seg) & 0x01) == 0x01)
2747 Vec_IntPushOrder(
oDep[i], j);
2748 if(((*seg) & 0x02) == 0x02)
2749 Vec_IntPushOrder(
oDep[i], j+1);
2750 if(((*seg) & 0x04) == 0x04)
2751 Vec_IntPushOrder(
oDep[i], j+2);
2752 if(((*seg) & 0x08) == 0x08)
2753 Vec_IntPushOrder(
oDep[i], j+3);
2754 if(((*seg) & 0x10) == 0x10)
2755 Vec_IntPushOrder(
oDep[i], j+4);
2756 if(((*seg) & 0x20) == 0x20)
2757 Vec_IntPushOrder(
oDep[i], j+5);
2758 if(((*seg) & 0x40) == 0x40)
2759 Vec_IntPushOrder(
oDep[i], j+6);
2760 if(((*seg) & 0x80) == 0x80)
2761 Vec_IntPushOrder(
oDep[i], j+7);
2767 for(i = 0; i < Abc_NtkPoNum(
pNtk); i++)
2768 for(j = 0; j < Vec_IntSize(
oDep[i]); j++)
2769 Vec_IntPush(
iDep[Vec_IntEntry(
oDep[i], j)], i);
2799 for(i = 0; i < Abc_NtkPoNum(
pNtk); i++)
2800 for(j = 0; j < Abc_NtkPiNum(
pNtk); j++)
2801 Vec_IntPush(
oDep[i], j);
2803 for(i = 0; i < Abc_NtkPiNum(
pNtk); i++)
2804 for(j = 0; j < Abc_NtkPoNum(
pNtk); j++)
2805 Vec_IntPush(
iDep[i], j);
2815 n = Abc_NtkPoNum(pNtk) + Abc_NtkPiNum(pNtk);
2816 for (
e = 0, i = 0; i < Abc_NtkPoNum(pNtk); i++)
2817 e += Vec_IntSize(oDep[i]);
2829 for (i = 0; i <
n; i++) {
2831 if ( i < Abc_NtkPoNum(pNtk)) {
2832 adj[i+1] =
adj[i] + Vec_IntSize(oDep[i]);
2833 for (k = 0, j =
adj[i]; j <
adj[i+1]; j++, k++)
2834 edg[j] = Vec_IntEntry(oDep[i], k) + Abc_NtkPoNum(pNtk);
2837 adj[i+1] =
adj[i] + Vec_IntSize(iDep[i-Abc_NtkPoNum(pNtk)]);
2838 for (k = 0, j =
adj[i]; j <
adj[i+1]; j++, k++)
2839 edg[j] = Vec_IntEntry(iDep[i-Abc_NtkPoNum(pNtk)], k);
2857 Vec_Int_t * randVec = Vec_IntAlloc( 1 );
2860 for (i = 0; i < Abc_NtkPiNum(pNtk); i += (c->
clen[i+Abc_NtkPoNum(pNtk)]+1)) {
2862 Vec_IntPush(randVec, bit);
2872 int i, j, k, bit, input;
2873 int numouts = Abc_NtkPoNum(pNtk);
2874 int numins = Abc_NtkPiNum(pNtk);
2875 int n = numouts + numins;
2879 for (i = numouts, k = 0; i <
n; i += (c->
clen[i]+1), k++) {
2880 if (k == Vec_IntSize(randomVector))
break;
2882 bit = Vec_IntEntry(randomVector, k);
2883 for (j = i; j <= (i + c->
clen[i]); j++) {
2884 input = c->
lab[j] - numouts;
2885 vPiValues[input] = bit;
2899ifInputVectorsAreConsistent(
struct saucy * s,
int * leftVec,
int * rightVec )
2904 int left_bit, right_bit;
2905 int numouts = Abc_NtkPoNum(s->
pNtk);
2906 int n = numouts + Abc_NtkPiNum(s->
pNtk);
2908 for (i = numouts; i <
n; i += (s->
right.
clen[i]+1)) {
2909 lab = s->left.lab[i] - numouts;
2910 left_bit = leftVec[lab];
2911 for (j = i+1; j <= (i + s->
right.
clen[i]); j++) {
2912 lab = s->left.lab[j] - numouts;
2913 if (left_bit != leftVec[lab])
return -1;
2917 right_bit = rightVec[lab];
2918 for (j = i+1; j <= (i + s->
right.
clen[i]); j++) {
2920 if (right_bit != rightVec[lab])
return 0;
2923 if (left_bit != right_bit)
2931ifOutputVectorsAreConsistent(
struct saucy * s,
int * leftVec,
int * rightVec )
2937 for (i = 0; i < Abc_NtkPoNum(s->
pNtk); i += (s->
right.
clen[i]+1)) {
2938 count1 = count2 = 0;
2939 for (j = i; j <= (i + s->
right.
clen[i]); j++) {
2940 if (leftVec[s->left.lab[j]]) count1++;
2941 if (rightVec[s->
right.
lab[j]]) count2++;
2944 if (count1 != count2)
return 0;
2956 int * vPiValues, * output;
2957 int numOneOutputs = 0;
2958 int numouts = Abc_NtkPoNum(pNtk);
2959 int numins = Abc_NtkPiNum(pNtk);
2961 vPiValues = generateProperInputVector(pNtk, c, randVec);
2962 if (vPiValues == NULL)
2967 for (i = 0; i < numouts; i++) {
2973 n = numouts + numins;
2974 e = numins * numOneOutputs;
2983 for (i = 0; i < numouts; i++) {
2985 adj[i+1] =
adj[i] + Vec_IntSize(oDep[i]);
2986 for (j =
adj[i], k = 0; j <
adj[i+1]; j++, k++)
2987 edg[j] = Vec_IntEntry(oDep[i], k) + numouts;
2993 for (i = 0; i < numins; i++) {
2994 adj[i+numouts+1] =
adj[i+numouts];
2995 for (k = 0, j =
adj[i+numouts]; k < Vec_IntSize(iDep[i]); k++) {
2996 if (output[Vec_IntEntry(iDep[i], k)]) {
2997 edg[j++] = Vec_IntEntry(iDep[i], k);
3024 int * output, * output2;
3025 int numouts = Abc_NtkPoNum(pNtk);
3026 int numins = Abc_NtkPiNum(pNtk);
3030 vPiValues = generateProperInputVector(pNtk, c, randVec);
3031 if (vPiValues == NULL)
3036 for (i = 0; i < numins; i++) {
3037 if (!c->
clen[c->
cfront[i+numouts]])
continue;
3038 if (vPiValues[i] == 0) vPiValues[i] = 1;
3039 else vPiValues[i] = 0;
3043 for (j = 0; j < Vec_IntSize(iDep[i]); j++) {
3044 if (output[Vec_IntEntry(iDep[i], j)] != output2[Vec_IntEntry(iDep[i], j)]) {
3045 Vec_IntPush(obs[i], Vec_IntEntry(iDep[i], j));
3046 Vec_IntPush(ctrl[Vec_IntEntry(iDep[i], j)], i);
3051 if (vPiValues[i] == 0) vPiValues[i] = 1;
3052 else vPiValues[i] = 0;
3059 n = numouts + numins;
3068 for (i = 0; i < numouts; i++) {
3069 adj[i+1] =
adj[i] + Vec_IntSize(ctrl[i]);
3070 for (k = 0, j =
adj[i]; j <
adj[i+1]; j++, k++)
3071 edg[j] = Vec_IntEntry(ctrl[i], k) + numouts;
3073 for (i = 0; i < numins; i++) {
3074 adj[i+numouts+1] =
adj[i+numouts] + Vec_IntSize(obs[i]);
3075 for (k = 0, j =
adj[i+numouts]; j <
adj[i+numouts+1]; j++, k++)
3076 edg[j] = Vec_IntEntry(obs[i], k);
3089 for (j = 0; j < numins; j++)
3090 Vec_IntClear(obs[j]);
3091 for (j = 0; j < numouts; j++)
3092 Vec_IntClear(ctrl[j]);
3114reduceDB(
struct saucy * s )
3142analyzeConflict(
Abc_Ntk_t * pNtk,
int * pModel,
int fVerbose )
3148 int numouts = Abc_NtkPoNum(pNtk);
3149 int numins = Abc_NtkPiNum(pNtk);
3152 cex->
inVec = ints( numins );
3153 cex->
outVec = ints( numouts );
3159 cex->
inVec[Abc_ObjId(pNode)-1] = pModel[i];
3161 cex->
outVec[Abc_ObjId(pNode)-numins-1] = pValues[i];
3162 if (pValues[i]) count++;
3195 if ( pMiter == NULL )
3197 printf(
"Miter computation has failed.\n" );
3201 if ( RetValue == 0 )
3206 for (i = 0; i < Abc_NtkPiNum(pNtk1); i++)
3207 pModel[i] = pMiter->
pModel[i];
3212 if ( RetValue == 1 )
3224 printf(
"Renoding for CNF has failed.\n" );
3229 RetValue =
Abc_NtkMiterSat( pCnf, (ABC_INT64_T)nConfLimit, (ABC_INT64_T)nInsLimit, 0, NULL, NULL );
3230 if ( RetValue == -1 ) {
3231 printf(
"Networks are undecided (SAT solver timed out).\n" );
3239 for (i = 0; i < Abc_NtkPiNum(pNtk1); i++)
3240 pModel[i] = pCnf->
pModel[i];
3250 int fLookForSwaps,
int fFixOutputs,
int fFixInputs,
int fQuiet,
int fPrintTree )
3256 int i, clk = clock();
3258 if (pNodePo == NULL)
3263 if (Abc_NtkPiNum(pNtk) == 0) {
3264 Abc_Print( 0,
"This output is not dependent on any input\n" );
3272 printf(
"Build functional dependency graph (dependency stats are below) ... ");
3274 printf(
"\t--------------------\n");
3281 colors = ints(Abc_NtkPoNum(pNtk) + Abc_NtkPiNum(pNtk));
3283 for (i = 0; i < Abc_NtkPoNum(pNtk); i++)
3286 for (i = 0; i < Abc_NtkPoNum(pNtk); i++)
3290 int c = (fFixOutputs) ? Abc_NtkPoNum(pNtk) : 1;
3291 for (i = 0; i < Abc_NtkPiNum(pNtk); i++)
3292 colors[i+Abc_NtkPoNum(pNtk)] = c+i;
3294 int c = (fFixOutputs) ? Abc_NtkPoNum(pNtk) : 1;
3295 for (i = 0; i < Abc_NtkPiNum(pNtk); i++)
3296 colors[i+Abc_NtkPoNum(pNtk)] = c;
3301 if (fBooleanMatching) {
3328 print_stats(stdout, stats);
3329 if (fBooleanMatching) {
3331 printf(
"*** Networks are equivalent ***\n");
3333 printf(
"*** Networks are NOT equivalent ***\n");
3339 FILE * hadi = fopen(
"hadi.txt",
"a");
3340 fprintf(hadi,
"group size = %fe%d\n",
3345 ABC_PRT(
"Runtime", clock() - clk );
int * Abc_NtkSimulateOneNode(Abc_Ntk_t *pNtk, int *pModel, int input, Vec_Ptr_t **topOrder)
void getDependencies(Abc_Ntk_t *pNtk, Vec_Int_t **iDep, Vec_Int_t **oDep)
Vec_Ptr_t ** findTopologicalOrder(Abc_Ntk_t *pNtk)
void Abc_NtkDfsReverse_rec(Abc_Obj_t *pNode, Vec_Ptr_t *vNodes)
ABC_NAMESPACE_IMPL_START Abc_Ntk_t * Abc_NtkMulti(Abc_Ntk_t *pNtk, int nThresh, int nFaninMax, int fCnf, int fMulti, int fSimple, int fFactor)
DECLARATIONS ///.
void unprepare_permutation_ntk(struct saucy *s)
void saucy_search(Abc_Ntk_t *pNtk, struct saucy *s, int directed, const int *colors, struct saucy_stats *stats)
void saucyGateWay(Abc_Ntk_t *pNtkOrig, Abc_Obj_t *pNodePo, FILE *gFile, int fBooleanMatching, int fLookForSwaps, int fFixOutputs, int fFixInputs, int fQuiet, int fPrintTree)
void saucy_free(struct saucy *s)
struct saucy * saucy_alloc(Abc_Ntk_t *pNtk)
void prepare_permutation_ntk(struct saucy *s)
#define SELECT_DYNAMICALLY
struct Abc_Obj_t_ Abc_Obj_t
#define Abc_NtkForEachCo(pNtk, pCo, i)
ABC_DLL void Abc_NtkOrderObjsByName(Abc_Ntk_t *pNtk, int fComb)
ABC_DLL Abc_Ntk_t * Abc_NtkCreateCone(Abc_Ntk_t *pNtk, Abc_Obj_t *pNode, char *pNodeName, int fUseAllCis)
#define Abc_ObjForEachFanout(pObj, pFanout, i)
ABC_DLL char * Abc_ObjName(Abc_Obj_t *pNode)
DECLARATIONS ///.
struct Abc_Ntk_t_ Abc_Ntk_t
ABC_DLL char * Abc_ObjAssignName(Abc_Obj_t *pObj, char *pName, char *pSuffix)
ABC_DLL int Abc_NtkMiterSat(Abc_Ntk_t *pNtk, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, int fVerbose, ABC_INT64_T *pNumConfs, ABC_INT64_T *pNumInspects)
FUNCTION DEFINITIONS ///.
ABC_DLL int * Abc_NtkVerifySimulatePattern(Abc_Ntk_t *pNtk, int *pModel)
ABC_DLL int * Abc_NtkVerifyGetCleanModel(Abc_Ntk_t *pNtk, int nFrames)
ABC_DLL Abc_Ntk_t * Abc_NtkMiter(Abc_Ntk_t *pNtk1, Abc_Ntk_t *pNtk2, int fComb, int nPartSize, int fImplic, int fMulti)
FUNCTION DEFINITIONS ///.
#define Abc_NtkForEachCi(pNtk, pCi, i)
ABC_DLL void Abc_NtkDelete(Abc_Ntk_t *pNtk)
ABC_DLL Abc_Ntk_t * Abc_NtkDup(Abc_Ntk_t *pNtk)
ABC_DLL int Abc_NtkMiterIsConstant(Abc_Ntk_t *pMiter)
#define ABC_ALLOC(type, num)
#define ABC_CALLOC(type, num)
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
ABC_NAMESPACE_IMPL_START typedef signed char value
void Nm_ManFree(Nm_Man_t *p)
Nm_Man_t * Nm_ManCreate(int nSize)
MACRO DEFINITIONS ///.
#define SIM_RANDOM_UNSIGNED
Vec_Ptr_t * Sim_ComputeFunSupp(Abc_Ntk_t *pNtk, int fVerbose)
int(* print_automorphism)(FILE *f, int n, const int *gamma, int nsupp, const int *support, char *marks, Abc_Ntk_t *pNtk)
int(* ref_nonsingle)(struct saucy *, struct coloring *, int)
int(* is_automorphism)(struct saucy *)
void(* select_decomposition)(struct saucy *, int *, int *, int *)
Abc_Ntk_t * pNtk_permuted
int(* refineBySim2)(struct saucy *, struct coloring *)
struct saucy_stats * stats
int * randomVectorSplit_sim2
struct coloring left right
Vec_Ptr_t * satCounterExamples
int(* ref_singleton)(struct saucy *, struct coloring *, int)
Vec_Ptr_t * randomVectorArray_sim2
int(* refineBySim1)(struct saucy *, struct coloring *)
int(* split)(struct saucy *, struct coloring *, int, int)
int * randomVectorSplit_sim1
Vec_Ptr_t * randomVectorArray_sim1
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.