abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddZddLin.c File Reference
#include "misc/util/util_hack.h"
#include "cuddInt.h"

Go to the source code of this file.

Macros

#define CUDD_SWAP_MOVE   0
 
#define CUDD_LINEAR_TRANSFORM_MOVE   1
 
#define CUDD_INVERSE_TRANSFORM_MOVE   2
 

Functions

static int cuddZddLinearInPlace (DdManager *table, int x, int y)
 
static int cuddZddLinearAux (DdManager *table, int x, int xLow, int xHigh)
 
static MovecuddZddLinearUp (DdManager *table, int y, int xLow, Move *prevMoves)
 
static MovecuddZddLinearDown (DdManager *table, int x, int xHigh, Move *prevMoves)
 
static int cuddZddLinearBackward (DdManager *table, int size, Move *moves)
 
static MovecuddZddUndoMoves (DdManager *table, Move *moves)
 
int cuddZddLinearSifting (DdManager *table, int lower, int upper)
 

Variables

static char rcsid[] DD_UNUSED = "$Id: cuddZddLin.c,v 1.14 2004/08/13 18:04:53 fabio Exp $"
 
int * zdd_entry
 
int zddTotalNumberSwapping
 
static int zddTotalNumberLinearTr
 
static DdNodeempty
 

Macro Definition Documentation

#define CUDD_INVERSE_TRANSFORM_MOVE   2

Definition at line 75 of file cuddZddLin.c.

#define CUDD_LINEAR_TRANSFORM_MOVE   1

Definition at line 74 of file cuddZddLin.c.

#define CUDD_SWAP_MOVE   0

CFile***********************************************************************

FileName [cuddZddLin.c]

PackageName [cudd]

Synopsis [Procedures for dynamic variable ordering of ZDDs.]

Description [Internal procedures included in this module:

Static procedures included in this module:

]

SeeAlso [cuddLinear.c cuddZddReord.c]

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 73 of file cuddZddLin.c.

Function Documentation

static int cuddZddLinearAux ( DdManager table,
int  x,
int  xLow,
int  xHigh 
)
static

Function********************************************************************

Synopsis [Given xLow <= x <= xHigh moves x up and down between the boundaries.]

