abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cuddLinear.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
 
#define BPL   32
 
#define LOGBPL   5
 

Functions

static int ddLinearUniqueCompare (int *ptrX, int *ptrY)
 
static int ddLinearAndSiftingAux (DdManager *table, int x, int xLow, int xHigh)
 
static MoveddLinearAndSiftingUp (DdManager *table, int y, int xLow, Move *prevMoves)
 
static MoveddLinearAndSiftingDown (DdManager *table, int x, int xHigh, Move *prevMoves)
 
static int ddLinearAndSiftingBackward (DdManager *table, int size, Move *moves)
 
static MoveddUndoMoves (DdManager *table, Move *moves)
 
static void cuddXorLinear (DdManager *table, int x, int y)
 
int Cudd_PrintLinear (DdManager *table)
 
int Cudd_ReadLinear (DdManager *table, int x, int y)
 
int cuddLinearAndSifting (DdManager *table, int lower, int upper)
 
int cuddLinearInPlace (DdManager *table, int x, int y)
 
void cuddUpdateInteractionMatrix (DdManager *table, int xindex, int yindex)
 
int cuddInitLinear (DdManager *table)
 
int cuddResizeLinear (DdManager *table)
 

Variables

static char rcsid[] DD_UNUSED = "$Id: cuddLinear.c,v 1.28 2009/02/19 16:21:03 fabio Exp $"
 
static int * entry
 

Macro Definition Documentation

#define BPL   32

Definition at line 82 of file cuddLinear.c.

#define CUDD_INVERSE_TRANSFORM_MOVE   2

Definition at line 77 of file cuddLinear.c.

#define CUDD_LINEAR_TRANSFORM_MOVE   1

Definition at line 76 of file cuddLinear.c.

#define CUDD_SWAP_MOVE   0

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

FileName [cuddLinear.c]

PackageName [cudd]

Synopsis [Functions for DD reduction by linear transformations.]

Description [ Internal procedures included in this module:

Static procedures included in this module:

]

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 75 of file cuddLinear.c.

#define LOGBPL   5

Definition at line 83 of file cuddLinear.c.

Function Documentation

int Cudd_PrintLinear ( DdManager table)

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

Synopsis [Prints the linear transform matrix.]

Description [Prints the linear transform matrix. Returns 1 in case of success; 0 otherwise.]

SideEffects [none]

SeeAlso []

Definition at line 153 of file cuddLinear.c.

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 */
#define BPL
Definition: cuddLinear.c:82
#define LOGBPL
Definition: cuddLinear.c:83
FILE * out
Definition: cuddInt.h:441
unsigned __int64 word
DECLARATIONS ///.
Definition: kitPerm.c:36
long * linear
Definition: cuddInt.h:395
int linearSize
Definition: cuddInt.h:393
int Cudd_ReadLinear ( DdManager table,
int  x,
int  y 
)

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

Synopsis [Reads an entry of the linear transform matrix.]

Description [Reads an entry of the linear transform matrix.]

SideEffects [none]

SeeAlso []

Definition at line 191 of file cuddLinear.c.

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 */
#define BPL
Definition: cuddLinear.c:82
int size
Definition: cuddInt.h:361
#define LOGBPL
Definition: cuddLinear.c:83
unsigned __int64 word
DECLARATIONS ///.
Definition: kitPerm.c:36
long * linear
Definition: cuddInt.h:395
int linearSize
Definition: cuddInt.h:393
#define assert(ex)
Definition: util_old.h:213
static int result
Definition: cuddGenetic.c:125
int cuddInitLinear ( DdManager table)

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

Synopsis [Initializes the linear transform matrix.]

Description [Initializes the linear transform matrix. Returns 1 if successful; 0 otherwise.]

SideEffects [none]

SeeAlso []

Definition at line 759 of file cuddLinear.c.

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 */
#define BPL
Definition: cuddLinear.c:82
int size
Definition: cuddInt.h:361
#define LOGBPL
Definition: cuddLinear.c:83
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
unsigned __int64 word
DECLARATIONS ///.
Definition: kitPerm.c:36
long * linear
Definition: cuddInt.h:395
int linearSize
Definition: cuddInt.h:393
unsigned long memused
Definition: cuddInt.h:449
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
int cuddLinearAndSifting ( DdManager table,
int  lower,
int  upper 
)

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

