abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddWindow.c
Go to the documentation of this file.
1 /**CFile***********************************************************************
2 
3  FileName [cuddWindow.c]
4 
5  PackageName [cudd]
6 
7  Synopsis [Functions for variable reordering by window permutation.]
8 
9  Description [Internal procedures included in this module:
10  <ul>
11  <li> cuddWindowReorder()
12  </ul>
13  Static procedures included in this module:
14  <ul>
15  <li> ddWindow2()
16  <li> ddWindowConv2()
17  <li> ddPermuteWindow3()
18  <li> ddWindow3()
19  <li> ddWindowConv3()
20  <li> ddPermuteWindow4()
21  <li> ddWindow4()
22  <li> ddWindowConv4()
23  </ul>]
24 
25  Author [Fabio Somenzi]
26 
27  Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
28 
29  All rights reserved.
30 
31  Redistribution and use in source and binary forms, with or without
32  modification, are permitted provided that the following conditions
33  are met:
34 
35  Redistributions of source code must retain the above copyright
36  notice, this list of conditions and the following disclaimer.
37 
38  Redistributions in binary form must reproduce the above copyright
39  notice, this list of conditions and the following disclaimer in the
40  documentation and/or other materials provided with the distribution.
41 
42  Neither the name of the University of Colorado nor the names of its
43  contributors may be used to endorse or promote products derived from
44  this software without specific prior written permission.
45 
46  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
47  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
48  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
49  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
50  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
51  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
52  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
53  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
54  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
56  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
57  POSSIBILITY OF SUCH DAMAGE.]
58 
59 ******************************************************************************/
60 
61 #include "misc/util/util_hack.h"
62 #include "cuddInt.h"
63 
65 
66 
67 
68 /*---------------------------------------------------------------------------*/
69 /* Constant declarations */
70 /*---------------------------------------------------------------------------*/
71 
72 
73 /*---------------------------------------------------------------------------*/
74 /* Stucture declarations */
75 /*---------------------------------------------------------------------------*/
76 
77 
78 /*---------------------------------------------------------------------------*/
79 /* Type declarations */
80 /*---------------------------------------------------------------------------*/
81 
82 
83 /*---------------------------------------------------------------------------*/
84 /* Variable declarations */
85 /*---------------------------------------------------------------------------*/
86 
87 #ifndef lint
88 static char rcsid[] DD_UNUSED = "$Id: cuddWindow.c,v 1.14 2009/02/20 02:14:58 fabio Exp $";
89 #endif
90 
91 #ifdef DD_STATS
92 extern int ddTotalNumberSwapping;
93 extern int ddTotalNISwaps;
94 #endif
95 
96 /*---------------------------------------------------------------------------*/
97 /* Macro declarations */
98 /*---------------------------------------------------------------------------*/
99 
100 
101 /**AutomaticStart*************************************************************/
102 
103 /*---------------------------------------------------------------------------*/
104 /* Static function prototypes */
105 /*---------------------------------------------------------------------------*/
106 
107 static int ddWindow2 (DdManager *table, int low, int high);
108 static int ddWindowConv2 (DdManager *table, int low, int high);
109 static int ddPermuteWindow3 (DdManager *table, int x);
110 static int ddWindow3 (DdManager *table, int low, int high);
111 static int ddWindowConv3 (DdManager *table, int low, int high);
112 static int ddPermuteWindow4 (DdManager *table, int w);
113 static int ddWindow4 (DdManager *table, int low, int high);
114 static int ddWindowConv4 (DdManager *table, int low, int high);
115 
116 /**AutomaticEnd***************************************************************/
117 
118 
119 /*---------------------------------------------------------------------------*/
120 /* Definition of exported functions */
121 /*---------------------------------------------------------------------------*/
122 
123 /*---------------------------------------------------------------------------*/
124 /* Definition of internal functions */
125 /*---------------------------------------------------------------------------*/
126 
127 
128 /**Function********************************************************************
129 
130  Synopsis [Reorders by applying the method of the sliding window.]
131 
132  Description [Reorders by applying the method of the sliding window.
133  Tries all possible permutations to the variables in a window that
134  slides from low to high. The size of the window is determined by
135  submethod. Assumes that no dead nodes are present. Returns 1 in
136  case of success; 0 otherwise.]
137 
138  SideEffects [None]
139 
140 ******************************************************************************/
141 int
143  DdManager * table /* DD table */,
144  int low /* lowest index to reorder */,
145  int high /* highest index to reorder */,
146  Cudd_ReorderingType submethod /* window reordering option */)
147 {
148 
149  int res;
150 #ifdef DD_DEBUG
151  int supposedOpt;
152 #endif
153 
154  switch (submethod) {
156  res = ddWindow2(table,low,high);
157  break;
159  res = ddWindow3(table,low,high);
160  break;
162  res = ddWindow4(table,low,high);
163  break;
165  res = ddWindowConv2(table,low,high);
166  break;
168  res = ddWindowConv3(table,low,high);
169 #ifdef DD_DEBUG
170  supposedOpt = table->keys - table->isolated;
171  res = ddWindow3(table,low,high);
172  if (table->keys - table->isolated != (unsigned) supposedOpt) {
173  (void) fprintf(table->err, "Convergence failed! (%d != %d)\n",
174  table->keys - table->isolated, supposedOpt);
175  }
176 #endif
177  break;
179  res = ddWindowConv4(table,low,high);
180 #ifdef DD_DEBUG
181  supposedOpt = table->keys - table->isolated;
182  res = ddWindow4(table,low,high);
183  if (table->keys - table->isolated != (unsigned) supposedOpt) {
184  (void) fprintf(table->err,"Convergence failed! (%d != %d)\n",
185  table->keys - table->isolated, supposedOpt);
186  }
187 #endif
188  break;
189  default: return(0);
190  }
191 
192  return(res);
193 
194 } /* end of cuddWindowReorder */
195 
196 
197 /*---------------------------------------------------------------------------*/
198 /* Definition of static functions */
199 /*---------------------------------------------------------------------------*/
200 
201 /**Function********************************************************************
202 
203  Synopsis [Reorders by applying a sliding window of width 2.]
204 
205  Description [Reorders by applying a sliding window of width 2.
206  Tries both permutations of the variables in a window
207  that slides from low to high. Assumes that no dead nodes are
208  present. Returns 1 in case of success; 0 otherwise.]
209 
210  SideEffects [None]
211 
212 ******************************************************************************/
213 static int
215  DdManager * table,
216  int low,
217  int high)
218 {
219 
220  int x;
221  int res;
222  int size;
223 
224 #ifdef DD_DEBUG
225  assert(low >= 0 && high < table->size);
226 #endif
227 
228  if (high-low < 1) return(0);
229 
230  res = table->keys - table->isolated;
231  for (x = low; x < high; x++) {
232  size = res;
233  res = cuddSwapInPlace(table,x,x+1);
234  if (res == 0) return(0);
235  if (res >= size) { /* no improvement: undo permutation */
236  res = cuddSwapInPlace(table,x,x+1);
237  if (res == 0) return(0);
238  }
239 #ifdef DD_STATS
240  if (res < size) {
241  (void) fprintf(table->out,"-");
242  } else {
243  (void) fprintf(table->out,"=");
244  }
245  fflush(table->out);
246 #endif
247  }
248 
249  return(1);
250 
251 } /* end of ddWindow2 */
252 
253 
254 /**Function********************************************************************
255 
256  Synopsis [Reorders by repeatedly applying a sliding window of width 2.]
257 
258  Description [Reorders by repeatedly applying a sliding window of width
259  2. Tries both permutations of the variables in a window
260  that slides from low to high. Assumes that no dead nodes are
261  present. Uses an event-driven approach to determine convergence.
262  Returns 1 in case of success; 0 otherwise.]
263 
264  SideEffects [None]
265 
266 ******************************************************************************/
267 static int
269  DdManager * table,
270  int low,
271  int high)
272 {
273  int x;
274  int res;
275  int nwin;
276  int newevent;
277  int *events;
278  int size;
279 
280 #ifdef DD_DEBUG
281  assert(low >= 0 && high < table->size);
282 #endif
283 
284  if (high-low < 1) return(ddWindowConv2(table,low,high));
285 
286  nwin = high-low;
287  events = ABC_ALLOC(int,nwin);
288  if (events == NULL) {
289  table->errorCode = CUDD_MEMORY_OUT;
290  return(0);
291  }
292  for (x=0; x<nwin; x++) {
293  events[x] = 1;
294  }
295 
296  res = table->keys - table->isolated;
297  do {
298  newevent = 0;
299  for (x=0; x<nwin; x++) {
300  if (events[x]) {
301  size = res;
302  res = cuddSwapInPlace(table,x+low,x+low+1);
303  if (res == 0) {
304  ABC_FREE(events);
305  return(0);
306  }
307  if (res >= size) { /* no improvement: undo permutation */
308  res = cuddSwapInPlace(table,x+low,x+low+1);
309  if (res == 0) {
310  ABC_FREE(events);
311  return(0);
312  }
313  }
314  if (res < size) {
315  if (x < nwin-1) events[x+1] = 1;
316  if (x > 0) events[x-1] = 1;
317  newevent = 1;
318  }
319  events[x] = 0;
320 #ifdef DD_STATS
321  if (res < size) {
322  (void) fprintf(table->out,"-");
323  } else {
324  (void) fprintf(table->out,"=");
325  }
326  fflush(table->out);
327 #endif
328  }
329  }
330 #ifdef DD_STATS
331  if (newevent) {
332  (void) fprintf(table->out,"|");
333  fflush(table->out);
334  }
335 #endif
336  } while (newevent);
337 
338  ABC_FREE(events);
339 
340  return(1);
341 
342 } /* end of ddWindowConv3 */
343 
344 
345 /**Function********************************************************************
346 
347  Synopsis [Tries all the permutations of the three variables between
348  x and x+2 and retains the best.]
349 
350  Description [Tries all the permutations of the three variables between
351  x and x+2 and retains the best. Assumes that no dead nodes are
352  present. Returns the index of the best permutation (1-6) in case of
353  success; 0 otherwise.Assumes that no dead nodes are present. Returns
354  the index of the best permutation (1-6) in case of success; 0
355  otherwise.]
356 
357  SideEffects [None]
358 
359 ******************************************************************************/
360 static int
362  DdManager * table,
363  int x)
364 {
365  int y,z;
366  int size,sizeNew;
367  int best;
368 
369 #ifdef DD_DEBUG
370  assert(table->dead == 0);
371  assert(x+2 < table->size);
372 #endif
373 
374  size = table->keys - table->isolated;
375  y = x+1; z = y+1;
376 
377  /* The permutation pattern is:
378  ** (x,y)(y,z)
379  ** repeated three times to get all 3! = 6 permutations.
380  */
381 #define ABC 1
382  best = ABC;
383 
384 #define BAC 2
385  sizeNew = cuddSwapInPlace(table,x,y);
386  if (sizeNew < size) {
387  if (sizeNew == 0) return(0);
388  best = BAC;
389  size = sizeNew;
390  }
391 #define BCA 3
392  sizeNew = cuddSwapInPlace(table,y,z);
393  if (sizeNew < size) {
394  if (sizeNew == 0) return(0);
395  best = BCA;
396  size = sizeNew;
397  }
398 #define CBA 4
399  sizeNew = cuddSwapInPlace(table,x,y);
400  if (sizeNew < size) {
401  if (sizeNew == 0) return(0);
402  best = CBA;
403  size = sizeNew;
404  }
405 #define CAB 5
406  sizeNew = cuddSwapInPlace(table,y,z);
407  if (sizeNew < size) {
408  if (sizeNew == 0) return(0);
409  best = CAB;
410  size = sizeNew;
411  }
412 #define ACB 6
413  sizeNew = cuddSwapInPlace(table,x,y);
414  if (sizeNew < size) {
415  if (sizeNew == 0) return(0);
416  best = ACB;
417  size = sizeNew;
418  }
419 
420  /* Now take the shortest route to the best permuytation.
421  ** The initial permutation is ACB.
422  */
423  switch(best) {
424  case BCA: if (!cuddSwapInPlace(table,y,z)) return(0);
425  case CBA: if (!cuddSwapInPlace(table,x,y)) return(0);
426  case ABC: if (!cuddSwapInPlace(table,y,z)) return(0);
427  case ACB: break;
428  case BAC: if (!cuddSwapInPlace(table,y,z)) return(0);
429  case CAB: if (!cuddSwapInPlace(table,x,y)) return(0);
430  break;
431  default: return(0);
432  }
433 
434 #ifdef DD_DEBUG
435  assert(table->keys - table->isolated == (unsigned) size);
436 #endif
437 
438  return(best);
439 
440 } /* end of ddPermuteWindow3 */
441 
442 
443 /**Function********************************************************************
444 
445  Synopsis [Reorders by applying a sliding window of width 3.]
446 
447  Description [Reorders by applying a sliding window of width 3.
448  Tries all possible permutations to the variables in a
449  window that slides from low to high. Assumes that no dead nodes are
450  present. Returns 1 in case of success; 0 otherwise.]
451 
452  SideEffects [None]
453 
454 ******************************************************************************/
455 static int
457  DdManager * table,
458  int low,
459  int high)
460 {
461 
462  int x;
463  int res;
464 
465 #ifdef DD_DEBUG
466  assert(low >= 0 && high < table->size);
467 #endif
468 
469  if (high-low < 2) return(ddWindow2(table,low,high));
470 
471  for (x = low; x+1 < high; x++) {
472  res = ddPermuteWindow3(table,x);
473  if (res == 0) return(0);
474 #ifdef DD_STATS
475  if (res == ABC) {
476  (void) fprintf(table->out,"=");
477  } else {
478  (void) fprintf(table->out,"-");
479  }
480  fflush(table->out);
481 #endif
482  }
483 
484  return(1);
485 
486 } /* end of ddWindow3 */
487 
488 
489 /**Function********************************************************************
490 
491  Synopsis [Reorders by repeatedly applying a sliding window of width 3.]
492 
493  Description [Reorders by repeatedly applying a sliding window of width
494  3. Tries all possible permutations to the variables in a
495  window that slides from low to high. Assumes that no dead nodes are
496  present. Uses an event-driven approach to determine convergence.
497  Returns 1 in case of success; 0 otherwise.]
498 
499  SideEffects [None]
500 
501 ******************************************************************************/
502 static int
504  DdManager * table,
505  int low,
506  int high)
507 {
508  int x;
509  int res;
510  int nwin;
511  int newevent;
512  int *events;
513 
514 #ifdef DD_DEBUG
515  assert(low >= 0 && high < table->size);
516 #endif
517 
518  if (high-low < 2) return(ddWindowConv2(table,low,high));
519 
520  nwin = high-low-1;
521  events = ABC_ALLOC(int,nwin);
522  if (events == NULL) {
523  table->errorCode = CUDD_MEMORY_OUT;
524  return(0);
525  }
526  for (x=0; x<nwin; x++) {
527  events[x] = 1;
528  }
529 
530  do {
531  newevent = 0;
532  for (x=0; x<nwin; x++) {
533  if (events[x]) {
534  res = ddPermuteWindow3(table,x+low);
535  switch (res) {
536  case ABC:
537  break;
538  case BAC:
539  if (x < nwin-1) events[x+1] = 1;
540  if (x > 1) events[x-2] = 1;
541  newevent = 1;
542  break;
543  case BCA:
544  case CBA:
545  case CAB:
546  if (x < nwin-2) events[x+2] = 1;
547  if (x < nwin-1) events[x+1] = 1;
548  if (x > 0) events[x-1] = 1;
549  if (x > 1) events[x-2] = 1;
550  newevent = 1;
551  break;
552  case ACB:
553  if (x < nwin-2) events[x+2] = 1;
554  if (x > 0) events[x-1] = 1;
555  newevent = 1;
556  break;
557  default:
558  ABC_FREE(events);
559  return(0);
560  }
561  events[x] = 0;
562 #ifdef DD_STATS
563  if (res == ABC) {
564  (void) fprintf(table->out,"=");
565  } else {
566  (void) fprintf(table->out,"-");
567  }
568  fflush(table->out);
569 #endif
570  }
571  }
572 #ifdef DD_STATS
573  if (newevent) {
574  (void) fprintf(table->out,"|");
575  fflush(table->out);
576  }
577 #endif
578  } while (newevent);
579 
580  ABC_FREE(events);
581 
582  return(1);
583 
584 } /* end of ddWindowConv3 */
585 
586 
587 /**Function********************************************************************
588 
589  Synopsis [Tries all the permutations of the four variables between w
590  and w+3 and retains the best.]
591 
592  Description [Tries all the permutations of the four variables between
593  w and w+3 and retains the best. Assumes that no dead nodes are
594  present. Returns the index of the best permutation (1-24) in case of
595  success; 0 otherwise.]
596 
597  SideEffects [None]
598 
599 ******************************************************************************/
600 static int
602  DdManager * table,
603  int w)
604 {
605  int x,y,z;
606  int size,sizeNew;
607  int best;
608 
609 #ifdef DD_DEBUG
610  assert(table->dead == 0);
611  assert(w+3 < table->size);
612 #endif
613 
614  size = table->keys - table->isolated;
615  x = w+1; y = x+1; z = y+1;
616 
617  /* The permutation pattern is:
618  * (w,x)(y,z)(w,x)(x,y)
619  * (y,z)(w,x)(y,z)(x,y)
620  * repeated three times to get all 4! = 24 permutations.
621  * This gives a hamiltonian circuit of Cayley's graph.
622  * The codes to the permutation are assigned in topological order.
623  * The permutations at lower distance from the final permutation are
624  * assigned lower codes. This way we can choose, between
625  * permutations that give the same size, one that requires the minimum
626  * number of swaps from the final permutation of the hamiltonian circuit.
627  * There is an exception to this rule: ABCD is given Code 1, to
628  * avoid oscillation when convergence is sought.
629  */
630 #define ABCD 1
631  best = ABCD;
632 
633 #define BACD 7
634  sizeNew = cuddSwapInPlace(table,w,x);
635  if (sizeNew < size) {
636  if (sizeNew == 0) return(0);
637  best = BACD;
638  size = sizeNew;
639  }
640 #define BADC 13
641  sizeNew = cuddSwapInPlace(table,y,z);
642  if (sizeNew < size) {
643  if (sizeNew == 0) return(0);
644  best = BADC;
645  size = sizeNew;
646  }
647 #define ABDC 8
648  sizeNew = cuddSwapInPlace(table,w,x);
649  if (sizeNew < size || (sizeNew == size && ABDC < best)) {
650  if (sizeNew == 0) return(0);
651  best = ABDC;
652  size = sizeNew;
653  }
654 #define ADBC 14
655  sizeNew = cuddSwapInPlace(table,x,y);
656  if (sizeNew < size) {
657  if (sizeNew == 0) return(0);
658  best = ADBC;
659  size = sizeNew;
660  }
661 #define ADCB 9
662  sizeNew = cuddSwapInPlace(table,y,z);
663  if (sizeNew < size || (sizeNew == size && ADCB < best)) {
664  if (sizeNew == 0) return(0);
665  best = ADCB;
666  size = sizeNew;
667  }
668 #define DACB 15
669  sizeNew = cuddSwapInPlace(table,w,x);
670  if (sizeNew < size) {
671  if (sizeNew == 0) return(0);
672  best = DACB;
673  size = sizeNew;
674  }
675 #define DABC 20
676  sizeNew = cuddSwapInPlace(table,y,z);
677  if (sizeNew < size) {
678  if (sizeNew == 0) return(0);
679  best = DABC;
680  size = sizeNew;
681  }
682 #define DBAC 23
683  sizeNew = cuddSwapInPlace(table,x,y);
684  if (sizeNew < size) {
685  if (sizeNew == 0) return(0);
686  best = DBAC;
687  size = sizeNew;
688  }
689 #define BDAC 19
690  sizeNew = cuddSwapInPlace(table,w,x);
691  if (sizeNew < size || (sizeNew == size && BDAC < best)) {
692  if (sizeNew == 0) return(0);
693  best = BDAC;
694  size = sizeNew;
695  }
696 #define BDCA 21
697  sizeNew = cuddSwapInPlace(table,y,z);
698  if (sizeNew < size || (sizeNew == size && BDCA < best)) {
699  if (sizeNew == 0) return(0);
700  best = BDCA;
701  size = sizeNew;
702  }
703 #define DBCA 24
704  sizeNew = cuddSwapInPlace(table,w,x);
705  if (sizeNew < size) {
706  if (sizeNew == 0) return(0);
707  best = DBCA;
708  size = sizeNew;
709  }
710 #define DCBA 22
711  sizeNew = cuddSwapInPlace(table,x,y);
712  if (sizeNew < size || (sizeNew == size && DCBA < best)) {
713  if (sizeNew == 0) return(0);
714  best = DCBA;
715  size = sizeNew;
716  }
717 #define DCAB 18
718  sizeNew = cuddSwapInPlace(table,y,z);
719  if (sizeNew < size || (sizeNew == size && DCAB < best)) {
720  if (sizeNew == 0) return(0);
721  best = DCAB;
722  size = sizeNew;
723  }
724 #define CDAB 12
725  sizeNew = cuddSwapInPlace(table,w,x);
726  if (sizeNew < size || (sizeNew == size && CDAB < best)) {
727  if (sizeNew == 0) return(0);
728  best = CDAB;
729  size = sizeNew;
730  }
731 #define CDBA 17
732  sizeNew = cuddSwapInPlace(table,y,z);
733  if (sizeNew < size || (sizeNew == size && CDBA < best)) {
734  if (sizeNew == 0) return(0);
735  best = CDBA;
736  size = sizeNew;
737  }
738 #define CBDA 11
739  sizeNew = cuddSwapInPlace(table,x,y);
740  if (sizeNew < size || (sizeNew == size && CBDA < best)) {
741  if (sizeNew == 0) return(0);
742  best = CBDA;
743  size = sizeNew;
744  }
745 #define BCDA 16
746  sizeNew = cuddSwapInPlace(table,w,x);
747  if (sizeNew < size || (sizeNew == size && BCDA < best)) {
748  if (sizeNew == 0) return(0);
749  best = BCDA;
750  size = sizeNew;
751  }
752 #define BCAD 10
753  sizeNew = cuddSwapInPlace(table,y,z);
754  if (sizeNew < size || (sizeNew == size && BCAD < best)) {
755  if (sizeNew == 0) return(0);
756  best = BCAD;
757  size = sizeNew;
758  }
759 #define CBAD 5
760  sizeNew = cuddSwapInPlace(table,w,x);
761  if (sizeNew < size || (sizeNew == size && CBAD < best)) {
762  if (sizeNew == 0) return(0);
763  best = CBAD;
764  size = sizeNew;
765  }
766 #define CABD 3
767  sizeNew = cuddSwapInPlace(table,x,y);
768  if (sizeNew < size || (sizeNew == size && CABD < best)) {
769  if (sizeNew == 0) return(0);
770  best = CABD;
771  size = sizeNew;
772  }
773 #define CADB 6
774  sizeNew = cuddSwapInPlace(table,y,z);
775  if (sizeNew < size || (sizeNew == size && CADB < best)) {
776  if (sizeNew == 0) return(0);
777  best = CADB;
778  size = sizeNew;
779  }
780 #define ACDB 4
781  sizeNew = cuddSwapInPlace(table,w,x);
782  if (sizeNew < size || (sizeNew == size && ACDB < best)) {
783  if (sizeNew == 0) return(0);
784  best = ACDB;
785  size = sizeNew;
786  }
787 #define ACBD 2
788  sizeNew = cuddSwapInPlace(table,y,z);
789  if (sizeNew < size || (sizeNew == size && ACBD < best)) {
790  if (sizeNew == 0) return(0);
791  best = ACBD;
792  size = sizeNew;
793  }
794 
795  /* Now take the shortest route to the best permutation.
796  ** The initial permutation is ACBD.
797  */
798  switch(best) {
799  case DBCA: if (!cuddSwapInPlace(table,y,z)) return(0);
800  case BDCA: if (!cuddSwapInPlace(table,x,y)) return(0);
801  case CDBA: if (!cuddSwapInPlace(table,w,x)) return(0);
802  case ADBC: if (!cuddSwapInPlace(table,y,z)) return(0);
803  case ABDC: if (!cuddSwapInPlace(table,x,y)) return(0);
804  case ACDB: if (!cuddSwapInPlace(table,y,z)) return(0);
805  case ACBD: break;
806  case DCBA: if (!cuddSwapInPlace(table,y,z)) return(0);
807  case BCDA: if (!cuddSwapInPlace(table,x,y)) return(0);
808  case CBDA: if (!cuddSwapInPlace(table,w,x)) return(0);
809  if (!cuddSwapInPlace(table,x,y)) return(0);
810  if (!cuddSwapInPlace(table,y,z)) return(0);
811  break;
812  case DBAC: if (!cuddSwapInPlace(table,x,y)) return(0);
813  case DCAB: if (!cuddSwapInPlace(table,w,x)) return(0);
814  case DACB: if (!cuddSwapInPlace(table,y,z)) return(0);
815  case BACD: if (!cuddSwapInPlace(table,x,y)) return(0);
816  case CABD: if (!cuddSwapInPlace(table,w,x)) return(0);
817  break;
818  case DABC: if (!cuddSwapInPlace(table,y,z)) return(0);
819  case BADC: if (!cuddSwapInPlace(table,x,y)) return(0);
820  case CADB: if (!cuddSwapInPlace(table,w,x)) return(0);
821  if (!cuddSwapInPlace(table,y,z)) return(0);
822  break;
823  case BDAC: if (!cuddSwapInPlace(table,x,y)) return(0);
824  case CDAB: if (!cuddSwapInPlace(table,w,x)) return(0);
825  case ADCB: if (!cuddSwapInPlace(table,y,z)) return(0);
826  case ABCD: if (!cuddSwapInPlace(table,x,y)) return(0);
827  break;
828  case BCAD: if (!cuddSwapInPlace(table,x,y)) return(0);
829  case CBAD: if (!cuddSwapInPlace(table,w,x)) return(0);
830  if (!cuddSwapInPlace(table,x,y)) return(0);
831  break;
832  default: return(0);
833  }
834 
835 #ifdef DD_DEBUG
836  assert(table->keys - table->isolated == (unsigned) size);
837 #endif
838 
839  return(best);
840 
841 } /* end of ddPermuteWindow4 */
842 
843 
844 /**Function********************************************************************
845 
846  Synopsis [Reorders by applying a sliding window of width 4.]
847 
848  Description [Reorders by applying a sliding window of width 4.
849  Tries all possible permutations to the variables in a
850  window that slides from low to high. Assumes that no dead nodes are
851  present. Returns 1 in case of success; 0 otherwise.]
852 
853  SideEffects [None]
854 
855 ******************************************************************************/
856 static int
858  DdManager * table,
859  int low,
860  int high)
861 {
862 
863  int w;
864  int res;
865 
866 #ifdef DD_DEBUG
867  assert(low >= 0 && high < table->size);
868 #endif
869 
870  if (high-low < 3) return(ddWindow3(table,low,high));
871 
872  for (w = low; w+2 < high; w++) {
873  res = ddPermuteWindow4(table,w);
874  if (res == 0) return(0);
875 #ifdef DD_STATS
876  if (res == ABCD) {
877  (void) fprintf(table->out,"=");
878  } else {
879  (void) fprintf(table->out,"-");
880  }
881  fflush(table->out);
882 #endif
883  }
884 
885  return(1);
886 
887 } /* end of ddWindow4 */
888 
889 
890 /**Function********************************************************************
891 
892  Synopsis [Reorders by repeatedly applying a sliding window of width 4.]
893 
894  Description [Reorders by repeatedly applying a sliding window of width
895  4. Tries all possible permutations to the variables in a
896  window that slides from low to high. Assumes that no dead nodes are
897  present. Uses an event-driven approach to determine convergence.
898  Returns 1 in case of success; 0 otherwise.]
899 
900  SideEffects [None]
901 
902 ******************************************************************************/
903 static int
905  DdManager * table,
906  int low,
907  int high)
908 {
909  int x;
910  int res;
911  int nwin;
912  int newevent;
913  int *events;
914 
915 #ifdef DD_DEBUG
916  assert(low >= 0 && high < table->size);
917 #endif
918 
919  if (high-low < 3) return(ddWindowConv3(table,low,high));
920 
921  nwin = high-low-2;
922  events = ABC_ALLOC(int,nwin);
923  if (events == NULL) {
924  table->errorCode = CUDD_MEMORY_OUT;
925  return(0);
926  }
927  for (x=0; x<nwin; x++) {
928  events[x] = 1;
929  }
930 
931  do {
932  newevent = 0;
933  for (x=0; x<nwin; x++) {
934  if (events[x]) {
935  res = ddPermuteWindow4(table,x+low);
936  switch (res) {
937  case ABCD:
938  break;
939  case BACD:
940  if (x < nwin-1) events[x+1] = 1;
941  if (x > 2) events[x-3] = 1;
942  newevent = 1;
943  break;
944  case BADC:
945  if (x < nwin-3) events[x+3] = 1;
946  if (x < nwin-1) events[x+1] = 1;
947  if (x > 0) events[x-1] = 1;
948  if (x > 2) events[x-3] = 1;
949  newevent = 1;
950  break;
951  case ABDC:
952  if (x < nwin-3) events[x+3] = 1;
953  if (x > 0) events[x-1] = 1;
954  newevent = 1;
955  break;
956  case ADBC:
957  case ADCB:
958  case ACDB:
959  if (x < nwin-3) events[x+3] = 1;
960  if (x < nwin-2) events[x+2] = 1;
961  if (x > 0) events[x-1] = 1;
962  if (x > 1) events[x-2] = 1;
963  newevent = 1;
964  break;
965  case DACB:
966  case DABC:
967  case DBAC:
968  case BDAC:
969  case BDCA:
970  case DBCA:
971  case DCBA:
972  case DCAB:
973  case CDAB:
974  case CDBA:
975  case CBDA:
976  case BCDA:
977  case CADB:
978  if (x < nwin-3) events[x+3] = 1;
979  if (x < nwin-2) events[x+2] = 1;
980  if (x < nwin-1) events[x+1] = 1;
981  if (x > 0) events[x-1] = 1;
982  if (x > 1) events[x-2] = 1;
983  if (x > 2) events[x-3] = 1;
984  newevent = 1;
985  break;
986  case BCAD:
987  case CBAD:
988  case CABD:
989  if (x < nwin-2) events[x+2] = 1;
990  if (x < nwin-1) events[x+1] = 1;
991  if (x > 1) events[x-2] = 1;
992  if (x > 2) events[x-3] = 1;
993  newevent = 1;
994  break;
995  case ACBD:
996  if (x < nwin-2) events[x+2] = 1;
997  if (x > 1) events[x-2] = 1;
998  newevent = 1;
999  break;
1000  default:
1001  ABC_FREE(events);
1002  return(0);
1003  }
1004  events[x] = 0;
1005 #ifdef DD_STATS
1006  if (res == ABCD) {
1007  (void) fprintf(table->out,"=");
1008  } else {
1009  (void) fprintf(table->out,"-");
1010  }
1011  fflush(table->out);
1012 #endif
1013  }
1014  }
1015 #ifdef DD_STATS
1016  if (newevent) {
1017  (void) fprintf(table->out,"|");
1018  fflush(table->out);
1019  }
1020 #endif
1021  } while (newevent);
1022 
1023  ABC_FREE(events);
1024 
1025  return(1);
1026 
1027 } /* end of ddWindowConv4 */
1028 
1029 
1031 
static int ddPermuteWindow3(DdManager *table, int x)
Definition: cuddWindow.c:361
#define CADB
#define DACB
static int ddWindow2(DdManager *table, int low, int high)
Definition: cuddWindow.c:214
static int ddWindow4(DdManager *table, int low, int high)
Definition: cuddWindow.c:857
static int ddWindow3(DdManager *table, int low, int high)
Definition: cuddWindow.c:456
int size
Definition: cuddInt.h:361
#define BCAD
#define BAC
static int ddWindowConv2(DdManager *table, int low, int high)
Definition: cuddWindow.c:268
FILE * err
Definition: cuddInt.h:442
static int ddWindowConv4(DdManager *table, int low, int high)
Definition: cuddWindow.c:904
#define ADCB
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
static int ddPermuteWindow4(DdManager *table, int w)
Definition: cuddWindow.c:601
#define DCBA
#define ABDC
int cuddWindowReorder(DdManager *table, int low, int high, Cudd_ReorderingType submethod)
Definition: cuddWindow.c:142
unsigned int dead
Definition: cuddInt.h:371
static ABC_NAMESPACE_IMPL_START char rcsid[] DD_UNUSED
Definition: cuddWindow.c:88
int ddTotalNumberSwapping
Definition: cuddReorder.c:107
#define BCA
#define BDCA
#define CAB
#define DCAB
unsigned int keys
Definition: cuddInt.h:369
FILE * out
Definition: cuddInt.h:441
#define BCDA
#define CDBA
#define ACBD
#define ADBC
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
#define CBDA
static int size
Definition: cuddSign.c:86
#define DBAC
#define ABC
#define BDAC
#define CDAB
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
#define DBCA
#define CBAD
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddReorder.c:761
#define ABC_FREE(obj)
Definition: abc_global.h:232
#define ACB
#define CABD
#define assert(ex)
Definition: util_old.h:213
int isolated
Definition: cuddInt.h:385
#define ABCD
#define BACD
#define BADC
#define CBA
Cudd_ReorderingType
Definition: cudd.h:151
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
static int ddWindowConv3(DdManager *table, int low, int high)
Definition: cuddWindow.c:503
#define ACDB
#define DABC