Description [Given xLow <= x <= xHigh moves x up and down between the boundaries. Finds the best position and does the required changes. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 577 of file cuddZddLin.c.

582 {
583  Move *move;
584  Move *moveUp; /* list of up move */
585  Move *moveDown; /* list of down move */
586 
587  int initial_size;
588  int result;
589 
590  initial_size = table->keysZ;
591 
592 #ifdef DD_DEBUG
593  assert(table->subtableZ[x].keys > 0);
594 #endif
595 
596  moveDown = NULL;
597  moveUp = NULL;
598 
599  if (x == xLow) {
600  moveDown = cuddZddLinearDown(table, x, xHigh, NULL);
601  /* At this point x --> xHigh. */
602  if (moveDown == (Move *) CUDD_OUT_OF_MEM)
603  goto cuddZddLinearAuxOutOfMem;
604  /* Move backward and stop at best position. */
605  result = cuddZddLinearBackward(table, initial_size, moveDown);
606  if (!result)
607  goto cuddZddLinearAuxOutOfMem;
608 
609  } else if (x == xHigh) {
610  moveUp = cuddZddLinearUp(table, x, xLow, NULL);
611  /* At this point x --> xLow. */
612  if (moveUp == (Move *) CUDD_OUT_OF_MEM)
613  goto cuddZddLinearAuxOutOfMem;
614  /* Move backward and stop at best position. */
615  result = cuddZddLinearBackward(table, initial_size, moveUp);
616  if (!result)
617  goto cuddZddLinearAuxOutOfMem;
618 
619  } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */
620  moveDown = cuddZddLinearDown(table, x, xHigh, NULL);
621  /* At this point x --> xHigh. */
622  if (moveDown == (Move *) CUDD_OUT_OF_MEM)
623  goto cuddZddLinearAuxOutOfMem;
624  moveUp = cuddZddUndoMoves(table,moveDown);
625 #ifdef DD_DEBUG
626  assert(moveUp == NULL || moveUp->x == x);
627 #endif
628  moveUp = cuddZddLinearUp(table, x, xLow, moveUp);
629  if (moveUp == (Move *) CUDD_OUT_OF_MEM)
630  goto cuddZddLinearAuxOutOfMem;
631  /* Move backward and stop at best position. */
632  result = cuddZddLinearBackward(table, initial_size, moveUp);
633  if (!result)
634  goto cuddZddLinearAuxOutOfMem;
635 
636  } else {
637  moveUp = cuddZddLinearUp(table, x, xLow, NULL);
638  /* At this point x --> xHigh. */
639  if (moveUp == (Move *) CUDD_OUT_OF_MEM)
640  goto cuddZddLinearAuxOutOfMem;
641  /* Then move up. */
642  moveDown = cuddZddUndoMoves(table,moveUp);
643 #ifdef DD_DEBUG
644  assert(moveDown == NULL || moveDown->y == x);
645 #endif
646  moveDown = cuddZddLinearDown(table, x, xHigh, moveDown);
647  if (moveDown == (Move *) CUDD_OUT_OF_MEM)
648  goto cuddZddLinearAuxOutOfMem;
649  /* Move backward and stop at best position. */
650  result = cuddZddLinearBackward(table, initial_size, moveDown);
651  if (!result)
652  goto cuddZddLinearAuxOutOfMem;
653  }
654 
655  while (moveDown != NULL) {
656  move = moveDown->next;
657  cuddDeallocMove(table, moveDown);
658  moveDown = move;
659  }
660  while (moveUp != NULL) {
661  move = moveUp->next;
662  cuddDeallocMove(table, moveUp);
663  moveUp = move;
664  }
665 
666  return(1);
667 
668 cuddZddLinearAuxOutOfMem:
669  if (moveDown != (Move *) CUDD_OUT_OF_MEM) {
670  while (moveDown != NULL) {
671  move = moveDown->next;
672  cuddDeallocMove(table, moveDown);
673  moveDown = move;
674  }
675  }
676  if (moveUp != (Move *) CUDD_OUT_OF_MEM) {
677  while (moveUp != NULL) {
678  move = moveUp->next;
679  cuddDeallocMove(table, moveUp);
680  moveUp = move;
681  }
682  }
683 
684  return(0);
685 
686 } /* end of cuddZddLinearAux */
unsigned int keys
Definition: cuddInt.h:330
#define CUDD_OUT_OF_MEM
Definition: cudd.h:95
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:564
Definition: cuddInt.h:492
static Move * cuddZddLinearUp(DdManager *table, int y, int xLow, Move *prevMoves)
Definition: cuddZddLin.c:704
DdHalfWord x
Definition: cuddInt.h:493
static Move * cuddZddUndoMoves(DdManager *table, Move *moves)
Definition: cuddZddLin.c:921
static int cuddZddLinearBackward(DdManager *table, int size, Move *moves)
Definition: cuddZddLin.c:873
DdHalfWord y
Definition: cuddInt.h:494
struct Move * next
Definition: cuddInt.h:497
#define assert(ex)
Definition: util_old.h:213
static int result
Definition: cuddGenetic.c:125
static Move * cuddZddLinearDown(DdManager *table, int x, int xHigh, Move *prevMoves)
Definition: cuddZddLin.c:789
unsigned int keysZ
Definition: cuddInt.h:370
DdSubtable * subtableZ
Definition: cuddInt.h:366
static int cuddZddLinearBackward ( DdManager table,
int  size,
Move moves 
)
static

Function********************************************************************

Synopsis [Given a set of moves, returns the ZDD heap to the position giving the minimum size.]

Description [Given a set of moves, returns the ZDD heap to the position giving the minimum size. In case of ties, returns to the closest position giving the minimum size. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 873 of file cuddZddLin.c.

877 {
878  Move *move;
879  int res;
880 
881  /* Find the minimum size among moves. */
882  for (move = moves; move != NULL; move = move->next) {
883  if (move->size < size) {
884  size = move->size;
885  }
886  }
887 
888  for (move = moves; move != NULL; move = move->next) {
889  if (move->size == size) return(1);
890  if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) {
891  res = cuddZddLinearInPlace(table,(int)move->x,(int)move->y);
892  if (!res) return(0);
893  }
894  res = cuddZddSwapInPlace(table, move->x, move->y);
895  if (!res)
896  return(0);
897  if (move->flags == CUDD_INVERSE_TRANSFORM_MOVE) {
898  res = cuddZddLinearInPlace(table,(int)move->x,(int)move->y);
899  if (!res) return(0);
900  }
901  }
902 
903  return(1);
904 
905 } /* end of cuddZddLinearBackward */
#define CUDD_INVERSE_TRANSFORM_MOVE
Definition: cuddZddLin.c:75
#define CUDD_LINEAR_TRANSFORM_MOVE
Definition: cuddZddLin.c:74
Definition: cuddInt.h:492
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddZddReord.c:484
unsigned int flags
Definition: cuddInt.h:495
DdHalfWord x
Definition: cuddInt.h:493
static int size
Definition: cuddSign.c:86
static int cuddZddLinearInPlace(DdManager *table, int x, int y)
Definition: cuddZddLin.c:255
DdHalfWord y
Definition: cuddInt.h:494
struct Move * next
Definition: cuddInt.h:497
int size
Definition: cuddInt.h:496
static Move * cuddZddLinearDown ( DdManager table,
int  x,
int  xHigh,
Move prevMoves 
)
static