Synopsis [BDD reduction based on combination of sifting and linear transformations.]

Description [BDD reduction based on combination of sifting and linear transformations. 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, remembering each time the total size of the DD heap. At each position, linear transformation of the two adjacent variables is tried and is accepted if it reduces the size of the DD.
  3. Select the best permutation.
  4. Repeat 3 and 4 for all variables.

Returns 1 if successful; 0 otherwise.]

SideEffects [None]

Definition at line 240 of file cuddLinear.c.

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 */
unsigned int keys
Definition: cuddInt.h:330
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
int cuddInitLinear(DdManager *table)
Definition: cuddLinear.c:759
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
DdSubtable * subtables
Definition: cuddInt.h:365
int cuddResizeLinear(DdManager *table)
Definition: cuddLinear.c:804
int Cudd_PrintLinear(DdManager *table)
Definition: cuddLinear.c:153
unsigned int keys
Definition: cuddInt.h:369
FILE * out
Definition: cuddInt.h:441
long * linear
Definition: cuddInt.h:395
int Cudd_DebugCheck(DdManager *table)
Definition: cuddCheck.c:142
int linearSize
Definition: cuddInt.h:393
static int size
Definition: cuddSign.c:86
#define ddMin(x, y)
Definition: cuddInt.h:818
int siftMaxVar
Definition: cuddInt.h:411
static int * entry
Definition: cuddLinear.c:102
#define ABC_FREE(obj)
Definition: abc_global.h:232
static int ddLinearUniqueCompare(int *ptrX, int *ptrY)
Definition: cuddLinear.c:872
static int result
Definition: cuddGenetic.c:125
int isolated
Definition: cuddInt.h:385
int * perm
Definition: cuddInt.h:386
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
static int ddLinearAndSiftingAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddLinear.c:900
int cuddLinearInPlace ( DdManager table,
int  x,
int  y 
)

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

Synopsis [Linearly combines two adjacent variables.]

Description [Linearly combines two adjacent variables. Specifically, replaces the top variable with the exclusive nor of the two 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. cuddLinearInPlace assumes that x < y. Returns the number of keys in the table if successful; 0 otherwise.]

SideEffects [The two subtables corrresponding to variables x and y are modified. The global counters of the unique table are also affected.]

SeeAlso [cuddSwapInPlace]

Definition at line 364 of file cuddLinear.c.

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 */
DdHalfWord ref
Definition: cudd.h:280
unsigned int keys
Definition: cuddInt.h:330
unsigned short DdHalfWord
Definition: cudd.h:262
#define ddHash(f, g, s)
Definition: cuddInt.h:737
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 Cudd_Regular(node)
Definition: cudd.h:397
FILE * err
Definition: cuddInt.h:442
DdSubtable * subtables
Definition: cuddInt.h:365
#define Cudd_IsComplement(node)
Definition: cudd.h:425
DdNode sentinel
Definition: cuddInt.h:344
unsigned int keys
Definition: cuddInt.h:369
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
#define cuddT(node)
Definition: cuddInt.h:636
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:406
#define cuddDeallocNode(unique, node)
Definition: cuddInt.h:547
int cuddNextHigh(DdManager *table, int x)
Definition: cuddReorder.c:716
DdHalfWord index
Definition: cudd.h:279
unsigned int slots
Definition: cuddInt.h:329
DdNode ** vars
Definition: cuddInt.h:390
#define cuddE(node)
Definition: cuddInt.h:652
#define cuddSatDec(x)
Definition: cuddInt.h:896
#define assert(ex)
Definition: util_old.h:213
int * invperm
Definition: cuddInt.h:388
int isolated
Definition: cuddInt.h:385
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInteract.c:191
int shift
Definition: cuddInt.h:328
static DdNode * zero
Definition: cuddApa.c:100
#define cuddSatInc(x)
Definition: cuddInt.h:878
int cuddResizeLinear ( DdManager table)

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

Synopsis [Resizes the linear transform matrix.]

Description [Resizes the linear transform matrix. Returns 1 if successful; 0 otherwise.]

SideEffects [none]

SeeAlso []

