abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddLinear.c
Go to the documentation of this file.
1 /**CFile***********************************************************************
2 
3  FileName [cuddLinear.c]
4 
5  PackageName [cudd]
6 
7  Synopsis [Functions for DD reduction by linear transformations.]
8 
9  Description [ Internal procedures included in this module:
10  <ul>
11  <li> cuddLinearAndSifting()
12  <li> cuddLinearInPlace()
13  <li> cuddUpdateInteractionMatrix()
14  <li> cuddInitLinear()
15  <li> cuddResizeLinear()
16  </ul>
17  Static procedures included in this module:
18  <ul>
19  <li> ddLinearUniqueCompare()
20  <li> ddLinearAndSiftingAux()
21  <li> ddLinearAndSiftingUp()
22  <li> ddLinearAndSiftingDown()
23  <li> ddLinearAndSiftingBackward()
24  <li> ddUndoMoves()
25  <li> cuddXorLinear()
26  </ul>]
27 
28  Author [Fabio Somenzi]
29 
30  Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
31 
32  All rights reserved.
33 
34  Redistribution and use in source and binary forms, with or without
35  modification, are permitted provided that the following conditions
36  are met:
37 
38  Redistributions of source code must retain the above copyright
39  notice, this list of conditions and the following disclaimer.
40 
41  Redistributions in binary form must reproduce the above copyright
42  notice, this list of conditions and the following disclaimer in the
43  documentation and/or other materials provided with the distribution.
44 
45  Neither the name of the University of Colorado nor the names of its
46  contributors may be used to endorse or promote products derived from
47  this software without specific prior written permission.
48 
49  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
50  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
51  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
52  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
53  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
54  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
55  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
56  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
57  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
59  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
60  POSSIBILITY OF SUCH DAMAGE.]
61 
62 ******************************************************************************/
63 
64 #include "misc/util/util_hack.h"
65 #include "cuddInt.h"
66 
68 
69 
70 
71 /*---------------------------------------------------------------------------*/
72 /* Constant declarations */
73 /*---------------------------------------------------------------------------*/
74 
75 #define CUDD_SWAP_MOVE 0
76 #define CUDD_LINEAR_TRANSFORM_MOVE 1
77 #define CUDD_INVERSE_TRANSFORM_MOVE 2
78 #if SIZEOF_LONG == 8
79 #define BPL 64
80 #define LOGBPL 6
81 #else
82 #define BPL 32
83 #define LOGBPL 5
84 #endif
85 
86 /*---------------------------------------------------------------------------*/
87 /* Stucture declarations */
88 /*---------------------------------------------------------------------------*/
89 
90 /*---------------------------------------------------------------------------*/
91 /* Type declarations */
92 /*---------------------------------------------------------------------------*/
93 
94 /*---------------------------------------------------------------------------*/
95 /* Variable declarations */
96 /*---------------------------------------------------------------------------*/
97 
98 #ifndef lint
99 static char rcsid[] DD_UNUSED = "$Id: cuddLinear.c,v 1.28 2009/02/19 16:21:03 fabio Exp $";
100 #endif
101 
102 static int *entry;
103 
104 #ifdef DD_STATS
105 extern int ddTotalNumberSwapping;
106 extern int ddTotalNISwaps;
107 static int ddTotalNumberLinearTr;
108 #endif
109 
110 #ifdef DD_DEBUG
111 static int zero = 0;
112 #endif
113 
114 /*---------------------------------------------------------------------------*/
115 /* Macro declarations */
116 /*---------------------------------------------------------------------------*/
117 
118 /**AutomaticStart*************************************************************/
119 
120 /*---------------------------------------------------------------------------*/
121 /* Static function prototypes */
122 /*---------------------------------------------------------------------------*/
123 
124 static int ddLinearUniqueCompare (int *ptrX, int *ptrY);
125 static int ddLinearAndSiftingAux (DdManager *table, int x, int xLow, int xHigh);
126 static Move * ddLinearAndSiftingUp (DdManager *table, int y, int xLow, Move *prevMoves);
127 static Move * ddLinearAndSiftingDown (DdManager *table, int x, int xHigh, Move *prevMoves);
128 static int ddLinearAndSiftingBackward (DdManager *table, int size, Move *moves);
129 static Move* ddUndoMoves (DdManager *table, Move *moves);
130 static void cuddXorLinear (DdManager *table, int x, int y);
131 
132 /**AutomaticEnd***************************************************************/
133 
134 
135 /*---------------------------------------------------------------------------*/
136 /* Definition of exported functions */
137 /*---------------------------------------------------------------------------*/
138 
139 
140 /**Function********************************************************************
141 
142  Synopsis [Prints the linear transform matrix.]
143 
144  Description [Prints the linear transform matrix. Returns 1 in case of
145  success; 0 otherwise.]
146 
147  SideEffects [none]
148 
149  SeeAlso []
150 
151 ******************************************************************************/
152 int
154  DdManager * table)
155 {
156  int i,j,k;
157  int retval;
158  int nvars = table->linearSize;
159  int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
160  long word;
161 
162  for (i = 0; i < nvars; i++) {
163  for (j = 0; j < wordsPerRow; j++) {
164  word = table->linear[i*wordsPerRow + j];
165  for (k = 0; k < BPL; k++) {
166  retval = fprintf(table->out,"%ld",word & 1);
167  if (retval == 0) return(0);
168  word >>= 1;
169  }
170  }
171  retval = fprintf(table->out,"\n");
172  if (retval == 0) return(0);
173  }
174  return(1);
175 
176 } /* end of Cudd_PrintLinear */
177 
178 
179 /**Function********************************************************************
180 
181  Synopsis [Reads an entry of the linear transform matrix.]
182 
183  Description [Reads an entry of the linear transform matrix.]
184 
185  SideEffects [none]
186 
187  SeeAlso []
188 
189 ******************************************************************************/
190 int
192  DdManager * table /* CUDD manager */,
193  int x /* row index */,
194  int y /* column index */)
195 {
196  int nvars = table->size;
197  int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
198  long word;
199  int bit;
200  int result;
201 
202  assert(table->size == table->linearSize);
203 
204  word = wordsPerRow * x + (y >> LOGBPL);
205  bit = y & (BPL-1);
206  result = (int) ((table->linear[word] >> bit) & 1);
207  return(result);
208 
209 } /* end of Cudd_ReadLinear */
210 
211 
212 /*---------------------------------------------------------------------------*/
213 /* Definition of internal functions */
214 /*---------------------------------------------------------------------------*/
215 
216 
217 /**Function********************************************************************
218 
219  Synopsis [BDD reduction based on combination of sifting and linear
220  transformations.]
221 
222  Description [BDD reduction based on combination of sifting and linear
223  transformations. Assumes that no dead nodes are present.
224  <ol>
225  <li> Order all the variables according to the number of entries
226  in each unique table.
227  <li> Sift the variable up and down, remembering each time the
228  total size of the DD heap. At each position, linear transformation
229  of the two adjacent variables is tried and is accepted if it reduces
230  the size of the DD.
231  <li> Select the best permutation.
232  <li> Repeat 3 and 4 for all variables.
233  </ol>
234  Returns 1 if successful; 0 otherwise.]
235 
236  SideEffects [None]
237 
238 ******************************************************************************/
239 int
241  DdManager * table,
242  int lower,
243  int upper)
244 {
245  int i;
246  int *var;
247  int size;
248  int x;
249  int result;
250 #ifdef DD_STATS
251  int previousSize;
252 #endif
253 
254 #ifdef DD_STATS
255  ddTotalNumberLinearTr = 0;
256 #endif
257 
258  size = table->size;
259 
260  var = NULL;
261  entry = NULL;
262  if (table->linear == NULL) {
263  result = cuddInitLinear(table);
264  if (result == 0) goto cuddLinearAndSiftingOutOfMem;
265 #if 0
266  (void) fprintf(table->out,"\n");
267  result = Cudd_PrintLinear(table);
268  if (result == 0) goto cuddLinearAndSiftingOutOfMem;
269 #endif
270  } else if (table->size != table->linearSize) {
271  result = cuddResizeLinear(table);
272  if (result == 0) goto cuddLinearAndSiftingOutOfMem;
273 #if 0
274  (void) fprintf(table->out,"\n");
275  result = Cudd_PrintLinear(table);
276  if (result == 0) goto cuddLinearAndSiftingOutOfMem;
277 #endif
278  }
279 
280  /* Find order in which to sift variables. */
281  entry = ABC_ALLOC(int,size);
282  if (entry == NULL) {
283  table->errorCode = CUDD_MEMORY_OUT;
284  goto cuddLinearAndSiftingOutOfMem;
285  }
286  var = ABC_ALLOC(int,size);
287  if (var == NULL) {
288  table->errorCode = CUDD_MEMORY_OUT;
289  goto cuddLinearAndSiftingOutOfMem;
290  }
291 
292  for (i = 0; i < size; i++) {
293  x = table->perm[i];
294  entry[i] = table->subtables[x].keys;
295  var[i] = i;
296  }
297 
298  qsort((void *)var,size,sizeof(int),(DD_QSFP)ddLinearUniqueCompare);
299 
300  /* Now sift. */
301  for (i = 0; i < ddMin(table->siftMaxVar,size); i++) {
302  x = table->perm[var[i]];
303  if (x < lower || x > upper) continue;
304 #ifdef DD_STATS
305  previousSize = table->keys - table->isolated;
306 #endif
307  result = ddLinearAndSiftingAux(table,x,lower,upper);
308  if (!result) goto cuddLinearAndSiftingOutOfMem;
309 #ifdef DD_STATS
310  if (table->keys < (unsigned) previousSize + table->isolated) {
311  (void) fprintf(table->out,"-");
312  } else if (table->keys > (unsigned) previousSize + table->isolated) {
313  (void) fprintf(table->out,"+"); /* should never happen */
314  (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]);
315  } else {
316  (void) fprintf(table->out,"=");
317  }
318  fflush(table->out);
319 #endif
320 #ifdef DD_DEBUG
321  (void) Cudd_DebugCheck(table);
322 #endif
323  }
324 
325  ABC_FREE(var);
326  ABC_FREE(entry);
327 
328 #ifdef DD_STATS
329  (void) fprintf(table->out,"\n#:L_LINSIFT %8d: linear trans.",
330  ddTotalNumberLinearTr);
331 #endif
332 
333  return(1);
334 
335 cuddLinearAndSiftingOutOfMem:
336 
337  if (entry != NULL) ABC_FREE(entry);
338  if (var != NULL) ABC_FREE(var);
339 
340  return(0);
341 
342 } /* end of cuddLinearAndSifting */
343 
344 
345 /**Function********************************************************************
346 
347  Synopsis [Linearly combines two adjacent variables.]
348 
349  Description [Linearly combines two adjacent variables. Specifically,
350  replaces the top variable with the exclusive nor of the two variables.
351  It assumes that no dead nodes are present on entry to this
352  procedure. The procedure then guarantees that no dead nodes will be
353  present when it terminates. cuddLinearInPlace assumes that x &lt;
354  y. Returns the number of keys in the table if successful; 0
355  otherwise.]
356 
357  SideEffects [The two subtables corrresponding to variables x and y are
358  modified. The global counters of the unique table are also affected.]
359 
360  SeeAlso [cuddSwapInPlace]
361 
362 ******************************************************************************/
363 int
365  DdManager * table,
366  int x,
367  int y)
368 {
369  DdNodePtr *xlist, *ylist;
370  int xindex, yindex;
371  int xslots, yslots;
372  int xshift, yshift;
373  int oldxkeys, oldykeys;
374  int newxkeys, newykeys;
375  int comple, newcomplement;
376  int i;
377  int posn;
378  int isolated;
379  DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10,*newf1,*newf0;
380  DdNode *g,*next,*last=NULL;
381  DdNodePtr *previousP;
382  DdNode *tmp;
383  DdNode *sentinel = &(table->sentinel);
384 #ifdef DD_DEBUG
385  int count, idcheck;
386 #endif
387 
388 #ifdef DD_DEBUG
389  assert(x < y);
390  assert(cuddNextHigh(table,x) == y);
391  assert(table->subtables[x].keys != 0);
392  assert(table->subtables[y].keys != 0);
393  assert(table->subtables[x].dead == 0);
394  assert(table->subtables[y].dead == 0);
395 #endif
396 
397  xindex = table->invperm[x];
398  yindex = table->invperm[y];
399 
400  if (cuddTestInteract(table,xindex,yindex)) {
401 #ifdef DD_STATS
402  ddTotalNumberLinearTr++;
403 #endif
404  /* Get parameters of x subtable. */
405  xlist = table->subtables[x].nodelist;
406  oldxkeys = table->subtables[x].keys;
407  xslots = table->subtables[x].slots;
408  xshift = table->subtables[x].shift;
409 
410  /* Get parameters of y subtable. */
411  ylist = table->subtables[y].nodelist;
412  oldykeys = table->subtables[y].keys;
413  yslots = table->subtables[y].slots;
414  yshift = table->subtables[y].shift;
415 
416  newxkeys = 0;
417  newykeys = oldykeys;
418 
419  /* Check whether the two projection functions involved in this
420  ** swap are isolated. At the end, we'll be able to tell how many
421  ** isolated projection functions are there by checking only these
422  ** two functions again. This is done to eliminate the isolated
423  ** projection functions from the node count.
424  */
425  isolated = - ((table->vars[xindex]->ref == 1) +
426  (table->vars[yindex]->ref == 1));
427 
428  /* The nodes in the x layer are put in a chain.
429  ** The chain is handled as a FIFO; g points to the beginning and
430  ** last points to the end.
431  */
432  g = NULL;
433 #ifdef DD_DEBUG
434  last = NULL;
435 #endif
436  for (i = 0; i < xslots; i++) {
437  f = xlist[i];
438  if (f == sentinel) continue;
439  xlist[i] = sentinel;
440  if (g == NULL) {
441  g = f;
442  } else {
443  last->next = f;
444  }
445  while ((next = f->next) != sentinel) {
446  f = next;
447  } /* while there are elements in the collision chain */
448  last = f;
449  } /* for each slot of the x subtable */
450 #ifdef DD_DEBUG
451  /* last is always assigned in the for loop because there is at
452  ** least one key */
453  assert(last != NULL);
454 #endif
455  last->next = NULL;
456 
457 #ifdef DD_COUNT
458  table->swapSteps += oldxkeys;
459 #endif
460  /* Take care of the x nodes that must be re-expressed.
461  ** They form a linked list pointed by g.
462  */
463  f = g;
464  while (f != NULL) {
465  next = f->next;
466  /* Find f1, f0, f11, f10, f01, f00. */
467  f1 = cuddT(f);
468 #ifdef DD_DEBUG
469  assert(!(Cudd_IsComplement(f1)));
470 #endif
471  if ((int) f1->index == yindex) {
472  f11 = cuddT(f1); f10 = cuddE(f1);
473  } else {
474  f11 = f10 = f1;
475  }
476 #ifdef DD_DEBUG
477  assert(!(Cudd_IsComplement(f11)));
478 #endif
479  f0 = cuddE(f);
480  comple = Cudd_IsComplement(f0);
481  f0 = Cudd_Regular(f0);
482  if ((int) f0->index == yindex) {
483  f01 = cuddT(f0); f00 = cuddE(f0);
484  } else {
485  f01 = f00 = f0;
486  }
487  if (comple) {
488  f01 = Cudd_Not(f01);
489  f00 = Cudd_Not(f00);
490  }
491  /* Decrease ref count of f1. */
492  cuddSatDec(f1->ref);
493  /* Create the new T child. */
494  if (f11 == f00) {
495  newf1 = f11;
496  cuddSatInc(newf1->ref);
497  } else {
498  /* Check ylist for triple (yindex,f11,f00). */
499  posn = ddHash(cuddF2L(f11), cuddF2L(f00), yshift);
500  /* For each element newf1 in collision list ylist[posn]. */
501  previousP = &(ylist[posn]);
502  newf1 = *previousP;
503  while (f11 < cuddT(newf1)) {
504  previousP = &(newf1->next);
505  newf1 = *previousP;
506  }
507  while (f11 == cuddT(newf1) && f00 < cuddE(newf1)) {
508  previousP = &(newf1->next);
509  newf1 = *previousP;
510  }
511  if (cuddT(newf1) == f11 && cuddE(newf1) == f00) {
512  cuddSatInc(newf1->ref);
513  } else { /* no match */
514  newf1 = cuddDynamicAllocNode(table);
515  if (newf1 == NULL)
516  goto cuddLinearOutOfMem;
517  newf1->index = yindex; newf1->ref = 1;
518  cuddT(newf1) = f11;
519  cuddE(newf1) = f00;
520  /* Insert newf1 in the collision list ylist[posn];
521  ** increase the ref counts of f11 and f00.
522  */
523  newykeys++;
524  newf1->next = *previousP;
525  *previousP = newf1;
526  cuddSatInc(f11->ref);
527  tmp = Cudd_Regular(f00);
528  cuddSatInc(tmp->ref);
529  }
530  }
531  cuddT(f) = newf1;
532 #ifdef DD_DEBUG
533  assert(!(Cudd_IsComplement(newf1)));
534 #endif
535 
536  /* Do the same for f0, keeping complement dots into account. */
537  /* decrease ref count of f0 */
538  tmp = Cudd_Regular(f0);
539  cuddSatDec(tmp->ref);
540  /* create the new E child */
541  if (f01 == f10) {
542  newf0 = f01;
543  tmp = Cudd_Regular(newf0);
544  cuddSatInc(tmp->ref);
545  } else {
546  /* make sure f01 is regular */
547  newcomplement = Cudd_IsComplement(f01);
548  if (newcomplement) {
549  f01 = Cudd_Not(f01);
550  f10 = Cudd_Not(f10);
551  }
552  /* Check ylist for triple (yindex,f01,f10). */
553  posn = ddHash(cuddF2L(f01), cuddF2L(f10), yshift);
554  /* For each element newf0 in collision list ylist[posn]. */
555  previousP = &(ylist[posn]);
556  newf0 = *previousP;
557  while (f01 < cuddT(newf0)) {
558  previousP = &(newf0->next);
559  newf0 = *previousP;
560  }
561  while (f01 == cuddT(newf0) && f10 < cuddE(newf0)) {
562  previousP = &(newf0->next);
563  newf0 = *previousP;
564  }
565  if (cuddT(newf0) == f01 && cuddE(newf0) == f10) {
566  cuddSatInc(newf0->ref);
567  } else { /* no match */
568  newf0 = cuddDynamicAllocNode(table);
569  if (newf0 == NULL)
570  goto cuddLinearOutOfMem;
571  newf0->index = yindex; newf0->ref = 1;
572  cuddT(newf0) = f01;
573  cuddE(newf0) = f10;
574  /* Insert newf0 in the collision list ylist[posn];
575  ** increase the ref counts of f01 and f10.
576  */
577  newykeys++;
578  newf0->next = *previousP;
579  *previousP = newf0;
580  cuddSatInc(f01->ref);
581  tmp = Cudd_Regular(f10);
582  cuddSatInc(tmp->ref);
583  }
584  if (newcomplement) {
585  newf0 = Cudd_Not(newf0);
586  }
587  }
588  cuddE(f) = newf0;
589 
590  /* Re-insert the modified f in xlist.
591  ** The modified f does not already exists in xlist.
592  ** (Because of the uniqueness of the cofactors.)
593  */
594  posn = ddHash(cuddF2L(newf1), cuddF2L(newf0), xshift);
595  newxkeys++;
596  previousP = &(xlist[posn]);
597  tmp = *previousP;
598  while (newf1 < cuddT(tmp)) {
599  previousP = &(tmp->next);
600  tmp = *previousP;
601  }
602  while (newf1 == cuddT(tmp) && newf0 < cuddE(tmp)) {
603  previousP = &(tmp->next);
604  tmp = *previousP;
605  }
606  f->next = *previousP;
607  *previousP = f;
608  f = next;
609  } /* while f != NULL */
610 
611  /* GC the y layer. */
612 
613  /* For each node f in ylist. */
614  for (i = 0; i < yslots; i++) {
615  previousP = &(ylist[i]);
616  f = *previousP;
617  while (f != sentinel) {
618  next = f->next;
619  if (f->ref == 0) {
620  tmp = cuddT(f);
621  cuddSatDec(tmp->ref);
622  tmp = Cudd_Regular(cuddE(f));
623  cuddSatDec(tmp->ref);
624  cuddDeallocNode(table,f);
625  newykeys--;
626  } else {
627  *previousP = f;
628  previousP = &(f->next);
629  }
630  f = next;
631  } /* while f */
632  *previousP = sentinel;
633  } /* for every collision list */
634 
635 #ifdef DD_DEBUG
636 #if 0
637  (void) fprintf(table->out,"Linearly combining %d and %d\n",x,y);
638 #endif
639  count = 0;
640  idcheck = 0;
641  for (i = 0; i < yslots; i++) {
642  f = ylist[i];
643  while (f != sentinel) {
644  count++;
645  if (f->index != (DdHalfWord) yindex)
646  idcheck++;
647  f = f->next;
648  }
649  }
650  if (count != newykeys) {
651  fprintf(table->err,"Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n",oldykeys,newykeys,count);
652  }
653  if (idcheck != 0)
654  fprintf(table->err,"Error in id's of ylist\twrong id's = %d\n",idcheck);
655  count = 0;
656  idcheck = 0;
657  for (i = 0; i < xslots; i++) {
658  f = xlist[i];
659  while (f != sentinel) {
660  count++;
661  if (f->index != (DdHalfWord) xindex)
662  idcheck++;
663  f = f->next;
664  }
665  }
666  if (count != newxkeys || newxkeys != oldxkeys) {
667  fprintf(table->err,"Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n",oldxkeys,newxkeys,count);
668  }
669  if (idcheck != 0)
670  fprintf(table->err,"Error in id's of xlist\twrong id's = %d\n",idcheck);
671 #endif
672 
673  isolated += (table->vars[xindex]->ref == 1) +
674  (table->vars[yindex]->ref == 1);
675  table->isolated += isolated;
676 
677  /* Set the appropriate fields in table. */
678  table->subtables[y].keys = newykeys;
679 
680  /* Here we should update the linear combination table
681  ** to record that x <- x EXNOR y. This is done by complementing
682  ** the (x,y) entry of the table.
683  */
684 
685  table->keys += newykeys - oldykeys;
686 
687  cuddXorLinear(table,xindex,yindex);
688  }
689 
690 #ifdef DD_DEBUG
691  if (zero) {
692  (void) Cudd_DebugCheck(table);
693  }
694 #endif
695 
696  return(table->keys - table->isolated);
697 
698 cuddLinearOutOfMem:
699  (void) fprintf(table->err,"Error: cuddLinearInPlace out of memory\n");
700 
701  return (0);
702 
703 } /* end of cuddLinearInPlace */
704 
705 
706 /**Function********************************************************************
707 
708  Synopsis [Updates the interaction matrix.]
709 
710  Description []
711 
712  SideEffects [none]
713 
714  SeeAlso []
715 
716 ******************************************************************************/
717 void
719  DdManager * table,
720  int xindex,
721  int yindex)
722 {
723  int i;
724  for (i = 0; i < yindex; i++) {
725  if (i != xindex && cuddTestInteract(table,i,yindex)) {
726  if (i < xindex) {
727  cuddSetInteract(table,i,xindex);
728  } else {
729  cuddSetInteract(table,xindex,i);
730  }
731  }
732  }
733  for (i = yindex+1; i < table->size; i++) {
734  if (i != xindex && cuddTestInteract(table,yindex,i)) {
735  if (i < xindex) {
736  cuddSetInteract(table,i,xindex);
737  } else {
738  cuddSetInteract(table,xindex,i);
739  }
740  }
741  }
742 
743 } /* end of cuddUpdateInteractionMatrix */
744 
745 
746 /**Function********************************************************************
747 
748  Synopsis [Initializes the linear transform matrix.]
749 
750  Description [Initializes the linear transform matrix. Returns 1 if
751  successful; 0 otherwise.]
752 
753  SideEffects [none]
754 
755  SeeAlso []
756 
757 ******************************************************************************/
758 int
760  DdManager * table)
761 {
762  int words;
763  int wordsPerRow;
764  int nvars;
765  int word;
766  int bit;
767  int i;
768  long *linear;
769 
770  nvars = table->size;
771  wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
772  words = wordsPerRow * nvars;
773  table->linear = linear = ABC_ALLOC(long,words);
774  if (linear == NULL) {
775  table->errorCode = CUDD_MEMORY_OUT;
776  return(0);
777  }
778  table->memused += words * sizeof(long);
779  table->linearSize = nvars;
780  for (i = 0; i < words; i++) linear[i] = 0;
781  for (i = 0; i < nvars; i++) {
782  word = wordsPerRow * i + (i >> LOGBPL);
783  bit = i & (BPL-1);
784  linear[word] = 1 << bit;
785  }
786  return(1);
787 
788 } /* end of cuddInitLinear */
789 
790 
791 /**Function********************************************************************
792 
793  Synopsis [Resizes the linear transform matrix.]
794 
795  Description [Resizes the linear transform matrix. Returns 1 if
796  successful; 0 otherwise.]
797 
798  SideEffects [none]
799 
800  SeeAlso []
801 
802 ******************************************************************************/
803 int
805  DdManager * table)
806 {
807  int words,oldWords;
808  int wordsPerRow,oldWordsPerRow;
809  int nvars,oldNvars;
810  int word,oldWord;
811  int bit;
812  int i,j;
813  long *linear,*oldLinear;
814 
815  oldNvars = table->linearSize;
816  oldWordsPerRow = ((oldNvars - 1) >> LOGBPL) + 1;
817  oldWords = oldWordsPerRow * oldNvars;
818  oldLinear = table->linear;
819 
820  nvars = table->size;
821  wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
822  words = wordsPerRow * nvars;
823  table->linear = linear = ABC_ALLOC(long,words);
824  if (linear == NULL) {
825  table->errorCode = CUDD_MEMORY_OUT;
826  return(0);
827  }
828  table->memused += (words - oldWords) * sizeof(long);
829  for (i = 0; i < words; i++) linear[i] = 0;
830 
831  /* Copy old matrix. */
832  for (i = 0; i < oldNvars; i++) {
833  for (j = 0; j < oldWordsPerRow; j++) {
834  oldWord = oldWordsPerRow * i + j;
835  word = wordsPerRow * i + j;
836  linear[word] = oldLinear[oldWord];
837  }
838  }
839  ABC_FREE(oldLinear);
840 
841  /* Add elements to the diagonal. */
842  for (i = oldNvars; i < nvars; i++) {
843  word = wordsPerRow * i + (i >> LOGBPL);
844  bit = i & (BPL-1);
845  linear[word] = 1 << bit;
846  }
847  table->linearSize = nvars;
848 
849  return(1);
850 
851 } /* end of cuddResizeLinear */
852 
853 
854 /*---------------------------------------------------------------------------*/
855 /* Definition of static functions */
856 /*---------------------------------------------------------------------------*/
857 
858 
859 /**Function********************************************************************
860 
861  Synopsis [Comparison function used by qsort.]
862 
863  Description [Comparison function used by qsort to order the
864  variables according to the number of keys in the subtables.
865  Returns the difference in number of keys between the two
866  variables being compared.]
867 
868  SideEffects [None]
869 
870 ******************************************************************************/
871 static int
873  int * ptrX,
874  int * ptrY)
875 {
876 #if 0
877  if (entry[*ptrY] == entry[*ptrX]) {
878  return((*ptrX) - (*ptrY));
879  }
880 #endif
881  return(entry[*ptrY] - entry[*ptrX]);
882 
883 } /* end of ddLinearUniqueCompare */
884 
885 
886 /**Function********************************************************************
887 
888  Synopsis [Given xLow <= x <= xHigh moves x up and down between the
889  boundaries.]
890 
891  Description [Given xLow <= x <= xHigh moves x up and down between the
892  boundaries. At each step a linear transformation is tried, and, if it
893  decreases the size of the DD, it is accepted. Finds the best position
894  and does the required changes. Returns 1 if successful; 0 otherwise.]
895 
896  SideEffects [None]
897 
898 ******************************************************************************/
899 static int
901  DdManager * table,
902  int x,
903  int xLow,
904  int xHigh)
905 {
906 
907  Move *move;
908  Move *moveUp; /* list of up moves */
909  Move *moveDown; /* list of down moves */
910  int initialSize;
911  int result;
912 
913  initialSize = table->keys - table->isolated;
914 
915  moveDown = NULL;
916  moveUp = NULL;
917 
918  if (x == xLow) {
919  moveDown = ddLinearAndSiftingDown(table,x,xHigh,NULL);
920  /* At this point x --> xHigh unless bounding occurred. */
921  if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem;
922  /* Move backward and stop at best position. */
923  result = ddLinearAndSiftingBackward(table,initialSize,moveDown);
924  if (!result) goto ddLinearAndSiftingAuxOutOfMem;
925 
926  } else if (x == xHigh) {
927  moveUp = ddLinearAndSiftingUp(table,x,xLow,NULL);
928  /* At this point x --> xLow unless bounding occurred. */
929  if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem;
930  /* Move backward and stop at best position. */
931  result = ddLinearAndSiftingBackward(table,initialSize,moveUp);
932  if (!result) goto ddLinearAndSiftingAuxOutOfMem;
933 
934  } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */
935  moveDown = ddLinearAndSiftingDown(table,x,xHigh,NULL);
936  /* At this point x --> xHigh unless bounding occurred. */
937  if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem;
938  moveUp = ddUndoMoves(table,moveDown);
939 #ifdef DD_DEBUG
940  assert(moveUp == NULL || moveUp->x == x);
941 #endif
942  moveUp = ddLinearAndSiftingUp(table,x,xLow,moveUp);
943  if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem;
944  /* Move backward and stop at best position. */
945  result = ddLinearAndSiftingBackward(table,initialSize,moveUp);
946  if (!result) goto ddLinearAndSiftingAuxOutOfMem;
947 
948  } else { /* must go up first: shorter */
949  moveUp = ddLinearAndSiftingUp(table,x,xLow,NULL);
950  /* At this point x --> xLow unless bounding occurred. */
951  if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem;
952  moveDown = ddUndoMoves(table,moveUp);
953 #ifdef DD_DEBUG
954  assert(moveDown == NULL || moveDown->y == x);
955 #endif
956  moveDown = ddLinearAndSiftingDown(table,x,xHigh,moveDown);
957  if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem;
958  /* Move backward and stop at best position. */
959  result = ddLinearAndSiftingBackward(table,initialSize,moveDown);
960  if (!result) goto ddLinearAndSiftingAuxOutOfMem;
961  }
962 
963  while (moveDown != NULL) {
964  move = moveDown->next;
965  cuddDeallocMove(table, moveDown);
966  moveDown = move;
967  }
968  while (moveUp != NULL) {
969  move = moveUp->next;
970  cuddDeallocMove(table, moveUp);
971  moveUp = move;
972  }
973 
974  return(1);
975 
976 ddLinearAndSiftingAuxOutOfMem:
977  while (moveDown != NULL) {
978  move = moveDown->next;
979  cuddDeallocMove(table, moveDown);
980  moveDown = move;
981  }
982  while (moveUp != NULL) {
983  move = moveUp->next;
984  cuddDeallocMove(table, moveUp);
985  moveUp = move;
986  }
987 
988  return(0);
989 
990 } /* end of ddLinearAndSiftingAux */
991 
992 
993 /**Function********************************************************************
994 
995  Synopsis [Sifts a variable up and applies linear transformations.]
996 
997  Description [Sifts a variable up and applies linear transformations.
998  Moves y up until either it reaches the bound (xLow) or the size of
999  the DD heap increases too much. Returns the set of moves in case of
1000  success; NULL if memory is full.]
1001 
1002  SideEffects [None]
1003 
1004 ******************************************************************************/
1005 static Move *
1007  DdManager * table,
1008  int y,
1009  int xLow,
1010  Move * prevMoves)
1011 {
1012  Move *moves;
1013  Move *move;
1014  int x;
1015  int size, newsize;
1016  int limitSize;
1017  int xindex, yindex;
1018  int isolated;
1019  int L; /* lower bound on DD size */
1020 #ifdef DD_DEBUG
1021  int checkL;
1022  int z;
1023  int zindex;
1024 #endif
1025 
1026  moves = prevMoves;
1027  yindex = table->invperm[y];
1028 
1029  /* Initialize the lower bound.
1030  ** The part of the DD below y will not change.
1031  ** The part of the DD above y that does not interact with y will not
1032  ** change. The rest may vanish in the best case, except for
1033  ** the nodes at level xLow, which will not vanish, regardless.
1034  */
1035  limitSize = L = table->keys - table->isolated;
1036  for (x = xLow + 1; x < y; x++) {
1037  xindex = table->invperm[x];
1038  if (cuddTestInteract(table,xindex,yindex)) {
1039  isolated = table->vars[xindex]->ref == 1;
1040  L -= table->subtables[x].keys - isolated;
1041  }
1042  }
1043  isolated = table->vars[yindex]->ref == 1;
1044  L -= table->subtables[y].keys - isolated;
1045 
1046  x = cuddNextLow(table,y);
1047  while (x >= xLow && L <= limitSize) {
1048  xindex = table->invperm[x];
1049 #ifdef DD_DEBUG
1050  checkL = table->keys - table->isolated;
1051  for (z = xLow + 1; z < y; z++) {
1052  zindex = table->invperm[z];
1053  if (cuddTestInteract(table,zindex,yindex)) {
1054  isolated = table->vars[zindex]->ref == 1;
1055  checkL -= table->subtables[z].keys - isolated;
1056  }
1057  }
1058  isolated = table->vars[yindex]->ref == 1;
1059  checkL -= table->subtables[y].keys - isolated;
1060  if (L != checkL) {
1061  (void) fprintf(table->out, "checkL(%d) != L(%d)\n",checkL,L);
1062  }
1063 #endif
1064  size = cuddSwapInPlace(table,x,y);
1065  if (size == 0) goto ddLinearAndSiftingUpOutOfMem;
1066  newsize = cuddLinearInPlace(table,x,y);
1067  if (newsize == 0) goto ddLinearAndSiftingUpOutOfMem;
1068  move = (Move *) cuddDynamicAllocNode(table);
1069  if (move == NULL) goto ddLinearAndSiftingUpOutOfMem;
1070  move->x = x;
1071  move->y = y;
1072  move->next = moves;
1073  moves = move;
1074  move->flags = CUDD_SWAP_MOVE;
1075  if (newsize >= size) {
1076  /* Undo transformation. The transformation we apply is
1077  ** its own inverse. Hence, we just apply the transformation
1078  ** again.
1079  */
1080  newsize = cuddLinearInPlace(table,x,y);
1081  if (newsize == 0) goto ddLinearAndSiftingUpOutOfMem;
1082 #ifdef DD_DEBUG
1083  if (newsize != size) {
1084  (void) fprintf(table->out,"Change in size after identity transformation! From %d to %d\n",size,newsize);
1085  }
1086 #endif
1087  } else if (cuddTestInteract(table,xindex,yindex)) {
1088  size = newsize;
1090  cuddUpdateInteractionMatrix(table,xindex,yindex);
1091  }
1092  move->size = size;
1093  /* Update the lower bound. */
1094  if (cuddTestInteract(table,xindex,yindex)) {
1095  isolated = table->vars[xindex]->ref == 1;
1096  L += table->subtables[y].keys - isolated;
1097  }
1098  if ((double) size > (double) limitSize * table->maxGrowth) break;
1099  if (size < limitSize) limitSize = size;
1100  y = x;
1101  x = cuddNextLow(table,y);
1102  }
1103  return(moves);
1104 
1105 ddLinearAndSiftingUpOutOfMem:
1106  while (moves != NULL) {
1107  move = moves->next;
1108  cuddDeallocMove(table, moves);
1109  moves = move;
1110  }
1111  return((Move *) CUDD_OUT_OF_MEM);
1112 
1113 } /* end of ddLinearAndSiftingUp */
1114 
1115 
1116 /**Function********************************************************************
1117 
1118  Synopsis [Sifts a variable down and applies linear transformations.]
1119 
1120  Description [Sifts a variable down and applies linear
1121  transformations. Moves x down until either it reaches the bound
1122  (xHigh) or the size of the DD heap increases too much. Returns the
1123  set of moves in case of success; NULL if memory is full.]
1124 
1125  SideEffects [None]
1126 
1127 ******************************************************************************/
1128 static Move *
1130  DdManager * table,
1131  int x,
1132  int xHigh,
1133  Move * prevMoves)
1134 {
1135  Move *moves;
1136  Move *move;
1137  int y;
1138  int size, newsize;
1139  int R; /* upper bound on node decrease */
1140  int limitSize;
1141  int xindex, yindex;
1142  int isolated;
1143 #ifdef DD_DEBUG
1144  int checkR;
1145  int z;
1146  int zindex;
1147 #endif
1148 
1149  moves = prevMoves;
1150  /* Initialize R */
1151  xindex = table->invperm[x];
1152  limitSize = size = table->keys - table->isolated;
1153  R = 0;
1154  for (y = xHigh; y > x; y--) {
1155  yindex = table->invperm[y];
1156  if (cuddTestInteract(table,xindex,yindex)) {
1157  isolated = table->vars[yindex]->ref == 1;
1158  R += table->subtables[y].keys - isolated;
1159  }
1160  }
1161 
1162  y = cuddNextHigh(table,x);
1163  while (y <= xHigh && size - R < limitSize) {
1164 #ifdef DD_DEBUG
1165  checkR = 0;
1166  for (z = xHigh; z > x; z--) {
1167  zindex = table->invperm[z];
1168  if (cuddTestInteract(table,xindex,zindex)) {
1169  isolated = table->vars[zindex]->ref == 1;
1170  checkR += table->subtables[z].keys - isolated;
1171  }
1172  }
1173  if (R != checkR) {
1174  (void) fprintf(table->out, "checkR(%d) != R(%d)\n",checkR,R);
1175  }
1176 #endif
1177  /* Update upper bound on node decrease. */
1178  yindex = table->invperm[y];
1179  if (cuddTestInteract(table,xindex,yindex)) {
1180  isolated = table->vars[yindex]->ref == 1;
1181  R -= table->subtables[y].keys - isolated;
1182  }
1183  size = cuddSwapInPlace(table,x,y);
1184  if (size == 0) goto ddLinearAndSiftingDownOutOfMem;
1185  newsize = cuddLinearInPlace(table,x,y);
1186  if (newsize == 0) goto ddLinearAndSiftingDownOutOfMem;
1187  move = (Move *) cuddDynamicAllocNode(table);
1188  if (move == NULL) goto ddLinearAndSiftingDownOutOfMem;
1189  move->x = x;
1190  move->y = y;
1191  move->next = moves;
1192  moves = move;
1193  move->flags = CUDD_SWAP_MOVE;
1194  if (newsize >= size) {
1195  /* Undo transformation. The transformation we apply is
1196  ** its own inverse. Hence, we just apply the transformation
1197  ** again.
1198  */
1199  newsize = cuddLinearInPlace(table,x,y);
1200  if (newsize == 0) goto ddLinearAndSiftingDownOutOfMem;
1201  if (newsize != size) {
1202  (void) fprintf(table->out,"Change in size after identity transformation! From %d to %d\n",size,newsize);
1203  }
1204  } else if (cuddTestInteract(table,xindex,yindex)) {
1205  size = newsize;
1207  cuddUpdateInteractionMatrix(table,xindex,yindex);
1208  }
1209  move->size = size;
1210  if ((double) size > (double) limitSize * table->maxGrowth) break;
1211  if (size < limitSize) limitSize = size;
1212  x = y;
1213  y = cuddNextHigh(table,x);
1214  }
1215  return(moves);
1216 
1217 ddLinearAndSiftingDownOutOfMem:
1218  while (moves != NULL) {
1219  move = moves->next;
1220  cuddDeallocMove(table, moves);
1221  moves = move;
1222  }
1223  return((Move *) CUDD_OUT_OF_MEM);
1224 
1225 } /* end of ddLinearAndSiftingDown */
1226 
1227 
1228 /**Function********************************************************************
1229 
1230  Synopsis [Given a set of moves, returns the DD heap to the order
1231  giving the minimum size.]
1232 
1233  Description [Given a set of moves, returns the DD heap to the
1234  position giving the minimum size. In case of ties, returns to the
1235  closest position giving the minimum size. Returns 1 in case of
1236  success; 0 otherwise.]
1237 
1238  SideEffects [None]
1239 
1240 ******************************************************************************/
1241 static int
1243  DdManager * table,
1244  int size,
1245  Move * moves)
1246 {
1247  Move *move;
1248  int res;
1249 
1250  for (move = moves; move != NULL; move = move->next) {
1251  if (move->size < size) {
1252  size = move->size;
1253  }
1254  }
1255 
1256  for (move = moves; move != NULL; move = move->next) {
1257  if (move->size == size) return(1);
1258  if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) {
1259  res = cuddLinearInPlace(table,(int)move->x,(int)move->y);
1260  if (!res) return(0);
1261  }
1262  res = cuddSwapInPlace(table,(int)move->x,(int)move->y);
1263  if (!res) return(0);
1264  if (move->flags == CUDD_INVERSE_TRANSFORM_MOVE) {
1265  res = cuddLinearInPlace(table,(int)move->x,(int)move->y);
1266  if (!res) return(0);
1267  }
1268  }
1269 
1270  return(1);
1271 
1272 } /* end of ddLinearAndSiftingBackward */
1273 
1274 
1275 /**Function********************************************************************
1276 
1277  Synopsis [Given a set of moves, returns the DD heap to the order
1278  in effect before the moves.]
1279 
1280  Description [Given a set of moves, returns the DD heap to the
1281  order in effect before the moves. Returns 1 in case of success;
1282  0 otherwise.]
1283 
1284  SideEffects [None]
1285 
1286 ******************************************************************************/
1287 static Move*
1289  DdManager * table,
1290  Move * moves)
1291 {
1292  Move *invmoves = NULL;
1293  Move *move;
1294  Move *invmove;
1295  int size;
1296 
1297  for (move = moves; move != NULL; move = move->next) {
1298  invmove = (Move *) cuddDynamicAllocNode(table);
1299  if (invmove == NULL) goto ddUndoMovesOutOfMem;
1300  invmove->x = move->x;
1301  invmove->y = move->y;
1302  invmove->next = invmoves;
1303  invmoves = invmove;
1304  if (move->flags == CUDD_SWAP_MOVE) {
1305  invmove->flags = CUDD_SWAP_MOVE;
1306  size = cuddSwapInPlace(table,(int)move->x,(int)move->y);
1307  if (!size) goto ddUndoMovesOutOfMem;
1308  } else if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) {
1310  size = cuddLinearInPlace(table,(int)move->x,(int)move->y);
1311  if (!size) goto ddUndoMovesOutOfMem;
1312  size = cuddSwapInPlace(table,(int)move->x,(int)move->y);
1313  if (!size) goto ddUndoMovesOutOfMem;
1314  } else { /* must be CUDD_INVERSE_TRANSFORM_MOVE */
1315 #ifdef DD_DEBUG
1316  (void) fprintf(table->err,"Unforseen event in ddUndoMoves!\n");
1317 #endif
1318  invmove->flags = CUDD_LINEAR_TRANSFORM_MOVE;
1319  size = cuddSwapInPlace(table,(int)move->x,(int)move->y);
1320  if (!size) goto ddUndoMovesOutOfMem;
1321  size = cuddLinearInPlace(table,(int)move->x,(int)move->y);
1322  if (!size) goto ddUndoMovesOutOfMem;
1323  }
1324  invmove->size = size;
1325  }
1326 
1327  return(invmoves);
1328 
1329 ddUndoMovesOutOfMem:
1330  while (invmoves != NULL) {
1331  move = invmoves->next;
1332  cuddDeallocMove(table, invmoves);
1333  invmoves = move;
1334  }
1335  return((Move *) CUDD_OUT_OF_MEM);
1336 
1337 } /* end of ddUndoMoves */
1338 
1339 
1340 /**Function********************************************************************
1341 
1342  Synopsis [XORs two rows of the linear transform matrix.]
1343 
1344  Description [XORs two rows of the linear transform matrix and replaces
1345  the first row with the result.]
1346 
1347  SideEffects [none]
1348 
1349  SeeAlso []
1350 
1351 ******************************************************************************/
1352 static void
1354  DdManager * table,
1355  int x,
1356  int y)
1357 {
1358  int i;
1359  int nvars = table->size;
1360  int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
1361  int xstart = wordsPerRow * x;
1362  int ystart = wordsPerRow * y;
1363  long *linear = table->linear;
1364 
1365  for (i = 0; i < wordsPerRow; i++) {
1366  linear[xstart+i] ^= linear[ystart+i];
1367  }
1368 
1369 } /* end of cuddXorLinear */
1370 
1371 
1373 
static char rcsid[] DD_UNUSED
Definition: cuddLinear.c:99
DdHalfWord ref
Definition: cudd.h:280
unsigned int keys
Definition: cuddInt.h:330
#define CUDD_OUT_OF_MEM
Definition: cudd.h:95
unsigned short DdHalfWord
Definition: cudd.h:262
#define ddHash(f, g, s)
Definition: cuddInt.h:737
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:564
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
static void cuddXorLinear(DdManager *table, int x, int y)
Definition: cuddLinear.c:1353
#define BPL
Definition: cuddLinear.c:82
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:326
int size
Definition: cuddInt.h:361
int var(Lit p)
Definition: SolverTypes.h:62
Definition: cuddInt.h:492
void cuddSetInteract(DdManager *table, int x, int y)
Definition: cuddInteract.c:156
#define Cudd_Regular(node)
Definition: cudd.h:397
int cuddNextLow(DdManager *table, int x)
Definition: cuddReorder.c:738
#define CUDD_INVERSE_TRANSFORM_MOVE
Definition: cuddLinear.c:77
int cuddInitLinear(DdManager *table)
Definition: cuddLinear.c:759
double maxGrowth
Definition: cuddInt.h:413
FILE * err
Definition: cuddInt.h:442
static int ddLinearAndSiftingBackward(DdManager *table, int size, Move *moves)
Definition: cuddLinear.c:1242
#define LOGBPL
Definition: cuddLinear.c:83
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
DdSubtable * subtables
Definition: cuddInt.h:365
int Cudd_ReadLinear(DdManager *table, int x, int y)
Definition: cuddLinear.c:191
int cuddResizeLinear(DdManager *table)
Definition: cuddLinear.c:804
int ddTotalNumberSwapping
Definition: cuddReorder.c:107
#define Cudd_IsComplement(node)
Definition: cudd.h:425
int Cudd_PrintLinear(DdManager *table)
Definition: cuddLinear.c:153
DdNode sentinel
Definition: cuddInt.h:344
unsigned int keys
Definition: cuddInt.h:369
unsigned int dead
Definition: cuddInt.h:332
static Move * ddUndoMoves(DdManager *table, Move *moves)
Definition: cuddLinear.c:1288
FILE * out
Definition: cuddInt.h:441
unsigned int flags
Definition: cuddInt.h:495
DdHalfWord x
Definition: cuddInt.h:493
DdNode * next
Definition: cudd.h:281
#define CUDD_SWAP_MOVE
Definition: cuddLinear.c:75
#define CUDD_LINEAR_TRANSFORM_MOVE
Definition: cuddLinear.c:76
unsigned __int64 word
DECLARATIONS ///.
Definition: kitPerm.c:36
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
long * linear
Definition: cuddInt.h:395
DdNode ** nodelist
Definition: cuddInt.h:327
int cuddLinearAndSifting(DdManager *table, int lower, int upper)
Definition: cuddLinear.c:240
int Cudd_DebugCheck(DdManager *table)
Definition: cuddCheck.c:142
int linearSize
Definition: cuddInt.h:393
static int size
Definition: cuddSign.c:86
void cuddUpdateInteractionMatrix(DdManager *table, int xindex, int yindex)
Definition: cuddLinear.c:718
#define cuddF2L(f)
Definition: cuddInt.h:718
#define ddMin(x, y)
Definition: cuddInt.h:818
int cuddLinearInPlace(DdManager *table, int x, int y)
Definition: cuddLinear.c:364
#define cuddT(node)
Definition: cuddInt.h:636
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:406
#define cuddDeallocNode(unique, node)
Definition: cuddInt.h:547
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
int cuddNextHigh(DdManager *table, int x)
Definition: cuddReorder.c:716
static Move * ddLinearAndSiftingUp(DdManager *table, int y, int xLow, Move *prevMoves)
Definition: cuddLinear.c:1006
unsigned long memused
Definition: cuddInt.h:449
int siftMaxVar
Definition: cuddInt.h:411
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddReorder.c:761
static int * entry
Definition: cuddLinear.c:102
DdHalfWord index
Definition: cudd.h:279
#define ABC_FREE(obj)
Definition: abc_global.h:232
unsigned int slots
Definition: cuddInt.h:329
DdHalfWord y
Definition: cuddInt.h:494
DdNode ** vars
Definition: cuddInt.h:390
#define cuddE(node)
Definition: cuddInt.h:652
struct Move * next
Definition: cuddInt.h:497
static int ddLinearUniqueCompare(int *ptrX, int *ptrY)
Definition: cuddLinear.c:872
static Move * ddLinearAndSiftingDown(DdManager *table, int x, int xHigh, Move *prevMoves)
Definition: cuddLinear.c:1129
#define cuddSatDec(x)
Definition: cuddInt.h:896
#define assert(ex)
Definition: util_old.h:213
int * invperm
Definition: cuddInt.h:388
static int result
Definition: cuddGenetic.c:125
int isolated
Definition: cuddInt.h:385
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInteract.c:191
int shift
Definition: cuddInt.h:328
int * perm
Definition: cuddInt.h:386
int size
Definition: cuddInt.h:496
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
static DdNode * zero
Definition: cuddApa.c:100
#define cuddSatInc(x)
Definition: cuddInt.h:878
static int ddLinearAndSiftingAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddLinear.c:900