Function********************************************************************

Synopsis [Sifts a variable down and applies the XOR transformation.]

Description [Sifts a variable down. Moves x down until either it reaches the bound (xHigh) or the size of the ZDD heap increases too much. Returns the set of moves in case of success; NULL if memory is full.]

SideEffects [None]

SeeAlso []

Definition at line 789 of file cuddZddLin.c.

794 {
795  Move *moves;
796  Move *move;
797  int y;
798  int size, newsize;
799  int limitSize;
800 
801  moves = prevMoves;
802  limitSize = table->keysZ;
803 
804  y = cuddZddNextHigh(table, x);
805  while (y <= xHigh) {
806  size = cuddZddSwapInPlace(table, x, y);
807  if (size == 0)
808  goto cuddZddLinearDownOutOfMem;
809  newsize = cuddZddLinearInPlace(table, x, y);
810  if (newsize == 0)
811  goto cuddZddLinearDownOutOfMem;
812  move = (Move *) cuddDynamicAllocNode(table);
813  if (move == NULL)
814  goto cuddZddLinearDownOutOfMem;
815  move->x = x;
816  move->y = y;
817  move->next = moves;
818  moves = move;
819  move->flags = CUDD_SWAP_MOVE;
820  if (newsize > size) {
821  /* Undo transformation. The transformation we apply is
822  ** its own inverse. Hence, we just apply the transformation
823  ** again.
824  */
825  newsize = cuddZddLinearInPlace(table,x,y);
826  if (newsize == 0) goto cuddZddLinearDownOutOfMem;
827  if (newsize != size) {
828  (void) fprintf(table->err,"Change in size after identity transformation! From %d to %d\n",size,newsize);
829  }
830  } else {
831  size = newsize;
833  }
834  move->size = size;
835 
836  if ((double)size > (double)limitSize * table->maxGrowth)
837  break;
838  if (size < limitSize)
839  limitSize = size;
840 
841  x = y;
842  y = cuddZddNextHigh(table, x);
843  }
844  return(moves);
845 
846 cuddZddLinearDownOutOfMem:
847  while (moves != NULL) {
848  move = moves->next;
849  cuddDeallocMove(table, moves);
850  moves = move;
851  }
852  return((Move *) CUDD_OUT_OF_MEM);
853 
854 } /* end of cuddZddLinearDown */
#define CUDD_LINEAR_TRANSFORM_MOVE
Definition: cuddZddLin.c:74
#define CUDD_OUT_OF_MEM
Definition: cudd.h:95
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:564
Definition: cuddInt.h:492
double maxGrowth
Definition: cuddInt.h:413
FILE * err
Definition: cuddInt.h:442
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddZddReord.c:484
unsigned int flags
Definition: cuddInt.h:495
DdHalfWord x
Definition: cuddInt.h:493
static int size
Definition: cuddSign.c:86
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddZddReord.c:413
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:406
static int cuddZddLinearInPlace(DdManager *table, int x, int y)
Definition: cuddZddLin.c:255
DdHalfWord y
Definition: cuddInt.h:494
struct Move * next
Definition: cuddInt.h:497
unsigned int keysZ
Definition: cuddInt.h:370
#define CUDD_SWAP_MOVE
Definition: cuddZddLin.c:73
int size
Definition: cuddInt.h:496
static int cuddZddLinearInPlace ( DdManager table,
int  x,
int  y 
)
static

AutomaticStart

Function********************************************************************

Synopsis [Linearly combines two adjacent variables.]

Description [Linearly combines two adjacent variables. It assumes that no dead nodes are present on entry to this procedure. The procedure then guarantees that no dead nodes will be present when it terminates. cuddZddLinearInPlace assumes that x < y. Returns the number of keys in the table if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddZddSwapInPlace cuddLinearInPlace]

Definition at line 255 of file cuddZddLin.c.