Definition at line 804 of file cuddLinear.c.

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 */
#define BPL
Definition: cuddLinear.c:82
int size
Definition: cuddInt.h:361
#define LOGBPL
Definition: cuddLinear.c:83
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
unsigned __int64 word
DECLARATIONS ///.
Definition: kitPerm.c:36
long * linear
Definition: cuddInt.h:395
int linearSize
Definition: cuddInt.h:393
unsigned long memused
Definition: cuddInt.h:449
#define ABC_FREE(obj)
Definition: abc_global.h:232
Cudd_ErrorType errorCode
Definition: cuddInt.h:447
void cuddUpdateInteractionMatrix ( DdManager table,
int  xindex,
int  yindex 
)

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

Synopsis [Updates the interaction matrix.]

Description []

SideEffects [none]

SeeAlso []

Definition at line 718 of file cuddLinear.c.

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 */
int size
Definition: cuddInt.h:361
void cuddSetInteract(DdManager *table, int x, int y)
Definition: cuddInteract.c:156
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInteract.c:191
static void cuddXorLinear ( DdManager table,
int  x,
int  y 
)
static

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

Synopsis [XORs two rows of the linear transform matrix.]

Description [XORs two rows of the linear transform matrix and replaces the first row with the result.]

SideEffects [none]

SeeAlso []

