ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
abcSaucy.c
Go to the documentation of this file.
1
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
60 int levels;
61 int nodes;
62 int bads;
63 int gens;
65};
66
68 int n;
69 int e;
70 int *adj;
71 int *edg;
72};
73
74struct 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
81struct sim_result {
82 int *inVec;
83 int *outVec;
86 double activity;
87};
88
89struct 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;
184 char * marks;
185 int * pModel;
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
199static int *ints(int n) { return ABC_ALLOC(int, n); }
200static int *zeros(int n) { return ABC_CALLOC(int, n); }
201static char *bits(int n) { return ABC_CALLOC(char, n); }
202
203static char * getVertexName(Abc_Ntk_t *pNtk, int v);
204static int * generateProperInputVector(Abc_Ntk_t * pNtk, struct coloring *c, Vec_Int_t * randomVector);
205static int ifInputVectorsAreConsistent(struct saucy * s, int * leftVec, int * rightVec);
206static int ifOutputVectorsAreConsistent(struct saucy * s, int * leftVec, int * rightVec);
208static void getDependencies(Abc_Ntk_t *pNtk, Vec_Int_t** iDep, Vec_Int_t** oDep);
209static struct saucy_graph * buildDepGraph (Abc_Ntk_t *pNtk, Vec_Int_t ** iDep, Vec_Int_t ** oDep);
210static struct saucy_graph * buildSim1Graph(Abc_Ntk_t * pNtk, struct coloring *c, Vec_Int_t * randVec, Vec_Int_t ** iDep, Vec_Int_t ** oDep);
211static 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);
212static Vec_Int_t * assignRandomBitsToCells(Abc_Ntk_t * pNtk, struct coloring *c);
213static int Abc_NtkCecSat_saucy(Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int * pModel);
214static struct sim_result * analyzeConflict(Abc_Ntk_t * pNtk, int * pModel, int fVerbose);
215static void bumpActivity (struct saucy * s, struct sim_result * cex);
216static void reduceDB(struct saucy * s);
217
218
219static int
220print_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
254static int
255print_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
288static int
289print_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
294static int
295array_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
304static void
305swap(int *a, int x, int y)
306{
307 int tmp = a[x];
308 a[x] = a[y];
309 a[y] = tmp;
310}
311
312static void
313sift_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
328static void
329sift_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
345static void
346heap_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
359static void
360insertion_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
372static int
373partition(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
388static int
389log_base2(int n)
390{
391 int k = 0;
392 while (n > 1) {
393 ++k;
394 n >>= 1;
395 }
396 return k;
397}
398
399static int
400median(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
414static void
415introsort_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
430static void
431introsort(int *a, int n)
432{
433 introsort_loop(a, n, 2 * log_base2(n));
434 insertion_sort(a, n);
435}
436
437static int
438do_find_min(struct coloring *c, int t)
439{
440 return array_find_min(c->lab + t, c->clen[t] + 1) + t;
441}
442
443static int
444find_min(struct saucy *s, int t)
445{
446 return do_find_min(&s->right, t);
447}
448
449static void
450set_label(struct coloring *c, int index, int value)
451{
452 c->lab[index] = value;
453 c->unlab[value] = index;
454}
455
456static void
457swap_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
464static void
465move_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
478static void
479data_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
487static void
488data_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
496static int
497check_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
520static int
521add_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
543 Vec_PtrPush(s->satCounterExamples, cex);
544 bumpActivity(s, cex);
545 return 1;
546}
547
548static int
549is_undirected_automorphism(struct saucy *s)
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);
570 if (Vec_PtrSize(s->satCounterExamples) >= MAX_LEARNTS)
571 reduceDB(s);
572 }
573
574 return ret;
575}
576
577static int
578is_directed_automorphism(struct saucy *s)
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
590static void
591add_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
602static void
603fix_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
611static void
612array_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
634static int
635at_terminal(struct saucy *s)
636{
637 return s->nsplits == s->n;
638}
639
640static void
641add_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
650static void
651remove_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
664static void
665add_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
674static int
675is_a_pair(struct saucy *s, int k)
676{
677 return s->unpairs[k] != -1;
678}
679
680static int
681in_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
687static void
688add_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
696static void
697eat_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
706static void
707pick_all_the_pairs(struct saucy *s)
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
716static void
717clear_undiffnons(struct saucy *s)
718{
719 int i;
720 for (i = 0 ; i < s->ndiffnons ; ++i) {
721 s->undiffnons[s->diffnons[i]] = -1;
722 }
723}
724
725static void
726fix_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
758static void
759fix_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
781static void
782fix_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
798static void
799split_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
813static void
814split_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
827static int
828split_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
842static int
843split_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
863static int
864split_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
885static int
886print_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
925static int
926refine_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
954static int
955maybe_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
960static int
961ref_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
967static int
968ref_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
982static int
983ref_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
989static int
990ref_singleton_undirected(struct saucy *s, struct coloring *c, int cf)
991{
992 return ref_singleton(s, c, s->adj, s->edg, cf);
993}
994
995static int
996ref_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
1052static int
1053ref_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
1088static int
1089ref_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
1095static int
1096ref_nonsingle_undirected(struct saucy *s, struct coloring *c, int cf)
1097{
1098 return ref_nonsingle(s, c, s->adj, s->edg, cf);
1099}
1100
1101static void
1102clear_refine(struct saucy *s)
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
1114static int
1115refine(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
1148static int
1149refineByDepGraph(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
1157static int
1158backtrackBysatCounterExamples(struct saucy *s, struct coloring *c)
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
1207static int
1208refineBySim1_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
1261static int
1262refineBySim1_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
1314 s->randomVectorSplit_sim1[s->lev] = Vec_PtrSize(s->randomVectorArray_sim1);
1315
1316 return 1;
1317}
1318
1319static int
1320refineBySim1_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
1367static int
1368refineBySim2_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
1407static int
1408refineBySim2_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
1446 s->randomVectorSplit_sim2[s->lev] = Vec_PtrSize(s->randomVectorArray_sim2);
1447
1448 return 1;
1449}
1450
1451static int
1452refineBySim2_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
1502static int
1503check_OPP_only_has_swaps(struct saucy *s, struct coloring *c)
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
1538static int
1539check_OPP_for_Boolean_matching(struct saucy *s, struct coloring *c)
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
1581static int
1582double_check_OPP_isomorphism(struct saucy *s, struct coloring * c)
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
1624static int
1625descend(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
1665static int
1666select_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
1699static int
1700descend_leftmost(struct saucy *s)
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
1729static int
1730zeta_fixed(struct saucy *s)
1731{
1732 return s->ndiffs == s->nundiffs;
1733}
1734
1735static void
1736select_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
1787static void
1788select_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
1802static int
1803descend_left(struct saucy *s)
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) {
1826 s->refineBySim1 = refineBySim1_left;
1827 s->refineBySim2 = refineBySim2_left;
1828 }
1829 descend(s, &s->left, target, lmin);
1830 s->splitlev[s->lev] = s->nsplits;
1831 s->split = split_other;
1832 if (SELECT_DYNAMICALLY) {
1833 s->refineBySim1 = refineBySim1_other;
1834 s->refineBySim2 = refineBySim2_other;
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
1847static int
1848find_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
1862static void
1863update_theta(struct saucy *s)
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
1888static int
1889theta_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
1905static int
1906orbit_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
1933static void
1934note_anctar_reps(struct saucy *s)
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 }
1968 array_indirect_sort(s->anctar, s->thsize, s->kanctar);
1969}
1970
1971static void
1972multiply_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
1980static int
1981backtrack_leftmost(struct saucy *s)
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
2002static int
2003backtrack_other(struct saucy *s)
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
2036static void
2037rewind_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
2048static void
2049rewind_simulation_vectors(struct saucy *s, int lev)
2050{
2051 int i;
2052 for (i = s->randomVectorSplit_sim1[lev]; i < Vec_PtrSize(s->randomVectorArray_sim1); i++)
2053 Vec_IntFree((Vec_Int_t *)Vec_PtrEntry(s->randomVectorArray_sim1, i));
2054 Vec_PtrShrink(s->randomVectorArray_sim1, s->randomVectorSplit_sim1[lev]);
2055
2056 for (i = s->randomVectorSplit_sim2[lev]; i < Vec_PtrSize(s->randomVectorArray_sim2); i++)
2057 Vec_IntFree((Vec_Int_t *)Vec_PtrEntry(s->randomVectorArray_sim2, i));
2058 Vec_PtrShrink(s->randomVectorArray_sim2, s->randomVectorSplit_sim2[lev]);
2059}
2060
2061static int
2062do_backtrack(struct saucy *s)
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
2095static int
2096backtrack_loop(struct saucy *s)
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
2108static int
2109backtrack(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;
2119 rewind_simulation_vectors(s, s->lev+1);
2120
2121 return min;
2122}
2123
2124static int
2125backtrack_bad(struct saucy *s)
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;
2149 rewind_simulation_vectors(s, s->lev+1);
2150
2151 return min;
2152}
2153
2154void
2156{
2157 int i;
2158 Abc_Obj_t * pObj, * pObjPerm;
2159 int numouts = Abc_NtkPoNum(s->pNtk);
2160
2162 s->pNtk_permuted->pManName = Nm_ManCreate( Abc_NtkCiNum(s->pNtk) + Abc_NtkCoNum(s->pNtk) + Abc_NtkBoxNum(s->pNtk) );
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
2196static void
2197prepare_permutation(struct saucy *s)
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
2208void
2210{
2211 int i;
2212 Abc_Obj_t * pObj, * pObjPerm;
2213 int numouts = Abc_NtkPoNum(s->pNtk);
2214
2216 s->pNtk_permuted->pManName = Nm_ManCreate( Abc_NtkCiNum(s->pNtk) + Abc_NtkCoNum(s->pNtk) + Abc_NtkBoxNum(s->pNtk) );
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
2235static void
2236unprepare_permutation(struct saucy *s)
2237{
2238 int i;
2240 for (i = 0; i < s->ndiffs; ++i) {
2241 s->gamma[s->unsupp[i]] = s->unsupp[i];
2242 }
2243}
2244
2245static int
2246do_search(struct saucy *s)
2247{
2248 int min;
2249
2250 unprepare_permutation(s);
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 */
2274 prepare_permutation(s);
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);
2282 unprepare_permutation(s);
2283 return 1;
2284 }
2285 else {
2286 unprepare_permutation(s);
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
2310void
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) {
2342 s->is_automorphism = is_directed_automorphism;
2343 s->ref_singleton = ref_singleton_directed;
2344 s->ref_nonsingle = ref_nonsingle_directed;
2345 }
2346 else {
2347 s->is_automorphism = is_undirected_automorphism;
2348 s->ref_singleton = ref_singleton_undirected;
2349 s->ref_nonsingle = ref_nonsingle_undirected;
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;
2443 s->refineBySim1 = refineBySim1_init;
2444 s->refineBySim2 = refineBySim2_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 */
2460 s->refineBySim1 = refineBySim1_left;
2461 s->refineBySim2 = refineBySim2_left;
2462 descend_leftmost(s);
2463 s->split = split_other;
2464 s->refineBySim1 = refineBySim1_other;
2465 s->refineBySim2 = refineBySim2_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 */
2481 if (SELECT_DYNAMICALLY) s->select_decomposition = select_dynamically;
2482 else s->select_decomposition = select_statically;
2483
2484 /* Keep running till we're out of automorphisms */
2485 while (do_search(s));
2486
2487 ABC_FREE(g);
2488}
2489
2490void
2492{
2493 int i;
2494
2495 ABC_FREE(s->undiffnons);
2496 ABC_FREE(s->diffnons);
2497 ABC_FREE(s->unpairs);
2498 ABC_FREE(s->pairs);
2499 ABC_FREE(s->thfront);
2500 ABC_FREE(s->threp);
2501 ABC_FREE(s->thnext);
2502 ABC_FREE(s->thprev);
2503 ABC_FREE(s->specmin);
2504 ABC_FREE(s->anctar);
2505 ABC_FREE(s->thsize);
2506 ABC_FREE(s->undifflev);
2507 ABC_FREE(s->difflev);
2508 ABC_FREE(s->diffs);
2509 ABC_FREE(s->diffmark);
2510 ABC_FREE(s->conncnts);
2511 ABC_FREE(s->unsupp);
2512 ABC_FREE(s->splitlev);
2513 ABC_FREE(s->splitfrom);
2514 ABC_FREE(s->splitwho);
2515 ABC_FREE(s->splitvar);
2516 ABC_FREE(s->right.unlab);
2517 ABC_FREE(s->right.lab);
2518 ABC_FREE(s->left.unlab);
2519 ABC_FREE(s->left.lab);
2520 ABC_FREE(s->theta);
2521 ABC_FREE(s->junk);
2522 ABC_FREE(s->gamma);
2523 ABC_FREE(s->start);
2524 ABC_FREE(s->prevnon);
2525 free(s->nextnon-1);
2526 ABC_FREE(s->clist);
2527 ABC_FREE(s->ccount);
2528 ABC_FREE(s->count);
2529 ABC_FREE(s->bucket);
2530 ABC_FREE(s->stuff);
2531 ABC_FREE(s->right.clen);
2532 ABC_FREE(s->right.cfront);
2533 ABC_FREE(s->left.clen);
2534 ABC_FREE(s->left.cfront);
2535 ABC_FREE(s->indmark);
2536 ABC_FREE(s->sinduce);
2537 ABC_FREE(s->ninduce);
2538 ABC_FREE(s->depAdj);
2539 ABC_FREE(s->depEdg);
2540 ABC_FREE(s->marks);
2541 for (i = 0; i < Abc_NtkPiNum(s->pNtk); i++) {
2542 Vec_IntFree( s->iDep[i] );
2543 Vec_IntFree( s->obs[i] );
2544 Vec_PtrFree( s->topOrder[i] );
2545 }
2546 for (i = 0; i < Abc_NtkPoNum(s->pNtk); i++) {
2547 Vec_IntFree( s->oDep[i] );
2548 Vec_IntFree( s->ctrl[i] );
2549 }
2550 for (i = 0; i < Vec_PtrSize(s->randomVectorArray_sim1); i++)
2551 Vec_IntFree((Vec_Int_t *)Vec_PtrEntry(s->randomVectorArray_sim1, i));
2552 for (i = 0; i < Vec_PtrSize(s->randomVectorArray_sim2); i++)
2553 Vec_IntFree((Vec_Int_t *)Vec_PtrEntry(s->randomVectorArray_sim2, i));
2554 Vec_PtrFree( s->randomVectorArray_sim1 );
2555 Vec_PtrFree( s->randomVectorArray_sim2 );
2559 for (i = 0; i < Vec_PtrSize(s->satCounterExamples); i++) {
2560 struct sim_result * cex = (struct sim_result *)Vec_PtrEntry(s->satCounterExamples, i);
2561 ABC_FREE( cex->inVec );
2562 ABC_FREE( cex->outVec );
2563 ABC_FREE( cex );
2564 }
2565 Vec_PtrFree(s->satCounterExamples);
2566 ABC_FREE( s->pModel );
2567 ABC_FREE( s->iDep );
2568 ABC_FREE( s->oDep );
2569 ABC_FREE( s->obs );
2570 ABC_FREE( s->ctrl );
2571 ABC_FREE( s->topOrder );
2572 ABC_FREE(s);
2573}
2574
2575struct saucy *
2577{
2578 int i;
2579 int numouts = Abc_NtkPoNum(pNtk);
2580 int numins = Abc_NtkPiNum(pNtk);
2581 int n = numins + numouts;
2582 struct saucy *s = ABC_ALLOC(struct saucy, 1);
2583 if (s == NULL) return NULL;
2584
2585 s->ninduce = ints(n);
2586 s->sinduce = ints(n);
2587 s->indmark = bits(n);
2588 s->left.cfront = zeros(n);
2589 s->left.clen = ints(n);
2590 s->right.cfront = zeros(n);
2591 s->right.clen = ints(n);
2592 s->stuff = bits(n+1);
2593 s->bucket = ints(n+2);
2594 s->count = ints(n+1);
2595 s->ccount = zeros(n);
2596 s->clist = ints(n);
2597 s->nextnon = ints(n+1) + 1;
2598 s->prevnon = ints(n+1);
2599 s->anctar = ints(n);
2600 s->start = ints(n);
2601 s->gamma = ints(n);
2602 s->junk = ints(n);
2603 s->theta = ints(n);
2604 s->thsize = ints(n);
2605 s->left.lab = ints(n);
2606 s->left.unlab = ints(n);
2607 s->right.lab = ints(n);
2608 s->right.unlab = ints(n);
2609 s->splitvar = ints(n);
2610 s->splitwho = ints(n);
2611 s->splitfrom = ints(n);
2612 s->splitlev = ints(n+1);
2613 s->unsupp = ints(n);
2614 s->conncnts = zeros(n);
2615 s->diffmark = bits(n);
2616 s->diffs = ints(n);
2617 s->difflev = ints(n);
2618 s->undifflev = ints(n);
2619 s->specmin = ints(n);
2620 s->thnext = ints(n);
2621 s->thprev = ints(n);
2622 s->threp = ints(n);
2623 s->thfront = ints(n);
2624 s->pairs = ints(n);
2625 s->unpairs = ints(n);
2626 s->diffnons = ints(n);
2627 s->undiffnons = ints(n);
2628 s->marks = bits(n);
2629
2630 s->iDep = ABC_ALLOC( Vec_Int_t*, numins );
2631 s->oDep = ABC_ALLOC( Vec_Int_t*, numouts );
2632 s->obs = ABC_ALLOC( Vec_Int_t*, numins );
2633 s->ctrl = ABC_ALLOC( Vec_Int_t*, numouts );
2634
2635 for(i = 0; i < numins; i++) {
2636 s->iDep[i] = Vec_IntAlloc( 1 );
2637 s->obs[i] = Vec_IntAlloc( 1 );
2638 }
2639 for(i = 0; i < numouts; i++) {
2640 s->oDep[i] = Vec_IntAlloc( 1 );
2641 s->ctrl[i] = Vec_IntAlloc( 1 );
2642 }
2643
2644 s->randomVectorArray_sim1 = Vec_PtrAlloc( n );
2645 s->randomVectorSplit_sim1 = zeros( n );
2646 s->randomVectorArray_sim2 = Vec_PtrAlloc( n );
2647 s->randomVectorSplit_sim2= zeros( n );
2648
2649 s->satCounterExamples = Vec_PtrAlloc( 1 );
2650 s->pModel = ints( numins );
2651
2652 if (s->ninduce && s->sinduce && s->left.cfront && s->left.clen
2653 && s->right.cfront && s->right.clen
2654 && s->stuff && s->bucket && s->count && s->ccount
2655 //&& s->clist && s->nextnon-1 && s->prevnon
2656 && s->clist && s->nextnon[-1] && s->prevnon
2657 && s->start && s->gamma && s->theta && s->left.unlab
2658 && s->right.lab && s->right.unlab
2659 && s->left.lab && s->splitvar && s->splitwho && s->junk
2660 && s->splitfrom && s->splitlev && s->thsize
2661 && s->unsupp && s->conncnts && s->anctar
2662 && s->diffmark && s->diffs && s->indmark
2663 && s->thnext && s->thprev && s->threp && s->thfront
2664 && s->pairs && s->unpairs && s->diffnons && s->undiffnons
2665 && s->difflev && s->undifflev && s->specmin)
2666 {
2667 return s;
2668 }
2669 else {
2670 saucy_free(s);
2671 return NULL;
2672 }
2673}
2674
2675static void
2676print_stats(FILE *f, struct saucy_stats stats )
2677{
2678 fprintf(f, "group size = %fe%d\n",
2680 fprintf(f, "levels = %d\n", stats.levels);
2681 fprintf(f, "nodes = %d\n", stats.nodes);
2682 fprintf(f, "generators = %d\n", stats.gens);
2683 fprintf(f, "total support = %d\n", stats.support);
2684 fprintf(f, "average support = %.2f\n",(double)(stats.support)/(double)(stats.gens));
2685 fprintf(f, "nodes per generator = %.2f\n",(double)(stats.nodes)/(double)(stats.gens));
2686 fprintf(f, "bad nodes = %d\n", stats.bads);
2687}
2688
2689
2690/* From this point up are SAUCY functions*/
2692/* From this point down are new functions */
2693
2694static char *
2695getVertexName(Abc_Ntk_t *pNtk, int v)
2696{
2697 Abc_Obj_t * pObj;
2698 int numouts = Abc_NtkPoNum(pNtk);
2699
2700 if (v < numouts)
2701 pObj = (Abc_Obj_t *)Vec_PtrEntry(pNtk->vPos, v);
2702 else
2703 pObj = (Abc_Obj_t *)Vec_PtrEntry(pNtk->vPis, v - numouts);
2704
2705 return Abc_ObjName(pObj);
2706}
2707
2708static Vec_Ptr_t **
2710{
2711 Vec_Ptr_t ** vNodes;
2712 Abc_Obj_t * pObj, * pFanout;
2713 int i, k;
2714
2715 extern void Abc_NtkDfsReverse_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes );
2716
2717 /* start the array of nodes */
2718 vNodes = ABC_ALLOC(Vec_Ptr_t *, Abc_NtkPiNum(pNtk));
2719 for(i = 0; i < Abc_NtkPiNum(pNtk); i++)
2720 vNodes[i] = Vec_PtrAlloc(50);
2721
2722 Abc_NtkForEachCi( pNtk, pObj, i )
2723 {
2724 /* set the traversal ID */
2725 Abc_NtkIncrementTravId( pNtk );
2726 Abc_NodeSetTravIdCurrent( pObj );
2727 pObj = Abc_ObjFanout0Ntk(pObj);
2728 Abc_ObjForEachFanout( pObj, pFanout, k )
2729 Abc_NtkDfsReverse_rec( pFanout, vNodes[i] );
2730 }
2731
2732 return vNodes;
2733}
2734
2735static void
2737{
2738 Vec_Ptr_t * vSuppFun;
2739 int i, j;
2740
2741 vSuppFun = Sim_ComputeFunSupp(pNtk, 0);
2742 for(i = 0; i < Abc_NtkPoNum(pNtk); i++) {
2743 char * seg = (char *)vSuppFun->pArray[i];
2744
2745 for(j = 0; j < Abc_NtkPiNum(pNtk); j+=8) {
2746 if(((*seg) & 0x01) == 0x01)
2747 Vec_IntPushOrder(oDep[i], j);
2748 if(((*seg) & 0x02) == 0x02)
2749 Vec_IntPushOrder(oDep[i], j+1);
2750 if(((*seg) & 0x04) == 0x04)
2751 Vec_IntPushOrder(oDep[i], j+2);
2752 if(((*seg) & 0x08) == 0x08)
2753 Vec_IntPushOrder(oDep[i], j+3);
2754 if(((*seg) & 0x10) == 0x10)
2755 Vec_IntPushOrder(oDep[i], j+4);
2756 if(((*seg) & 0x20) == 0x20)
2757 Vec_IntPushOrder(oDep[i], j+5);
2758 if(((*seg) & 0x40) == 0x40)
2759 Vec_IntPushOrder(oDep[i], j+6);
2760 if(((*seg) & 0x80) == 0x80)
2761 Vec_IntPushOrder(oDep[i], j+7);
2762
2763 seg++;
2764 }
2765 }
2766
2767 for(i = 0; i < Abc_NtkPoNum(pNtk); i++)
2768 for(j = 0; j < Vec_IntSize(oDep[i]); j++)
2769 Vec_IntPush(iDep[Vec_IntEntry(oDep[i], j)], i);
2770
2771
2772 /*for(i = 0; i < Abc_NtkPoNum(pNtk); i++)
2773 {
2774 printf("Output %d: ", i);
2775 for(j = 0; j < Vec_IntSize(oDep[i]); j++)
2776 printf("%d ", Vec_IntEntry(oDep[i], j));
2777 printf("\n");
2778 }
2779
2780 printf("\n");
2781
2782 for(i = 0; i < Abc_NtkPiNum(pNtk); i++)
2783 {
2784 printf("Input %d: ", i);
2785 for(j = 0; j < Vec_IntSize(iDep[i]); j++)
2786 printf("%d ", Vec_IntEntry(iDep[i], j));
2787 printf("\n");
2788 }
2789
2790 printf("\n"); */
2791}
2792
2793static void
2794getDependenciesDummy(Abc_Ntk_t *pNtk, Vec_Int_t** iDep, Vec_Int_t** oDep)
2795{
2796 int i, j;
2797
2798 /* let's assume that every output is dependent on every input */
2799 for(i = 0; i < Abc_NtkPoNum(pNtk); i++)
2800 for(j = 0; j < Abc_NtkPiNum(pNtk); j++)
2801 Vec_IntPush(oDep[i], j);
2802
2803 for(i = 0; i < Abc_NtkPiNum(pNtk); i++)
2804 for(j = 0; j < Abc_NtkPoNum(pNtk); j++)
2805 Vec_IntPush(iDep[i], j);
2806}
2807
2808static struct saucy_graph *
2809buildDepGraph(Abc_Ntk_t *pNtk, Vec_Int_t ** iDep, Vec_Int_t ** oDep)
2810{
2811 int i, j, k;
2812 struct saucy_graph *g = NULL;
2813 int n, e, *adj, *edg;
2814
2815 n = Abc_NtkPoNum(pNtk) + Abc_NtkPiNum(pNtk);
2816 for (e = 0, i = 0; i < Abc_NtkPoNum(pNtk); i++)
2817 e += Vec_IntSize(oDep[i]);
2818
2819 g = ABC_ALLOC(struct saucy_graph, 1);
2820 adj = zeros(n+1);
2821 edg = ints(2*e);
2822
2823 g->n = n;
2824 g->e = e;
2825 g->adj = adj;
2826 g->edg = edg;
2827
2828 adj[0] = 0;
2829 for (i = 0; i < n; i++) {
2830 /* first add outputs and then inputs */
2831 if ( i < Abc_NtkPoNum(pNtk)) {
2832 adj[i+1] = adj[i] + Vec_IntSize(oDep[i]);
2833 for (k = 0, j = adj[i]; j < adj[i+1]; j++, k++)
2834 edg[j] = Vec_IntEntry(oDep[i], k) + Abc_NtkPoNum(pNtk);
2835 }
2836 else {
2837 adj[i+1] = adj[i] + Vec_IntSize(iDep[i-Abc_NtkPoNum(pNtk)]);
2838 for (k = 0, j = adj[i]; j < adj[i+1]; j++, k++)
2839 edg[j] = Vec_IntEntry(iDep[i-Abc_NtkPoNum(pNtk)], k);
2840 }
2841 }
2842
2843 /* print graph for testing */
2844 /*for (i = 0; i < n; i++) {
2845 printf("%d: ", i);
2846 for (j = adj[i]; j < adj[i+1]; j++)
2847 printf("%d ", edg[j]);
2848 printf("\n");
2849 }*/
2850
2851 return g;
2852}
2853
2854static Vec_Int_t *
2855assignRandomBitsToCells(Abc_Ntk_t * pNtk, struct coloring *c)
2856{
2857 Vec_Int_t * randVec = Vec_IntAlloc( 1 );
2858 int i, bit;
2859
2860 for (i = 0; i < Abc_NtkPiNum(pNtk); i += (c->clen[i+Abc_NtkPoNum(pNtk)]+1)) {
2861 bit = (int)(SIM_RANDOM_UNSIGNED % 2);
2862 Vec_IntPush(randVec, bit);
2863 }
2864
2865 return randVec;
2866}
2867
2868static int *
2869generateProperInputVector( Abc_Ntk_t * pNtk, struct coloring *c, Vec_Int_t * randomVector )
2870{
2871 int * vPiValues;
2872 int i, j, k, bit, input;
2873 int numouts = Abc_NtkPoNum(pNtk);
2874 int numins = Abc_NtkPiNum(pNtk);
2875 int n = numouts + numins;
2876
2877 vPiValues = ABC_ALLOC( int, numins);
2878
2879 for (i = numouts, k = 0; i < n; i += (c->clen[i]+1), k++) {
2880 if (k == Vec_IntSize(randomVector)) break;
2881
2882 bit = Vec_IntEntry(randomVector, k);
2883 for (j = i; j <= (i + c->clen[i]); j++) {
2884 input = c->lab[j] - numouts;
2885 vPiValues[input] = bit;
2886 }
2887 }
2888
2889 //if (k != Vec_IntSize(randomVector)) {
2890 if (i < n) {
2891 ABC_FREE( vPiValues );
2892 return NULL;
2893 }
2894
2895 return vPiValues;
2896}
2897
2898static int
2899ifInputVectorsAreConsistent( struct saucy * s, int * leftVec, int * rightVec )
2900{
2901 /* This function assumes that left and right partitions are isomorphic */
2902 int i, j;
2903 int lab;
2904 int left_bit, right_bit;
2905 int numouts = Abc_NtkPoNum(s->pNtk);
2906 int n = numouts + Abc_NtkPiNum(s->pNtk);
2907
2908 for (i = numouts; i < n; i += (s->right.clen[i]+1)) {
2909 lab = s->left.lab[i] - numouts;
2910 left_bit = leftVec[lab];
2911 for (j = i+1; j <= (i + s->right.clen[i]); j++) {
2912 lab = s->left.lab[j] - numouts;
2913 if (left_bit != leftVec[lab]) return -1;
2914 }
2915
2916 lab = s->right.lab[i] - numouts;
2917 right_bit = rightVec[lab];
2918 for (j = i+1; j <= (i + s->right.clen[i]); j++) {
2919 lab = s->right.lab[j] - numouts;
2920 if (right_bit != rightVec[lab]) return 0;
2921 }
2922
2923 if (left_bit != right_bit)
2924 return 0;
2925 }
2926
2927 return 1;
2928}
2929
2930static int
2931ifOutputVectorsAreConsistent( struct saucy * s, int * leftVec, int * rightVec )
2932{
2933 /* This function assumes that left and right partitions are isomorphic */
2934 int i, j;
2935 int count1, count2;
2936
2937 for (i = 0; i < Abc_NtkPoNum(s->pNtk); i += (s->right.clen[i]+1)) {
2938 count1 = count2 = 0;
2939 for (j = i; j <= (i + s->right.clen[i]); j++) {
2940 if (leftVec[s->left.lab[j]]) count1++;
2941 if (rightVec[s->right.lab[j]]) count2++;
2942 }
2943
2944 if (count1 != count2) return 0;
2945 }
2946
2947 return 1;
2948}
2949
2950static struct saucy_graph *
2951buildSim1Graph( Abc_Ntk_t * pNtk, struct coloring *c, Vec_Int_t * randVec, Vec_Int_t ** iDep, Vec_Int_t ** oDep )
2952{
2953 int i, j, k;
2954 struct saucy_graph *g;
2955 int n, e, *adj, *edg;
2956 int * vPiValues, * output;
2957 int numOneOutputs = 0;
2958 int numouts = Abc_NtkPoNum(pNtk);
2959 int numins = Abc_NtkPiNum(pNtk);
2960
2961 vPiValues = generateProperInputVector(pNtk, c, randVec);
2962 if (vPiValues == NULL)
2963 return NULL;
2964
2965 output = Abc_NtkVerifySimulatePattern(pNtk, vPiValues);
2966
2967 for (i = 0; i < numouts; i++) {
2968 if (output[i])
2969 numOneOutputs++;
2970 }
2971
2972 g = ABC_ALLOC(struct saucy_graph, 1);
2973 n = numouts + numins;
2974 e = numins * numOneOutputs;
2975 adj = ints(n+1);
2976 edg = ints(2*e);
2977 g->n = n;
2978 g->e = e;
2979 g->adj = adj;
2980 g->edg = edg;
2981
2982 adj[0] = 0;
2983 for (i = 0; i < numouts; i++) {
2984 if (output[i]) {
2985 adj[i+1] = adj[i] + Vec_IntSize(oDep[i]);
2986 for (j = adj[i], k = 0; j < adj[i+1]; j++, k++)
2987 edg[j] = Vec_IntEntry(oDep[i], k) + numouts;
2988 } else {
2989 adj[i+1] = adj[i];
2990 }
2991 }
2992
2993 for (i = 0; i < numins; i++) {
2994 adj[i+numouts+1] = adj[i+numouts];
2995 for (k = 0, j = adj[i+numouts]; k < Vec_IntSize(iDep[i]); k++) {
2996 if (output[Vec_IntEntry(iDep[i], k)]) {
2997 edg[j++] = Vec_IntEntry(iDep[i], k);
2998 adj[i+numouts+1]++;
2999 }
3000 }
3001 }
3002
3003 /* print graph */
3004 /*for (i = 0; i < n; i++) {
3005 printf("%d: ", i);
3006 for (j = adj[i]; j < adj[i+1]; j++)
3007 printf("%d ", edg[j]);
3008 printf("\n");
3009 }*/
3010
3011 ABC_FREE( vPiValues );
3012 ABC_FREE( output );
3013
3014 return g;
3015}
3016
3017static struct saucy_graph *
3018buildSim2Graph( 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 )
3019{
3020 int i, j, k;
3021 struct saucy_graph *g = NULL;
3022 int n, e = 0, *adj, *edg;
3023 int * vPiValues;
3024 int * output, * output2;
3025 int numouts = Abc_NtkPoNum(pNtk);
3026 int numins = Abc_NtkPiNum(pNtk);
3027
3028 extern int * Abc_NtkSimulateOneNode( Abc_Ntk_t * , int * , int , Vec_Ptr_t ** );
3029
3030 vPiValues = generateProperInputVector(pNtk, c, randVec);
3031 if (vPiValues == NULL)
3032 return NULL;
3033
3034 output = Abc_NtkVerifySimulatePattern( pNtk, vPiValues );
3035
3036 for (i = 0; i < numins; i++) {
3037 if (!c->clen[c->cfront[i+numouts]]) continue;
3038 if (vPiValues[i] == 0) vPiValues[i] = 1;
3039 else vPiValues[i] = 0;
3040
3041 output2 = Abc_NtkSimulateOneNode( pNtk, vPiValues, i, topOrder );
3042
3043 for (j = 0; j < Vec_IntSize(iDep[i]); j++) {
3044 if (output[Vec_IntEntry(iDep[i], j)] != output2[Vec_IntEntry(iDep[i], j)]) {
3045 Vec_IntPush(obs[i], Vec_IntEntry(iDep[i], j));
3046 Vec_IntPush(ctrl[Vec_IntEntry(iDep[i], j)], i);
3047 e++;
3048 }
3049 }
3050
3051 if (vPiValues[i] == 0) vPiValues[i] = 1;
3052 else vPiValues[i] = 0;
3053
3054 ABC_FREE( output2 );
3055 }
3056
3057 /* build the graph */
3058 g = ABC_ALLOC(struct saucy_graph, 1);
3059 n = numouts + numins;
3060 adj = ints(n+1);
3061 edg = ints(2*e);
3062 g->n = n;
3063 g->e = e;
3064 g->adj = adj;
3065 g->edg = edg;
3066
3067 adj[0] = 0;
3068 for (i = 0; i < numouts; i++) {
3069 adj[i+1] = adj[i] + Vec_IntSize(ctrl[i]);
3070 for (k = 0, j = adj[i]; j < adj[i+1]; j++, k++)
3071 edg[j] = Vec_IntEntry(ctrl[i], k) + numouts;
3072 }
3073 for (i = 0; i < numins; i++) {
3074 adj[i+numouts+1] = adj[i+numouts] + Vec_IntSize(obs[i]);
3075 for (k = 0, j = adj[i+numouts]; j < adj[i+numouts+1]; j++, k++)
3076 edg[j] = Vec_IntEntry(obs[i], k);
3077 }
3078
3079 /* print graph */
3080 /*for (i = 0; i < n; i++) {
3081 printf("%d: ", i);
3082 for (j = adj[i]; j < adj[i+1]; j++)
3083 printf("%d ", edg[j]);
3084 printf("\n");
3085 }*/
3086
3087 ABC_FREE( output );
3088 ABC_FREE( vPiValues );
3089 for (j = 0; j < numins; j++)
3090 Vec_IntClear(obs[j]);
3091 for (j = 0; j < numouts; j++)
3092 Vec_IntClear(ctrl[j]);
3093
3094 return g;
3095}
3096
3097static void
3098bumpActivity( struct saucy * s, struct sim_result * cex )
3099{
3100 int i;
3101 struct sim_result * cex2;
3102
3103 if ( (cex->activity += s->activityInc) > 1e20 ) {
3104 /* Rescale: */
3105 for (i = 0; i < Vec_PtrSize(s->satCounterExamples); i++) {
3106 cex2 = (struct sim_result *)Vec_PtrEntry(s->satCounterExamples, i);
3107 cex2->activity *= 1e-20;
3108 }
3109 s->activityInc *= 1e-20;
3110 }
3111}
3112
3113static void
3114reduceDB( struct saucy * s )
3115{
3116 int i, j;
3117 double extra_lim = s->activityInc / Vec_PtrSize(s->satCounterExamples); /* Remove any clause below this activity */
3118 struct sim_result * cex;
3119
3120 while (Vec_PtrSize(s->satCounterExamples) > (0.7 * MAX_LEARNTS)) {
3121 for (i = j = 0; i < Vec_PtrSize(s->satCounterExamples); i++) {
3122 cex = (struct sim_result *)Vec_PtrEntry(s->satCounterExamples, i);
3123 if (cex->activity < extra_lim) {
3124 ABC_FREE(cex->inVec);
3125 ABC_FREE(cex->outVec);
3126 ABC_FREE(cex);
3127 }
3128 else if (j < i) {
3129 Vec_PtrWriteEntry(s->satCounterExamples, j, cex);
3130 j++;
3131 }
3132 }
3133 //printf("Database size reduced from %d to %d\n", Vec_PtrSize(s->satCounterExamples), j);
3134 Vec_PtrShrink(s->satCounterExamples, j);
3135 extra_lim *= 2;
3136 }
3137
3138 assert(Vec_PtrSize(s->satCounterExamples) <= (0.7 * MAX_LEARNTS));
3139}
3140
3141static struct sim_result *
3142analyzeConflict( Abc_Ntk_t * pNtk, int * pModel, int fVerbose )
3143{
3144 Abc_Obj_t * pNode;
3145 int i, count = 0;
3146 int * pValues;
3147 struct sim_result * cex;
3148 int numouts = Abc_NtkPoNum(pNtk);
3149 int numins = Abc_NtkPiNum(pNtk);
3150
3151 cex = ABC_ALLOC(struct sim_result, 1);
3152 cex->inVec = ints( numins );
3153 cex->outVec = ints( numouts );
3154
3155 /* get the CO values under this model */
3156 pValues = Abc_NtkVerifySimulatePattern( pNtk, pModel );
3157
3158 Abc_NtkForEachCi( pNtk, pNode, i )
3159 cex->inVec[Abc_ObjId(pNode)-1] = pModel[i];
3160 Abc_NtkForEachCo( pNtk, pNode, i ) {
3161 cex->outVec[Abc_ObjId(pNode)-numins-1] = pValues[i];
3162 if (pValues[i]) count++;
3163 }
3164
3165 cex->outVecOnes = count;
3166 cex->activity = 0;
3167
3168 if (fVerbose) {
3169 Abc_NtkForEachCi( pNtk, pNode, i )
3170 printf(" %s=%d", Abc_ObjName(pNode), pModel[i]);
3171 printf("\n");
3172 }
3173
3174 ABC_FREE( pValues );
3175
3176 return cex;
3177}
3178
3179static int
3180Abc_NtkCecSat_saucy( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int * pModel )
3181{
3182 extern Abc_Ntk_t * Abc_NtkMulti( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax, int fCnf, int fMulti, int fSimple, int fFactor );
3183 Abc_Ntk_t * pMiter;
3184 Abc_Ntk_t * pCnf;
3185 int RetValue;
3186 int nConfLimit;
3187 int nInsLimit;
3188 int i;
3189
3190 nConfLimit = 10000;
3191 nInsLimit = 0;
3192
3193 /* get the miter of the two networks */
3194 pMiter = Abc_NtkMiter( pNtk1, pNtk2, 1, 0, 0, 0 );
3195 if ( pMiter == NULL )
3196 {
3197 printf( "Miter computation has failed.\n" );
3198 exit(1);
3199 }
3200 RetValue = Abc_NtkMiterIsConstant( pMiter );
3201 if ( RetValue == 0 )
3202 {
3203 //printf( "Networks are NOT EQUIVALENT after structural hashing.\n" );
3204 /* report the error */
3205 pMiter->pModel = Abc_NtkVerifyGetCleanModel( pMiter, 1 );
3206 for (i = 0; i < Abc_NtkPiNum(pNtk1); i++)
3207 pModel[i] = pMiter->pModel[i];
3208 ABC_FREE( pMiter->pModel );
3209 Abc_NtkDelete( pMiter );
3210 return 0;
3211 }
3212 if ( RetValue == 1 )
3213 {
3214 Abc_NtkDelete( pMiter );
3215 //printf( "Networks are equivalent after structural hashing.\n" );
3216 return 1;
3217 }
3218
3219 /* convert the miter into a CNF */
3220 pCnf = Abc_NtkMulti( pMiter, 0, 100, 1, 0, 0, 0 );
3221 Abc_NtkDelete( pMiter );
3222 if ( pCnf == NULL )
3223 {
3224 printf( "Renoding for CNF has failed.\n" );
3225 exit(1);
3226 }
3227
3228 /* solve the CNF using the SAT solver */
3229 RetValue = Abc_NtkMiterSat( pCnf, (ABC_INT64_T)nConfLimit, (ABC_INT64_T)nInsLimit, 0, NULL, NULL );
3230 if ( RetValue == -1 ) {
3231 printf( "Networks are undecided (SAT solver timed out).\n" );
3232 exit(1);
3233 }
3234 /*else if ( RetValue == 0 )
3235 printf( "Networks are NOT EQUIVALENT after SAT.\n" );
3236 else
3237 printf( "Networks are equivalent after SAT.\n" );*/
3238 if ( pCnf->pModel ) {
3239 for (i = 0; i < Abc_NtkPiNum(pNtk1); i++)
3240 pModel[i] = pCnf->pModel[i];
3241 }
3242 ABC_FREE( pCnf->pModel );
3243 Abc_NtkDelete( pCnf );
3244
3245 return RetValue;
3246}
3247
3248
3249void saucyGateWay( Abc_Ntk_t * pNtkOrig, Abc_Obj_t * pNodePo, FILE * gFile, int fBooleanMatching,
3250 int fLookForSwaps, int fFixOutputs, int fFixInputs, int fQuiet, int fPrintTree )
3251{
3252 Abc_Ntk_t * pNtk;
3253 struct saucy *s;
3254 struct saucy_stats stats;
3255 int *colors;
3256 int i, clk = clock();
3257
3258 if (pNodePo == NULL)
3259 pNtk = Abc_NtkDup( pNtkOrig );
3260 else
3261 pNtk = Abc_NtkCreateCone( pNtkOrig, Abc_ObjFanin0(pNodePo), Abc_ObjName(pNodePo), 0 );
3262
3263 if (Abc_NtkPiNum(pNtk) == 0) {
3264 Abc_Print( 0, "This output is not dependent on any input\n" );
3265 Abc_NtkDelete( pNtk );
3266 return;
3267 }
3268
3269 s = saucy_alloc( pNtk );
3270
3271 /******* Getting Dependencies *******/
3272 printf("Build functional dependency graph (dependency stats are below) ... ");
3273 getDependencies( pNtk, s->iDep, s->oDep );
3274 printf("\t--------------------\n");
3275 /************************************/
3276
3277 /* Finding toplogical orde */
3278 s->topOrder = findTopologicalOrder( pNtk );
3279
3280 /* Setting graph colors: outputs = 0 and inputs = 1 */
3281 colors = ints(Abc_NtkPoNum(pNtk) + Abc_NtkPiNum(pNtk));
3282 if (fFixOutputs) {
3283 for (i = 0; i < Abc_NtkPoNum(pNtk); i++)
3284 colors[i] = i;
3285 } else {
3286 for (i = 0; i < Abc_NtkPoNum(pNtk); i++)
3287 colors[i] = 0;
3288 }
3289 if (fFixInputs) {
3290 int c = (fFixOutputs) ? Abc_NtkPoNum(pNtk) : 1;
3291 for (i = 0; i < Abc_NtkPiNum(pNtk); i++)
3292 colors[i+Abc_NtkPoNum(pNtk)] = c+i;
3293 } else {
3294 int c = (fFixOutputs) ? Abc_NtkPoNum(pNtk) : 1;
3295 for (i = 0; i < Abc_NtkPiNum(pNtk); i++)
3296 colors[i+Abc_NtkPoNum(pNtk)] = c;
3297 }
3298
3299 /* Are we looking for Boolean matching? */
3300 s->fBooleanMatching = fBooleanMatching;
3301 if (fBooleanMatching) {
3302 NUM_SIM1_ITERATION = 50;
3303 NUM_SIM2_ITERATION = 50;
3304 } else {
3305 NUM_SIM1_ITERATION = 200;
3306 NUM_SIM2_ITERATION = 200;
3307 }
3308
3309 /* Set the print automorphism routine */
3310 if (!fQuiet)
3311 s->print_automorphism = print_automorphism_ntk;
3312 else
3313 s->print_automorphism = print_automorphism_quiet;
3314
3315 /* Set the output file for generators */
3316 if (gFile == NULL)
3317 s->gFile = stdout;
3318 else
3319 s->gFile = gFile;
3320
3321 /* Set print tree option */
3322 s->fPrintTree = fPrintTree;
3323
3324 /* Set input permutations option */
3325 s->fLookForSwaps = fLookForSwaps;
3326
3327 saucy_search(pNtk, s, 0, colors, &stats);
3328 print_stats(stdout, stats);
3329 if (fBooleanMatching) {
3330 if (stats.grpsize_base > 1 || stats.grpsize_exp > 0)
3331 printf("*** Networks are equivalent ***\n");
3332 else
3333 printf("*** Networks are NOT equivalent ***\n");
3334 }
3335 saucy_free(s);
3336 Abc_NtkDelete(pNtk);
3337
3338 if (1) {
3339 FILE * hadi = fopen("hadi.txt", "a");
3340 fprintf(hadi, "group size = %fe%d\n",
3341 stats.grpsize_base, stats.grpsize_exp);
3342 fclose(hadi);
3343 }
3344
3345 ABC_PRT( "Runtime", clock() - clk );
3346
3348
3349
int * Abc_NtkSimulateOneNode(Abc_Ntk_t *pNtk, int *pModel, int input, Vec_Ptr_t **topOrder)
Definition abcBm.c:449
void getDependencies(Abc_Ntk_t *pNtk, Vec_Int_t **iDep, Vec_Int_t **oDep)
Definition abcBm.c:46
Vec_Ptr_t ** findTopologicalOrder(Abc_Ntk_t *pNtk)
Definition abcBm.c:422
void Abc_NtkDfsReverse_rec(Abc_Obj_t *pNode, Vec_Ptr_t *vNodes)
Definition abcDfs.c:187
ABC_NAMESPACE_IMPL_START Abc_Ntk_t * Abc_NtkMulti(Abc_Ntk_t *pNtk, int nThresh, int nFaninMax, int fCnf, int fMulti, int fSimple, int fFactor)
DECLARATIONS ///.
Definition abcMulti.c:650
int NUM_SIM2_ITERATION
Definition abcSaucy.c:40
#define BACKTRACK_BY_SAT
Definition abcSaucy.c:35
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
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:3249
#define REFINE_BY_SIM_1
Definition abcSaucy.c:33
int NUM_SIM1_ITERATION
Definition abcSaucy.c:39
#define REFINE_BY_SIM_2
Definition abcSaucy.c:34
void saucy_free(struct saucy *s)
Definition abcSaucy.c:2491
#define CLAUSE_DECAY
Definition abcSaucy.c:43
struct saucy * saucy_alloc(Abc_Ntk_t *pNtk)
Definition abcSaucy.c:2576
void prepare_permutation_ntk(struct saucy *s)
Definition abcSaucy.c:2155
#define MAX_LEARNTS
Definition abcSaucy.c:44
#define SELECT_DYNAMICALLY
Definition abcSaucy.c:36
struct Abc_Obj_t_ Abc_Obj_t
Definition abc.h:116
#define Abc_NtkForEachCo(pNtk, pCo, i)
Definition abc.h:522
ABC_DLL void Abc_NtkOrderObjsByName(Abc_Ntk_t *pNtk, int fComb)
Definition abcNames.c:330
ABC_DLL Abc_Ntk_t * Abc_NtkCreateCone(Abc_Ntk_t *pNtk, Abc_Obj_t *pNode, char *pNodeName, int fUseAllCis)
Definition abcNtk.c:925
#define Abc_ObjForEachFanout(pObj, pFanout, i)
Definition abc.h:529
ABC_DLL char * Abc_ObjName(Abc_Obj_t *pNode)
DECLARATIONS ///.
Definition abcNames.c:49
struct Abc_Ntk_t_ Abc_Ntk_t
Definition abc.h:115
ABC_DLL char * Abc_ObjAssignName(Abc_Obj_t *pObj, char *pName, char *pSuffix)
Definition abcNames.c:69
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:58
ABC_DLL int * Abc_NtkVerifySimulatePattern(Abc_Ntk_t *pNtk, int *pModel)
Definition abcVerify.c:696
ABC_DLL int * Abc_NtkVerifyGetCleanModel(Abc_Ntk_t *pNtk, int nFrames)
Definition abcVerify.c:678
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:59
#define Abc_NtkForEachCi(pNtk, pCi, i)
Definition abc.h:518
ABC_DLL void Abc_NtkDelete(Abc_Ntk_t *pNtk)
Definition abcNtk.c:1421
ABC_DLL Abc_Ntk_t * Abc_NtkDup(Abc_Ntk_t *pNtk)
Definition abcNtk.c:472
ABC_DLL int Abc_NtkMiterIsConstant(Abc_Ntk_t *pMiter)
Definition abcMiter.c:682
#define ABC_PRT(a, t)
Definition abc_global.h:255
#define ABC_ALLOC(type, num)
Definition abc_global.h:264
#define ABC_CALLOC(type, num)
Definition abc_global.h:265
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
ABC_NAMESPACE_IMPL_START typedef signed char value
int descend()
Cube * p
Definition exorList.c:222
char * name
Definition main.h:24
unsigned long long size
Definition giaNewBdd.h:39
void Nm_ManFree(Nm_Man_t *p)
Definition nmApi.c:76
Nm_Man_t * Nm_ManCreate(int nSize)
MACRO DEFINITIONS ///.
Definition nmApi.c:45
#define SIM_RANDOM_UNSIGNED
Definition sim.h:158
Vec_Ptr_t * Sim_ComputeFunSupp(Abc_Ntk_t *pNtk, int fVerbose)
Definition simSupp.c:103
Vec_Ptr_t * vPos
Definition abc.h:164
int * pModel
Definition abc.h:198
Nm_Man_t * pManName
Definition abc.h:160
Vec_Ptr_t * vPis
Definition abc.h:163
int * clen
Definition abcSaucy.c:78
int * lab
Definition abcSaucy.c:75
int * unlab
Definition abcSaucy.c:76
int * cfront
Definition abcSaucy.c:77
int * adj
Definition abcSaucy.c:70
int * edg
Definition abcSaucy.c:71
double grpsize_base
Definition abcSaucy.c:58
int grpsize_exp
Definition abcSaucy.c:59
int support
Definition abcSaucy.c:64
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 * adj
Definition abcSaucy.c:92
int * ninduce
Definition abcSaucy.c:104
int * pModel
Definition abcSaucy.c:185
int(* ref_nonsingle)(struct saucy *, struct coloring *, int)
Definition abcSaucy.c:166
Vec_Int_t ** ctrl
Definition abcSaucy.c:178
int(* is_automorphism)(struct saucy *)
Definition abcSaucy.c:164
int * sinduce
Definition abcSaucy.c:105
int * nextnon
Definition abcSaucy.c:99
int kanctar
Definition abcSaucy.c:126
int * splitlev
Definition abcSaucy.c:143
void(* select_decomposition)(struct saucy *, int *, int *, int *)
Definition abcSaucy.c:167
int n
Definition abcSaucy.c:91
int * conncnts
Definition abcSaucy.c:120
int * anctar
Definition abcSaucy.c:125
int lev
Definition abcSaucy.c:123
Abc_Ntk_t * pNtk_permuted
Definition abcSaucy.c:174
int * splitwho
Definition abcSaucy.c:141
int * dedg
Definition abcSaucy.c:95
int(* refineBySim2)(struct saucy *, struct coloring *)
Definition abcSaucy.c:195
struct saucy_stats * stats
Definition abcSaucy.c:170
int nsplits
Definition abcSaucy.c:144
int csize
Definition abcSaucy.c:111
int npairs
Definition abcSaucy.c:157
int * randomVectorSplit_sim2
Definition abcSaucy.c:183
int nundiffs
Definition abcSaucy.c:152
int * undifflev
Definition abcSaucy.c:151
int indmin
Definition abcSaucy.c:128
int * edg
Definition abcSaucy.c:93
int * theta
Definition abcSaucy.c:132
Vec_Int_t ** iDep
Definition abcSaucy.c:177
int * splitvar
Definition abcSaucy.c:140
int * clist
Definition abcSaucy.c:110
int * threp
Definition abcSaucy.c:136
struct coloring left right
Definition abcSaucy.c:98
int * dadj
Definition abcSaucy.c:94
int anc
Definition abcSaucy.c:124
Vec_Ptr_t * satCounterExamples
Definition abcSaucy.c:186
int * undiffnons
Definition abcSaucy.c:159
int * thprev
Definition abcSaucy.c:135
int * gamma
Definition abcSaucy.c:119
int * prevnon
Definition abcSaucy.c:100
int * specmin
Definition abcSaucy.c:154
int fLookForSwaps
Definition abcSaucy.c:191
char * diffmark
Definition abcSaucy.c:147
int * thsize
Definition abcSaucy.c:133
int match
Definition abcSaucy.c:129
int * count
Definition abcSaucy.c:117
int * thnext
Definition abcSaucy.c:134
int(* ref_singleton)(struct saucy *, struct coloring *, int)
Definition abcSaucy.c:165
int ndiffnons
Definition abcSaucy.c:160
char * stuff
Definition abcSaucy.c:114
int fPrintTree
Definition abcSaucy.c:190
int nsinduce
Definition abcSaucy.c:107
char * marks
Definition abcSaucy.c:184
Vec_Int_t ** oDep
Definition abcSaucy.c:177
FILE * gFile
Definition abcSaucy.c:192
int fBooleanMatching
Definition abcSaucy.c:189
int * depAdj
Definition abcSaucy.c:175
int * diffs
Definition abcSaucy.c:148
Vec_Ptr_t * randomVectorArray_sim2
Definition abcSaucy.c:182
int(* refineBySim1)(struct saucy *, struct coloring *)
Definition abcSaucy.c:194
int ndiffs
Definition abcSaucy.c:150
int * junk
Definition abcSaucy.c:118
int * splitfrom
Definition abcSaucy.c:142
int * thfront
Definition abcSaucy.c:137
Vec_Ptr_t ** topOrder
Definition abcSaucy.c:179
int * start
Definition abcSaucy.c:127
int(* split)(struct saucy *, struct coloring *, int, int)
Definition abcSaucy.c:163
int * pairs
Definition abcSaucy.c:155
int * depEdg
Definition abcSaucy.c:176
int * unsupp
Definition abcSaucy.c:153
Abc_Ntk_t * pNtk
Definition abcSaucy.c:173
int nninduce
Definition abcSaucy.c:106
int * diffnons
Definition abcSaucy.c:158
int * bucket
Definition abcSaucy.c:116
int * ccount
Definition abcSaucy.c:115
int * randomVectorSplit_sim1
Definition abcSaucy.c:181
Vec_Int_t ** obs
Definition abcSaucy.c:178
int * unpairs
Definition abcSaucy.c:156
char * indmark
Definition abcSaucy.c:103
Vec_Ptr_t * randomVectorArray_sim1
Definition abcSaucy.c:180
double activityInc
Definition abcSaucy.c:187
int * difflev
Definition abcSaucy.c:149
int outVecOnes
Definition abcSaucy.c:85
int * outVec
Definition abcSaucy.c:83
int inVecSignature
Definition abcSaucy.c:84
int * inVec
Definition abcSaucy.c:82
double activity
Definition abcSaucy.c:86
#define assert(ex)
Definition util_old.h:213
char * memcpy()
VOID_HACK abort()
VOID_HACK free()
VOID_HACK exit()
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition vecPtr.h:42