259 {
260  DdNodePtr *xlist, *ylist;
261  int xindex, yindex;
262  int xslots, yslots;
263  int xshift, yshift;
264  int oldxkeys, oldykeys;
265  int newxkeys, newykeys;
266  int i;
267  int posn;
268  DdNode *f, *f1, *f0, *f11, *f10, *f01, *f00;
269  DdNode *newf1, *newf0, *g, *next, *previous;
270  DdNode *special;
271 
272 #ifdef DD_DEBUG
273  assert(x < y);
274  assert(cuddZddNextHigh(table,x) == y);
275  assert(table->subtableZ[x].keys != 0);
276  assert(table->subtableZ[y].keys != 0);
277  assert(table->subtableZ[x].dead == 0);
278  assert(table->subtableZ[y].dead == 0);
279 #endif
280 
282 
283  /* Get parameters of x subtable. */
284  xindex = table->invpermZ[x];
285  xlist = table->subtableZ[x].nodelist;
286  oldxkeys = table->subtableZ[x].keys;
287  xslots = table->subtableZ[x].slots;
288  xshift = table->subtableZ[x].shift;
289  newxkeys = 0;
290 
291  /* Get parameters of y subtable. */
292  yindex = table->invpermZ[y];
293  ylist = table->subtableZ[y].nodelist;
294  oldykeys = table->subtableZ[y].keys;
295  yslots = table->subtableZ[y].slots;
296  yshift = table->subtableZ[y].shift;
297  newykeys = oldykeys;
298 
299  /* The nodes in the x layer are put in two chains. The chain
300  ** pointed by g holds the normal nodes. When re-expressed they stay
301  ** in the x list. The chain pointed by special holds the elements
302  ** that will move to the y list.
303  */
304  g = special = NULL;
305  for (i = 0; i < xslots; i++) {
306  f = xlist[i];
307  if (f == NULL) continue;
308  xlist[i] = NULL;
309  while (f != NULL) {
310  next = f->next;
311  f1 = cuddT(f);
312  /* if (f1->index == yindex) */ cuddSatDec(f1->ref);
313  f0 = cuddE(f);
314  /* if (f0->index == yindex) */ cuddSatDec(f0->ref);
315  if ((int) f1->index == yindex && cuddE(f1) == empty &&
316  (int) f0->index != yindex) {
317  f->next = special;
318  special = f;
319  } else {
320  f->next = g;
321  g = f;
322  }
323  f = next;
324  } /* while there are elements in the collision chain */
325  } /* for each slot of the x subtable */
326 
327  /* Mark y nodes with pointers from above x. We mark them by
328  ** changing their index to x.
329  */
330  for (i = 0; i < yslots; i++) {
331  f = ylist[i];
332  while (f != NULL) {
333  if (f->ref != 0) {
334  f->index = xindex;
335  }
336  f = f->next;
337  } /* while there are elements in the collision chain */
338  } /* for each slot of the y subtable */
339 
340  /* Move special nodes to the y list. */
341  f = special;
342  while (f != NULL) {
343  next = f->next;
344  f1 = cuddT(f);
345  f11 = cuddT(f1);
346  cuddT(f) = f11;
347  cuddSatInc(f11->ref);
348  f0 = cuddE(f);
349  cuddSatInc(f0->ref);
350  f->index = yindex;
351  /* Insert at the beginning of the list so that it will be
352  ** found first if there is a duplicate. The duplicate will
353  ** eventually be moved or garbage collected. No node
354  ** re-expression will add a pointer to it.
355  */
356  posn = ddHash(cuddF2L(f11), cuddF2L(f0), yshift);
357  f->next = ylist[posn];
358  ylist[posn] = f;
359  newykeys++;
360  f = next;
361  }
362 
363  /* Take care of the remaining x nodes that must be re-expressed.
364  ** They form a linked list pointed by g.
365  */
366  f = g;
367  while (f != NULL) {
368 #ifdef DD_COUNT
369  table->swapSteps++;
370 #endif
371  next = f->next;
372  /* Find f1, f0, f11, f10, f01, f00. */
373  f1 = cuddT(f);
374  if ((int) f1->index == yindex || (int) f1->index == xindex) {
375  f11 = cuddT(f1); f10 = cuddE(f1);
376  } else {
377  f11 = empty; f10 = f1;
378  }
379  f0 = cuddE(f);
380  if ((int) f0->index == yindex || (int) f0->index == xindex) {
381  f01 = cuddT(f0); f00 = cuddE(f0);
382  } else {
383  f01 = empty; f00 = f0;
384  }
385  /* Create the new T child. */
386  if (f01 == empty) {
387  newf1 = f10;
388  cuddSatInc(newf1->ref);
389  } else {
390  /* Check ylist for triple (yindex, f01, f10). */
391  posn = ddHash(cuddF2L(f01), cuddF2L(f10), yshift);
392  /* For each element newf1 in collision list ylist[posn]. */
393  newf1 = ylist[posn];
394  /* Search the collision chain skipping the marked nodes. */
395  while (newf1 != NULL) {
396  if (cuddT(newf1) == f01 && cuddE(newf1) == f10 &&
397  (int) newf1->index == yindex) {
398  cuddSatInc(newf1->ref);
399  break; /* match */
400  }
401  newf1 = newf1->next;
402  } /* while newf1 */
403  if (newf1 == NULL) { /* no match */
404  newf1 = cuddDynamicAllocNode(table);
405  if (newf1 == NULL)
406  goto zddSwapOutOfMem;
407  newf1->index = yindex; newf1->ref = 1;
408  cuddT(newf1) = f01;
409  cuddE(newf1) = f10;
410  /* Insert newf1 in the collision list ylist[pos];
411  ** increase the ref counts of f01 and f10
412  */
413  newykeys++;
414  newf1->next = ylist[posn];
415  ylist[posn] = newf1;
416  cuddSatInc(f01->ref);
417  cuddSatInc(f10->ref);
418  }
419  }
420  cuddT(f) = newf1;
421 
422  /* Do the same for f0. */
423  /* Create the new E child. */
424  if (f11 == empty) {
425  newf0 = f00;
426  cuddSatInc(newf0->ref);
427  } else {
428  /* Check ylist for triple (yindex, f11, f00). */
429  posn = ddHash(cuddF2L(f11), cuddF2L(f00), yshift);
430  /* For each element newf0 in collision list ylist[posn]. */
431  newf0 = ylist[posn];
432  while (newf0 != NULL) {
433  if (cuddT(newf0) == f11 && cuddE(newf0) == f00 &&
434  (int) newf0->index == yindex) {
435  cuddSatInc(newf0->ref);
436  break; /* match */
437  }
438  newf0 = newf0->next;
439  } /* while newf0 */
440  if (newf0 == NULL) { /* no match */
441  newf0 = cuddDynamicAllocNode(table);
442  if (newf0 == NULL)
443  goto zddSwapOutOfMem;
444  newf0->index = yindex; newf0->ref = 1;
445  cuddT(newf0) = f11; cuddE(newf0) = f00;
446  /* Insert newf0 in the collision list ylist[posn];
447  ** increase the ref counts of f11 and f00.
448  */
449  newykeys++;
450  newf0->next = ylist[posn];
451  ylist[posn] = newf0;
452  cuddSatInc(f11->ref);
453  cuddSatInc(f00->ref);
454  }
455  }
456  cuddE(f) = newf0;
457 
458  /* Re-insert the modified f in xlist.
459  ** The modified f does not already exists in xlist.
460  ** (Because of the uniqueness of the cofactors.)
461  */
462  posn = ddHash(cuddF2L(newf1), cuddF2L(newf0), xshift);
463  newxkeys++;
464  f->next = xlist[posn];
465  xlist[posn] = f;
466  f = next;
467  } /* while f != NULL */
468 
469  /* GC the y layer and move the marked nodes to the x list. */
470 
471  /* For each node f in ylist. */
472  for (i = 0; i < yslots; i++) {
473  previous = NULL;
474  f = ylist[i];
475  while (f != NULL) {
476  next = f->next;
477  if (f->ref == 0) {
478  cuddSatDec(cuddT(f)->ref);
479  cuddSatDec(cuddE(f)->ref);
480  cuddDeallocNode(table, f);
481  newykeys--;
482  if (previous == NULL)
483  ylist[i] = next;
484  else
485  previous->next = next;
486  } else if ((int) f->index == xindex) { /* move marked node */
487  if (previous == NULL)
488  ylist[i] = next;
489  else
490  previous->next = next;
491  f1 = cuddT(f);
492  cuddSatDec(f1->ref);
493  /* Check ylist for triple (yindex, f1, empty). */
494  posn = ddHash(cuddF2L(f1), cuddF2L(empty), yshift);
495  /* For each element newf1 in collision list ylist[posn]. */
496  newf1 = ylist[posn];
497  while (newf1 != NULL) {
498  if (cuddT(newf1) == f1 && cuddE(newf1) == empty &&
499  (int) newf1->index == yindex) {
500  cuddSatInc(newf1->ref);
501  break; /* match */
502  }
503  newf1 = newf1->next;
504  } /* while newf1 */
505  if (newf1 == NULL) { /* no match */
506  newf1 = cuddDynamicAllocNode(table);
507  if (newf1 == NULL)
508  goto zddSwapOutOfMem;
509  newf1->index = yindex; newf1->ref = 1;
510  cuddT(newf1) = f1; cuddE(newf1) = empty;
511  /* Insert newf1 in the collision list ylist[posn];
512  ** increase the ref counts of f1 and empty.
513  */
514  newykeys++;
515  newf1->next = ylist[posn];
516  ylist[posn] = newf1;
517  if (posn == i && previous == NULL)
518  previous = newf1;
519  cuddSatInc(f1->ref);
520  cuddSatInc(empty->ref);
521  }
522  cuddT(f) = newf1;
523  f0 = cuddE(f);
524  /* Insert f in x list. */
525  posn = ddHash(cuddF2L(newf1), cuddF2L(f0), xshift);
526  newxkeys++;
527  newykeys--;
528  f->next = xlist[posn];
529  xlist[posn] = f;
530  } else {
531  previous = f;
532  }
533  f = next;
534  } /* while f */
535  } /* for i */
536 
537  /* Set the appropriate fields in table. */
538  table->subtableZ[x].keys = newxkeys;
539  table->subtableZ[y].keys = newykeys;
540 
541  table->keysZ += newxkeys + newykeys - oldxkeys - oldykeys;
542 
543  /* Update univ section; univ[x] remains the same. */
544  table->univ[y] = cuddT(table->univ[x]);
545 
546 #if 0
547  (void) fprintf(table->out,"x = %d y = %d\n", x, y);
548  (void) Cudd_DebugCheck(table);
549  (void) Cudd_CheckKeys(table);
550 #endif
551 
552  return (table->keysZ);
553 
554 zddSwapOutOfMem:
555  (void) fprintf(table->err, "Error: cuddZddSwapInPlace out of memory\n");
556 
557  return (0);
558 
559 } /* end of cuddZddLinearInPlace */
DdHalfWord ref
Definition: cudd.h:280
static int zddTotalNumberLinearTr
Definition: cuddZddLin.c:97
unsigned int keys
Definition: cuddInt.h:330
#define ddHash(f, g, s)
Definition: cuddInt.h:737
Definition: cudd.h:278
int * invpermZ
Definition: cuddInt.h:389
FILE * err
Definition: cuddInt.h:442
unsigned int dead
Definition: cuddInt.h:332
FILE * out
Definition: cuddInt.h:441
DdNode * next
Definition: cudd.h:281
DdNode ** nodelist
Definition: cuddInt.h:327
int Cudd_DebugCheck(DdManager *table)
Definition: cuddCheck.c:142
#define cuddF2L(f)
Definition: cuddInt.h:718
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddZddReord.c:413
#define cuddT(node)
Definition: cuddInt.h:636
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:406
#define cuddDeallocNode(unique, node)
Definition: cuddInt.h:547
DdHalfWord index
Definition: cudd.h:279
unsigned int slots
Definition: cuddInt.h:329
int Cudd_CheckKeys(DdManager *table)
Definition: cuddCheck.c:458
#define cuddE(node)
Definition: cuddInt.h:652
#define cuddSatDec(x)
Definition: cuddInt.h:896
#define assert(ex)
Definition: util_old.h:213
static DdNode * empty
Definition: cuddZddLin.c:98
int shift
Definition: cuddInt.h:328
unsigned int keysZ
Definition: cuddInt.h:370
#define cuddSatInc(x)
Definition: cuddInt.h:878
DdSubtable * subtableZ
Definition: cuddInt.h:366
DdNode ** univ
Definition: cuddInt.h:392
int cuddZddLinearSifting ( DdManager table,
int  lower,
int  upper 
)

