abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
abcSaucy.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [abcSaucy.c]
4 
5  SystemName [ABC: Logic synthesis and verification system.]
6 
7  PackageName [Symmetry Detection Package.]
8 
9  Synopsis [Finds symmetries under permutation (but not negation) of I/Os.]
10 
11  Author [Hadi Katebi]
12 
13  Affiliation [University of Michigan]
14 
15  Date [Ver. 1.0. Started - April, 2012.]
16 
17  Revision [No revisions so far]
18 
19  Comments []
20 
21  Debugging [There are some part of the code that are commented out. Those parts mostly print
22  the contents of the data structures to the standard output. Un-comment them if you
23  find them useful for debugging.]
24 
25 ***********************************************************************/
26 
27 #include "base/abc/abc.h"
28 #include "opt/sim/sim.h"
29 
31 
32 /* on/off switches */
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
37 
38 /* number of iterations for sim1 and sim2 refinements */
41 
42 /* conflict analysis */
43 #define CLAUSE_DECAY 0.9
44 #define MAX_LEARNTS 50
45 
46 /*
47  * saucy.c
48  *
49  * by Paul T. Darga <pdarga@umich.edu>
50  * and Mark Liffiton <liffiton@umich.edu>
51  * and Hadi Katebi <hadik@eecs.umich.edu>
52  *
53  * Copyright (C) 2004, The Regents of the University of Michigan
54  * See the LICENSE file for details.
55  */
56 
57 struct saucy_stats {
58  double grpsize_base;
60  int levels;
61  int nodes;
62  int bads;
63  int gens;
64  int support;
65 };
66 
67 struct saucy_graph {
68  int n;
69  int e;
70  int *adj;
71  int *edg;
72 };
73 
74 struct coloring {
75  int *lab; /* Labelling of objects */
76  int *unlab; /* Inverse of lab */
77  int *cfront; /* Pointer to front of cells */
78  int *clen; /* Length of cells (defined for cfront's) */
79 };
80 
81 struct sim_result {
82  int *inVec;
83  int *outVec;
85  int outVecOnes;
86  double activity;
87 };
88 
89 struct saucy {
90  /* Graph data */
91  int n; /* Size of domain */
92  int *adj; /* Neighbors of k: edg[adj[k]]..edg[adj[k+1]] */
93  int *edg; /* Actual neighbor data */
94  int *dadj; /* Fanin neighbor indices, for digraphs */
95  int *dedg; /* Fanin neighbor data, for digraphs */
96 
97  /* Coloring data */
98  struct coloring left, right;
99  int *nextnon; /* Forward next-nonsingleton pointers */
100  int *prevnon; /* Backward next-nonsingleton pointers */
101 
102  /* Refinement: inducers */
103  char *indmark; /* Induce marks */
104  int *ninduce; /* Nonsingletons that might induce refinement */
105  int *sinduce; /* Singletons that might induce refinement */
106  int nninduce; /* Size of ninduce stack */
107  int nsinduce; /* Size of sinduce stack */
108 
109  /* Refinement: marked cells */
110  int *clist; /* List of cells marked for refining */
111  int csize; /* Number of cells in clist */
112 
113  /* Refinement: workspace */
114  char *stuff; /* Bit vector, but one char per bit */
115  int *ccount; /* Number of connections to refining cell */
116  int *bucket; /* Workspace */
117  int *count; /* Num vertices with same adj count to ref cell */
118  int *junk; /* More workspace */
119  int *gamma; /* Working permutation */
120  int *conncnts; /* Connection counts for cell fronts */
121 
122  /* Search data */
123  int lev; /* Current search tree level */
124  int anc; /* Level of greatest common ancestor with zeta */
125  int *anctar; /* Copy of target cell at anc */
126  int kanctar; /* Location within anctar to iterate from */
127  int *start; /* Location of target at each level */
128  int indmin; /* Used for group size computation */
129  int match; /* Have we not diverged from previous left? */
130 
131  /* Search: orbit partition */
132  int *theta; /* Running approximation of orbit partition */
133  int *thsize; /* Size of cells in theta, defined for mcrs */
134  int *thnext; /* Next rep in list (circular list) */
135  int *thprev; /* Previous rep in list */
136  int *threp; /* First rep for a given cell front */
137  int *thfront; /* The cell front associated with this rep */
138 
139  /* Search: split record */
140  int *splitvar; /* The actual value of the splits on the left-most branch */
141  int *splitwho; /* List of where splits occurred */
142  int *splitfrom; /* List of cells which were split */
143  int *splitlev; /* Where splitwho/from begins for each level */
144  int nsplits; /* Number of splits at this point */
145 
146  /* Search: differences from leftmost */
147  char *diffmark; /* Marked for diff labels */
148  int *diffs; /* List of diff labels */
149  int *difflev; /* How many labels diffed at each level */
150  int ndiffs; /* Current number of diffs */
151  int *undifflev; /* How many diff labels fixed at each level */
152  int nundiffs; /* Current number of diffs in singletons (fixed) */
153  int *unsupp; /* Inverted diff array */
154  int *specmin; /* Speculated mappings */
155  int *pairs; /* Not-undiffed diffs that can make two-cycles */
156  int *unpairs; /* Indices into pairs */
157  int npairs; /* Number of such pairs */
158  int *diffnons; /* Diffs that haven't been undiffed */
159  int *undiffnons; /* Inverse of that */
160  int ndiffnons; /* Number of such diffs */
161 
162  /* Polymorphic functions */
163  int (*split)(struct saucy *, struct coloring *, int, int);
164  int (*is_automorphism)(struct saucy *);
165  int (*ref_singleton)(struct saucy *, struct coloring *, int);
166  int (*ref_nonsingle)(struct saucy *, struct coloring *, int);
167  void (*select_decomposition)(struct saucy *, int *, int *, int *);
168 
169  /* Statistics structure */
171 
172  /* New data structures for Boolean formulas */
175  int * depAdj;
176  int * depEdg;
178  Vec_Int_t ** obs, ** ctrl;
184  char * marks;
185  int * pModel;
187  double activityInc;
188 
192  FILE * gFile;
193 
194  int (*refineBySim1)(struct saucy *, struct coloring *);
195  int (*refineBySim2)(struct saucy *, struct coloring *);
196  int (*print_automorphism)(FILE *f, int n, const int *gamma, int nsupp, const int *support, char * marks, Abc_Ntk_t * pNtk);
197 };
198 
199 static int *ints(int n) { return ABC_ALLOC(int, n); }
200 static int *zeros(int n) { return ABC_CALLOC(int, n); }
201 static char *bits(int n) { return ABC_CALLOC(char, n); }
202 
203 static char * getVertexName(Abc_Ntk_t *pNtk, int v);
204 static int * generateProperInputVector(Abc_Ntk_t * pNtk, struct coloring *c, Vec_Int_t * randomVector);
205 static int ifInputVectorsAreConsistent(struct saucy * s, int * leftVec, int * rightVec);
206 static int ifOutputVectorsAreConsistent(struct saucy * s, int * leftVec, int * rightVec);
207 static Vec_Ptr_t ** findTopologicalOrder(Abc_Ntk_t * pNtk);
208 static void getDependencies(Abc_Ntk_t *pNtk, Vec_Int_t** iDep, Vec_Int_t** oDep);
209 static struct saucy_graph * buildDepGraph (Abc_Ntk_t *pNtk, Vec_Int_t ** iDep, Vec_Int_t ** oDep);
210 static struct saucy_graph * buildSim1Graph(Abc_Ntk_t * pNtk, struct coloring *c, Vec_Int_t * randVec, Vec_Int_t ** iDep, Vec_Int_t ** oDep);
211 static struct saucy_graph * buildSim2Graph(Abc_Ntk_t * pNtk, struct coloring *c, Vec_Int_t * randVec, Vec_Int_t ** iDep, Vec_Int_t ** oDep, Vec_Ptr_t ** topOrder, Vec_Int_t ** obs, Vec_Int_t ** ctrl);
212 static Vec_Int_t * assignRandomBitsToCells(Abc_Ntk_t * pNtk, struct coloring *c);
213 static int Abc_NtkCecSat_saucy(Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int * pModel);
214 static struct sim_result * analyzeConflict(Abc_Ntk_t * pNtk, int * pModel, int fVerbose);
215 static void bumpActivity (struct saucy * s, struct sim_result * cex);
216 static void reduceDB(struct saucy * s);
217 
218 
219 static int
220 print_automorphism_ntk(FILE *f, int n, const int *gamma, int nsupp, const int *support, char * marks, Abc_Ntk_t * pNtk)
221 {
222  int i, j, k;
223 
224  /* We presume support is already sorted */
225  for (i = 0; i < nsupp; ++i) {
226  k = support[i];
227 
228  /* Skip elements already seen */
229  if (marks[k]) continue;
230 
231  /* Start an orbit */
232  marks[k] = 1;
233  fprintf(f, "(%s", getVertexName(pNtk, k));
234 
235  /* Mark and notify elements in this orbit */
236  for (j = gamma[k]; j != k; j = gamma[j]) {
237  marks[j] = 1;
238  fprintf(f, " %s", getVertexName(pNtk, j));
239  }
240 
241  /* Finish off the orbit */
242  fprintf(f, ")");
243  }
244  fprintf(f, "\n");
245 
246  /* Clean up after ourselves */
247  for (i = 0; i < nsupp; ++i) {
248  marks[support[i]] = 0;
249  }
250 
251  return 1;
252 }
253 
254 static int
255 print_automorphism_ntk2(FILE *f, int n, const int *gamma, int nsupp, const int *support, char * marks, Abc_Ntk_t * pNtk)
256 {
257  int i, j, k;
258 
259  /* We presume support is already sorted */
260  for (i = 0; i < nsupp; ++i) {
261  k = support[i];
262 
263  /* Skip elements already seen */
264  if (marks[k]) continue;
265 
266  /* Start an orbit */
267  marks[k] = 1;
268  fprintf(f, "%d", k-1);
269 
270  /* Mark and notify elements in this orbit */
271  for (j = gamma[k]; j != k; j = gamma[j]) {
272  marks[j] = 1;
273  fprintf(f, " %d ", j-1);
274  }
275 
276  /* Finish off the orbit */
277  }
278  fprintf(f, "-1\n");
279 
280  /* Clean up after ourselves */
281  for (i = 0; i < nsupp; ++i) {
282  marks[support[i]] = 0;
283  }
284 
285  return 1;
286 }
287 
288 static int
289 print_automorphism_quiet(FILE *f, int n, const int *gamma, int nsupp, const int *support, char * marks, Abc_Ntk_t * pNtk)
290 {
291  return 1;
292 }
293 
294 static int
295 array_find_min(const int *a, int n)
296 {
297  const int *start = a, *end = a + n, *min = a;
298  while (++a != end) {
299  if (*a < *min) min = a;
300  }
301  return min - start;
302 }
303 
304 static void
305 swap(int *a, int x, int y)
306 {
307  int tmp = a[x];
308  a[x] = a[y];
309  a[y] = tmp;
310 }
311 
312 static void
313 sift_up(int *a, int k)
314 {
315  int p;
316  do {
317  p = k / 2;
318  if (a[k] <= a[p]) {
319  return;
320  }
321  else {
322  swap(a, k, p);
323  k = p;
324  }
325  } while (k > 1);
326 }
327 
328 static void
329 sift_down(int *a, int n)
330 {
331  int p = 1, k = 2;
332  while (k <= n) {
333  if (k < n && a[k] < a[k+1]) ++k;
334  if (a[p] < a[k]) {
335  swap(a, p, k);
336  p = k;
337  k = 2 * p;
338  }
339  else {
340  return;
341  }
342  }
343 }
344 
345 static void
346 heap_sort(int *a, int n)
347 {
348  int i;
349  for (i = 1; i < n; ++i) {
350  sift_up(a-1, i+1);
351  }
352  --i;
353  while (i > 0) {
354  swap(a, 0, i);
355  sift_down(a-1, i--);
356  }
357 }
358 
359 static void
360 insertion_sort(int *a, int n)
361 {
362  int i, j, k;
363  for (i = 1; i < n; ++i) {
364  k = a[i];
365  for (j = i; j > 0 && a[j-1] > k; --j) {
366  a[j] = a[j-1];
367  }
368  a[j] = k;
369  }
370 }
371 
372 static int
373 partition(int *a, int n, int m)
374 {
375  int f = 0, b = n;
376  for (;;) {
377  while (a[f] <= m) ++f;
378  do --b; while (m <= a[b]);
379  if (f < b) {
380  swap(a, f, b);
381  ++f;
382  }
383  else break;
384  }
385  return f;
386 }
387 
388 static int
389 log_base2(int n)
390 {
391  int k = 0;
392  while (n > 1) {
393  ++k;
394  n >>= 1;
395  }
396  return k;
397 }
398 
399 static int
400 median(int a, int b, int c)
401 {
402  if (a <= b) {
403  if (b <= c) return b;
404  if (a <= c) return c;
405  return a;
406  }
407  else {
408  if (a <= c) return a;
409  if (b <= c) return c;
410  return b;
411  }
412 }
413 
414 static void
415 introsort_loop(int *a, int n, int lim)
416 {
417  int p;
418  while (n > 16) {
419  if (lim == 0) {
420  heap_sort(a, n);
421  return;
422  }
423  --lim;
424  p = partition(a, n, median(a[0], a[n/2], a[n-1]));
425  introsort_loop(a + p, n - p, lim);
426  n = p;
427  }
428 }
429 
430 static void
431 introsort(int *a, int n)
432 {
433  introsort_loop(a, n, 2 * log_base2(n));
434  insertion_sort(a, n);
435 }
436 
437 static int
438 do_find_min(struct coloring *c, int t)
439 {
440  return array_find_min(c->lab + t, c->clen[t] + 1) + t;
441 }
442 
443 static int
444 find_min(struct saucy *s, int t)
445 {
446  return do_find_min(&s->right, t);
447 }
448 
449 static void
450 set_label(struct coloring *c, int index, int value)
451 {
452  c->lab[index] = value;
453  c->unlab[value] = index;
454 }
455 
456 static void
457 swap_labels(struct coloring *c, int a, int b)
458 {
459  int tmp = c->lab[a];
460  set_label(c, a, c->lab[b]);
461  set_label(c, b, tmp);
462 }
463 
464 static void
465 move_to_back(struct saucy *s, struct coloring *c, int k)
466 {
467  int cf = c->cfront[k];
468  int cb = cf + c->clen[cf];
469  int offset = s->conncnts[cf]++;
470 
471  /* Move this connected label to the back of its cell */
472  swap_labels(c, cb - offset, c->unlab[k]);
473 
474  /* Add it to the cell list if it's the first one swapped */
475  if (!offset) s->clist[s->csize++] = cf;
476 }
477 
478 static void
479 data_mark(struct saucy *s, struct coloring *c, int k)
480 {
481  int cf = c->cfront[k];
482 
483  /* Move connects to the back of nonsingletons */
484  if (c->clen[cf]) move_to_back(s, c, k);
485 }
486 
487 static void
488 data_count(struct saucy *s, struct coloring *c, int k)
489 {
490  int cf = c->cfront[k];
491 
492  /* Move to back and count the number of connections */
493  if (c->clen[cf] && !s->ccount[k]++) move_to_back(s, c, k);
494 }
495 
496 static int
497 check_mapping(struct saucy *s, const int *adj, const int *edg, int k)
498 {
499  int i, gk, ret = 1;
500 
501  /* Mark gamma of neighbors */
502  for (i = adj[k]; i != adj[k+1]; ++i) {
503  s->stuff[s->gamma[edg[i]]] = 1;
504  }
505 
506  /* Check neighbors of gamma */
507  gk = s->gamma[k];
508  for (i = adj[gk]; ret && i != adj[gk+1]; ++i) {
509  ret = s->stuff[edg[i]];
510  }
511 
512  /* Clear out bit vector before we leave */
513  for (i = adj[k]; i != adj[k+1]; ++i) {
514  s->stuff[s->gamma[edg[i]]] = 0;
515  }
516 
517  return ret;
518 }
519 
520 static int
521 add_conterexample(struct saucy *s, struct sim_result * cex)
522 {
523  int i;
524  int nins = Abc_NtkPiNum(s->pNtk);
525  struct sim_result * savedcex;
526 
527  cex->inVecSignature = 0;
528  for (i = 0; i < nins; i++) {
529  if (cex->inVec[i]) {
530  cex->inVecSignature += (cex->inVec[i] * i * i);
531  cex->inVecSignature ^= 0xABCD;
532  }
533  }
534 
535  for (i = 0; i < Vec_PtrSize(s->satCounterExamples); i++) {
536  savedcex = (struct sim_result *)Vec_PtrEntry(s->satCounterExamples, i);
537  if (savedcex->inVecSignature == cex->inVecSignature) {
538  //bumpActivity(s, savedcex);
539  return 0;
540  }
541  }
542 
544  bumpActivity(s, cex);
545  return 1;
546 }
547 
548 static int
550 {
551  int i, j, ret;
552 
553  for (i = 0; i < s->ndiffs; ++i) {
554  j = s->unsupp[i];
555  if (!check_mapping(s, s->adj, s->edg, j)) return 0;
556  }
557 
558  ret = Abc_NtkCecSat_saucy(s->pNtk, s->pNtk_permuted, s->pModel);
559 
560  if( BACKTRACK_BY_SAT && !ret ) {
561  struct sim_result * cex;
562 
563  cex = analyzeConflict( s->pNtk, s->pModel, s->fPrintTree );
564  add_conterexample(s, cex);
565 
566  cex = analyzeConflict( s->pNtk_permuted, s->pModel, s->fPrintTree );
567  add_conterexample(s, cex);
568 
569  s->activityInc *= (1 / CLAUSE_DECAY);
571  reduceDB(s);
572  }
573 
574  return ret;
575 }
576 
577 static int
579 {
580  int i, j;
581 
582  for (i = 0; i < s->ndiffs; ++i) {
583  j = s->unsupp[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;
586  }
587  return 1;
588 }
589 
590 static void
591 add_induce(struct saucy *s, struct coloring *c, int who)
592 {
593  if (!c->clen[who]) {
594  s->sinduce[s->nsinduce++] = who;
595  }
596  else {
597  s->ninduce[s->nninduce++] = who;
598  }
599  s->indmark[who] = 1;
600 }
601 
602 static void
603 fix_fronts(struct coloring *c, int cf, int ff)
604 {
605  int i, end = cf + c->clen[cf];
606  for (i = ff; i <= end; ++i) {
607  c->cfront[c->lab[i]] = cf;
608  }
609 }
610 
611 static void
612 array_indirect_sort(int *a, const int *b, int n)
613 {
614  int h, i, j, k;
615 
616  /* Shell sort, as implemented in nauty, (C) Brendan McKay */
617  j = n / 3;
618  h = 1;
619  do { h = 3 * h + 1; } while (h < j);
620 
621  do {
622  for (i = h; i < n; ++i) {
623  k = a[i];
624  for (j = i; b[a[j-h]] > b[k]; ) {
625  a[j] = a[j-h];
626  if ((j -= h) < h) break;
627  }
628  a[j] = k;
629  }
630  h /= 3;
631  } while (h > 0);
632 }
633 
634 static int
635 at_terminal(struct saucy *s)
636 {
637  return s->nsplits == s->n;
638 }
639 
640 static void
641 add_diffnon(struct saucy *s, int k)
642 {
643  /* Only add if we're in a consistent state */
644  if (s->ndiffnons == -1) return;
645 
646  s->undiffnons[k] = s->ndiffnons;
647  s->diffnons[s->ndiffnons++] = k;
648 }
649 
650 static void
651 remove_diffnon(struct saucy *s, int k)
652 {
653  int j;
654 
655  if (s->undiffnons[k] == -1) return;
656 
657  j = s->diffnons[--s->ndiffnons];
658  s->diffnons[s->undiffnons[k]] = j;
659  s->undiffnons[j] = s->undiffnons[k];
660 
661  s->undiffnons[k] = -1;
662 }
663 
664 static void
665 add_diff(struct saucy *s, int k)
666 {
667  if (!s->diffmark[k]) {
668  s->diffmark[k] = 1;
669  s->diffs[s->ndiffs++] = k;
670  add_diffnon(s, k);
671  }
672 }
673 
674 static int
675 is_a_pair(struct saucy *s, int k)
676 {
677  return s->unpairs[k] != -1;
678 }
679 
680 static int
681 in_cell_range(struct coloring *c, int ff, int cf)
682 {
683  int cb = cf + c->clen[cf];
684  return cf <= ff && ff <= cb;
685 }
686 
687 static void
688 add_pair(struct saucy *s, int k)
689 {
690  if (s->npairs != -1) {
691  s->unpairs[k] = s->npairs;
692  s->pairs[s->npairs++] = k;
693  }
694 }
695 
696 static void
697 eat_pair(struct saucy *s, int k)
698 {
699  int j;
700  j = s->pairs[--s->npairs];
701  s->pairs[s->unpairs[k]] = j;
702  s->unpairs[j] = s->unpairs[k];
703  s->unpairs[k] = -1;
704 }
705 
706 static void
708 {
709  int i;
710  for (i = 0; i < s->npairs; ++i) {
711  s->unpairs[s->pairs[i]] = -1;
712  }
713  s->npairs = 0;
714 }
715 
716 static void
718 {
719  int i;
720  for (i = 0 ; i < s->ndiffnons ; ++i) {
721  s->undiffnons[s->diffnons[i]] = -1;
722  }
723 }
724 
725 static void
726 fix_diff_singleton(struct saucy *s, int cf)
727 {
728  int r = s->right.lab[cf];
729  int l = s->left.lab[cf];
730  int rcfl;
731 
732  if (!s->right.clen[cf] && r != l) {
733 
734  /* Make sure diff is marked */
735  add_diff(s, r);
736 
737  /* It is now undiffed since it is singleton */
738  ++s->nundiffs;
739  remove_diffnon(s, r);
740 
741  /* Mark the other if not singleton already */
742  rcfl = s->right.cfront[l];
743  if (s->right.clen[rcfl]) {
744  add_diff(s, l);
745 
746  /* Check for pairs */
747  if (in_cell_range(&s->right, s->left.unlab[r], rcfl)) {
748  add_pair(s, l);
749  }
750  }
751  /* Otherwise we might be eating a pair */
752  else if (is_a_pair(s, r)) {
753  eat_pair(s, r);
754  }
755  }
756 }
757 
758 static void
759 fix_diff_subtract(struct saucy *s, int cf, const int *a, const int *b)
760 {
761  int i, k;
762  int cb = cf + s->right.clen[cf];
763 
764  /* Mark the contents of the first set */
765  for (i = cf; i <= cb; ++i) {
766  s->stuff[a[i]] = 1;
767  }
768 
769  /* Add elements from second set not present in the first */
770  for (i = cf; i <= cb; ++i) {
771  k = b[i];
772  if (!s->stuff[k]) add_diff(s, k);
773  }
774 
775  /* Clear the marks of the first set */
776  for (i = cf; i <= cb; ++i) {
777  s->stuff[a[i]] = 0;
778  }
779 }
780 
781 static void
782 fix_diffs(struct saucy *s, int cf, int ff)
783 {
784  int min;
785 
786  /* Check for singleton cases in both cells */
787  fix_diff_singleton(s, cf);
788  fix_diff_singleton(s, ff);
789 
790  /* If they're both nonsingleton, do subtraction on smaller */
791  if (s->right.clen[cf] && s->right.clen[ff]) {
792  min = s->right.clen[cf] < s->right.clen[ff] ? cf : 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);
795  }
796 }
797 
798 static void
799 split_color(struct coloring *c, int cf, int ff)
800 {
801  int cb, fb;
802 
803  /* Fix lengths */
804  fb = ff - 1;
805  cb = cf + c->clen[cf];
806  c->clen[cf] = fb - cf;
807  c->clen[ff] = cb - ff;
808 
809  /* Fix cell front pointers */
810  fix_fronts(c, ff, ff);
811 }
812 
813 static void
814 split_common(struct saucy *s, struct coloring *c, int cf, int ff)
815 {
816  split_color(c, cf, ff);
817 
818  /* Add to refinement */
819  if (s->indmark[cf] || c->clen[ff] < c->clen[cf]) {
820  add_induce(s, c, ff);
821  }
822  else {
823  add_induce(s, c, cf);
824  }
825 }
826 
827 static int
828 split_left(struct saucy *s, struct coloring *c, int cf, int ff)
829 {
830  /* Record the split */
831  s->splitwho[s->nsplits] = ff;
832  s->splitfrom[s->nsplits] = cf;
833  ++s->nsplits;
834 
835  /* Do common splitting tasks */
836  split_common(s, c, cf, ff);
837 
838  /* Always succeeds */
839  return 1;
840 }
841 
842 static int
843 split_init(struct saucy *s, struct coloring *c, int cf, int ff)
844 {
845  split_left(s, c, cf, ff);
846 
847  /* Maintain nonsingleton list for finding new targets */
848  if (c->clen[ff]) {
849  s->prevnon[s->nextnon[cf]] = ff;
850  s->nextnon[ff] = s->nextnon[cf];
851  s->prevnon[ff] = cf;
852  s->nextnon[cf] = ff;
853  }
854  if (!c->clen[cf]) {
855  s->nextnon[s->prevnon[cf]] = s->nextnon[cf];
856  s->prevnon[s->nextnon[cf]] = s->prevnon[cf];
857  }
858 
859  /* Always succeeds */
860  return 1;
861 }
862 
863 static int
864 split_other(struct saucy *s, struct coloring *c, int cf, int ff)
865 {
866  int k = s->nsplits;
867 
868  /* Verify the split with init */
869  if (s->splitwho[k] != ff || s->splitfrom[k] != cf
870  || k >= s->splitlev[s->lev]) {
871  return 0;
872  }
873  ++s->nsplits;
874 
875  /* Do common splitting tasks */
876  split_common(s, c, cf, ff);
877 
878  /* Fix differences with init */
879  fix_diffs(s, cf, ff);
880 
881  /* If we got this far we succeeded */
882  return 1;
883 }
884 
885 static int
886 print_partition(struct coloring *left, struct coloring *right, int n, Abc_Ntk_t * pNtk, int fNames)
887 {
888  int i, j;
889 
890  printf("top = |");
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]);
895  }
896  if((i+left->clen[i]+1) < n) printf("|");
897  }
898  printf("|\n");
899 
900  /*printf("(cfront = {");
901  for (i = 0; i < n; i++)
902  printf("%d ", left->cfront[i]);
903  printf("})\n");*/
904 
905  if (right == NULL) return 1;
906 
907  printf("bot = |");
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]);
912  }
913  if((i+right->clen[i]+1) < n) printf("|");
914  }
915  printf("|\n");
916 
917  /*printf("(cfront = {");
918  for (i = 0; i < n; i++)
919  printf("%d ", right->cfront[i]);
920  printf("})\n");*/
921 
922  return 1;
923 }
924 
925 static int
926 refine_cell(struct saucy *s, struct coloring *c,
927  int (*refine)(struct saucy *, struct coloring *, int))
928 {
929  int i, cf, ret = 1;
930 
931  /*
932  * The connected list must be consistent. This is for
933  * detecting mappings across nodes at a given level. However,
934  * at the root of the tree, we never have to map with another
935  * node, so we lack this consistency constraint in that case.
936  */
937  if (s->lev > 1) introsort(s->clist, s->csize);
938 
939  /* Now iterate over the marked cells */
940  for (i = 0; ret && i < s->csize; ++i) {
941  cf = s->clist[i];
942  ret = refine(s, c, cf);
943  }
944 
945  /* Clear the connected marks */
946  for (i = 0; i < s->csize; ++i) {
947  cf = s->clist[i];
948  s->conncnts[cf] = 0;
949  }
950  s->csize = 0;
951  return ret;
952 }
953 
954 static int
955 maybe_split(struct saucy *s, struct coloring *c, int cf, int ff)
956 {
957  return cf == ff ? 1 : s->split(s, c, cf, ff);
958 }
959 
960 static int
961 ref_single_cell(struct saucy *s, struct coloring *c, int cf)
962 {
963  int zcnt = c->clen[cf] + 1 - s->conncnts[cf];
964  return maybe_split(s, c, cf, cf + zcnt);
965 }
966 
967 static int
968 ref_singleton(struct saucy *s, struct coloring *c,
969  const int *adj, const int *edg, int cf)
970 {
971  int i, k = c->lab[cf];
972 
973  /* Find the cells we're connected to, and mark our neighbors */
974  for (i = adj[k]; i != adj[k+1]; ++i) {
975  data_mark(s, c, edg[i]);
976  }
977 
978  /* Refine the cells we're connected to */
979  return refine_cell(s, c, ref_single_cell);
980 }
981 
982 static int
983 ref_singleton_directed(struct saucy *s, struct coloring *c, int cf)
984 {
985  return ref_singleton(s, c, s->adj, s->edg, cf)
986  && ref_singleton(s, c, s->dadj, s->dedg, cf);
987 }
988 
989 static int
990 ref_singleton_undirected(struct saucy *s, struct coloring *c, int cf)
991 {
992  return ref_singleton(s, c, s->adj, s->edg, cf);
993 }
994 
995 static int
996 ref_nonsingle_cell(struct saucy *s, struct coloring *c, int cf)
997 {
998  int cnt, i, cb, nzf, ff, fb, bmin, bmax;
999 
1000  /* Find the front and back */
1001  cb = cf + c->clen[cf];
1002  nzf = cb - s->conncnts[cf] + 1;
1003 
1004  /* Prepare the buckets */
1005  ff = nzf;
1006  cnt = s->ccount[c->lab[ff]];
1007  s->count[ff] = bmin = bmax = cnt;
1008  s->bucket[cnt] = 1;
1009 
1010  /* Iterate through the rest of the vertices */
1011  while (++ff <= cb) {
1012  cnt = s->ccount[c->lab[ff]];
1013 
1014  /* Initialize intermediate buckets */
1015  while (bmin > cnt) s->bucket[--bmin] = 0;
1016  while (bmax < cnt) s->bucket[++bmax] = 0;
1017 
1018  /* Mark this count */
1019  ++s->bucket[cnt];
1020  s->count[ff] = cnt;
1021  }
1022 
1023  /* If they all had the same count, bail */
1024  if (bmin == bmax && cf == nzf) return 1;
1025  ff = fb = nzf;
1026 
1027  /* Calculate bucket locations, sizes */
1028  for (i = bmin; i <= bmax; ++i, ff = fb) {
1029  if (!s->bucket[i]) continue;
1030  fb = ff + s->bucket[i];
1031  s->bucket[i] = fb;
1032  }
1033 
1034  /* Repair the partition nest */
1035  for (i = nzf; i <= cb; ++i) {
1036  s->junk[--s->bucket[s->count[i]]] = c->lab[i];
1037  }
1038  for (i = nzf; i <= cb; ++i) {
1039  set_label(c, i, s->junk[i]);
1040  }
1041 
1042  /* Split; induce */
1043  for (i = bmax; i > bmin; --i) {
1044  ff = s->bucket[i];
1045  if (ff && !s->split(s, c, cf, ff)) return 0;
1046  }
1047 
1048  /* If there was a zero area, then there's one more cell */
1049  return maybe_split(s, c, cf, s->bucket[bmin]);
1050 }
1051 
1052 static int
1053 ref_nonsingle(struct saucy *s, struct coloring *c,
1054  const int *adj, const int *edg, int cf)
1055 {
1056  int i, j, k, ret;
1057  const int cb = cf + c->clen[cf];
1058  const int size = cb - cf + 1;
1059 
1060  /* Double check for nonsingles which became singles later */
1061  if (cf == cb) {
1062  return ref_singleton(s, c, adj, edg, cf);
1063  }
1064 
1065  /* Establish connected list */
1066  memcpy(s->junk, c->lab + cf, size * sizeof(int));
1067  for (i = 0; i < size; ++i) {
1068  k = s->junk[i];
1069  for (j = adj[k]; j != adj[k+1]; ++j) {
1070  data_count(s, c, edg[j]);
1071  }
1072  }
1073 
1074  /* Refine the cells we're connected to */
1075  ret = refine_cell(s, c, ref_nonsingle_cell);
1076 
1077  /* Clear the counts; use lab because junk was overwritten */
1078  for (i = cf; i <= cb; ++i) {
1079  k = c->lab[i];
1080  for (j = adj[k]; j != adj[k+1]; ++j) {
1081  s->ccount[edg[j]] = 0;
1082  }
1083  }
1084 
1085  return ret;
1086 }
1087 
1088 static int
1089 ref_nonsingle_directed(struct saucy *s, struct coloring *c, int cf)
1090 {
1091  return ref_nonsingle(s, c, s->adj, s->edg, cf)
1092  && ref_nonsingle(s, c, s->dadj, s->dedg, cf);
1093 }
1094 
1095 static int
1096 ref_nonsingle_undirected(struct saucy *s, struct coloring *c, int cf)
1097 {
1098  return ref_nonsingle(s, c, s->adj, s->edg, cf);
1099 }
1100 
1101 static void
1103 {
1104  int i;
1105  for (i = 0; i < s->nninduce; ++i) {
1106  s->indmark[s->ninduce[i]] = 0;
1107  }
1108  for (i = 0; i < s->nsinduce; ++i) {
1109  s->indmark[s->sinduce[i]] = 0;
1110  }
1111  s->nninduce = s->nsinduce = 0;
1112 }
1113 
1114 static int
1115 refine(struct saucy *s, struct coloring *c)
1116 {
1117  int front;
1118 
1119  /* Keep going until refinement stops */
1120  while (1) {
1121 
1122  /* If discrete, bail */
1123  if (at_terminal(s)) {
1124  clear_refine(s);
1125  return 1;
1126  };
1127 
1128  /* Look for something else to refine on */
1129  if (s->nsinduce) {
1130  front = s->sinduce[--s->nsinduce];
1131  s->indmark[front] = 0;
1132  if (!s->ref_singleton(s, c, front)) break;
1133  }
1134  else if (s->nninduce) {
1135  front = s->ninduce[--s->nninduce];
1136  s->indmark[front] = 0;
1137  if (!s->ref_nonsingle(s, c, front)) break;
1138  }
1139  else {
1140  return 1;
1141  };
1142  }
1143 
1144  clear_refine(s);
1145  return 0;
1146 }
1147 
1148 static int
1149 refineByDepGraph(struct saucy *s, struct coloring *c)
1150 {
1151  s->adj = s->depAdj;
1152  s->edg = s->depEdg;
1153 
1154  return refine(s, c);
1155 }
1156 
1157 static int
1159 {
1160  int i, j, res;
1161  struct sim_result * cex1, * cex2;
1162  int * flag = zeros(Vec_PtrSize(s->satCounterExamples));
1163 
1164  if (c == &s->left) return 1;
1165  if (Vec_PtrSize(s->satCounterExamples) == 0) return 1;
1166 
1167  for (i = 0; i < Vec_PtrSize(s->satCounterExamples); i++) {
1168  cex1 = (struct sim_result *)Vec_PtrEntry(s->satCounterExamples, i);
1169 
1170  for (j = 0; j < Vec_PtrSize(s->satCounterExamples); j++) {
1171  if (flag[j]) continue;
1172 
1173  cex2 = (struct sim_result *)Vec_PtrEntry(s->satCounterExamples, j);
1174  res = ifInputVectorsAreConsistent(s, cex1->inVec, cex2->inVec);
1175 
1176  if (res == -2) {
1177  flag[j] = 1;
1178  continue;
1179  }
1180  if (res == -1) break;
1181  if (res == 0) continue;
1182 
1183  if (cex1->outVecOnes != cex2->outVecOnes) {
1184  bumpActivity(s, cex1);
1185  bumpActivity(s, cex2);
1186  ABC_FREE(flag);
1187  return 0;
1188  }
1189 
1190  /* if two input vectors produce the same number of ones (look above), and
1191  * pNtk's number of outputs is 1, then output vectors are definitely consistent. */
1192  if (Abc_NtkPoNum(s->pNtk) == 1) continue;
1193 
1194  if (!ifOutputVectorsAreConsistent(s, cex1->outVec, cex2->outVec)) {
1195  bumpActivity(s, cex1);
1196  bumpActivity(s, cex2);
1197  ABC_FREE(flag);
1198  return 0;
1199  }
1200  }
1201  }
1202 
1203  ABC_FREE(flag);
1204  return 1;
1205 }
1206 
1207 static int
1208 refineBySim1_init(struct saucy *s, struct coloring *c)
1209 {
1210  struct saucy_graph *g;
1211  Vec_Int_t * randVec;
1212  int i, j;
1213  int allOutputsAreDistinguished;
1214  int nsplits;
1215 
1216  if (Abc_NtkPoNum(s->pNtk) == 1) return 1;
1217 
1218  for (i = 0; i < NUM_SIM1_ITERATION; i++) {
1219 
1220  /* if all outputs are distinguished, quit */
1221  allOutputsAreDistinguished = 1;
1222  for (j = 0; j < Abc_NtkPoNum(s->pNtk); j++) {
1223  if (c->clen[j]) {
1224  allOutputsAreDistinguished = 0;
1225  break;
1226  }
1227  }
1228  if (allOutputsAreDistinguished) break;
1229 
1230  randVec = assignRandomBitsToCells(s->pNtk, c);
1231  g = buildSim1Graph(s->pNtk, c, randVec, s->iDep, s->oDep);
1232  assert(g != NULL);
1233 
1234  s->adj = g->adj;
1235  s->edg = g->edg;
1236 
1237  nsplits = s->nsplits;
1238 
1239  for (j = 0; j < s->n; j += c->clen[j]+1)
1240  add_induce(s, c, j);
1241  refine(s, c);
1242 
1243  if (s->nsplits > nsplits) {
1244  i = 0; /* reset i */
1245  /* do more refinement by dependency graph */
1246  for (j = 0; j < s->n; j += c->clen[j]+1)
1247  add_induce(s, c, j);
1248  refineByDepGraph(s, c);
1249  }
1250 
1251  Vec_IntFree(randVec);
1252  ABC_FREE( g->adj );
1253  ABC_FREE( g->edg );
1254  ABC_FREE( g );
1255  }
1256 
1257  return 1;
1258 }
1259 
1260 
1261 static int
1262 refineBySim1_left(struct saucy *s, struct coloring *c)
1263 {
1264  struct saucy_graph *g;
1265  Vec_Int_t * randVec;
1266  int i, j;
1267  int allOutputsAreDistinguished;
1268  int nsplits;
1269 
1270  if (Abc_NtkPoNum(s->pNtk) == 1) return 1;
1271 
1272  for (i = 0; i < NUM_SIM1_ITERATION; i++) {
1273 
1274  /* if all outputs are distinguished, quit */
1275  allOutputsAreDistinguished = 1;
1276  for (j = 0; j < Abc_NtkPoNum(s->pNtk); j++) {
1277  if (c->clen[j]) {
1278  allOutputsAreDistinguished = 0;
1279  break;
1280  }
1281  }
1282  if (allOutputsAreDistinguished) break;
1283 
1284  randVec = assignRandomBitsToCells(s->pNtk, c);
1285  g = buildSim1Graph(s->pNtk, c, randVec, s->iDep, s->oDep);
1286  assert(g != NULL);
1287 
1288  s->adj = g->adj;
1289  s->edg = g->edg;
1290 
1291  nsplits = s->nsplits;
1292 
1293  for (j = 0; j < s->n; j += c->clen[j]+1)
1294  add_induce(s, c, j);
1295  refine(s, c);
1296 
1297  if (s->nsplits > nsplits) {
1298  /* save the random vector */
1299  Vec_PtrPush(s->randomVectorArray_sim1, randVec);
1300  i = 0; /* reset i */
1301  /* do more refinement by dependency graph */
1302  for (j = 0; j < s->n; j += c->clen[j]+1)
1303  add_induce(s, c, j);
1304  refineByDepGraph(s, c);
1305  }
1306  else
1307  Vec_IntFree(randVec);
1308 
1309  ABC_FREE( g->adj );
1310  ABC_FREE( g->edg );
1311  ABC_FREE( g );
1312  }
1313 
1315 
1316  return 1;
1317 }
1318 
1319 static int
1320 refineBySim1_other(struct saucy *s, struct coloring *c)
1321 {
1322  struct saucy_graph *g;
1323  Vec_Int_t * randVec;
1324  int i, j;
1325  int ret, nsplits;
1326 
1327  for (i = s->randomVectorSplit_sim1[s->lev-1]; i < s->randomVectorSplit_sim1[s->lev]; i++) {
1328  randVec = (Vec_Int_t *)Vec_PtrEntry(s->randomVectorArray_sim1, i);
1329  g = buildSim1Graph(s->pNtk, c, randVec, s->iDep, s->oDep);
1330 
1331  if (g == NULL) {
1332  assert(c == &s->right);
1333  return 0;
1334  }
1335 
1336  s->adj = g->adj;
1337  s->edg = g->edg;
1338 
1339  nsplits = s->nsplits;
1340 
1341  for (j = 0; j < s->n; j += c->clen[j]+1)
1342  add_induce(s, c, j);
1343  ret = refine(s, c);
1344 
1345  if (s->nsplits == nsplits) {
1346  assert(c == &s->right);
1347  ret = 0;
1348  }
1349 
1350  if (ret) {
1351  /* do more refinement now by dependency graph */
1352  for (j = 0; j < s->n; j += c->clen[j]+1)
1353  add_induce(s, c, j);
1354  ret = refineByDepGraph(s, c);
1355  }
1356 
1357  ABC_FREE( g->adj );
1358  ABC_FREE( g->edg );
1359  ABC_FREE( g );
1360 
1361  if (!ret) return 0;
1362  }
1363 
1364  return 1;
1365 }
1366 
1367 static int
1368 refineBySim2_init(struct saucy *s, struct coloring *c)
1369 {
1370  struct saucy_graph *g;
1371  Vec_Int_t * randVec;
1372  int i, j;
1373  int nsplits;
1374 
1375  for (i = 0; i < NUM_SIM2_ITERATION; i++) {
1376  randVec = assignRandomBitsToCells(s->pNtk, c);
1377  g = buildSim2Graph(s->pNtk, c, randVec, s->iDep, s->oDep, s->topOrder, s->obs, s->ctrl);
1378  assert(g != NULL);
1379 
1380  s->adj = g->adj;
1381  s->edg = g->edg;
1382 
1383  nsplits = s->nsplits;
1384 
1385  for (j = 0; j < s->n; j += c->clen[j]+1)
1386  add_induce(s, c, j);
1387  refine(s, c);
1388 
1389  if (s->nsplits > nsplits) {
1390  i = 0; /* reset i */
1391  /* do more refinement by dependency graph */
1392  for (j = 0; j < s->n; j += c->clen[j]+1)
1393  add_induce(s, c, j);
1394  refineByDepGraph(s, c);
1395  }
1396 
1397  Vec_IntFree(randVec);
1398 
1399  ABC_FREE( g->adj );
1400  ABC_FREE( g->edg );
1401  ABC_FREE( g );
1402  }
1403 
1404  return 1;
1405 }
1406 
1407 static int
1408 refineBySim2_left(struct saucy *s, struct coloring *c)
1409 {
1410  struct saucy_graph *g;
1411  Vec_Int_t * randVec;
1412  int i, j;
1413  int nsplits;
1414 
1415  for (i = 0; i < NUM_SIM2_ITERATION; i++) {
1416  randVec = assignRandomBitsToCells(s->pNtk, c);
1417  g = buildSim2Graph(s->pNtk, c, randVec, s->iDep, s->oDep, s->topOrder, s->obs, s->ctrl);
1418  assert(g != NULL);
1419 
1420  s->adj = g->adj;
1421  s->edg = g->edg;
1422 
1423  nsplits = s->nsplits;
1424 
1425  for (j = 0; j < s->n; j += c->clen[j]+1)
1426  add_induce(s, c, j);
1427  refine(s, c);
1428 
1429  if (s->nsplits > nsplits) {
1430  /* save the random vector */
1431  Vec_PtrPush(s->randomVectorArray_sim2, randVec);
1432  i = 0; /* reset i */
1433  /* do more refinement by dependency graph */
1434  for (j = 0; j < s->n; j += c->clen[j]+1)
1435  add_induce(s, c, j);
1436  refineByDepGraph(s, c);
1437  }
1438  else
1439  Vec_IntFree(randVec);
1440 
1441  ABC_FREE( g->adj );
1442  ABC_FREE( g->edg );
1443  ABC_FREE( g );
1444  }
1445 
1447 
1448  return 1;
1449 }
1450 
1451 static int
1452 refineBySim2_other(struct saucy *s, struct coloring *c)
1453 {
1454  struct saucy_graph *g;
1455  Vec_Int_t * randVec;
1456  int i, j;
1457  int ret, nsplits;
1458 
1459  for (i = s->randomVectorSplit_sim2[s->lev-1]; i < s->randomVectorSplit_sim2[s->lev]; i++) {
1460  randVec = (Vec_Int_t *)Vec_PtrEntry(s->randomVectorArray_sim2, i);
1461  g = buildSim2Graph(s->pNtk, c, randVec, s->iDep, s->oDep, s->topOrder, s->obs, s->ctrl);
1462 
1463  if (g == NULL) {
1464  assert(c == &s->right);
1465  return 0;
1466  }
1467 
1468  s->adj = g->adj;
1469  s->edg = g->edg;
1470 
1471  nsplits = s->nsplits;
1472 
1473  for (j = 0; j < s->n; j += c->clen[j]+1)
1474  add_induce(s, c, j);
1475  ret = refine(s, c);
1476 
1477  if (s->nsplits == nsplits) {
1478  assert(c == &s->right);
1479  ret = 0;
1480  }
1481 
1482  if (ret) {
1483  /* do more refinement by dependency graph */
1484  for (j = 0; j < s->n; j += c->clen[j]+1)
1485  add_induce(s, c, j);
1486  ret = refineByDepGraph(s, c);
1487  }
1488 
1489  ABC_FREE( g->adj );
1490  ABC_FREE( g->edg );
1491  ABC_FREE( g );
1492 
1493  if (!ret) {
1494  assert(c == &s->right);
1495  return 0;
1496  }
1497  }
1498 
1499  return 1;
1500 }
1501 
1502 static int
1504 {
1505  int j, cell;
1506  Vec_Int_t * left_cfront, * right_cfront;
1507 
1508  if (c == &s->left)
1509  return 1;
1510 
1511  left_cfront = Vec_IntAlloc (1);
1512  right_cfront = Vec_IntAlloc (1);
1513 
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]]);
1518  }
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);
1525  return 0;
1526  }
1527  }
1528  Vec_IntClear(left_cfront);
1529  Vec_IntClear(right_cfront);
1530  }
1531 
1532  Vec_IntFree(left_cfront);
1533  Vec_IntFree(right_cfront);
1534 
1535  return 1;
1536 }
1537 
1538 static int
1540 {
1541  int j, cell;
1542  int countN1Left, countN2Left;
1543  int countN1Right, countN2Right;
1544  char *name;
1545 
1546  if (c == &s->left)
1547  return 1;
1548 
1549  for (cell = 0; cell < s->n; cell += (s->right.clen[cell]+1)) {
1550  countN1Left = countN2Left = countN1Right = countN2Right = 0;
1551 
1552  for (j = cell; j <= (cell+s->right.clen[cell]); j++) {
1553 
1554  name = getVertexName(s->pNtk, s->left.lab[j]);
1555  assert(name[0] == 'N' && name[2] == ':');
1556  if (name[1] == '1')
1557  countN1Left++;
1558  else {
1559  assert(name[1] == '2');
1560  countN2Left++;
1561  }
1562 
1563  name = getVertexName(s->pNtk, s->right.lab[j]);
1564  assert(name[0] == 'N' && name[2] == ':');
1565  if (name[1] == '1')
1566  countN1Right++;
1567  else {
1568  assert(name[1] == '2');
1569  countN2Right++;
1570  }
1571 
1572  }
1573 
1574  if (countN1Left != countN2Right || countN2Left != countN1Right)
1575  return 0;
1576  }
1577 
1578  return 1;
1579 }
1580 
1581 static int
1583 {
1584  /* This is the new enhancement in saucy 3.0 */
1585  int i, j, v, sum1, sum2, xor1, xor2;
1586 
1587  if (c == &s->left)
1588  return 1;
1589 
1590  for (i = s->nsplits - 1; i > s->splitlev[s->lev-1]; --i) {
1591  v = c->lab[s->splitwho[i]];
1592  sum1 = xor1 = 0;
1593  for (j = s->adj[v]; j < s->adj[v+1]; j++) {
1594  sum1 += c->cfront[s->edg[j]];
1595  xor1 ^= c->cfront[s->edg[j]];
1596  }
1597  v = s->left.lab[s->splitwho[i]];
1598  sum2 = xor2 = 0;
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]];
1602  }
1603  if ((sum1 != sum2) || (xor1 != xor2))
1604  return 0;
1605  v = c->lab[s->splitfrom[i]];
1606  sum1 = xor1 = 0;
1607  for (j = s->adj[v]; j < s->adj[v+1]; j++) {
1608  sum1 += c->cfront[s->edg[j]];
1609  xor1 ^= c->cfront[s->edg[j]];
1610  }
1611  v = s->left.lab[s->splitfrom[i]];
1612  sum2 = xor2 = 0;
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]];
1616  }
1617  if ((sum1 != sum2) || (xor1 != xor2))
1618  return 0;
1619  }
1620 
1621  return 1;
1622 }
1623 
1624 static int
1625 descend(struct saucy *s, struct coloring *c, int target, int min)
1626 {
1627  int back = target + c->clen[target];
1628 
1629  /* Count this node */
1630  ++s->stats->nodes;
1631 
1632  /* Move the minimum label to the back */
1633  swap_labels(c, min, back);
1634 
1635  /* Split the cell */
1636  s->difflev[s->lev] = s->ndiffs;
1637  s->undifflev[s->lev] = s->nundiffs;
1638  ++s->lev;
1639  s->split(s, c, target, back);
1640 
1641  /* Now go and do some work */
1642  //print_partition(&s->left, NULL, s->n, s->pNtk, 1);
1643  if (!refineByDepGraph(s, c)) return 0;
1644 
1645  /* if we are looking for a Boolean matching, check the OPP and
1646  * backtrack if the OPP maps part of one network to itself */
1647  if (s->fBooleanMatching && !check_OPP_for_Boolean_matching(s, c)) return 0;
1648 
1649  //print_partition(&s->left, NULL, s->n, s->pNtk, 1);
1650  if (REFINE_BY_SIM_1 && !s->refineBySim1(s, c)) return 0;
1651 
1652  //print_partition(&s->left, NULL, s->n, s->pNtk, 1);
1653  if (REFINE_BY_SIM_2 && !s->refineBySim2(s, c)) return 0;
1654 
1655  /* do the check once more, maybe the check fails, now that refinement is complete */
1656  if (s->fBooleanMatching && !check_OPP_for_Boolean_matching(s, c)) return 0;
1657 
1658  if (s->fLookForSwaps && !check_OPP_only_has_swaps(s, c)) return 0;
1659 
1660  if (!double_check_OPP_isomorphism(s, c)) return 0;
1661 
1662  return 1;
1663 }
1664 
1665 static int
1666 select_smallest_max_connected_cell(struct saucy *s, int start, int end)
1667 {
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);
1672 
1673  cell = start;
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]]) {
1680  connections++;
1681  connection_list[s->depEdg[i]] = 1;
1682  }
1683  }
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;
1688  }
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;
1691  }
1692  cell = s->nextnon[cell];
1693  }
1694 
1695  ABC_FREE( connection_list );
1696  return smallest_cell;
1697 }
1698 
1699 static int
1701 {
1702  int target, min;
1703 
1704  /* Keep going until we're discrete */
1705  //print_partition(&s->left, NULL, s->n, s->pNtk, 1);
1706  while (!at_terminal(s)) {
1707  //target = min = s->nextnon[-1];
1708  if (s->nextnon[-1] < Abc_NtkPoNum(s->pNtk))
1709  target = min = select_smallest_max_connected_cell(s, s->nextnon[-1], Abc_NtkPoNum(s->pNtk));
1710  else
1711  target = min = select_smallest_max_connected_cell(s, Abc_NtkPoNum(s->pNtk), s->n);
1712  if (s->fPrintTree)
1713  printf("%s->%s\n", getVertexName(s->pNtk, s->left.lab[min]), getVertexName(s->pNtk, s->left.lab[min]));
1714  s->splitvar[s->lev] = s->left.lab[min];
1715  s->start[s->lev] = target;
1716  s->splitlev[s->lev] = s->nsplits;
1717  if (!descend(s, &s->left, target, min)) return 0;
1718  }
1719  s->splitlev[s->lev] = s->n;
1720  return 1;
1721 }
1722 
1723 /*
1724  * If the remaining nonsingletons in this partition match exactly
1725  * those nonsingletons from the leftmost branch of the search tree,
1726  * then there is no point in continuing descent.
1727  */
1728 
1729 static int
1730 zeta_fixed(struct saucy *s)
1731 {
1732  return s->ndiffs == s->nundiffs;
1733 }
1734 
1735 static void
1736 select_dynamically(struct saucy *s, int *target, int *lmin, int *rmin)
1737 {
1738  /* Both clens are equal; this clarifies the code a bit */
1739  const int *clen = s->left.clen;
1740  int i, k;
1741  //int cf;
1742 
1743  /*
1744  * If there's a pair, use it. pairs[0] should always work,
1745  * but we use a checked loop instead because I'm not 100% sure
1746  * I'm "unpairing" at every point I should be.
1747  */
1748  for (i = 0; i < s->npairs; ++i) {
1749  k = s->pairs[i];
1750  *target = s->right.cfront[k];
1751  *lmin = s->left.unlab[s->right.lab[s->left.unlab[k]]];
1752  *rmin = s->right.unlab[k];
1753 
1754  if (clen[*target]
1755  && in_cell_range(&s->left, *lmin, *target)
1756  && in_cell_range(&s->right, *rmin, *target))
1757  return;
1758  }
1759 
1760  /* Diffnons is only consistent when there are no baddies */
1761  /*if (s->ndiffnons != -1) {
1762  *target = *lmin = *rmin = s->right.cfront[s->diffnons[0]];
1763  return;
1764  }*/
1765 
1766  /* Pick any old target cell and element */
1767  /*for (i = 0; i < s->ndiffs; ++i) {
1768  cf = s->right.cfront[s->diffs[i]];
1769  if (clen[cf]) {
1770  *lmin = *rmin = *target = cf;
1771  return;
1772  }
1773  }*/
1774 
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)
1779  *rmin = s->right.unlab[s->left.lab[*lmin]];
1780  return;
1781  }
1782 
1783  /* we should never get here */
1784  abort();
1785 }
1786 
1787 static void
1788 select_statically(struct saucy *s, int *target, int *lmin, int *rmin)
1789 {
1790  int i;
1791 
1792  *target = *rmin = s->left.cfront[s->splitvar[s->lev]];
1793  *lmin = s->left.unlab[s->splitvar[s->lev]];
1794  /* try to map identically! */
1795  for (i = *rmin; i <= (*rmin + s->right.clen[*target]); i++)
1796  if (s->right.lab[*rmin] == s->left.lab[*lmin]) {
1797  *rmin = i;
1798  break;
1799  }
1800 }
1801 
1802 static int
1804 {
1805  int target, lmin, rmin;
1806 
1807  /* Check that we ended at the right spot */
1808  if (s->nsplits != s->splitlev[s->lev]) return 0;
1809 
1810  /* Keep going until we're discrete */
1811  while (!at_terminal(s) /*&& !zeta_fixed(s)*/) {
1812 
1813  /* We can pick any old target cell and element */
1814  s->select_decomposition(s, &target, &lmin, &rmin);
1815 
1816  if (s->fPrintTree) {
1817  //printf("in level %d: %d->%d\n", s->lev, s->left.lab[lmin], s->right.lab[rmin]);
1818  printf("in level %d: %s->%s\n", s->lev, getVertexName(s->pNtk, s->left.lab[lmin]), getVertexName(s->pNtk, s->right.lab[rmin]));
1819  }
1820 
1821  /* Check if we need to refine on the left */
1822  s->match = 0;
1823  s->start[s->lev] = target;
1824  s->split = split_left;
1825  if (SELECT_DYNAMICALLY) {
1828  }
1829  descend(s, &s->left, target, lmin);
1830  s->splitlev[s->lev] = s->nsplits;
1831  s->split = split_other;
1832  if (SELECT_DYNAMICALLY) {
1835  }
1836  --s->lev;
1837  s->nsplits = s->splitlev[s->lev];
1838 
1839  /* Now refine on the right and ensure matching */
1840  s->specmin[s->lev] = s->right.lab[rmin];
1841  if (!descend(s, &s->right, target, rmin)) return 0;
1842  if (s->nsplits != s->splitlev[s->lev]) return 0;
1843  }
1844  return 1;
1845 }
1846 
1847 static int
1848 find_representative(int k, int *theta)
1849 {
1850  int rep, tmp;
1851 
1852  /* Find the minimum cell representative */
1853  for (rep = k; rep != theta[rep]; rep = theta[rep]);
1854 
1855  /* Update all intermediaries */
1856  while (theta[k] != rep) {
1857  tmp = theta[k]; theta[k] = rep; k = tmp;
1858  }
1859  return rep;
1860 }
1861 
1862 static void
1864 {
1865  int i, k, x, y, tmp;
1866 
1867  for (i = 0; i < s->ndiffs; ++i) {
1868  k = s->unsupp[i];
1869  x = find_representative(k, s->theta);
1870  y = find_representative(s->gamma[k], s->theta);
1871 
1872  if (x != y) {
1873  if (x > y) {
1874  tmp = x;
1875  x = y;
1876  y = tmp;
1877  }
1878  s->theta[y] = x;
1879  s->thsize[x] += s->thsize[y];
1880 
1881  s->thnext[s->thprev[y]] = s->thnext[y];
1882  s->thprev[s->thnext[y]] = s->thprev[y];
1883  s->threp[s->thfront[y]] = s->thnext[y];
1884  }
1885  }
1886 }
1887 
1888 static int
1889 theta_prune(struct saucy *s)
1890 {
1891  int start = s->start[s->lev];
1892  int label, rep, irep;
1893 
1894  irep = find_representative(s->indmin, s->theta);
1895  while (s->kanctar) {
1896  label = s->anctar[--s->kanctar];
1897  rep = find_representative(label, s->theta);
1898  if (rep == label && rep != irep) {
1899  return s->right.unlab[label] - start;
1900  }
1901  }
1902  return -1;
1903 }
1904 
1905 static int
1906 orbit_prune(struct saucy *s)
1907 {
1908  int i, label, fixed, min = -1;
1909  int k = s->start[s->lev];
1910  int size = s->right.clen[k] + 1;
1911  int *cell = s->right.lab + k;
1912 
1913  /* The previously fixed value */
1914  fixed = cell[size-1];
1915 
1916  /* Look for the next minimum cell representative */
1917  for (i = 0; i < size-1; ++i) {
1918  label = cell[i];
1919 
1920  /* Skip things we've already considered */
1921  if (label <= fixed) continue;
1922 
1923  /* Skip things that we'll consider later */
1924  if (min != -1 && label > cell[min]) continue;
1925 
1926  /* New candidate minimum */
1927  min = i;
1928  }
1929 
1930  return min;
1931 }
1932 
1933 static void
1935 {
1936  int i, j, k, m, f, rep, tmp;
1937 
1938  /*
1939  * Undo the previous level's splits along leftmost so that we
1940  * join the appropriate lists of theta reps.
1941  */
1942  for (i = s->splitlev[s->anc+1]-1; i >= s->splitlev[s->anc]; --i) {
1943  f = s->splitfrom[i];
1944  j = s->threp[f];
1945  k = s->threp[s->splitwho[i]];
1946 
1947  s->thnext[s->thprev[j]] = k;
1948  s->thnext[s->thprev[k]] = j;
1949 
1950  tmp = s->thprev[j];
1951  s->thprev[j] = s->thprev[k];
1952  s->thprev[k] = tmp;
1953 
1954  for (m = k; m != j; m = s->thnext[m]) {
1955  s->thfront[m] = f;
1956  }
1957  }
1958 
1959  /*
1960  * Just copy over the target's reps and sort by cell size, in
1961  * the hopes of trimming some otherwise redundant generators.
1962  */
1963  s->kanctar = 0;
1964  s->anctar[s->kanctar++] = rep = s->threp[s->start[s->lev]];
1965  for (k = s->thnext[rep]; k != rep; k = s->thnext[k]) {
1966  s->anctar[s->kanctar++] = k;
1967  }
1969 }
1970 
1971 static void
1972 multiply_index(struct saucy *s, int k)
1973 {
1974  if ((s->stats->grpsize_base *= k) > 1e10) {
1975  s->stats->grpsize_base /= 1e10;
1976  s->stats->grpsize_exp += 10;
1977  }
1978 }
1979 
1980 static int
1982 {
1983  int rep = find_representative(s->indmin, s->theta);
1984  int repsize = s->thsize[rep];
1985  int min = -1;
1986 
1987  pick_all_the_pairs(s);
1988  clear_undiffnons(s);
1989  s->ndiffs = s->nundiffs = s->npairs = s->ndiffnons = 0;
1990 
1991  if (repsize != s->right.clen[s->start[s->lev]]+1) {
1992  min = theta_prune(s);
1993  }
1994 
1995  if (min == -1) {
1996  multiply_index(s, repsize);
1997  }
1998 
1999  return min;
2000 }
2001 
2002 static int
2004 {
2005  int cf = s->start[s->lev];
2006  int cb = cf + s->right.clen[cf];
2007  int spec = s->specmin[s->lev];
2008  int min;
2009 
2010  /* Avoid using pairs until we get back to leftmost. */
2011  pick_all_the_pairs(s);
2012 
2013  clear_undiffnons(s);
2014 
2015  s->npairs = s->ndiffnons = -1;
2016 
2017  if (s->right.lab[cb] == spec) {
2018  min = find_min(s, cf);
2019  if (min == cb) {
2020  min = orbit_prune(s);
2021  }
2022  else {
2023  min -= cf;
2024  }
2025  }
2026  else {
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);
2031  }
2032  }
2033  return min;
2034 }
2035 
2036 static void
2037 rewind_coloring(struct saucy *s, struct coloring *c, int lev)
2038 {
2039  int i, cf, ff, splits = s->splitlev[lev];
2040  for (i = s->nsplits - 1; i >= splits; --i) {
2041  cf = s->splitfrom[i];
2042  ff = s->splitwho[i];
2043  c->clen[cf] += c->clen[ff] + 1;
2044  fix_fronts(c, cf, ff);
2045  }
2046 }
2047 
2048 static void
2050 {
2051  int i;
2052  for (i = s->randomVectorSplit_sim1[lev]; i < Vec_PtrSize(s->randomVectorArray_sim1); i++)
2055 
2056  for (i = s->randomVectorSplit_sim2[lev]; i < Vec_PtrSize(s->randomVectorArray_sim2); i++)
2059 }
2060 
2061 static int
2063 {
2064  int i, cf, cb;
2065 
2066  /* Undo the splits up to this level */
2067  rewind_coloring(s, &s->right, s->lev);
2068  s->nsplits = s->splitlev[s->lev];
2069 
2070  /* Rewind diff information */
2071  for (i = s->ndiffs - 1; i >= s->difflev[s->lev]; --i) {
2072  s->diffmark[s->diffs[i]] = 0;
2073  }
2074  s->ndiffs = s->difflev[s->lev];
2075  s->nundiffs = s->undifflev[s->lev];
2076 
2077  /* Point to the target cell */
2078  cf = s->start[s->lev];
2079  cb = cf + s->right.clen[cf];
2080 
2081  /* Update ancestor with zeta if we've rewound more */
2082  if (s->anc > s->lev) {
2083  s->anc = s->lev;
2084  s->indmin = s->left.lab[cb];
2085  s->match = 1;
2086  note_anctar_reps(s);
2087  }
2088 
2089  /* Perform backtracking appropriate to our location */
2090  return s->lev == s->anc
2091  ? backtrack_leftmost(s)
2092  : backtrack_other(s);
2093 }
2094 
2095 static int
2097 {
2098  int min;
2099 
2100  /* Backtrack as long as we're exhausting target cells */
2101  for (--s->lev; s->lev; --s->lev) {
2102  min = do_backtrack(s);
2103  if (min != -1) return min + s->start[s->lev];
2104  }
2105  return -1;
2106 }
2107 
2108 static int
2109 backtrack(struct saucy *s)
2110 {
2111  int min, old, tmp;
2112  old = s->nsplits;
2113  min = backtrack_loop(s);
2114  tmp = s->nsplits;
2115  s->nsplits = old;
2116  rewind_coloring(s, &s->left, s->lev+1);
2117  s->nsplits = tmp;
2118  if (SELECT_DYNAMICALLY)
2119  rewind_simulation_vectors(s, s->lev+1);
2120 
2121  return min;
2122 }
2123 
2124 static int
2126 {
2127  int min, old, tmp;
2128  old = s->lev;
2129  min = backtrack_loop(s);
2130  if (BACKTRACK_BY_SAT) {
2131  int oldLev = s->lev;
2132  while (!backtrackBysatCounterExamples(s, &s->right)) {
2133  min = backtrack_loop(s);
2134  if (!s->lev) {
2135  if (s->fPrintTree)
2136  printf("Backtrack by SAT from level %d to %d\n", oldLev, 0);
2137  return -1;
2138  }
2139  }
2140  if (s->fPrintTree)
2141  if (s->lev < oldLev)
2142  printf("Backtrack by SAT from level %d to %d\n", oldLev, s->lev);
2143  }
2144  tmp = s->nsplits;
2145  s->nsplits = s->splitlev[old];
2146  rewind_coloring(s, &s->left, s->lev+1);
2147  s->nsplits = tmp;
2148  if (SELECT_DYNAMICALLY)
2149  rewind_simulation_vectors(s, s->lev+1);
2150 
2151  return min;
2152 }
2153 
2154 void
2156 {
2157  int i;
2158  Abc_Obj_t * pObj, * pObjPerm;
2159  int numouts = Abc_NtkPoNum(s->pNtk);
2160 
2163 
2164  for (i = 0; i < s->n; ++i) {
2165  if (i < numouts) {
2166  pObj = (Abc_Obj_t *)Vec_PtrEntry(s->pNtk->vPos, i);
2167  pObjPerm = (Abc_Obj_t *)Vec_PtrEntry(s->pNtk_permuted->vPos, s->gamma[i]);
2168  }
2169  else {
2170  pObj = (Abc_Obj_t *)Vec_PtrEntry(s->pNtk->vPis, i - numouts);
2171  pObjPerm = (Abc_Obj_t *)Vec_PtrEntry(s->pNtk_permuted->vPis, s->gamma[i] - numouts);
2172 
2173  }
2174  Abc_ObjAssignName( pObjPerm, Abc_ObjName(pObj), NULL );
2175  }
2176 
2178 
2179  /* print the permutation */
2180  /*for (i = 0; i < s->ndiffs; ++i)
2181  printf(" %d->%d", s->unsupp[i], s->diffs[i]);
2182  printf("\n");
2183  Abc_NtkForEachCo( s->pNtk, pObj, i )
2184  printf (" %d", Abc_ObjId(pObj)-1-Abc_NtkPiNum(s->pNtk));
2185  Abc_NtkForEachCi( s->pNtk, pObj, i )
2186  printf (" %d", Abc_ObjId(pObj)-1+Abc_NtkPoNum(s->pNtk));
2187  printf("\n");
2188  Abc_NtkForEachCo( s->pNtk_permuted, pObj, i )
2189  printf (" %d", Abc_ObjId(pObj)-1-Abc_NtkPiNum(s->pNtk_permuted));
2190  Abc_NtkForEachCi( s->pNtk_permuted, pObj, i )
2191  printf (" %d", Abc_ObjId(pObj)-1+Abc_NtkPoNum(s->pNtk_permuted));
2192  printf("\n");*/
2193 }
2194 
2195 
2196 static void
2198 {
2199  int i, k;
2200  for (i = 0; i < s->ndiffs; ++i) {
2201  k = s->right.unlab[s->diffs[i]];
2202  s->unsupp[i] = s->left.lab[k];
2203  s->gamma[s->left.lab[k]] = s->right.lab[k];
2204  }
2206 }
2207 
2208 void
2210 {
2211  int i;
2212  Abc_Obj_t * pObj, * pObjPerm;
2213  int numouts = Abc_NtkPoNum(s->pNtk);
2214 
2217 
2218  for (i = 0; i < s->n; ++i) {
2219  if (i < numouts) {
2220  pObj = (Abc_Obj_t *)Vec_PtrEntry(s->pNtk->vPos, s->gamma[i]);
2221  pObjPerm = (Abc_Obj_t *)Vec_PtrEntry(s->pNtk_permuted->vPos, i);
2222  }
2223  else {
2224  pObj = (Abc_Obj_t *)Vec_PtrEntry(s->pNtk->vPis, s->gamma[i] - numouts);
2225  pObjPerm = (Abc_Obj_t *)Vec_PtrEntry(s->pNtk_permuted->vPis, i - numouts);
2226 
2227  }
2228  Abc_ObjAssignName( pObjPerm, Abc_ObjName(pObj), NULL );
2229  }
2230 
2232 }
2233 
2234 
2235 static void
2237 {
2238  int i;
2240  for (i = 0; i < s->ndiffs; ++i) {
2241  s->gamma[s->unsupp[i]] = s->unsupp[i];
2242  }
2243 }
2244 
2245 static int
2246 do_search(struct saucy *s)
2247 {
2248  int min;
2249 
2251 
2252  /* Backtrack to the ancestor with zeta */
2253  if (s->lev > s->anc) s->lev = s->anc + 1;
2254 
2255  /* Perform additional backtracking */
2256  min = backtrack(s);
2257 
2258  if (s->fBooleanMatching && (s->stats->grpsize_base > 1 || s->stats->grpsize_exp > 0))
2259  return 0;
2260 
2261  if (s->fPrintTree && s->lev > 0) {
2262  //printf("in level %d: %d->%d\n", s->lev, s->left.lab[s->splitwho[s->nsplits]], s->right.lab[min]);
2263  printf("in level %d: %s->%s\n", s->lev, getVertexName(s->pNtk, s->left.lab[s->splitwho[s->nsplits]]), getVertexName(s->pNtk, s->right.lab[min]));
2264  }
2265 
2266  /* Keep going while there are tree nodes to expand */
2267  while (s->lev) {
2268 
2269  /* Descend to a new leaf node */
2270  if (descend(s, &s->right, s->start[s->lev], min)
2271  && descend_left(s)) {
2272 
2273  /* Prepare permutation */
2275 
2276  /* If we found an automorphism, return it */
2277  if (s->is_automorphism(s)) {
2278  ++s->stats->gens;
2279  s->stats->support += s->ndiffs;
2280  update_theta(s);
2281  s->print_automorphism(s->gFile, s->n, s->gamma, s->ndiffs, s->unsupp, s->marks, s->pNtk);
2283  return 1;
2284  }
2285  else {
2287  }
2288  }
2289 
2290  /* If we get here, something went wrong; backtrack */
2291  ++s->stats->bads;
2292  min = backtrack_bad(s);
2293  if (s->fPrintTree) {
2294  printf("BAD NODE\n");
2295  if (s->lev > 0) {
2296  //printf("in level %d: %d->%d\n", s->lev, s->left.lab[s->splitwho[s->nsplits]], s->right.lab[min]);
2297  printf("in level %d: %s->%s\n", s->lev, getVertexName(s->pNtk, s->left.lab[s->splitwho[s->nsplits]]), getVertexName(s->pNtk, s->right.lab[min]));
2298  }
2299  }
2300  }
2301 
2302  /* Normalize group size */
2303  while (s->stats->grpsize_base >= 10.0) {
2304  s->stats->grpsize_base /= 10;
2305  ++s->stats->grpsize_exp;
2306  }
2307  return 0;
2308 }
2309 
2310 void
2312  Abc_Ntk_t * pNtk,
2313  struct saucy *s,
2314  int directed,
2315  const int *colors,
2316  struct saucy_stats *stats)
2317 {
2318  int i, j, max = 0;
2319  struct saucy_graph *g;
2320 
2321  extern Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk );
2322 
2323  /* Save network information */
2324  s->pNtk = pNtk;
2325  s->pNtk_permuted = Abc_NtkDup( pNtk );
2326 
2327  /* Builde dependency graph */
2328  g = buildDepGraph(pNtk, s->iDep, s->oDep);
2329 
2330  /* Save graph information */
2331  s->n = g->n;
2332  s->depAdj = g->adj;
2333  s->depEdg = g->edg;
2334  /*s->dadj = g->adj + g->n + 1;
2335  s->dedg = g->edg + g->e;*/
2336 
2337  /* Save client information */
2338  s->stats = stats;
2339 
2340  /* Polymorphism */
2341  if (directed) {
2345  }
2346  else {
2350  }
2351 
2352  /* Initialize scalars */
2353  s->indmin = 0;
2354  s->lev = s->anc = 1;
2355  s->ndiffs = s->nundiffs = s->ndiffnons = 0;
2356  s->activityInc = 1;
2357 
2358  /* The initial orbit partition is discrete */
2359  for (i = 0; i < s->n; ++i) {
2360  s->theta[i] = i;
2361  }
2362 
2363  /* The initial permutation is the identity */
2364  for (i = 0; i < s->n; ++i) {
2365  s->gamma[i] = i;
2366  }
2367 
2368  /* Initially every cell of theta has one element */
2369  for (i = 0; i < s->n; ++i) {
2370  s->thsize[i] = 1;
2371  }
2372 
2373  /* Every theta rep list is singleton */
2374  for (i = 0; i < s->n; ++i) {
2375  s->thprev[i] = s->thnext[i] = i;
2376  }
2377 
2378  /* We have no pairs yet */
2379  s->npairs = 0;
2380  for (i = 0; i < s->n; ++i) {
2381  s->unpairs[i] = -1;
2382  }
2383 
2384  /* Ensure no stray pointers in undiffnons, which is checked by removed_diffnon() */
2385  for (i = 0; i < s->n; ++i) {
2386  s->undiffnons[i] = -1;
2387  }
2388 
2389  /* Initialize stats */
2390  s->stats->grpsize_base = 1.0;
2391  s->stats->grpsize_exp = 0;
2392  s->stats->nodes = 1;
2393  s->stats->bads = s->stats->gens = s->stats->support = 0;
2394 
2395  /* Prepare for refinement */
2396  s->nninduce = s->nsinduce = 0;
2397  s->csize = 0;
2398 
2399  /* Count cell sizes */
2400  for (i = 0; i < s->n; ++i) {
2401  s->ccount[colors[i]]++;
2402  if (max < colors[i]) max = colors[i];
2403  }
2404  s->nsplits = max + 1;
2405 
2406  /* Build cell lengths */
2407  s->left.clen[0] = s->ccount[0] - 1;
2408  for (i = 0; i < max; ++i) {
2409  s->left.clen[s->ccount[i]] = s->ccount[i+1] - 1;
2410  s->ccount[i+1] += s->ccount[i];
2411  }
2412 
2413  /* Build the label array */
2414  for (i = 0; i < s->n; ++i) {
2415  set_label(&s->left, --s->ccount[colors[i]], i);
2416  }
2417 
2418  /* Clear out ccount */
2419  for (i = 0; i <= max; ++i) {
2420  s->ccount[i] = 0;
2421  }
2422 
2423  /* Update refinement stuff based on initial partition */
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);
2427  }
2428 
2429  /* Prepare lists based on cell lengths */
2430  for (i = 0, j = -1; i < s->n; i += s->left.clen[i] + 1) {
2431  if (!s->left.clen[i]) continue;
2432  s->prevnon[i] = j;
2433  s->nextnon[j] = i;
2434  j = i;
2435  }
2436 
2437  /* Fix the end */
2438  s->prevnon[s->n] = j;
2439  s->nextnon[j] = s->n;
2440 
2441  /* Preprocessing after initial coloring */
2442  s->split = split_init;
2445 
2446  //print_partition(&s->left, NULL, s->n, s->pNtk, 1);
2447  printf("Initial Refine by Dependency graph ... ");
2448  refineByDepGraph(s, &s->left);
2449  //print_partition(&s->left, NULL, s->n, s->pNtk, 1);
2450  printf("done!\n");
2451 
2452  printf("Initial Refine by Simulation ... ");
2453  if (REFINE_BY_SIM_1) s->refineBySim1(s, &s->left);
2454  //print_partition(&s->left, NULL, s->n, s->pNtk, 1);
2455  if (REFINE_BY_SIM_2) s->refineBySim2(s, &s->left);
2456  //print_partition(&s->left, NULL, s->n, s->pNtk, 1);
2457  printf("done!\n\t--------------------\n");
2458 
2459  /* Descend along the leftmost branch and compute zeta */
2462  descend_leftmost(s);
2463  s->split = split_other;
2466 
2467  /* Our common ancestor with zeta is the current level */
2468  s->stats->levels = s->anc = s->lev;
2469 
2470  /* Copy over this data to our non-leftmost coloring */
2471  memcpy(s->right.lab, s->left.lab, s->n * sizeof(int));
2472  memcpy(s->right.unlab, s->left.unlab, s->n * sizeof(int));
2473  memcpy(s->right.clen, s->left.clen, s->n * sizeof(int));
2474  memcpy(s->right.cfront, s->left.cfront, s->n * sizeof(int));
2475 
2476  /* The reps are just the labels at this point */
2477  memcpy(s->threp, s->left.lab, s->n * sizeof(int));
2478  memcpy(s->thfront, s->left.unlab, s->n * sizeof(int));
2479 
2480  /* choose cell selection method */
2483 
2484  /* Keep running till we're out of automorphisms */
2485  while (do_search(s));
2486 }
2487 
2488 void
2489 saucy_free(struct saucy *s)
2490 {
2491  int i;
2492 
2493  ABC_FREE(s->undiffnons);
2494  ABC_FREE(s->diffnons);
2495  ABC_FREE(s->unpairs);
2496  ABC_FREE(s->pairs);
2497  ABC_FREE(s->thfront);
2498  ABC_FREE(s->threp);
2499  ABC_FREE(s->thnext);
2500  ABC_FREE(s->thprev);
2501  ABC_FREE(s->specmin);
2502  ABC_FREE(s->anctar);
2503  ABC_FREE(s->thsize);
2504  ABC_FREE(s->undifflev);
2505  ABC_FREE(s->difflev);
2506  ABC_FREE(s->diffs);
2507  ABC_FREE(s->diffmark);
2508  ABC_FREE(s->conncnts);
2509  ABC_FREE(s->unsupp);
2510  ABC_FREE(s->splitlev);
2511  ABC_FREE(s->splitfrom);
2512  ABC_FREE(s->splitwho);
2513  ABC_FREE(s->splitvar);
2514  ABC_FREE(s->right.unlab);
2515  ABC_FREE(s->right.lab);
2516  ABC_FREE(s->left.unlab);
2517  ABC_FREE(s->left.lab);
2518  ABC_FREE(s->theta);
2519  ABC_FREE(s->junk);
2520  ABC_FREE(s->gamma);
2521  ABC_FREE(s->start);
2522  ABC_FREE(s->prevnon);
2523  free(s->nextnon-1);
2524  ABC_FREE(s->clist);
2525  ABC_FREE(s->ccount);
2526  ABC_FREE(s->count);
2527  ABC_FREE(s->bucket);
2528  ABC_FREE(s->stuff);
2529  ABC_FREE(s->right.clen);
2530  ABC_FREE(s->right.cfront);
2531  ABC_FREE(s->left.clen);
2532  ABC_FREE(s->left.cfront);
2533  ABC_FREE(s->indmark);
2534  ABC_FREE(s->sinduce);
2535  ABC_FREE(s->ninduce);
2536  ABC_FREE(s->depAdj);
2537  ABC_FREE(s->depEdg);
2538  ABC_FREE(s->marks);
2539  for (i = 0; i < Abc_NtkPiNum(s->pNtk); i++) {
2540  Vec_IntFree( s->iDep[i] );
2541  Vec_IntFree( s->obs[i] );
2542  Vec_PtrFree( s->topOrder[i] );
2543  }
2544  for (i = 0; i < Abc_NtkPoNum(s->pNtk); i++) {
2545  Vec_IntFree( s->oDep[i] );
2546  Vec_IntFree( s->ctrl[i] );
2547  }
2548  for (i = 0; i < Vec_PtrSize(s->randomVectorArray_sim1); i++)
2550  for (i = 0; i < Vec_PtrSize(s->randomVectorArray_sim2); i++)
2557  for (i = 0; i < Vec_PtrSize(s->satCounterExamples); i++) {
2558  struct sim_result * cex = (struct sim_result *)Vec_PtrEntry(s->satCounterExamples, i);
2559  ABC_FREE( cex->inVec );
2560  ABC_FREE( cex->outVec );
2561  ABC_FREE( cex );
2562  }
2564  ABC_FREE( s->pModel );
2565  ABC_FREE( s->iDep );
2566  ABC_FREE( s->oDep );
2567  ABC_FREE( s->obs );
2568  ABC_FREE( s->ctrl );
2569  ABC_FREE( s->topOrder );
2570  ABC_FREE(s);
2571 }
2572 
2573 struct saucy *
2575 {
2576  int i;
2577  int numouts = Abc_NtkPoNum(pNtk);
2578  int numins = Abc_NtkPiNum(pNtk);
2579  int n = numins + numouts;
2580  struct saucy *s = ABC_ALLOC(struct saucy, 1);
2581  if (s == NULL) return NULL;
2582 
2583  s->ninduce = ints(n);
2584  s->sinduce = ints(n);
2585  s->indmark = bits(n);
2586  s->left.cfront = zeros(n);
2587  s->left.clen = ints(n);
2588  s->right.cfront = zeros(n);
2589  s->right.clen = ints(n);
2590  s->stuff = bits(n+1);
2591  s->bucket = ints(n+2);
2592  s->count = ints(n+1);
2593  s->ccount = zeros(n);
2594  s->clist = ints(n);
2595  s->nextnon = ints(n+1) + 1;
2596  s->prevnon = ints(n+1);
2597  s->anctar = ints(n);
2598  s->start = ints(n);
2599  s->gamma = ints(n);
2600  s->junk = ints(n);
2601  s->theta = ints(n);
2602  s->thsize = ints(n);
2603  s->left.lab = ints(n);
2604  s->left.unlab = ints(n);
2605  s->right.lab = ints(n);
2606  s->right.unlab = ints(n);
2607  s->splitvar = ints(n);
2608  s->splitwho = ints(n);
2609  s->splitfrom = ints(n);
2610  s->splitlev = ints(n+1);
2611  s->unsupp = ints(n);
2612  s->conncnts = zeros(n);
2613  s->diffmark = bits(n);
2614  s->diffs = ints(n);
2615  s->difflev = ints(n);
2616  s->undifflev = ints(n);
2617  s->specmin = ints(n);
2618  s->thnext = ints(n);
2619  s->thprev = ints(n);
2620  s->threp = ints(n);
2621  s->thfront = ints(n);
2622  s->pairs = ints(n);
2623  s->unpairs = ints(n);
2624  s->diffnons = ints(n);
2625  s->undiffnons = ints(n);
2626  s->marks = bits(n);
2627 
2628  s->iDep = ABC_ALLOC( Vec_Int_t*, numins );
2629  s->oDep = ABC_ALLOC( Vec_Int_t*, numouts );
2630  s->obs = ABC_ALLOC( Vec_Int_t*, numins );
2631  s->ctrl = ABC_ALLOC( Vec_Int_t*, numouts );
2632 
2633  for(i = 0; i < numins; i++) {
2634  s->iDep[i] = Vec_IntAlloc( 1 );
2635  s->obs[i] = Vec_IntAlloc( 1 );
2636  }
2637  for(i = 0; i < numouts; i++) {
2638  s->oDep[i] = Vec_IntAlloc( 1 );
2639  s->ctrl[i] = Vec_IntAlloc( 1 );
2640  }
2641 
2643  s->randomVectorSplit_sim1 = zeros( n );
2645  s->randomVectorSplit_sim2= zeros( n );
2646 
2647  s->satCounterExamples = Vec_PtrAlloc( 1 );
2648  s->pModel = ints( numins );
2649 
2650  if (s->ninduce && s->sinduce && s->left.cfront && s->left.clen
2651  && s->right.cfront && s->right.clen
2652  && s->stuff && s->bucket && s->count && s->ccount
2653  && s->clist && s->nextnon-1 && s->prevnon
2654  && s->start && s->gamma && s->theta && s->left.unlab
2655  && s->right.lab && s->right.unlab
2656  && s->left.lab && s->splitvar && s->splitwho && s->junk
2657  && s->splitfrom && s->splitlev && s->thsize
2658  && s->unsupp && s->conncnts && s->anctar
2659  && s->diffmark && s->diffs && s->indmark
2660  && s->thnext && s->thprev && s->threp && s->thfront
2661  && s->pairs && s->unpairs && s->diffnons && s->undiffnons
2662  && s->difflev && s->undifflev && s->specmin)
2663  {
2664  return s;
2665  }
2666  else {
2667  saucy_free(s);
2668  return NULL;
2669  }
2670 }
2671 
2672 static void
2673 print_stats(FILE *f, struct saucy_stats stats )
2674 {
2675  fprintf(f, "group size = %fe%d\n",
2676  stats.grpsize_base, stats.grpsize_exp);
2677  fprintf(f, "levels = %d\n", stats.levels);
2678  fprintf(f, "nodes = %d\n", stats.nodes);
2679  fprintf(f, "generators = %d\n", stats.gens);
2680  fprintf(f, "total support = %d\n", stats.support);
2681  fprintf(f, "average support = %.2f\n",(double)(stats.support)/(double)(stats.gens));
2682  fprintf(f, "nodes per generator = %.2f\n",(double)(stats.nodes)/(double)(stats.gens));
2683  fprintf(f, "bad nodes = %d\n", stats.bads);
2684 }
2685 
2686 
2687 /* From this point up are SAUCY functions*/
2688 /////////////////////////////////////////////////////////////////////////////////////////////////////////
2689 /* From this point down are new functions */
2690 
2691 static char *
2693 {
2694  Abc_Obj_t * pObj;
2695  int numouts = Abc_NtkPoNum(pNtk);
2696 
2697  if (v < numouts)
2698  pObj = (Abc_Obj_t *)Vec_PtrEntry(pNtk->vPos, v);
2699  else
2700  pObj = (Abc_Obj_t *)Vec_PtrEntry(pNtk->vPis, v - numouts);
2701 
2702  return Abc_ObjName(pObj);
2703 }
2704 
2705 static Vec_Ptr_t **
2707 {
2708  Vec_Ptr_t ** vNodes;
2709  Abc_Obj_t * pObj, * pFanout;
2710  int i, k;
2711 
2712  extern void Abc_NtkDfsReverse_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes );
2713 
2714  /* start the array of nodes */
2715  vNodes = ABC_ALLOC(Vec_Ptr_t *, Abc_NtkPiNum(pNtk));
2716  for(i = 0; i < Abc_NtkPiNum(pNtk); i++)
2717  vNodes[i] = Vec_PtrAlloc(50);
2718 
2719  Abc_NtkForEachCi( pNtk, pObj, i )
2720  {
2721  /* set the traversal ID */
2722  Abc_NtkIncrementTravId( pNtk );
2723  Abc_NodeSetTravIdCurrent( pObj );
2724  pObj = Abc_ObjFanout0Ntk(pObj);
2725  Abc_ObjForEachFanout( pObj, pFanout, k )
2726  Abc_NtkDfsReverse_rec( pFanout, vNodes[i] );
2727  }
2728 
2729  return vNodes;
2730 }
2731 
2732 static void
2734 {
2735  Vec_Ptr_t * vSuppFun;
2736  int i, j;
2737 
2738  vSuppFun = Sim_ComputeFunSupp(pNtk, 0);
2739  for(i = 0; i < Abc_NtkPoNum(pNtk); i++) {
2740  char * seg = (char *)vSuppFun->pArray[i];
2741 
2742  for(j = 0; j < Abc_NtkPiNum(pNtk); j+=8) {
2743  if(((*seg) & 0x01) == 0x01)
2744  Vec_IntPushOrder(oDep[i], j);
2745  if(((*seg) & 0x02) == 0x02)
2746  Vec_IntPushOrder(oDep[i], j+1);
2747  if(((*seg) & 0x04) == 0x04)
2748  Vec_IntPushOrder(oDep[i], j+2);
2749  if(((*seg) & 0x08) == 0x08)
2750  Vec_IntPushOrder(oDep[i], j+3);
2751  if(((*seg) & 0x10) == 0x10)
2752  Vec_IntPushOrder(oDep[i], j+4);
2753  if(((*seg) & 0x20) == 0x20)
2754  Vec_IntPushOrder(oDep[i], j+5);
2755  if(((*seg) & 0x40) == 0x40)
2756  Vec_IntPushOrder(oDep[i], j+6);
2757  if(((*seg) & 0x80) == 0x80)
2758  Vec_IntPushOrder(oDep[i], j+7);
2759 
2760  seg++;
2761  }
2762  }
2763 
2764  for(i = 0; i < Abc_NtkPoNum(pNtk); i++)
2765  for(j = 0; j < Vec_IntSize(oDep[i]); j++)
2766  Vec_IntPush(iDep[Vec_IntEntry(oDep[i], j)], i);
2767 
2768 
2769  /*for(i = 0; i < Abc_NtkPoNum(pNtk); i++)
2770  {
2771  printf("Output %d: ", i);
2772  for(j = 0; j < Vec_IntSize(oDep[i]); j++)
2773  printf("%d ", Vec_IntEntry(oDep[i], j));
2774  printf("\n");
2775  }
2776 
2777  printf("\n");
2778 
2779  for(i = 0; i < Abc_NtkPiNum(pNtk); i++)
2780  {
2781  printf("Input %d: ", i);
2782  for(j = 0; j < Vec_IntSize(iDep[i]); j++)
2783  printf("%d ", Vec_IntEntry(iDep[i], j));
2784  printf("\n");
2785  }
2786 
2787  printf("\n"); */
2788 }
2789 
2790 static void
2792 {
2793  int i, j;
2794 
2795  /* let's assume that every output is dependent on every input */
2796  for(i = 0; i < Abc_NtkPoNum(pNtk); i++)
2797  for(j = 0; j < Abc_NtkPiNum(pNtk); j++)
2798  Vec_IntPush(oDep[i], j);
2799 
2800  for(i = 0; i < Abc_NtkPiNum(pNtk); i++)
2801  for(j = 0; j < Abc_NtkPoNum(pNtk); j++)
2802  Vec_IntPush(iDep[i], j);
2803 }
2804 
2805 static struct saucy_graph *
2806 buildDepGraph(Abc_Ntk_t *pNtk, Vec_Int_t ** iDep, Vec_Int_t ** oDep)
2807 {
2808  int i, j, k;
2809  struct saucy_graph *g = NULL;
2810  int n, e, *adj, *edg;
2811 
2812  n = Abc_NtkPoNum(pNtk) + Abc_NtkPiNum(pNtk);
2813  for (e = 0, i = 0; i < Abc_NtkPoNum(pNtk); i++)
2814  e += Vec_IntSize(oDep[i]);
2815 
2816  g = ABC_ALLOC(struct saucy_graph, 1);
2817  adj = zeros(n+1);
2818  edg = ints(2*e);
2819 
2820  g->n = n;
2821  g->e = e;
2822  g->adj = adj;
2823  g->edg = edg;
2824 
2825  adj[0] = 0;
2826  for (i = 0; i < n; i++) {
2827  /* first add outputs and then inputs */
2828  if ( i < Abc_NtkPoNum(pNtk)) {
2829  adj[i+1] = adj[i] + Vec_IntSize(oDep[i]);
2830  for (k = 0, j = adj[i]; j < adj[i+1]; j++, k++)
2831  edg[j] = Vec_IntEntry(oDep[i], k) + Abc_NtkPoNum(pNtk);
2832  }
2833  else {
2834  adj[i+1] = adj[i] + Vec_IntSize(iDep[i-Abc_NtkPoNum(pNtk)]);
2835  for (k = 0, j = adj[i]; j < adj[i+1]; j++, k++)
2836  edg[j] = Vec_IntEntry(iDep[i-Abc_NtkPoNum(pNtk)], k);
2837  }
2838  }
2839 
2840  /* print graph for testing */
2841  /*for (i = 0; i < n; i++) {
2842  printf("%d: ", i);
2843  for (j = adj[i]; j < adj[i+1]; j++)
2844  printf("%d ", edg[j]);
2845  printf("\n");
2846  }*/
2847 
2848  return g;
2849 }
2850 
2851 static Vec_Int_t *
2853 {
2854  Vec_Int_t * randVec = Vec_IntAlloc( 1 );
2855  int i, bit;
2856 
2857  for (i = 0; i < Abc_NtkPiNum(pNtk); i += (c->clen[i+Abc_NtkPoNum(pNtk)]+1)) {
2858  bit = (int)(SIM_RANDOM_UNSIGNED % 2);
2859  Vec_IntPush(randVec, bit);
2860  }
2861 
2862  return randVec;
2863 }
2864 
2865 static int *
2866 generateProperInputVector( Abc_Ntk_t * pNtk, struct coloring *c, Vec_Int_t * randomVector )
2867 {
2868  int * vPiValues;
2869  int i, j, k, bit, input;
2870  int numouts = Abc_NtkPoNum(pNtk);
2871  int numins = Abc_NtkPiNum(pNtk);
2872  int n = numouts + numins;
2873 
2874  vPiValues = ABC_ALLOC( int, numins);
2875 
2876  for (i = numouts, k = 0; i < n; i += (c->clen[i]+1), k++) {
2877  if (k == Vec_IntSize(randomVector)) break;
2878 
2879  bit = Vec_IntEntry(randomVector, k);
2880  for (j = i; j <= (i + c->clen[i]); j++) {
2881  input = c->lab[j] - numouts;
2882  vPiValues[input] = bit;
2883  }
2884  }
2885 
2886  //if (k != Vec_IntSize(randomVector)) {
2887  if (i < n) {
2888  ABC_FREE( vPiValues );
2889  return NULL;
2890  }
2891 
2892  return vPiValues;
2893 }
2894 
2895 static int
2896 ifInputVectorsAreConsistent( struct saucy * s, int * leftVec, int * rightVec )
2897 {
2898  /* This function assumes that left and right partitions are isomorphic */
2899  int i, j;
2900  int lab;
2901  int left_bit, right_bit;
2902  int numouts = Abc_NtkPoNum(s->pNtk);
2903  int n = numouts + Abc_NtkPiNum(s->pNtk);
2904 
2905  for (i = numouts; i < n; i += (s->right.clen[i]+1)) {
2906  lab = s->left.lab[i] - numouts;
2907  left_bit = leftVec[lab];
2908  for (j = i+1; j <= (i + s->right.clen[i]); j++) {
2909  lab = s->left.lab[j] - numouts;
2910  if (left_bit != leftVec[lab]) return -1;
2911  }
2912 
2913  lab = s->right.lab[i] - numouts;
2914  right_bit = rightVec[lab];
2915  for (j = i+1; j <= (i + s->right.clen[i]); j++) {
2916  lab = s->right.lab[j] - numouts;
2917  if (right_bit != rightVec[lab]) return 0;
2918  }
2919 
2920  if (left_bit != right_bit)
2921  return 0;
2922  }
2923 
2924  return 1;
2925 }
2926 
2927 static int
2928 ifOutputVectorsAreConsistent( struct saucy * s, int * leftVec, int * rightVec )
2929 {
2930  /* This function assumes that left and right partitions are isomorphic */
2931  int i, j;
2932  int count1, count2;
2933 
2934  for (i = 0; i < Abc_NtkPoNum(s->pNtk); i += (s->right.clen[i]+1)) {
2935  count1 = count2 = 0;
2936  for (j = i; j <= (i + s->right.clen[i]); j++) {
2937  if (leftVec[s->left.lab[j]]) count1++;
2938  if (rightVec[s->right.lab[j]]) count2++;
2939  }
2940 
2941  if (count1 != count2) return 0;
2942  }
2943 
2944  return 1;
2945 }
2946 
2947 static struct saucy_graph *
2948 buildSim1Graph( Abc_Ntk_t * pNtk, struct coloring *c, Vec_Int_t * randVec, Vec_Int_t ** iDep, Vec_Int_t ** oDep )
2949 {
2950  int i, j, k;
2951  struct saucy_graph *g;
2952  int n, e, *adj, *edg;
2953  int * vPiValues, * output;
2954  int numOneOutputs = 0;
2955  int numouts = Abc_NtkPoNum(pNtk);
2956  int numins = Abc_NtkPiNum(pNtk);
2957 
2958  vPiValues = generateProperInputVector(pNtk, c, randVec);
2959  if (vPiValues == NULL)
2960  return NULL;
2961 
2962  output = Abc_NtkVerifySimulatePattern(pNtk, vPiValues);
2963 
2964  for (i = 0; i < numouts; i++) {
2965  if (output[i])
2966  numOneOutputs++;
2967  }
2968 
2969  g = ABC_ALLOC(struct saucy_graph, 1);
2970  n = numouts + numins;
2971  e = numins * numOneOutputs;
2972  adj = ints(n+1);
2973  edg = ints(2*e);
2974  g->n = n;
2975  g->e = e;
2976  g->adj = adj;
2977  g->edg = edg;
2978 
2979  adj[0] = 0;
2980  for (i = 0; i < numouts; i++) {
2981  if (output[i]) {
2982  adj[i+1] = adj[i] + Vec_IntSize(oDep[i]);
2983  for (j = adj[i], k = 0; j < adj[i+1]; j++, k++)
2984  edg[j] = Vec_IntEntry(oDep[i], k) + numouts;
2985  } else {
2986  adj[i+1] = adj[i];
2987  }
2988  }
2989 
2990  for (i = 0; i < numins; i++) {
2991  adj[i+numouts+1] = adj[i+numouts];
2992  for (k = 0, j = adj[i+numouts]; k < Vec_IntSize(iDep[i]); k++) {
2993  if (output[Vec_IntEntry(iDep[i], k)]) {
2994  edg[j++] = Vec_IntEntry(iDep[i], k);
2995  adj[i+numouts+1]++;
2996  }
2997  }
2998  }
2999 
3000  /* print graph */
3001  /*for (i = 0; i < n; i++) {
3002  printf("%d: ", i);
3003  for (j = adj[i]; j < adj[i+1]; j++)
3004  printf("%d ", edg[j]);
3005  printf("\n");
3006  }*/
3007 
3008  ABC_FREE( vPiValues );
3009  ABC_FREE( output );
3010 
3011  return g;
3012 }
3013 
3014 static struct saucy_graph *
3015 buildSim2Graph( Abc_Ntk_t * pNtk, struct coloring *c, Vec_Int_t * randVec, Vec_Int_t ** iDep, Vec_Int_t ** oDep, Vec_Ptr_t ** topOrder, Vec_Int_t ** obs, Vec_Int_t ** ctrl )
3016 {
3017  int i, j, k;
3018  struct saucy_graph *g = NULL;
3019  int n, e = 0, *adj, *edg;
3020  int * vPiValues;
3021  int * output, * output2;
3022  int numouts = Abc_NtkPoNum(pNtk);
3023  int numins = Abc_NtkPiNum(pNtk);
3024 
3025  extern int * Abc_NtkSimulateOneNode( Abc_Ntk_t * , int * , int , Vec_Ptr_t ** );
3026 
3027  vPiValues = generateProperInputVector(pNtk, c, randVec);
3028  if (vPiValues == NULL)
3029  return NULL;
3030 
3031  output = Abc_NtkVerifySimulatePattern( pNtk, vPiValues );
3032 
3033  for (i = 0; i < numins; i++) {
3034  if (!c->clen[c->cfront[i+numouts]]) continue;
3035  if (vPiValues[i] == 0) vPiValues[i] = 1;
3036  else vPiValues[i] = 0;
3037 
3038  output2 = Abc_NtkSimulateOneNode( pNtk, vPiValues, i, topOrder );
3039 
3040  for (j = 0; j < Vec_IntSize(iDep[i]); j++) {
3041  if (output[Vec_IntEntry(iDep[i], j)] != output2[Vec_IntEntry(iDep[i], j)]) {
3042  Vec_IntPush(obs[i], Vec_IntEntry(iDep[i], j));
3043  Vec_IntPush(ctrl[Vec_IntEntry(iDep[i], j)], i);
3044  e++;
3045  }
3046  }
3047 
3048  if (vPiValues[i] == 0) vPiValues[i] = 1;
3049  else vPiValues[i] = 0;
3050 
3051  ABC_FREE( output2 );
3052  }
3053 
3054  /* build the graph */
3055  g = ABC_ALLOC(struct saucy_graph, 1);
3056  n = numouts + numins;
3057  adj = ints(n+1);
3058  edg = ints(2*e);
3059  g->n = n;
3060  g->e = e;
3061  g->adj = adj;
3062  g->edg = edg;
3063 
3064  adj[0] = 0;
3065  for (i = 0; i < numouts; i++) {
3066  adj[i+1] = adj[i] + Vec_IntSize(ctrl[i]);
3067  for (k = 0, j = adj[i]; j < adj[i+1]; j++, k++)
3068  edg[j] = Vec_IntEntry(ctrl[i], k) + numouts;
3069  }
3070  for (i = 0; i < numins; i++) {
3071  adj[i+numouts+1] = adj[i+numouts] + Vec_IntSize(obs[i]);
3072  for (k = 0, j = adj[i+numouts]; j < adj[i+numouts+1]; j++, k++)
3073  edg[j] = Vec_IntEntry(obs[i], k);
3074  }
3075 
3076  /* print graph */
3077  /*for (i = 0; i < n; i++) {
3078  printf("%d: ", i);
3079  for (j = adj[i]; j < adj[i+1]; j++)
3080  printf("%d ", edg[j]);
3081  printf("\n");
3082  }*/
3083 
3084  ABC_FREE( output );
3085  ABC_FREE( vPiValues );
3086  for (j = 0; j < numins; j++)
3087  Vec_IntClear(obs[j]);
3088  for (j = 0; j < numouts; j++)
3089  Vec_IntClear(ctrl[j]);
3090 
3091  return g;
3092 }
3093 
3094 static void
3095 bumpActivity( struct saucy * s, struct sim_result * cex )
3096 {
3097  int i;
3098  struct sim_result * cex2;
3099 
3100  if ( (cex->activity += s->activityInc) > 1e20 ) {
3101  /* Rescale: */
3102  for (i = 0; i < Vec_PtrSize(s->satCounterExamples); i++) {
3103  cex2 = (struct sim_result *)Vec_PtrEntry(s->satCounterExamples, i);
3104  cex2->activity *= 1e-20;
3105  }
3106  s->activityInc *= 1e-20;
3107  }
3108 }
3109 
3110 static void
3111 reduceDB( struct saucy * s )
3112 {
3113  int i, j;
3114  double extra_lim = s->activityInc / Vec_PtrSize(s->satCounterExamples); /* Remove any clause below this activity */
3115  struct sim_result * cex;
3116 
3117  while (Vec_PtrSize(s->satCounterExamples) > (0.7 * MAX_LEARNTS)) {
3118  for (i = j = 0; i < Vec_PtrSize(s->satCounterExamples); i++) {
3119  cex = (struct sim_result *)Vec_PtrEntry(s->satCounterExamples, i);
3120  if (cex->activity < extra_lim) {
3121  ABC_FREE(cex->inVec);
3122  ABC_FREE(cex->outVec);
3123  ABC_FREE(cex);
3124  }
3125  else if (j < i) {
3127  j++;
3128  }
3129  }
3130  //printf("Database size reduced from %d to %d\n", Vec_PtrSize(s->satCounterExamples), j);
3132  extra_lim *= 2;
3133  }
3134 
3136 }
3137 
3138 static struct sim_result *
3139 analyzeConflict( Abc_Ntk_t * pNtk, int * pModel, int fVerbose )
3140 {
3141  Abc_Obj_t * pNode;
3142  int i, count = 0;
3143  int * pValues;
3144  struct sim_result * cex;
3145  int numouts = Abc_NtkPoNum(pNtk);
3146  int numins = Abc_NtkPiNum(pNtk);
3147 
3148  cex = ABC_ALLOC(struct sim_result, 1);
3149  cex->inVec = ints( numins );
3150  cex->outVec = ints( numouts );
3151 
3152  /* get the CO values under this model */
3153  pValues = Abc_NtkVerifySimulatePattern( pNtk, pModel );
3154 
3155  Abc_NtkForEachCi( pNtk, pNode, i )
3156  cex->inVec[Abc_ObjId(pNode)-1] = pModel[i];
3157  Abc_NtkForEachCo( pNtk, pNode, i ) {
3158  cex->outVec[Abc_ObjId(pNode)-numins-1] = pValues[i];
3159  if (pValues[i]) count++;
3160  }
3161 
3162  cex->outVecOnes = count;
3163  cex->activity = 0;
3164 
3165  if (fVerbose) {
3166  Abc_NtkForEachCi( pNtk, pNode, i )
3167  printf(" %s=%d", Abc_ObjName(pNode), pModel[i]);
3168  printf("\n");
3169  }
3170 
3171  ABC_FREE( pValues );
3172 
3173  return cex;
3174 }
3175 
3176 static int
3177 Abc_NtkCecSat_saucy( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int * pModel )
3178 {
3179  extern Abc_Ntk_t * Abc_NtkMulti( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax, int fCnf, int fMulti, int fSimple, int fFactor );
3180  Abc_Ntk_t * pMiter;
3181  Abc_Ntk_t * pCnf;
3182  int RetValue;
3183  int nConfLimit;
3184  int nInsLimit;
3185  int i;
3186 
3187  nConfLimit = 10000;
3188  nInsLimit = 0;
3189 
3190  /* get the miter of the two networks */
3191  pMiter = Abc_NtkMiter( pNtk1, pNtk2, 1, 0, 0, 0 );
3192  if ( pMiter == NULL )
3193  {
3194  printf( "Miter computation has failed.\n" );
3195  exit(1);
3196  }
3197  RetValue = Abc_NtkMiterIsConstant( pMiter );
3198  if ( RetValue == 0 )
3199  {
3200  //printf( "Networks are NOT EQUIVALENT after structural hashing.\n" );
3201  /* report the error */
3202  pMiter->pModel = Abc_NtkVerifyGetCleanModel( pMiter, 1 );
3203  for (i = 0; i < Abc_NtkPiNum(pNtk1); i++)
3204  pModel[i] = pMiter->pModel[i];
3205  ABC_FREE( pMiter->pModel );
3206  Abc_NtkDelete( pMiter );
3207  return 0;
3208  }
3209  if ( RetValue == 1 )
3210  {
3211  Abc_NtkDelete( pMiter );
3212  //printf( "Networks are equivalent after structural hashing.\n" );
3213  return 1;
3214  }
3215 
3216  /* convert the miter into a CNF */
3217  pCnf = Abc_NtkMulti( pMiter, 0, 100, 1, 0, 0, 0 );
3218  Abc_NtkDelete( pMiter );
3219  if ( pCnf == NULL )
3220  {
3221  printf( "Renoding for CNF has failed.\n" );
3222  exit(1);
3223  }
3224 
3225  /* solve the CNF using the SAT solver */
3226  RetValue = Abc_NtkMiterSat( pCnf, (ABC_INT64_T)nConfLimit, (ABC_INT64_T)nInsLimit, 0, NULL, NULL );
3227  if ( RetValue == -1 ) {
3228  printf( "Networks are undecided (SAT solver timed out).\n" );
3229  exit(1);
3230  }
3231  /*else if ( RetValue == 0 )
3232  printf( "Networks are NOT EQUIVALENT after SAT.\n" );
3233  else
3234  printf( "Networks are equivalent after SAT.\n" );*/
3235  if ( pCnf->pModel ) {
3236  for (i = 0; i < Abc_NtkPiNum(pNtk1); i++)
3237  pModel[i] = pCnf->pModel[i];
3238  }
3239  ABC_FREE( pCnf->pModel );
3240  Abc_NtkDelete( pCnf );
3241 
3242  return RetValue;
3243 }
3244 
3245 
3246 void saucyGateWay( Abc_Ntk_t * pNtkOrig, Abc_Obj_t * pNodePo, FILE * gFile, int fBooleanMatching,
3247  int fLookForSwaps, int fFixOutputs, int fFixInputs, int fQuiet, int fPrintTree )
3248 {
3249  Abc_Ntk_t * pNtk;
3250  struct saucy *s;
3251  struct saucy_stats stats;
3252  int *colors;
3253  int i, clk = clock();
3254 
3255  if (pNodePo == NULL)
3256  pNtk = Abc_NtkDup( pNtkOrig );
3257  else
3258  pNtk = Abc_NtkCreateCone( pNtkOrig, Abc_ObjFanin0(pNodePo), Abc_ObjName(pNodePo), 0 );
3259 
3260  if (Abc_NtkPiNum(pNtk) == 0) {
3261  Abc_Print( 0, "This output is not dependent on any input\n" );
3262  Abc_NtkDelete( pNtk );
3263  return;
3264  }
3265 
3266  s = saucy_alloc( pNtk );
3267 
3268  /******* Getting Dependencies *******/
3269  printf("Build functional dependency graph (dependency stats are below) ... ");
3270  getDependencies( pNtk, s->iDep, s->oDep );
3271  printf("\t--------------------\n");
3272  /************************************/
3273 
3274  /* Finding toplogical orde */
3275  s->topOrder = findTopologicalOrder( pNtk );
3276 
3277  /* Setting graph colors: outputs = 0 and inputs = 1 */
3278  colors = ints(Abc_NtkPoNum(pNtk) + Abc_NtkPiNum(pNtk));
3279  if (fFixOutputs) {
3280  for (i = 0; i < Abc_NtkPoNum(pNtk); i++)
3281  colors[i] = i;
3282  } else {
3283  for (i = 0; i < Abc_NtkPoNum(pNtk); i++)
3284  colors[i] = 0;
3285  }
3286  if (fFixInputs) {
3287  int c = (fFixOutputs) ? Abc_NtkPoNum(pNtk) : 1;
3288  for (i = 0; i < Abc_NtkPiNum(pNtk); i++)
3289  colors[i+Abc_NtkPoNum(pNtk)] = c+i;
3290  } else {
3291  int c = (fFixOutputs) ? Abc_NtkPoNum(pNtk) : 1;
3292  for (i = 0; i < Abc_NtkPiNum(pNtk); i++)
3293  colors[i+Abc_NtkPoNum(pNtk)] = c;
3294  }
3295 
3296  /* Are we looking for Boolean matching? */
3297  s->fBooleanMatching = fBooleanMatching;
3298  if (fBooleanMatching) {
3299  NUM_SIM1_ITERATION = 50;
3300  NUM_SIM2_ITERATION = 50;
3301  } else {
3302  NUM_SIM1_ITERATION = 200;
3303  NUM_SIM2_ITERATION = 200;
3304  }
3305 
3306  /* Set the print automorphism routine */
3307  if (!fQuiet)
3309  else
3311 
3312  /* Set the output file for generators */
3313  if (gFile == NULL)
3314  s->gFile = stdout;
3315  else
3316  s->gFile = gFile;
3317 
3318  /* Set print tree option */
3319  s->fPrintTree = fPrintTree;
3320 
3321  /* Set input permutations option */
3322  s->fLookForSwaps = fLookForSwaps;
3323 
3324  saucy_search(pNtk, s, 0, colors, &stats);
3325  print_stats(stdout, stats);
3326  if (fBooleanMatching) {
3327  if (stats.grpsize_base > 1 || stats.grpsize_exp > 0)
3328  printf("*** Networks are equivalent ***\n");
3329  else
3330  printf("*** Networks are NOT equivalent ***\n");
3331  }
3332  saucy_free(s);
3333  Abc_NtkDelete(pNtk);
3334 
3335  if (1) {
3336  FILE * hadi = fopen("hadi.txt", "a");
3337  fprintf(hadi, "group size = %fe%d\n",
3338  stats.grpsize_base, stats.grpsize_exp);
3339  fclose(hadi);
3340  }
3341 
3342  ABC_PRT( "Runtime", clock() - clk );
3343 
3345 
3346 
int * gamma
Definition: abcSaucy.c:119
static unsigned Abc_ObjId(Abc_Obj_t *pObj)
Definition: abc.h:329
VOID_HACK exit()
static void Vec_IntPushOrder(Vec_Int_t *p, int Entry)
Definition: vecInt.h:751
int nundiffs
Definition: abcSaucy.c:152
static int check_mapping(struct saucy *s, const int *adj, const int *edg, int k)
Definition: abcSaucy.c:497
int * prevnon
Definition: abcSaucy.c:100
int(* is_automorphism)(struct saucy *)
Definition: abcSaucy.c:164
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition: vecPtr.h:42
static void eat_pair(struct saucy *s, int k)
Definition: abcSaucy.c:697
VOID_HACK free()
int(* refineBySim1)(struct saucy *, struct coloring *)
Definition: abcSaucy.c:194
int indmin
Definition: abcSaucy.c:128
int * undifflev
Definition: abcSaucy.c:151
Vec_Int_t ** ctrl
Definition: abcSaucy.c:178
static struct saucy_graph * buildDepGraph(Abc_Ntk_t *pNtk, Vec_Int_t **iDep, Vec_Int_t **oDep)
Definition: abcSaucy.c:2806
Vec_Ptr_t * satCounterExamples
Definition: abcSaucy.c:186
Vec_Ptr_t * randomVectorArray_sim1
Definition: abcSaucy.c:180
Nm_Man_t * pManName
Definition: abc.h:160
static int check_OPP_only_has_swaps(struct saucy *s, struct coloring *c)
Definition: abcSaucy.c:1503
ABC_DLL int * Abc_NtkVerifyGetCleanModel(Abc_Ntk_t *pNtk, int nFrames)
Definition: abcVerify.c:668
Vec_Int_t ** obs
Definition: abcSaucy.c:178
int * randomVectorSplit_sim2
Definition: abcSaucy.c:183
double activityInc
Definition: abcSaucy.c:187
static Llb_Mgr_t * p
Definition: llb3Image.c:950
static void move_to_back(struct saucy *s, struct coloring *c, int k)
Definition: abcSaucy.c:465
static void swap_labels(struct coloring *c, int a, int b)
Definition: abcSaucy.c:457
int grpsize_exp
Definition: abcSaucy.c:59
int inVecSignature
Definition: abcSaucy.c:84
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition: bblif.c:37
static void split_color(struct coloring *c, int cf, int ff)
Definition: abcSaucy.c:799
int NUM_SIM2_ITERATION
Definition: abcSaucy.c:40
static void add_pair(struct saucy *s, int k)
Definition: abcSaucy.c:688
static int add_conterexample(struct saucy *s, struct sim_result *cex)
Definition: abcSaucy.c:521
int nsinduce
Definition: abcSaucy.c:107
int * adj
Definition: abcSaucy.c:70
static Vec_Int_t * assignRandomBitsToCells(Abc_Ntk_t *pNtk, struct coloring *c)
Definition: abcSaucy.c:2852
static int backtrack(struct saucy *s)
Definition: abcSaucy.c:2109
int * start
Definition: abcSaucy.c:127
static int zeta_fixed(struct saucy *s)
Definition: abcSaucy.c:1730
int nninduce
Definition: abcSaucy.c:106
Abc_Ntk_t * Abc_NtkMulti(Abc_Ntk_t *pNtk, int nThresh, int nFaninMax, int fCnf, int fMulti, int fSimple, int fFactor)
FUNCTION DEFINITIONS ///.
Definition: abcMulti.c:59
int nodes
Definition: abcSaucy.c:61
static int Abc_NtkBoxNum(Abc_Ntk_t *pNtk)
Definition: abc.h:289
static int in_cell_range(struct coloring *c, int ff, int cf)
Definition: abcSaucy.c:681
#define SIM_RANDOM_UNSIGNED
Definition: sim.h:158
int(* ref_singleton)(struct saucy *, struct coloring *, int)
Definition: abcSaucy.c:165
static int check_OPP_for_Boolean_matching(struct saucy *s, struct coloring *c)
Definition: abcSaucy.c:1539
int * diffs
Definition: abcSaucy.c:148
static int is_undirected_automorphism(struct saucy *s)
Definition: abcSaucy.c:549
int * thfront
Definition: abcSaucy.c:137
int fPrintTree
Definition: abcSaucy.c:190
void saucyGateWay(Abc_Ntk_t *pNtkOrig, Abc_Obj_t *pNodePo, FILE *gFile, int fBooleanMatching, int fLookForSwaps, int fFixOutputs, int fFixInputs, int fQuiet, int fPrintTree)
Definition: abcSaucy.c:3246
static int refineBySim2_other(struct saucy *s, struct coloring *c)
Definition: abcSaucy.c:1452
int * edg
Definition: abcSaucy.c:71
static int ref_nonsingle_directed(struct saucy *s, struct coloring *c, int cf)
Definition: abcSaucy.c:1089
ABC_DLL Abc_Ntk_t * Abc_NtkDup(Abc_Ntk_t *pNtk)
Definition: abcNtk.c:419
char * memcpy()
static void Vec_PtrPush(Vec_Ptr_t *p, void *Entry)
Definition: vecPtr.h:606
static int refineByDepGraph(struct saucy *s, struct coloring *c)
Definition: abcSaucy.c:1149
static void set_label(struct coloring *c, int index, int value)
Definition: abcSaucy.c:450
void saucy_free(struct saucy *s)
Definition: abcSaucy.c:2489
static int Abc_NtkCiNum(Abc_Ntk_t *pNtk)
Definition: abc.h:287
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
int * anctar
Definition: abcSaucy.c:125
int * thprev
Definition: abcSaucy.c:135
static void add_diffnon(struct saucy *s, int k)
Definition: abcSaucy.c:641
#define Abc_NtkForEachCo(pNtk, pCo, i)
Definition: abc.h:519
int bads
Definition: abcSaucy.c:62
static int median(int a, int b, int c)
Definition: abcSaucy.c:400
static void pick_all_the_pairs(struct saucy *s)
Definition: abcSaucy.c:707
static void rewind_simulation_vectors(struct saucy *s, int lev)
Definition: abcSaucy.c:2049
static int descend_left(struct saucy *s)
Definition: abcSaucy.c:1803
static int refine_cell(struct saucy *s, struct coloring *c, int(*refine)(struct saucy *, struct coloring *, int))
Definition: abcSaucy.c:926
ABC_DLL char * Abc_ObjAssignName(Abc_Obj_t *pObj, char *pName, char *pSuffix)
Definition: abcNames.c:68
int(* split)(struct saucy *, struct coloring *, int, int)
Definition: abcSaucy.c:163
int gens
Definition: abcSaucy.c:63
Vec_Ptr_t * vPis
Definition: abc.h:163
static int do_search(struct saucy *s)
Definition: abcSaucy.c:2246
int * depAdj
Definition: abcSaucy.c:175
static int backtrackBysatCounterExamples(struct saucy *s, struct coloring *c)
Definition: abcSaucy.c:1158
int fBooleanMatching
Definition: abcSaucy.c:189
static int print_automorphism_ntk2(FILE *f, int n, const int *gamma, int nsupp, const int *support, char *marks, Abc_Ntk_t *pNtk)
Definition: abcSaucy.c:255
static int Vec_PtrSize(Vec_Ptr_t *p)
Definition: vecPtr.h:295
Vec_Ptr_t * randomVectorArray_sim2
Definition: abcSaucy.c:182
int * edg
Definition: abcSaucy.c:93
static void print_stats(FILE *f, struct saucy_stats stats)
Definition: abcSaucy.c:2673
static Abc_Obj_t * Abc_ObjFanin0(Abc_Obj_t *pObj)
Definition: abc.h:373
int * junk
Definition: abcSaucy.c:118
static void unprepare_permutation(struct saucy *s)
Definition: abcSaucy.c:2236
static void insertion_sort(int *a, int n)
Definition: abcSaucy.c:360
static int Abc_NtkCoNum(Abc_Ntk_t *pNtk)
Definition: abc.h:288
static void update_theta(struct saucy *s)
Definition: abcSaucy.c:1863
Vec_Int_t ** oDep
Definition: abcSaucy.c:177
#define BACKTRACK_BY_SAT
Definition: abcSaucy.c:35
int * adj
Definition: abcSaucy.c:92
ABC_DLL void Abc_NtkDelete(Abc_Ntk_t *pNtk)
Definition: abcNtk.c:1233
int * unpairs
Definition: abcSaucy.c:156
int * inVec
Definition: abcSaucy.c:82
FILE * gFile
Definition: abcSaucy.c:192
int kanctar
Definition: abcSaucy.c:126
int * pModel
Definition: abc.h:198
static struct saucy_graph * buildSim2Graph(Abc_Ntk_t *pNtk, struct coloring *c, Vec_Int_t *randVec, Vec_Int_t **iDep, Vec_Int_t **oDep, Vec_Ptr_t **topOrder, Vec_Int_t **obs, Vec_Int_t **ctrl)
Definition: abcSaucy.c:3015
int * count
Definition: abcSaucy.c:117
static void fix_fronts(struct coloring *c, int cf, int ff)
Definition: abcSaucy.c:603
static void sift_down(int *a, int n)
Definition: abcSaucy.c:329
int match
Definition: abcSaucy.c:129
int ndiffnons
Definition: abcSaucy.c:160
int * unlab
Definition: abcSaucy.c:76
static void select_statically(struct saucy *s, int *target, int *lmin, int *rmin)
Definition: abcSaucy.c:1788
static int do_find_min(struct coloring *c, int t)
Definition: abcSaucy.c:438
static int refineBySim2_init(struct saucy *s, struct coloring *c)
Definition: abcSaucy.c:1368
int * outVec
Definition: abcSaucy.c:83
static int * ints(int n)
Definition: abcSaucy.c:199
static int is_directed_automorphism(struct saucy *s)
Definition: abcSaucy.c:578
int * Abc_NtkSimulateOneNode(Abc_Ntk_t *pNtk, int *pModel, int input, Vec_Ptr_t **topOrder)
Definition: abcBm.c:447
struct saucy_stats * stats
Definition: abcSaucy.c:170
#define REFINE_BY_SIM_1
Definition: abcSaucy.c:33
Vec_Ptr_t * vPos
Definition: abc.h:164
int * pModel
Definition: abcSaucy.c:185
static void add_diff(struct saucy *s, int k)
Definition: abcSaucy.c:665
static int backtrack_loop(struct saucy *s)
Definition: abcSaucy.c:2096
static Vec_Int_t * Vec_IntAlloc(int nCap)
FUNCTION DEFINITIONS ///.
Definition: bblif.c:149
Vec_Ptr_t ** topOrder
Definition: abcSaucy.c:179
static int refineBySim1_left(struct saucy *s, struct coloring *c)
Definition: abcSaucy.c:1262
static int double_check_OPP_isomorphism(struct saucy *s, struct coloring *c)
Definition: abcSaucy.c:1582
static int find_representative(int k, int *theta)
Definition: abcSaucy.c:1848
static int refine(struct saucy *s, struct coloring *c)
Definition: abcSaucy.c:1115
static int ifOutputVectorsAreConsistent(struct saucy *s, int *leftVec, int *rightVec)
Definition: abcSaucy.c:2928
int * clist
Definition: abcSaucy.c:110
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 ///.
Definition: abcMiter.c:56
#define MAX_LEARNTS
Definition: abcSaucy.c:44
int * cfront
Definition: abcSaucy.c:77
static void clear_refine(struct saucy *s)
Definition: abcSaucy.c:1102
static int orbit_prune(struct saucy *s)
Definition: abcSaucy.c:1906
char * name
double grpsize_base
Definition: abcSaucy.c:58
static int Vec_IntEntry(Vec_Int_t *p, int i)
Definition: bblif.c:268
int * diffnons
Definition: abcSaucy.c:158
int fLookForSwaps
Definition: abcSaucy.c:191
int * conncnts
Definition: abcSaucy.c:120
int * randomVectorSplit_sim1
Definition: abcSaucy.c:181
static int partition(int *a, int n, int m)
Definition: abcSaucy.c:373
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
static void split_common(struct saucy *s, struct coloring *c, int cf, int ff)
Definition: abcSaucy.c:814
static void clear_undiffnons(struct saucy *s)
Definition: abcSaucy.c:717
int * ninduce
Definition: abcSaucy.c:104
VOID_HACK abort()
static double max
Definition: cuddSubsetHB.c:134
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 ///.
Definition: abcSat.c:53
static int print_automorphism_quiet(FILE *f, int n, const int *gamma, int nsupp, const int *support, char *marks, Abc_Ntk_t *pNtk)
Definition: abcSaucy.c:289
ABC_DLL Abc_Ntk_t * Abc_NtkCreateCone(Abc_Ntk_t *pNtk, Abc_Obj_t *pNode, char *pNodeName, int fUseAllCis)
Definition: abcNtk.c:819
char * stuff
Definition: abcSaucy.c:114
char * indmark
Definition: abcSaucy.c:103
static int size
Definition: cuddSign.c:86
static void Vec_IntPush(Vec_Int_t *p, int Entry)
Definition: bblif.c:468
Definition: abcSaucy.c:89
int * dadj
Definition: abcSaucy.c:94
int * theta
Definition: abcSaucy.c:132
int * depEdg
Definition: abcSaucy.c:176
static void getDependenciesDummy(Abc_Ntk_t *pNtk, Vec_Int_t **iDep, Vec_Int_t **oDep)
Definition: abcSaucy.c:2791
int n
Definition: abcSaucy.c:91
static Abc_Obj_t * Abc_ObjFanout0Ntk(Abc_Obj_t *pObj)
Definition: abc.h:376
int * pairs
Definition: abcSaucy.c:155
static int Abc_NtkCecSat_saucy(Abc_Ntk_t *pNtk1, Abc_Ntk_t *pNtk2, int *pModel)
Definition: abcSaucy.c:3177
double activity
Definition: abcSaucy.c:86
int * splitlev
Definition: abcSaucy.c:143
static void Abc_Print(int level, const char *format,...)
Definition: abc_global.h:313
static void sift_up(int *a, int k)
Definition: abcSaucy.c:313
static int array_find_min(const int *a, int n)
Definition: abcSaucy.c:295
static void select_dynamically(struct saucy *s, int *target, int *lmin, int *rmin)
Definition: abcSaucy.c:1736
int support
Definition: abcSaucy.c:64
int * thsize
Definition: abcSaucy.c:133
static int descend(struct saucy *s, struct coloring *c, int target, int min)
Definition: abcSaucy.c:1625
static int * zeros(int n)
Definition: abcSaucy.c:200
static void Vec_PtrWriteEntry(Vec_Ptr_t *p, int i, void *Entry)
Definition: vecPtr.h:396
#define CLAUSE_DECAY
Definition: abcSaucy.c:43
static int descend_leftmost(struct saucy *s)
Definition: abcSaucy.c:1700
int * clen
Definition: abcSaucy.c:78
static void data_count(struct saucy *s, struct coloring *c, int k)
Definition: abcSaucy.c:488
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
int * specmin
Definition: abcSaucy.c:154
Vec_Int_t ** iDep
Definition: abcSaucy.c:177
#define SELECT_DYNAMICALLY
Definition: abcSaucy.c:36
int * sinduce
Definition: abcSaucy.c:105
int(* ref_nonsingle)(struct saucy *, struct coloring *, int)
Definition: abcSaucy.c:166
static void * Vec_PtrEntry(Vec_Ptr_t *p, int i)
Definition: vecPtr.h:362
int * undiffnons
Definition: abcSaucy.c:159
int * splitvar
Definition: abcSaucy.c:140
static int ref_nonsingle_undirected(struct saucy *s, struct coloring *c, int cf)
Definition: abcSaucy.c:1096
static void add_induce(struct saucy *s, struct coloring *c, int who)
Definition: abcSaucy.c:591
int * thnext
Definition: abcSaucy.c:134
static void note_anctar_reps(struct saucy *s)
Definition: abcSaucy.c:1934
static int at_terminal(struct saucy *s)
Definition: abcSaucy.c:635
static int is_a_pair(struct saucy *s, int k)
Definition: abcSaucy.c:675
int(* print_automorphism)(FILE *f, int n, const int *gamma, int nsupp, const int *support, char *marks, Abc_Ntk_t *pNtk)
Definition: abcSaucy.c:196
int * difflev
Definition: abcSaucy.c:149
static int ref_singleton(struct saucy *s, struct coloring *c, const int *adj, const int *edg, int cf)
Definition: abcSaucy.c:968
int(* refineBySim2)(struct saucy *, struct coloring *)
Definition: abcSaucy.c:195
static int Vec_IntSize(Vec_Int_t *p)
Definition: bblif.c:252
static void fix_diff_subtract(struct saucy *s, int cf, const int *a, const int *b)
Definition: abcSaucy.c:759
static int do_backtrack(struct saucy *s)
Definition: abcSaucy.c:2062
static int split_other(struct saucy *s, struct coloring *c, int cf, int ff)
Definition: abcSaucy.c:864
static void fix_diff_singleton(struct saucy *s, int cf)
Definition: abcSaucy.c:726
int levels
Definition: abcSaucy.c:60
ABC_DLL int Abc_NtkMiterIsConstant(Abc_Ntk_t *pMiter)
Definition: abcMiter.c:679
int * dedg
Definition: abcSaucy.c:95
#define Abc_ObjForEachFanout(pObj, pFanout, i)
Definition: abc.h:526
static int print_partition(struct coloring *left, struct coloring *right, int n, Abc_Ntk_t *pNtk, int fNames)
Definition: abcSaucy.c:886
#define Abc_NtkForEachCi(pNtk, pCi, i)
Definition: abc.h:515
static int Abc_NtkPoNum(Abc_Ntk_t *pNtk)
Definition: abc.h:286
char * marks
Definition: abcSaucy.c:184
static Vec_Ptr_t * Vec_PtrAlloc(int nCap)
FUNCTION DEFINITIONS ///.
Definition: vecPtr.h:83
static int ifInputVectorsAreConsistent(struct saucy *s, int *leftVec, int *rightVec)
Definition: abcSaucy.c:2896
static int ref_singleton_directed(struct saucy *s, struct coloring *c, int cf)
Definition: abcSaucy.c:983
static int backtrack_leftmost(struct saucy *s)
Definition: abcSaucy.c:1981
void prepare_permutation_ntk(struct saucy *s)
Definition: abcSaucy.c:2155
static int ref_nonsingle_cell(struct saucy *s, struct coloring *c, int cf)
Definition: abcSaucy.c:996
static int ref_single_cell(struct saucy *s, struct coloring *c, int cf)
Definition: abcSaucy.c:961
static int split_init(struct saucy *s, struct coloring *c, int cf, int ff)
Definition: abcSaucy.c:843
static void data_mark(struct saucy *s, struct coloring *c, int k)
Definition: abcSaucy.c:479
int csize
Definition: abcSaucy.c:111
#define ABC_FREE(obj)
Definition: abc_global.h:232
static int backtrack_bad(struct saucy *s)
Definition: abcSaucy.c:2125
static void array_indirect_sort(int *a, const int *b, int n)
Definition: abcSaucy.c:612
static void fix_diffs(struct saucy *s, int cf, int ff)
Definition: abcSaucy.c:782
static int Abc_NtkPiNum(Abc_Ntk_t *pNtk)
Definition: abc.h:285
ABC_DLL char * Abc_ObjName(Abc_Obj_t *pNode)
DECLARATIONS ///.
Definition: abcNames.c:48
#define ABC_PRT(a, t)
Definition: abc_global.h:220
int * bucket
Definition: abcSaucy.c:116
void unprepare_permutation_ntk(struct saucy *s)
Definition: abcSaucy.c:2209
void saucy_search(Abc_Ntk_t *pNtk, struct saucy *s, int directed, const int *colors, struct saucy_stats *stats)
Definition: abcSaucy.c:2311
static int split_left(struct saucy *s, struct coloring *c, int cf, int ff)
Definition: abcSaucy.c:828
static void Abc_NtkIncrementTravId(Abc_Ntk_t *p)
Definition: abc.h:406
int * lab
Definition: abcSaucy.c:75
int * threp
Definition: abcSaucy.c:136
#define ABC_CALLOC(type, num)
Definition: abc_global.h:230
int * splitfrom
Definition: abcSaucy.c:142
Nm_Man_t * Nm_ManCreate(int nSize)
MACRO DEFINITIONS ///.
Definition: nmApi.c:45
int * ccount
Definition: abcSaucy.c:115
static void reduceDB(struct saucy *s)
Definition: abcSaucy.c:3111
static void swap(int *a, int x, int y)
Definition: abcSaucy.c:305
int outVecOnes
Definition: abcSaucy.c:85
int ndiffs
Definition: abcSaucy.c:150
Vec_Ptr_t * Sim_ComputeFunSupp(Abc_Ntk_t *pNtk, int fVerbose)
Definition: simSupp.c:103
int value
static int backtrack_other(struct saucy *s)
Definition: abcSaucy.c:2003
void Abc_NtkDfsReverse_rec(Abc_Obj_t *pNode, Vec_Ptr_t *vNodes)
Definition: abcDfs.c:156
static void Vec_IntSortUnsigned(Vec_Int_t *p)
Definition: vecInt.h:1511
static int theta_prune(struct saucy *s)
Definition: abcSaucy.c:1889
int * nextnon
Definition: abcSaucy.c:99
static void remove_diffnon(struct saucy *s, int k)
Definition: abcSaucy.c:651
int npairs
Definition: abcSaucy.c:157
int * splitwho
Definition: abcSaucy.c:141
static int maybe_split(struct saucy *s, struct coloring *c, int cf, int ff)
Definition: abcSaucy.c:955
#define assert(ex)
Definition: util_old.h:213
static int print_automorphism_ntk(FILE *f, int n, const int *gamma, int nsupp, const int *support, char *marks, Abc_Ntk_t *pNtk)
Definition: abcSaucy.c:220
int lev
Definition: abcSaucy.c:123
void Nm_ManFree(Nm_Man_t *p)
Definition: nmApi.c:76
static struct saucy_graph * buildSim1Graph(Abc_Ntk_t *pNtk, struct coloring *c, Vec_Int_t *randVec, Vec_Int_t **iDep, Vec_Int_t **oDep)
Definition: abcSaucy.c:2948
static Vec_Ptr_t ** findTopologicalOrder(Abc_Ntk_t *pNtk)
Definition: abcSaucy.c:2706
static void prepare_permutation(struct saucy *s)
Definition: abcSaucy.c:2197
static char * bits(int n)
Definition: abcSaucy.c:201
static int ref_nonsingle(struct saucy *s, struct coloring *c, const int *adj, const int *edg, int cf)
Definition: abcSaucy.c:1053
Abc_Ntk_t * pNtk_permuted
Definition: abcSaucy.c:174
static int refineBySim1_other(struct saucy *s, struct coloring *c)
Definition: abcSaucy.c:1320
ABC_DLL int * Abc_NtkVerifySimulatePattern(Abc_Ntk_t *pNtk, int *pModel)
Definition: abcVerify.c:686
void(* select_decomposition)(struct saucy *, int *, int *, int *)
Definition: abcSaucy.c:167
static void getDependencies(Abc_Ntk_t *pNtk, Vec_Int_t **iDep, Vec_Int_t **oDep)
Definition: abcSaucy.c:2733
#define REFINE_BY_SIM_2
Definition: abcSaucy.c:34
static void introsort_loop(int *a, int n, int lim)
Definition: abcSaucy.c:415
static void Vec_IntFree(Vec_Int_t *p)
Definition: bblif.c:235
static int find_min(struct saucy *s, int t)
Definition: abcSaucy.c:444
static int refineBySim1_init(struct saucy *s, struct coloring *c)
Definition: abcSaucy.c:1208
static int ref_singleton_undirected(struct saucy *s, struct coloring *c, int cf)
Definition: abcSaucy.c:990
int anc
Definition: abcSaucy.c:124
static void Vec_IntClear(Vec_Int_t *p)
Definition: bblif.c:452
struct coloring left right
Definition: abcSaucy.c:98
static void Vec_PtrShrink(Vec_Ptr_t *p, int nSizeNew)
Definition: vecPtr.h:528
int nsplits
Definition: abcSaucy.c:144
static void multiply_index(struct saucy *s, int k)
Definition: abcSaucy.c:1972
struct saucy * saucy_alloc(Abc_Ntk_t *pNtk)
Definition: abcSaucy.c:2574
static int refineBySim2_left(struct saucy *s, struct coloring *c)
Definition: abcSaucy.c:1408
static int log_base2(int n)
Definition: abcSaucy.c:389
int * unsupp
Definition: abcSaucy.c:153
ABC_DLL void Abc_NtkOrderObjsByName(Abc_Ntk_t *pNtk, int fComb)
Definition: abcNames.c:335
static int select_smallest_max_connected_cell(struct saucy *s, int start, int end)
Definition: abcSaucy.c:1666
static int * generateProperInputVector(Abc_Ntk_t *pNtk, struct coloring *c, Vec_Int_t *randomVector)
Definition: abcSaucy.c:2866
int NUM_SIM1_ITERATION
Definition: abcSaucy.c:39
static void Abc_NodeSetTravIdCurrent(Abc_Obj_t *p)
Definition: abc.h:409
static void introsort(int *a, int n)
Definition: abcSaucy.c:431
static void bumpActivity(struct saucy *s, struct sim_result *cex)
Definition: abcSaucy.c:3095
char * diffmark
Definition: abcSaucy.c:147
static void Vec_PtrFree(Vec_Ptr_t *p)
Definition: vecPtr.h:223
static void rewind_coloring(struct saucy *s, struct coloring *c, int lev)
Definition: abcSaucy.c:2037
static void heap_sort(int *a, int n)
Definition: abcSaucy.c:346
static char * getVertexName(Abc_Ntk_t *pNtk, int v)
Definition: abcSaucy.c:2692
Abc_Ntk_t * pNtk
Definition: abcSaucy.c:173
static struct sim_result * analyzeConflict(Abc_Ntk_t *pNtk, int *pModel, int fVerbose)
Definition: abcSaucy.c:3139