Definition at line 1353 of file cuddLinear.c.

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 */
int size
Definition: cuddInt.h:361
#define LOGBPL
Definition: cuddLinear.c:83
long * linear
Definition: cuddInt.h:395
static int ddLinearAndSiftingAux ( 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. At each step a linear transformation is tried, and, if it decreases the size of the DD, it is accepted. Finds the best position and does the required changes. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

Definition at line 900 of file cuddLinear.c.

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 */
#define CUDD_OUT_OF_MEM
Definition: cudd.h:95
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:564
Definition: cuddInt.h:492
static int ddLinearAndSiftingBackward(DdManager *table, int size, Move *moves)
Definition: cuddLinear.c:1242
unsigned int keys
Definition: cuddInt.h:369
static Move * ddUndoMoves(DdManager *table, Move *moves)
Definition: cuddLinear.c:1288
DdHalfWord x
Definition: cuddInt.h:493
static Move * ddLinearAndSiftingUp(DdManager *table, int y, int xLow, Move *prevMoves)
Definition: cuddLinear.c:1006
DdHalfWord y
Definition: cuddInt.h:494
struct Move * next
Definition: cuddInt.h:497
static Move * ddLinearAndSiftingDown(DdManager *table, int x, int xHigh, Move *prevMoves)
Definition: cuddLinear.c:1129
#define assert(ex)
Definition: util_old.h:213
static int result
Definition: cuddGenetic.c:125
int isolated
Definition: cuddInt.h:385
static int ddLinearAndSiftingBackward ( DdManager table,
int  size,
Move moves 
)
static

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

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

Description [Given a set of moves, returns the DD 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]

Definition at line 1242 of file cuddLinear.c.

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 */
Definition: cuddInt.h:492
#define CUDD_INVERSE_TRANSFORM_MOVE
Definition: cuddLinear.c:77
unsigned int flags
Definition: cuddInt.h:495
DdHalfWord x
Definition: cuddInt.h:493
#define CUDD_LINEAR_TRANSFORM_MOVE
Definition: cuddLinear.c:76
static int size
Definition: cuddSign.c:86
int cuddLinearInPlace(DdManager *table, int x, int y)
Definition: cuddLinear.c:364
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddReorder.c:761
DdHalfWord y
Definition: cuddInt.h:494
struct Move * next
Definition: cuddInt.h:497
int size
Definition: cuddInt.h:496
static Move * ddLinearAndSiftingDown ( DdManager table,
int  x,
int  xHigh,
Move prevMoves 
)
static

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

Synopsis [Sifts a variable down and applies linear transformations.]

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

SideEffects [None]

Definition at line 1129 of file cuddLinear.c.

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 */
DdHalfWord ref
Definition: cudd.h:280
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
double maxGrowth
Definition: cuddInt.h:413
DdSubtable * subtables
Definition: cuddInt.h:365
unsigned int keys
Definition: cuddInt.h:369
FILE * out
Definition: cuddInt.h:441
unsigned int flags
Definition: cuddInt.h:495
DdHalfWord x
Definition: cuddInt.h:493
#define CUDD_SWAP_MOVE
Definition: cuddLinear.c:75
#define CUDD_LINEAR_TRANSFORM_MOVE
Definition: cuddLinear.c:76
static int size
Definition: cuddSign.c:86
void cuddUpdateInteractionMatrix(DdManager *table, int xindex, int yindex)
Definition: cuddLinear.c:718
int cuddLinearInPlace(DdManager *table, int x, int y)
Definition: cuddLinear.c:364
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:406
int cuddNextHigh(DdManager *table, int x)
Definition: cuddReorder.c:716
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddReorder.c:761
DdHalfWord y
Definition: cuddInt.h:494
DdNode ** vars
Definition: cuddInt.h:390
struct Move * next
Definition: cuddInt.h:497
int * invperm
Definition: cuddInt.h:388
int isolated
Definition: cuddInt.h:385
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInteract.c:191
int size
Definition: cuddInt.h:496
static Move * ddLinearAndSiftingUp ( DdManager table,
int  y,
int  xLow,
Move prevMoves 
)
static

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

Synopsis [Sifts a variable up and applies linear transformations.]

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

SideEffects [None]

Definition at line 1006 of file cuddLinear.c.

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 */
DdHalfWord ref
Definition: cudd.h:280
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
int cuddNextLow(DdManager *table, int x)
Definition: cuddReorder.c:738
double maxGrowth
Definition: cuddInt.h:413
DdSubtable * subtables
Definition: cuddInt.h:365
unsigned int keys
Definition: cuddInt.h:369
FILE * out
Definition: cuddInt.h:441
unsigned int flags
Definition: cuddInt.h:495
DdHalfWord x
Definition: cuddInt.h:493
#define CUDD_SWAP_MOVE
Definition: cuddLinear.c:75
#define CUDD_LINEAR_TRANSFORM_MOVE
Definition: cuddLinear.c:76
static int size
Definition: cuddSign.c:86
void cuddUpdateInteractionMatrix(DdManager *table, int xindex, int yindex)
Definition: cuddLinear.c:718
int cuddLinearInPlace(DdManager *table, int x, int y)
Definition: cuddLinear.c:364
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:406
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddReorder.c:761
DdHalfWord y
Definition: cuddInt.h:494
DdNode ** vars
Definition: cuddInt.h:390
struct Move * next
Definition: cuddInt.h:497
int * invperm
Definition: cuddInt.h:388
int isolated
Definition: cuddInt.h:385
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInteract.c:191
int size
Definition: cuddInt.h:496
static int ddLinearUniqueCompare ( int *  ptrX,
int *  ptrY 
)
static

AutomaticStart

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

Synopsis [Comparison function used by qsort.]

Description [Comparison function used by qsort to order the variables according to the number of keys in the subtables. Returns the difference in number of keys between the two variables being compared.]

SideEffects [None]

Definition at line 872 of file cuddLinear.c.

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 */
static int * entry
Definition: cuddLinear.c:102
static Move * ddUndoMoves ( DdManager table,
Move moves 
)
static

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

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

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

SideEffects [None]

Definition at line 1288 of file cuddLinear.c.

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 */
#define CUDD_OUT_OF_MEM
Definition: cudd.h:95
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:564
Definition: cuddInt.h:492
#define CUDD_INVERSE_TRANSFORM_MOVE
Definition: cuddLinear.c:77
FILE * err
Definition: cuddInt.h:442
unsigned int flags
Definition: cuddInt.h:495
DdHalfWord x
Definition: cuddInt.h:493
#define CUDD_SWAP_MOVE
Definition: cuddLinear.c:75
#define CUDD_LINEAR_TRANSFORM_MOVE
Definition: cuddLinear.c:76
static int size
Definition: cuddSign.c:86
int cuddLinearInPlace(DdManager *table, int x, int y)
Definition: cuddLinear.c:364
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:406
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddReorder.c:761
DdHalfWord y
Definition: cuddInt.h:494
struct Move * next
Definition: cuddInt.h:497
int size
Definition: cuddInt.h:496

Variable Documentation

char rcsid [] DD_UNUSED = "$Id: cuddLinear.c,v 1.28 2009/02/19 16:21:03 fabio Exp $"
static

Definition at line 99 of file cuddLinear.c.

int* entry
static

Definition at line 102 of file cuddLinear.c.