AutomaticEnd Function********************************************************************

Synopsis [Implementation of the linear sifting algorithm for ZDDs.]

Description [Implementation of the linear sifting algorithm for ZDDs. Assumes that no dead nodes are present.

  1. Order all the variables according to the number of entries in each unique table.
  2. Sift the variable up and down and applies the XOR transformation, remembering each time the total size of the DD heap.
  3. Select the best permutation.
  4. Repeat 3 and 4 for all variables.

Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 156 of file cuddZddLin.c.

160 {
161  int i;
162  int *var;
163  int size;
164  int x;
165  int result;
166 #ifdef DD_STATS
167  int previousSize;
168 #endif
169 
170  size = table->sizeZ;
171  empty = table->zero;
172 
173  /* Find order in which to sift variables. */
174  var = NULL;
175  zdd_entry = ABC_ALLOC(int, size);
176  if (zdd_entry == NULL) {
177  table->errorCode = CUDD_MEMORY_OUT;
178  goto cuddZddSiftingOutOfMem;
179  }
180  var = ABC_ALLOC(int, size);
181  if (var == NULL) {
182  table->errorCode = CUDD_MEMORY_OUT;
183  goto cuddZddSiftingOutOfMem;
184  }
185 
186  for (i = 0; i < size; i++) {
187  x = table->permZ[i];
188  zdd_entry[i] = table->subtableZ[x].keys;
189  var[i] = i;
190  }
191 
192  qsort((void *)var, size, sizeof(int), (DD_QSFP)cuddZddUniqueCompare);
193 
194  /* Now sift. */
195  for (i = 0; i < ddMin(table->siftMaxVar, size); i++) {
196  if (zddTotalNumberSwapping >= table->siftMaxSwap)
197  break;
198  x = table->permZ[var[i]];
199  if (x < lower || x > upper) continue;
200 #ifdef DD_STATS
201  previousSize = table->keysZ;
202 #endif
203  result = cuddZddLinearAux(table, x, lower, upper);
204  if (!result)
205  goto cuddZddSiftingOutOfMem;
206 #ifdef DD_STATS
207  if (table->keysZ < (unsigned) previousSize) {
208  (void) fprintf(table->out,"-");
209  } else if (table->keysZ > (unsigned) previousSize) {
210  (void) fprintf(table->out,"+"); /* should never happen */
211  (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i]);
212  } else {
213  (void) fprintf(table->out,"=");
214  }
215  fflush(table->out);
216 #endif
217  }
218 
219  ABC_FREE(var);
221 
222  return(1);
223 
224 cuddZddSiftingOutOfMem:
225 
226  if (zdd_entry != NULL) ABC_FREE(zdd_entry);
227  if (var != NULL) ABC_FREE(var);
228 
229  return(0);
230 
231 } /* end of cuddZddLinearSifting */
unsigned int keys
Definition: cuddInt.h:330
int siftMaxSwap
Definition: cuddInt.h:412
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:326
int var(Lit p)
Definition: SolverTypes.h:62
DdNode * zero
Definition: cuddInt.h:346
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
int * permZ
Definition: cuddInt.h:387
FILE * out
Definition: cuddInt.h:441
static int cuddZddLinearAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddZddLin.c:577
static int size
Definition: cuddSign.c:86
#define ddMin(x, y)
Definition: cuddInt.h:818
int siftMaxVar
Definition: cuddInt.h:411
int sizeZ
Definition: cuddInt.h:362
#define ABC_FREE(obj)
Definition: abc_global.h:232
static int result
Definition: cuddGenetic.c:125
static DdNode * empty
Definition: cuddZddLin.c:98
unsigned int keysZ
Definition: cuddInt.h:370
int * zdd_entry
Definition: cuddZddReord.c:108
int cuddZddUniqueCompare(int *ptr_x, int *ptr_y)
Definition: cuddZddReord.c:459
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
int zddTotalNumberSwapping
Definition: cuddZddReord.c:110
DdSubtable * subtableZ
Definition: cuddInt.h:366
static Move * cuddZddLinearUp ( DdManager table,
int  y,
int  xLow,
Move prevMoves 
)
static

Function********************************************************************

Synopsis [Sifts a variable up applying the XOR transformation.]

Description [Sifts a variable up applying the XOR transformation. Moves y up until either it reaches the bound (xLow) or the size of the ZDD heap increases too much. Returns the set of moves in case of success; NULL if memory is full.]

SideEffects [None]

SeeAlso []

Definition at line 704 of file cuddZddLin.c.

709 {
710  Move *moves;
711  Move *move;
712  int x;
713  int size, newsize;
714  int limitSize;
715 
716  moves = prevMoves;
717  limitSize = table->keysZ;
718 
719  x = cuddZddNextLow(table, y);
720  while (x >= xLow) {
721  size = cuddZddSwapInPlace(table, x, y);
722  if (size == 0)
723  goto cuddZddLinearUpOutOfMem;
724  newsize = cuddZddLinearInPlace(table, x, y);
725  if (newsize == 0)
726  goto cuddZddLinearUpOutOfMem;
727  move = (Move *) cuddDynamicAllocNode(table);
728  if (move == NULL)
729  goto cuddZddLinearUpOutOfMem;
730  move->x = x;
731  move->y = y;
732  move->next = moves;
733  moves = move;
734  move->flags = CUDD_SWAP_MOVE;
735  if (newsize > size) {
736  /* Undo transformation. The transformation we apply is
737  ** its own inverse. Hence, we just apply the transformation
738  ** again.
739  */
740  newsize = cuddZddLinearInPlace(table,x,y);
741  if (newsize == 0) goto cuddZddLinearUpOutOfMem;
742 #ifdef DD_DEBUG
743  if (newsize != size) {
744  (void) fprintf(table->err,"Change in size after identity transformation! From %d to %d\n",size,newsize);
745  }
746 #endif
747  } else {
748  size = newsize;
750  }
751  move->size = size;
752 
753  if ((double)size > (double)limitSize * table->maxGrowth)
754  break;
755  if (size < limitSize)
756  limitSize = size;
757 
758  y = x;
759  x = cuddZddNextLow(table, y);
760  }
761  return(moves);
762 
763 cuddZddLinearUpOutOfMem:
764  while (moves != NULL) {
765  move = moves->next;
766  cuddDeallocMove(table, moves);
767  moves = move;
768  }
769  return((Move *) CUDD_OUT_OF_MEM);
770 
771 } /* end of cuddZddLinearUp */
#define CUDD_LINEAR_TRANSFORM_MOVE
Definition: cuddZddLin.c:74
#define CUDD_OUT_OF_MEM
Definition: cudd.h:95
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:564
Definition: cuddInt.h:492
double maxGrowth
Definition: cuddInt.h:413
FILE * err
Definition: cuddInt.h:442
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddZddReord.c:484
unsigned int flags
Definition: cuddInt.h:495
DdHalfWord x
Definition: cuddInt.h:493
static int size
Definition: cuddSign.c:86
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:406
static int cuddZddLinearInPlace(DdManager *table, int x, int y)
Definition: cuddZddLin.c:255
DdHalfWord y
Definition: cuddInt.h:494
struct Move * next
Definition: cuddInt.h:497
unsigned int keysZ
Definition: cuddInt.h:370
#define CUDD_SWAP_MOVE
Definition: cuddZddLin.c:73
int cuddZddNextLow(DdManager *table, int x)
Definition: cuddZddReord.c:435
int size
Definition: cuddInt.h:496
static Move * cuddZddUndoMoves ( DdManager table,
Move moves 
)
static

Function********************************************************************

Synopsis [Given a set of moves, returns the ZDD heap to the order in effect before the moves.]

Description [Given a set of moves, returns the ZDD heap to the order in effect before the moves. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 921 of file cuddZddLin.c.

924 {
925  Move *invmoves = NULL;
926  Move *move;
927  Move *invmove;
928  int size;
929 
930  for (move = moves; move != NULL; move = move->next) {
931  invmove = (Move *) cuddDynamicAllocNode(table);
932  if (invmove == NULL) goto cuddZddUndoMovesOutOfMem;
933  invmove->x = move->x;
934  invmove->y = move->y;
935  invmove->next = invmoves;
936  invmoves = invmove;
937  if (move->flags == CUDD_SWAP_MOVE) {
938  invmove->flags = CUDD_SWAP_MOVE;
939  size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y);
940  if (!size) goto cuddZddUndoMovesOutOfMem;
941  } else if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) {
943  size = cuddZddLinearInPlace(table,(int)move->x,(int)move->y);
944  if (!size) goto cuddZddUndoMovesOutOfMem;
945  size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y);
946  if (!size) goto cuddZddUndoMovesOutOfMem;
947  } else { /* must be CUDD_INVERSE_TRANSFORM_MOVE */
948 #ifdef DD_DEBUG
949  (void) fprintf(table->err,"Unforseen event in ddUndoMoves!\n");
950 #endif
952  size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y);
953  if (!size) goto cuddZddUndoMovesOutOfMem;
954  size = cuddZddLinearInPlace(table,(int)move->x,(int)move->y);
955  if (!size) goto cuddZddUndoMovesOutOfMem;
956  }
957  invmove->size = size;
958  }
959 
960  return(invmoves);
961 
962 cuddZddUndoMovesOutOfMem:
963  while (invmoves != NULL) {
964  move = invmoves->next;
965  cuddDeallocMove(table, invmoves);
966  invmoves = move;
967  }
968  return((Move *) CUDD_OUT_OF_MEM);
969 
970 } /* end of cuddZddUndoMoves */
#define CUDD_INVERSE_TRANSFORM_MOVE
Definition: cuddZddLin.c:75
#define CUDD_LINEAR_TRANSFORM_MOVE
Definition: cuddZddLin.c:74
#define CUDD_OUT_OF_MEM
Definition: cudd.h:95
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:564
Definition: cuddInt.h:492
FILE * err
Definition: cuddInt.h:442
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddZddReord.c:484
unsigned int flags
Definition: cuddInt.h:495
DdHalfWord x
Definition: cuddInt.h:493
static int size
Definition: cuddSign.c:86
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:406
static int cuddZddLinearInPlace(DdManager *table, int x, int y)
Definition: cuddZddLin.c:255
DdHalfWord y
Definition: cuddInt.h:494
struct Move * next
Definition: cuddInt.h:497
#define CUDD_SWAP_MOVE
Definition: cuddZddLin.c:73
int size
Definition: cuddInt.h:496

Variable Documentation

char rcsid [] DD_UNUSED = "$Id: cuddZddLin.c,v 1.14 2004/08/13 18:04:53 fabio Exp $"
static

Definition at line 92 of file cuddZddLin.c.

DdNode* empty
static

Definition at line 98 of file cuddZddLin.c.

int* zdd_entry

Definition at line 108 of file cuddZddReord.c.

int zddTotalNumberLinearTr
static

Definition at line 97 of file cuddZddLin.c.

int zddTotalNumberSwapping

Definition at line 110 of file cuddZddReord.c.