SVF
Macros | Functions | Variables
cuddLinear.c File Reference
#include "CUDD/util.h"
#include "CUDD/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.29 2012/02/05 01:07:19 fabio Exp $"
 
static int * entry
 

Macro Definition Documentation

◆ BPL

#define BPL   32

Definition at line 78 of file cuddLinear.c.

◆ CUDD_INVERSE_TRANSFORM_MOVE

#define CUDD_INVERSE_TRANSFORM_MOVE   2

Definition at line 73 of file cuddLinear.c.

◆ CUDD_LINEAR_TRANSFORM_MOVE

#define CUDD_LINEAR_TRANSFORM_MOVE   1

Definition at line 72 of file cuddLinear.c.

◆ CUDD_SWAP_MOVE

#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-2012, 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 71 of file cuddLinear.c.

◆ LOGBPL

#define LOGBPL   5

Definition at line 79 of file cuddLinear.c.

Function Documentation

◆ Cudd_PrintLinear()

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

151 {
152  int i,j,k;
153  int retval;
154  int nvars = table->linearSize;
155  int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
156  long word;
157 
158  for (i = 0; i < nvars; i++) {
159  for (j = 0; j < wordsPerRow; j++) {
160  word = table->linear[i*wordsPerRow + j];
161  for (k = 0; k < BPL; k++) {
162  retval = fprintf(table->out,"%ld",word & 1);
163  if (retval == 0) return(0);
164  word >>= 1;
165  }
166  }
167  retval = fprintf(table->out,"\n");
168  if (retval == 0) return(0);
169  }
170  return(1);
171 
172 } /* end of Cudd_PrintLinear */
#define BPL
Definition: cuddLinear.c:78
#define LOGBPL
Definition: cuddLinear.c:79
FILE * out
Definition: cuddInt.h:423
long * linear
Definition: cuddInt.h:378
int linearSize
Definition: cuddInt.h:376

◆ Cudd_ReadLinear()

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

191 {
192  int nvars = table->size;
193  int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
194  long word;
195  int bit;
196  int result;
197 
198  assert(table->size == table->linearSize);
199 
200  word = wordsPerRow * x + (y >> LOGBPL);
201  bit = y & (BPL-1);
202  result = (int) ((table->linear[word] >> bit) & 1);
203  return(result);
204 
205 } /* end of Cudd_ReadLinear */
#define assert(ex)
Definition: util.h:141
#define BPL
Definition: cuddLinear.c:78
int size
Definition: cuddInt.h:345
#define LOGBPL
Definition: cuddLinear.c:79
long * linear
Definition: cuddInt.h:378
int linearSize
Definition: cuddInt.h:376
static int result
Definition: cuddGenetic.c:121

◆ cuddInitLinear()

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

757 {
758  int words;
759  int wordsPerRow;
760  int nvars;
761  int word;
762  int bit;
763  int i;
764  long *linear;
765 
766  nvars = table->size;
767  wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
768  words = wordsPerRow * nvars;
769  table->linear = linear = ALLOC(long,words);
770  if (linear == NULL) {
771  table->errorCode = CUDD_MEMORY_OUT;
772  return(0);
773  }
774  table->memused += words * sizeof(long);
775  table->linearSize = nvars;
776  for (i = 0; i < words; i++) linear[i] = 0;
777  for (i = 0; i < nvars; i++) {
778  word = wordsPerRow * i + (i >> LOGBPL);
779  bit = i & (BPL-1);
780  linear[word] = 1 << bit;
781  }
782  return(1);
783 
784 } /* end of cuddInitLinear */
#define BPL
Definition: cuddLinear.c:78
int size
Definition: cuddInt.h:345
#define LOGBPL
Definition: cuddLinear.c:79
#define ALLOC(type, num)
Definition: util.h:76
long * linear
Definition: cuddInt.h:378
int linearSize
Definition: cuddInt.h:376
unsigned long memused
Definition: cuddInt.h:429
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddLinearAndSifting()

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

240 {
241  int i;
242  int *var;
243  int size;
244  int x;
245  int result;
246 #ifdef DD_STATS
247  int previousSize;
248 #endif
249 
250 #ifdef DD_STATS
251  ddTotalNumberLinearTr = 0;
252 #endif
253 
254  size = table->size;
255 
256  var = NULL;
257  entry = NULL;
258  if (table->linear == NULL) {
259  result = cuddInitLinear(table);
260  if (result == 0) goto cuddLinearAndSiftingOutOfMem;
261 #if 0
262  (void) fprintf(table->out,"\n");
263  result = Cudd_PrintLinear(table);
264  if (result == 0) goto cuddLinearAndSiftingOutOfMem;
265 #endif
266  } else if (table->size != table->linearSize) {
267  result = cuddResizeLinear(table);
268  if (result == 0) goto cuddLinearAndSiftingOutOfMem;
269 #if 0
270  (void) fprintf(table->out,"\n");
271  result = Cudd_PrintLinear(table);
272  if (result == 0) goto cuddLinearAndSiftingOutOfMem;
273 #endif
274  }
275 
276  /* Find order in which to sift variables. */
277  entry = ALLOC(int,size);
278  if (entry == NULL) {
279  table->errorCode = CUDD_MEMORY_OUT;
280  goto cuddLinearAndSiftingOutOfMem;
281  }
282  var = ALLOC(int,size);
283  if (var == NULL) {
284  table->errorCode = CUDD_MEMORY_OUT;
285  goto cuddLinearAndSiftingOutOfMem;
286  }
287 
288  for (i = 0; i < size; i++) {
289  x = table->perm[i];
290  entry[i] = table->subtables[x].keys;
291  var[i] = i;
292  }
293 
294  qsort((void *)var,size,sizeof(int),(DD_QSFP)ddLinearUniqueCompare);
295 
296  /* Now sift. */
297  for (i = 0; i < ddMin(table->siftMaxVar,size); i++) {
298  x = table->perm[var[i]];
299  if (x < lower || x > upper) continue;
300 #ifdef DD_STATS
301  previousSize = table->keys - table->isolated;
302 #endif
303  result = ddLinearAndSiftingAux(table,x,lower,upper);
304  if (!result) goto cuddLinearAndSiftingOutOfMem;
305 #ifdef DD_STATS
306  if (table->keys < (unsigned) previousSize + table->isolated) {
307  (void) fprintf(table->out,"-");
308  } else if (table->keys > (unsigned) previousSize + table->isolated) {
309  (void) fprintf(table->out,"+"); /* should never happen */
310  (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]);
311  } else {
312  (void) fprintf(table->out,"=");
313  }
314  fflush(table->out);
315 #endif
316 #ifdef DD_DEBUG
317  (void) Cudd_DebugCheck(table);
318 #endif
319  }
320 
321  FREE(var);
322  FREE(entry);
323 
324 #ifdef DD_STATS
325  (void) fprintf(table->out,"\n#:L_LINSIFT %8d: linear trans.",
326  ddTotalNumberLinearTr);
327 #endif
328 
329  return(1);
330 
331 cuddLinearAndSiftingOutOfMem:
332 
333  if (entry != NULL) FREE(entry);
334  if (var != NULL) FREE(var);
335 
336  return(0);
337 
338 } /* end of cuddLinearAndSifting */
unsigned int keys
Definition: cuddInt.h:314
#define FREE(obj)
Definition: util.h:80
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:313
int size
Definition: cuddInt.h:345
int cuddInitLinear(DdManager *table)
Definition: cuddLinear.c:755
DdSubtable * subtables
Definition: cuddInt.h:349
int cuddResizeLinear(DdManager *table)
Definition: cuddLinear.c:800
int Cudd_PrintLinear(DdManager *table)
Definition: cuddLinear.c:149
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
long * linear
Definition: cuddInt.h:378
int Cudd_DebugCheck(DdManager *table)
Definition: cuddCheck.c:138
int linearSize
Definition: cuddInt.h:376
#define ddMin(x, y)
Definition: cuddInt.h:771
int siftMaxVar
Definition: cuddInt.h:395
static int * entry
Definition: cuddLinear.c:98
static int ddLinearUniqueCompare(int *ptrX, int *ptrY)
Definition: cuddLinear.c:868
static int result
Definition: cuddGenetic.c:121
int isolated
Definition: cuddInt.h:368
int * perm
Definition: cuddInt.h:369
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
static int ddLinearAndSiftingAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddLinear.c:896

◆ cuddLinearInPlace()

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

364 {
365  DdNodePtr *xlist, *ylist;
366  int xindex, yindex;
367  int xslots, yslots;
368  int xshift, yshift;
369  int oldxkeys, oldykeys;
370  int newxkeys, newykeys;
371  int comple, newcomplement;
372  int i;
373  int posn;
374  int isolated;
375  DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10,*newf1,*newf0;
376  DdNode *g,*next,*last;
377  DdNodePtr *previousP;
378  DdNode *tmp;
379  DdNode *sentinel = &(table->sentinel);
380 #ifdef DD_DEBUG
381  int count, idcheck;
382 #endif
383 
384 #ifdef DD_DEBUG
385  assert(x < y);
386  assert(cuddNextHigh(table,x) == y);
387  assert(table->subtables[x].keys != 0);
388  assert(table->subtables[y].keys != 0);
389  assert(table->subtables[x].dead == 0);
390  assert(table->subtables[y].dead == 0);
391 #endif
392 
393  xindex = table->invperm[x];
394  yindex = table->invperm[y];
395 
396  if (cuddTestInteract(table,xindex,yindex)) {
397 #ifdef DD_STATS
398  ddTotalNumberLinearTr++;
399 #endif
400  /* Get parameters of x subtable. */
401  xlist = table->subtables[x].nodelist;
402  oldxkeys = table->subtables[x].keys;
403  xslots = table->subtables[x].slots;
404  xshift = table->subtables[x].shift;
405 
406  /* Get parameters of y subtable. */
407  ylist = table->subtables[y].nodelist;
408  oldykeys = table->subtables[y].keys;
409  yslots = table->subtables[y].slots;
410  yshift = table->subtables[y].shift;
411 
412  newxkeys = 0;
413  newykeys = oldykeys;
414 
415  /* Check whether the two projection functions involved in this
416  ** swap are isolated. At the end, we'll be able to tell how many
417  ** isolated projection functions are there by checking only these
418  ** two functions again. This is done to eliminate the isolated
419  ** projection functions from the node count.
420  */
421  isolated = - ((table->vars[xindex]->ref == 1) +
422  (table->vars[yindex]->ref == 1));
423 
424  /* The nodes in the x layer are put in a chain.
425  ** The chain is handled as a FIFO; g points to the beginning and
426  ** last points to the end.
427  */
428  g = NULL;
429 #ifdef DD_DEBUG
430  last = NULL;
431 #endif
432  for (i = 0; i < xslots; i++) {
433  f = xlist[i];
434  if (f == sentinel) continue;
435  xlist[i] = sentinel;
436  if (g == NULL) {
437  g = f;
438  } else {
439  last->next = f;
440  }
441  while ((next = f->next) != sentinel) {
442  f = next;
443  } /* while there are elements in the collision chain */
444  last = f;
445  } /* for each slot of the x subtable */
446 #ifdef DD_DEBUG
447  /* last is always assigned in the for loop because there is at
448  ** least one key */
449  assert(last != NULL);
450 #endif
451  last->next = NULL;
452 
453 #ifdef DD_COUNT
454  table->swapSteps += oldxkeys;
455 #endif
456  /* Take care of the x nodes that must be re-expressed.
457  ** They form a linked list pointed by g.
458  */
459  f = g;
460  while (f != NULL) {
461  next = f->next;
462  /* Find f1, f0, f11, f10, f01, f00. */
463  f1 = cuddT(f);
464 #ifdef DD_DEBUG
465  assert(!(Cudd_IsComplement(f1)));
466 #endif
467  if ((int) f1->index == yindex) {
468  f11 = cuddT(f1); f10 = cuddE(f1);
469  } else {
470  f11 = f10 = f1;
471  }
472 #ifdef DD_DEBUG
473  assert(!(Cudd_IsComplement(f11)));
474 #endif
475  f0 = cuddE(f);
476  comple = Cudd_IsComplement(f0);
477  f0 = Cudd_Regular(f0);
478  if ((int) f0->index == yindex) {
479  f01 = cuddT(f0); f00 = cuddE(f0);
480  } else {
481  f01 = f00 = f0;
482  }
483  if (comple) {
484  f01 = Cudd_Not(f01);
485  f00 = Cudd_Not(f00);
486  }
487  /* Decrease ref count of f1. */
488  cuddSatDec(f1->ref);
489  /* Create the new T child. */
490  if (f11 == f00) {
491  newf1 = f11;
492  cuddSatInc(newf1->ref);
493  } else {
494  /* Check ylist for triple (yindex,f11,f00). */
495  posn = ddHash(f11, f00, yshift);
496  /* For each element newf1 in collision list ylist[posn]. */
497  previousP = &(ylist[posn]);
498  newf1 = *previousP;
499  while (f11 < cuddT(newf1)) {
500  previousP = &(newf1->next);
501  newf1 = *previousP;
502  }
503  while (f11 == cuddT(newf1) && f00 < cuddE(newf1)) {
504  previousP = &(newf1->next);
505  newf1 = *previousP;
506  }
507  if (cuddT(newf1) == f11 && cuddE(newf1) == f00) {
508  cuddSatInc(newf1->ref);
509  } else { /* no match */
510  newf1 = cuddDynamicAllocNode(table);
511  if (newf1 == NULL)
512  goto cuddLinearOutOfMem;
513  newf1->index = yindex; newf1->ref = 1;
514  cuddT(newf1) = f11;
515  cuddE(newf1) = f00;
516  /* Insert newf1 in the collision list ylist[posn];
517  ** increase the ref counts of f11 and f00.
518  */
519  newykeys++;
520  newf1->next = *previousP;
521  *previousP = newf1;
522  cuddSatInc(f11->ref);
523  tmp = Cudd_Regular(f00);
524  cuddSatInc(tmp->ref);
525  }
526  }
527  cuddT(f) = newf1;
528 #ifdef DD_DEBUG
529  assert(!(Cudd_IsComplement(newf1)));
530 #endif
531 
532  /* Do the same for f0, keeping complement dots into account. */
533  /* decrease ref count of f0 */
534  tmp = Cudd_Regular(f0);
535  cuddSatDec(tmp->ref);
536  /* create the new E child */
537  if (f01 == f10) {
538  newf0 = f01;
539  tmp = Cudd_Regular(newf0);
540  cuddSatInc(tmp->ref);
541  } else {
542  /* make sure f01 is regular */
543  newcomplement = Cudd_IsComplement(f01);
544  if (newcomplement) {
545  f01 = Cudd_Not(f01);
546  f10 = Cudd_Not(f10);
547  }
548  /* Check ylist for triple (yindex,f01,f10). */
549  posn = ddHash(f01, f10, yshift);
550  /* For each element newf0 in collision list ylist[posn]. */
551  previousP = &(ylist[posn]);
552  newf0 = *previousP;
553  while (f01 < cuddT(newf0)) {
554  previousP = &(newf0->next);
555  newf0 = *previousP;
556  }
557  while (f01 == cuddT(newf0) && f10 < cuddE(newf0)) {
558  previousP = &(newf0->next);
559  newf0 = *previousP;
560  }
561  if (cuddT(newf0) == f01 && cuddE(newf0) == f10) {
562  cuddSatInc(newf0->ref);
563  } else { /* no match */
564  newf0 = cuddDynamicAllocNode(table);
565  if (newf0 == NULL)
566  goto cuddLinearOutOfMem;
567  newf0->index = yindex; newf0->ref = 1;
568  cuddT(newf0) = f01;
569  cuddE(newf0) = f10;
570  /* Insert newf0 in the collision list ylist[posn];
571  ** increase the ref counts of f01 and f10.
572  */
573  newykeys++;
574  newf0->next = *previousP;
575  *previousP = newf0;
576  cuddSatInc(f01->ref);
577  tmp = Cudd_Regular(f10);
578  cuddSatInc(tmp->ref);
579  }
580  if (newcomplement) {
581  newf0 = Cudd_Not(newf0);
582  }
583  }
584  cuddE(f) = newf0;
585 
586  /* Re-insert the modified f in xlist.
587  ** The modified f does not already exists in xlist.
588  ** (Because of the uniqueness of the cofactors.)
589  */
590  posn = ddHash(newf1, newf0, xshift);
591  newxkeys++;
592  previousP = &(xlist[posn]);
593  tmp = *previousP;
594  while (newf1 < cuddT(tmp)) {
595  previousP = &(tmp->next);
596  tmp = *previousP;
597  }
598  while (newf1 == cuddT(tmp) && newf0 < cuddE(tmp)) {
599  previousP = &(tmp->next);
600  tmp = *previousP;
601  }
602  f->next = *previousP;
603  *previousP = f;
604  f = next;
605  } /* while f != NULL */
606 
607  /* GC the y layer. */
608 
609  /* For each node f in ylist. */
610  for (i = 0; i < yslots; i++) {
611  previousP = &(ylist[i]);
612  f = *previousP;
613  while (f != sentinel) {
614  next = f->next;
615  if (f->ref == 0) {
616  tmp = cuddT(f);
617  cuddSatDec(tmp->ref);
618  tmp = Cudd_Regular(cuddE(f));
619  cuddSatDec(tmp->ref);
620  cuddDeallocNode(table,f);
621  newykeys--;
622  } else {
623  *previousP = f;
624  previousP = &(f->next);
625  }
626  f = next;
627  } /* while f */
628  *previousP = sentinel;
629  } /* for every collision list */
630 
631 #ifdef DD_DEBUG
632 #if 0
633  (void) fprintf(table->out,"Linearly combining %d and %d\n",x,y);
634 #endif
635  count = 0;
636  idcheck = 0;
637  for (i = 0; i < yslots; i++) {
638  f = ylist[i];
639  while (f != sentinel) {
640  count++;
641  if (f->index != (DdHalfWord) yindex)
642  idcheck++;
643  f = f->next;
644  }
645  }
646  if (count != newykeys) {
647  fprintf(table->err,"Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n",oldykeys,newykeys,count);
648  }
649  if (idcheck != 0)
650  fprintf(table->err,"Error in id's of ylist\twrong id's = %d\n",idcheck);
651  count = 0;
652  idcheck = 0;
653  for (i = 0; i < xslots; i++) {
654  f = xlist[i];
655  while (f != sentinel) {
656  count++;
657  if (f->index != (DdHalfWord) xindex)
658  idcheck++;
659  f = f->next;
660  }
661  }
662  if (count != newxkeys || newxkeys != oldxkeys) {
663  fprintf(table->err,"Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n",oldxkeys,newxkeys,count);
664  }
665  if (idcheck != 0)
666  fprintf(table->err,"Error in id's of xlist\twrong id's = %d\n",idcheck);
667 #endif
668 
669  isolated += (table->vars[xindex]->ref == 1) +
670  (table->vars[yindex]->ref == 1);
671  table->isolated += isolated;
672 
673  /* Set the appropriate fields in table. */
674  table->subtables[y].keys = newykeys;
675 
676  /* Here we should update the linear combination table
677  ** to record that x <- x EXNOR y. This is done by complementing
678  ** the (x,y) entry of the table.
679  */
680 
681  table->keys += newykeys - oldykeys;
682 
683  cuddXorLinear(table,xindex,yindex);
684  }
685 
686 #ifdef DD_DEBUG
687  if (zero) {
688  (void) Cudd_DebugCheck(table);
689  }
690 #endif
691 
692  return(table->keys - table->isolated);
693 
694 cuddLinearOutOfMem:
695  (void) fprintf(table->err,"Error: cuddLinearInPlace out of memory\n");
696 
697  return (0);
698 
699 } /* end of cuddLinearInPlace */
DdHalfWord ref
Definition: cudd.h:272
unsigned int keys
Definition: cuddInt.h:314
unsigned short DdHalfWord
Definition: cudd.h:259
#define ddHash(f, g, s)
Definition: cuddInt.h:696
Definition: cudd.h:270
#define Cudd_Not(node)
Definition: cudd.h:354
static void cuddXorLinear(DdManager *table, int x, int y)
Definition: cuddLinear.c:1349
#define assert(ex)
Definition: util.h:141
#define Cudd_Regular(node)
Definition: cudd.h:384
FILE * err
Definition: cuddInt.h:424
DdSubtable * subtables
Definition: cuddInt.h:349
#define Cudd_IsComplement(node)
Definition: cudd.h:412
DdNode sentinel
Definition: cuddInt.h:328
unsigned int keys
Definition: cuddInt.h:353
unsigned int dead
Definition: cuddInt.h:316
FILE * out
Definition: cuddInt.h:423
DdNode * next
Definition: cudd.h:273
DdNode ** nodelist
Definition: cuddInt.h:311
int Cudd_DebugCheck(DdManager *table)
Definition: cuddCheck.c:138
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:405
#define cuddDeallocNode(unique, node)
Definition: cuddInt.h:520
int cuddNextHigh(DdManager *table, int x)
Definition: cuddReorder.c:715
DdHalfWord index
Definition: cudd.h:271
unsigned int slots
Definition: cuddInt.h:313
DdNode ** vars
Definition: cuddInt.h:373
static DdNode * zero
Definition: cuddSat.c:105
#define cuddE(node)
Definition: cuddInt.h:625
#define cuddSatDec(x)
Definition: cuddInt.h:849
int * invperm
Definition: cuddInt.h:371
int isolated
Definition: cuddInt.h:368
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInteract.c:188
int shift
Definition: cuddInt.h:312
#define cuddSatInc(x)
Definition: cuddInt.h:831

◆ cuddResizeLinear()

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

802 {
803  int words,oldWords;
804  int wordsPerRow,oldWordsPerRow;
805  int nvars,oldNvars;
806  int word,oldWord;
807  int bit;
808  int i,j;
809  long *linear,*oldLinear;
810 
811  oldNvars = table->linearSize;
812  oldWordsPerRow = ((oldNvars - 1) >> LOGBPL) + 1;
813  oldWords = oldWordsPerRow * oldNvars;
814  oldLinear = table->linear;
815 
816  nvars = table->size;
817  wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
818  words = wordsPerRow * nvars;
819  table->linear = linear = ALLOC(long,words);
820  if (linear == NULL) {
821  table->errorCode = CUDD_MEMORY_OUT;
822  return(0);
823  }
824  table->memused += (words - oldWords) * sizeof(long);
825  for (i = 0; i < words; i++) linear[i] = 0;
826 
827  /* Copy old matrix. */
828  for (i = 0; i < oldNvars; i++) {
829  for (j = 0; j < oldWordsPerRow; j++) {
830  oldWord = oldWordsPerRow * i + j;
831  word = wordsPerRow * i + j;
832  linear[word] = oldLinear[oldWord];
833  }
834  }
835  FREE(oldLinear);
836 
837  /* Add elements to the diagonal. */
838  for (i = oldNvars; i < nvars; i++) {
839  word = wordsPerRow * i + (i >> LOGBPL);
840  bit = i & (BPL-1);
841  linear[word] = 1 << bit;
842  }
843  table->linearSize = nvars;
844 
845  return(1);
846 
847 } /* end of cuddResizeLinear */
#define FREE(obj)
Definition: util.h:80
#define BPL
Definition: cuddLinear.c:78
int size
Definition: cuddInt.h:345
#define LOGBPL
Definition: cuddLinear.c:79
#define ALLOC(type, num)
Definition: util.h:76
long * linear
Definition: cuddInt.h:378
int linearSize
Definition: cuddInt.h:376
unsigned long memused
Definition: cuddInt.h:429
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddUpdateInteractionMatrix()

void cuddUpdateInteractionMatrix ( DdManager table,
int  xindex,
int  yindex 
)

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

Synopsis [Updates the interaction matrix.]

Description []

SideEffects [none]

SeeAlso []

Definition at line 714 of file cuddLinear.c.

718 {
719  int i;
720  for (i = 0; i < yindex; i++) {
721  if (i != xindex && cuddTestInteract(table,i,yindex)) {
722  if (i < xindex) {
723  cuddSetInteract(table,i,xindex);
724  } else {
725  cuddSetInteract(table,xindex,i);
726  }
727  }
728  }
729  for (i = yindex+1; i < table->size; i++) {
730  if (i != xindex && cuddTestInteract(table,yindex,i)) {
731  if (i < xindex) {
732  cuddSetInteract(table,i,xindex);
733  } else {
734  cuddSetInteract(table,xindex,i);
735  }
736  }
737  }
738 
739 } /* end of cuddUpdateInteractionMatrix */
int size
Definition: cuddInt.h:345
void cuddSetInteract(DdManager *table, int x, int y)
Definition: cuddInteract.c:153
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInteract.c:188

◆ cuddXorLinear()

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

1353 {
1354  int i;
1355  int nvars = table->size;
1356  int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
1357  int xstart = wordsPerRow * x;
1358  int ystart = wordsPerRow * y;
1359  long *linear = table->linear;
1360 
1361  for (i = 0; i < wordsPerRow; i++) {
1362  linear[xstart+i] ^= linear[ystart+i];
1363  }
1364 
1365 } /* end of cuddXorLinear */
int size
Definition: cuddInt.h:345
#define LOGBPL
Definition: cuddLinear.c:79
long * linear
Definition: cuddInt.h:378

◆ ddLinearAndSiftingAux()

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

901 {
902 
903  Move *move;
904  Move *moveUp; /* list of up moves */
905  Move *moveDown; /* list of down moves */
906  int initialSize;
907  int result;
908 
909  initialSize = table->keys - table->isolated;
910 
911  moveDown = NULL;
912  moveUp = NULL;
913 
914  if (x == xLow) {
915  moveDown = ddLinearAndSiftingDown(table,x,xHigh,NULL);
916  /* At this point x --> xHigh unless bounding occurred. */
917  if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem;
918  /* Move backward and stop at best position. */
919  result = ddLinearAndSiftingBackward(table,initialSize,moveDown);
920  if (!result) goto ddLinearAndSiftingAuxOutOfMem;
921 
922  } else if (x == xHigh) {
923  moveUp = ddLinearAndSiftingUp(table,x,xLow,NULL);
924  /* At this point x --> xLow unless bounding occurred. */
925  if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem;
926  /* Move backward and stop at best position. */
927  result = ddLinearAndSiftingBackward(table,initialSize,moveUp);
928  if (!result) goto ddLinearAndSiftingAuxOutOfMem;
929 
930  } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */
931  moveDown = ddLinearAndSiftingDown(table,x,xHigh,NULL);
932  /* At this point x --> xHigh unless bounding occurred. */
933  if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem;
934  moveUp = ddUndoMoves(table,moveDown);
935 #ifdef DD_DEBUG
936  assert(moveUp == NULL || moveUp->x == x);
937 #endif
938  moveUp = ddLinearAndSiftingUp(table,x,xLow,moveUp);
939  if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem;
940  /* Move backward and stop at best position. */
941  result = ddLinearAndSiftingBackward(table,initialSize,moveUp);
942  if (!result) goto ddLinearAndSiftingAuxOutOfMem;
943 
944  } else { /* must go up first: shorter */
945  moveUp = ddLinearAndSiftingUp(table,x,xLow,NULL);
946  /* At this point x --> xLow unless bounding occurred. */
947  if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem;
948  moveDown = ddUndoMoves(table,moveUp);
949 #ifdef DD_DEBUG
950  assert(moveDown == NULL || moveDown->y == x);
951 #endif
952  moveDown = ddLinearAndSiftingDown(table,x,xHigh,moveDown);
953  if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem;
954  /* Move backward and stop at best position. */
955  result = ddLinearAndSiftingBackward(table,initialSize,moveDown);
956  if (!result) goto ddLinearAndSiftingAuxOutOfMem;
957  }
958 
959  while (moveDown != NULL) {
960  move = moveDown->next;
961  cuddDeallocMove(table, moveDown);
962  moveDown = move;
963  }
964  while (moveUp != NULL) {
965  move = moveUp->next;
966  cuddDeallocMove(table, moveUp);
967  moveUp = move;
968  }
969 
970  return(1);
971 
972 ddLinearAndSiftingAuxOutOfMem:
973  while (moveDown != NULL) {
974  move = moveDown->next;
975  cuddDeallocMove(table, moveDown);
976  moveDown = move;
977  }
978  while (moveUp != NULL) {
979  move = moveUp->next;
980  cuddDeallocMove(table, moveUp);
981  moveUp = move;
982  }
983 
984  return(0);
985 
986 } /* end of ddLinearAndSiftingAux */
#define CUDD_OUT_OF_MEM
Definition: cudd.h:91
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
static int ddLinearAndSiftingBackward(DdManager *table, int size, Move *moves)
Definition: cuddLinear.c:1238
unsigned int keys
Definition: cuddInt.h:353
static Move * ddUndoMoves(DdManager *table, Move *moves)
Definition: cuddLinear.c:1284
DdHalfWord x
Definition: cuddInt.h:470
static Move * ddLinearAndSiftingUp(DdManager *table, int y, int xLow, Move *prevMoves)
Definition: cuddLinear.c:1002
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
static Move * ddLinearAndSiftingDown(DdManager *table, int x, int xHigh, Move *prevMoves)
Definition: cuddLinear.c:1125
static int result
Definition: cuddGenetic.c:121
int isolated
Definition: cuddInt.h:368

◆ ddLinearAndSiftingBackward()

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

1242 {
1243  Move *move;
1244  int res;
1245 
1246  for (move = moves; move != NULL; move = move->next) {
1247  if (move->size < size) {
1248  size = move->size;
1249  }
1250  }
1251 
1252  for (move = moves; move != NULL; move = move->next) {
1253  if (move->size == size) return(1);
1254  if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) {
1255  res = cuddLinearInPlace(table,(int)move->x,(int)move->y);
1256  if (!res) return(0);
1257  }
1258  res = cuddSwapInPlace(table,(int)move->x,(int)move->y);
1259  if (!res) return(0);
1260  if (move->flags == CUDD_INVERSE_TRANSFORM_MOVE) {
1261  res = cuddLinearInPlace(table,(int)move->x,(int)move->y);
1262  if (!res) return(0);
1263  }
1264  }
1265 
1266  return(1);
1267 
1268 } /* end of ddLinearAndSiftingBackward */
Definition: cuddInt.h:469
#define CUDD_INVERSE_TRANSFORM_MOVE
Definition: cuddLinear.c:73
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
#define CUDD_LINEAR_TRANSFORM_MOVE
Definition: cuddLinear.c:72
int cuddLinearInPlace(DdManager *table, int x, int y)
Definition: cuddLinear.c:360
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddReorder.c:760
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
int size
Definition: cuddInt.h:473

◆ ddLinearAndSiftingDown()

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

1130 {
1131  Move *moves;
1132  Move *move;
1133  int y;
1134  int size, newsize;
1135  int R; /* upper bound on node decrease */
1136  int limitSize;
1137  int xindex, yindex;
1138  int isolated;
1139 #ifdef DD_DEBUG
1140  int checkR;
1141  int z;
1142  int zindex;
1143 #endif
1144 
1145  moves = prevMoves;
1146  /* Initialize R */
1147  xindex = table->invperm[x];
1148  limitSize = size = table->keys - table->isolated;
1149  R = 0;
1150  for (y = xHigh; y > x; y--) {
1151  yindex = table->invperm[y];
1152  if (cuddTestInteract(table,xindex,yindex)) {
1153  isolated = table->vars[yindex]->ref == 1;
1154  R += table->subtables[y].keys - isolated;
1155  }
1156  }
1157 
1158  y = cuddNextHigh(table,x);
1159  while (y <= xHigh && size - R < limitSize) {
1160 #ifdef DD_DEBUG
1161  checkR = 0;
1162  for (z = xHigh; z > x; z--) {
1163  zindex = table->invperm[z];
1164  if (cuddTestInteract(table,xindex,zindex)) {
1165  isolated = table->vars[zindex]->ref == 1;
1166  checkR += table->subtables[z].keys - isolated;
1167  }
1168  }
1169  if (R != checkR) {
1170  (void) fprintf(table->out, "checkR(%d) != R(%d)\n",checkR,R);
1171  }
1172 #endif
1173  /* Update upper bound on node decrease. */
1174  yindex = table->invperm[y];
1175  if (cuddTestInteract(table,xindex,yindex)) {
1176  isolated = table->vars[yindex]->ref == 1;
1177  R -= table->subtables[y].keys - isolated;
1178  }
1179  size = cuddSwapInPlace(table,x,y);
1180  if (size == 0) goto ddLinearAndSiftingDownOutOfMem;
1181  newsize = cuddLinearInPlace(table,x,y);
1182  if (newsize == 0) goto ddLinearAndSiftingDownOutOfMem;
1183  move = (Move *) cuddDynamicAllocNode(table);
1184  if (move == NULL) goto ddLinearAndSiftingDownOutOfMem;
1185  move->x = x;
1186  move->y = y;
1187  move->next = moves;
1188  moves = move;
1189  move->flags = CUDD_SWAP_MOVE;
1190  if (newsize >= size) {
1191  /* Undo transformation. The transformation we apply is
1192  ** its own inverse. Hence, we just apply the transformation
1193  ** again.
1194  */
1195  newsize = cuddLinearInPlace(table,x,y);
1196  if (newsize == 0) goto ddLinearAndSiftingDownOutOfMem;
1197  if (newsize != size) {
1198  (void) fprintf(table->out,"Change in size after identity transformation! From %d to %d\n",size,newsize);
1199  }
1200  } else if (cuddTestInteract(table,xindex,yindex)) {
1201  size = newsize;
1203  cuddUpdateInteractionMatrix(table,xindex,yindex);
1204  }
1205  move->size = size;
1206  if ((double) size > (double) limitSize * table->maxGrowth) break;
1207  if (size < limitSize) limitSize = size;
1208  x = y;
1209  y = cuddNextHigh(table,x);
1210  }
1211  return(moves);
1212 
1213 ddLinearAndSiftingDownOutOfMem:
1214  while (moves != NULL) {
1215  move = moves->next;
1216  cuddDeallocMove(table, moves);
1217  moves = move;
1218  }
1219  return((Move *) CUDD_OUT_OF_MEM);
1220 
1221 } /* end of ddLinearAndSiftingDown */
DdHalfWord ref
Definition: cudd.h:272
unsigned int keys
Definition: cuddInt.h:314
#define CUDD_OUT_OF_MEM
Definition: cudd.h:91
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
double maxGrowth
Definition: cuddInt.h:397
DdSubtable * subtables
Definition: cuddInt.h:349
unsigned int keys
Definition: cuddInt.h:353
FILE * out
Definition: cuddInt.h:423
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
#define CUDD_SWAP_MOVE
Definition: cuddLinear.c:71
#define CUDD_LINEAR_TRANSFORM_MOVE
Definition: cuddLinear.c:72
void cuddUpdateInteractionMatrix(DdManager *table, int xindex, int yindex)
Definition: cuddLinear.c:714
int cuddLinearInPlace(DdManager *table, int x, int y)
Definition: cuddLinear.c:360
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:405
int cuddNextHigh(DdManager *table, int x)
Definition: cuddReorder.c:715
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddReorder.c:760
DdHalfWord y
Definition: cuddInt.h:471
DdNode ** vars
Definition: cuddInt.h:373
struct Move * next
Definition: cuddInt.h:474
int * invperm
Definition: cuddInt.h:371
int isolated
Definition: cuddInt.h:368
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInteract.c:188
int size
Definition: cuddInt.h:473

◆ ddLinearAndSiftingUp()

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

1007 {
1008  Move *moves;
1009  Move *move;
1010  int x;
1011  int size, newsize;
1012  int limitSize;
1013  int xindex, yindex;
1014  int isolated;
1015  int L; /* lower bound on DD size */
1016 #ifdef DD_DEBUG
1017  int checkL;
1018  int z;
1019  int zindex;
1020 #endif
1021 
1022  moves = prevMoves;
1023  yindex = table->invperm[y];
1024 
1025  /* Initialize the lower bound.
1026  ** The part of the DD below y will not change.
1027  ** The part of the DD above y that does not interact with y will not
1028  ** change. The rest may vanish in the best case, except for
1029  ** the nodes at level xLow, which will not vanish, regardless.
1030  */
1031  limitSize = L = table->keys - table->isolated;
1032  for (x = xLow + 1; x < y; x++) {
1033  xindex = table->invperm[x];
1034  if (cuddTestInteract(table,xindex,yindex)) {
1035  isolated = table->vars[xindex]->ref == 1;
1036  L -= table->subtables[x].keys - isolated;
1037  }
1038  }
1039  isolated = table->vars[yindex]->ref == 1;
1040  L -= table->subtables[y].keys - isolated;
1041 
1042  x = cuddNextLow(table,y);
1043  while (x >= xLow && L <= limitSize) {
1044  xindex = table->invperm[x];
1045 #ifdef DD_DEBUG
1046  checkL = table->keys - table->isolated;
1047  for (z = xLow + 1; z < y; z++) {
1048  zindex = table->invperm[z];
1049  if (cuddTestInteract(table,zindex,yindex)) {
1050  isolated = table->vars[zindex]->ref == 1;
1051  checkL -= table->subtables[z].keys - isolated;
1052  }
1053  }
1054  isolated = table->vars[yindex]->ref == 1;
1055  checkL -= table->subtables[y].keys - isolated;
1056  if (L != checkL) {
1057  (void) fprintf(table->out, "checkL(%d) != L(%d)\n",checkL,L);
1058  }
1059 #endif
1060  size = cuddSwapInPlace(table,x,y);
1061  if (size == 0) goto ddLinearAndSiftingUpOutOfMem;
1062  newsize = cuddLinearInPlace(table,x,y);
1063  if (newsize == 0) goto ddLinearAndSiftingUpOutOfMem;
1064  move = (Move *) cuddDynamicAllocNode(table);
1065  if (move == NULL) goto ddLinearAndSiftingUpOutOfMem;
1066  move->x = x;
1067  move->y = y;
1068  move->next = moves;
1069  moves = move;
1070  move->flags = CUDD_SWAP_MOVE;
1071  if (newsize >= size) {
1072  /* Undo transformation. The transformation we apply is
1073  ** its own inverse. Hence, we just apply the transformation
1074  ** again.
1075  */
1076  newsize = cuddLinearInPlace(table,x,y);
1077  if (newsize == 0) goto ddLinearAndSiftingUpOutOfMem;
1078 #ifdef DD_DEBUG
1079  if (newsize != size) {
1080  (void) fprintf(table->out,"Change in size after identity transformation! From %d to %d\n",size,newsize);
1081  }
1082 #endif
1083  } else if (cuddTestInteract(table,xindex,yindex)) {
1084  size = newsize;
1086  cuddUpdateInteractionMatrix(table,xindex,yindex);
1087  }
1088  move->size = size;
1089  /* Update the lower bound. */
1090  if (cuddTestInteract(table,xindex,yindex)) {
1091  isolated = table->vars[xindex]->ref == 1;
1092  L += table->subtables[y].keys - isolated;
1093  }
1094  if ((double) size > (double) limitSize * table->maxGrowth) break;
1095  if (size < limitSize) limitSize = size;
1096  y = x;
1097  x = cuddNextLow(table,y);
1098  }
1099  return(moves);
1100 
1101 ddLinearAndSiftingUpOutOfMem:
1102  while (moves != NULL) {
1103  move = moves->next;
1104  cuddDeallocMove(table, moves);
1105  moves = move;
1106  }
1107  return((Move *) CUDD_OUT_OF_MEM);
1108 
1109 } /* end of ddLinearAndSiftingUp */
DdHalfWord ref
Definition: cudd.h:272
unsigned int keys
Definition: cuddInt.h:314
#define CUDD_OUT_OF_MEM
Definition: cudd.h:91
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
int cuddNextLow(DdManager *table, int x)
Definition: cuddReorder.c:737
double maxGrowth
Definition: cuddInt.h:397
DdSubtable * subtables
Definition: cuddInt.h:349
unsigned int keys
Definition: cuddInt.h:353
FILE * out
Definition: cuddInt.h:423
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
#define CUDD_SWAP_MOVE
Definition: cuddLinear.c:71
#define CUDD_LINEAR_TRANSFORM_MOVE
Definition: cuddLinear.c:72
void cuddUpdateInteractionMatrix(DdManager *table, int xindex, int yindex)
Definition: cuddLinear.c:714
int cuddLinearInPlace(DdManager *table, int x, int y)
Definition: cuddLinear.c:360
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:405
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddReorder.c:760
DdHalfWord y
Definition: cuddInt.h:471
DdNode ** vars
Definition: cuddInt.h:373
struct Move * next
Definition: cuddInt.h:474
int * invperm
Definition: cuddInt.h:371
int isolated
Definition: cuddInt.h:368
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInteract.c:188
int size
Definition: cuddInt.h:473

◆ ddLinearUniqueCompare()

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

871 {
872 #if 0
873  if (entry[*ptrY] == entry[*ptrX]) {
874  return((*ptrX) - (*ptrY));
875  }
876 #endif
877  return(entry[*ptrY] - entry[*ptrX]);
878 
879 } /* end of ddLinearUniqueCompare */
static int * entry
Definition: cuddLinear.c:98

◆ ddUndoMoves()

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

1287 {
1288  Move *invmoves = NULL;
1289  Move *move;
1290  Move *invmove;
1291  int size;
1292 
1293  for (move = moves; move != NULL; move = move->next) {
1294  invmove = (Move *) cuddDynamicAllocNode(table);
1295  if (invmove == NULL) goto ddUndoMovesOutOfMem;
1296  invmove->x = move->x;
1297  invmove->y = move->y;
1298  invmove->next = invmoves;
1299  invmoves = invmove;
1300  if (move->flags == CUDD_SWAP_MOVE) {
1301  invmove->flags = CUDD_SWAP_MOVE;
1302  size = cuddSwapInPlace(table,(int)move->x,(int)move->y);
1303  if (!size) goto ddUndoMovesOutOfMem;
1304  } else if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) {
1306  size = cuddLinearInPlace(table,(int)move->x,(int)move->y);
1307  if (!size) goto ddUndoMovesOutOfMem;
1308  size = cuddSwapInPlace(table,(int)move->x,(int)move->y);
1309  if (!size) goto ddUndoMovesOutOfMem;
1310  } else { /* must be CUDD_INVERSE_TRANSFORM_MOVE */
1311 #ifdef DD_DEBUG
1312  (void) fprintf(table->err,"Unforseen event in ddUndoMoves!\n");
1313 #endif
1314  invmove->flags = CUDD_LINEAR_TRANSFORM_MOVE;
1315  size = cuddSwapInPlace(table,(int)move->x,(int)move->y);
1316  if (!size) goto ddUndoMovesOutOfMem;
1317  size = cuddLinearInPlace(table,(int)move->x,(int)move->y);
1318  if (!size) goto ddUndoMovesOutOfMem;
1319  }
1320  invmove->size = size;
1321  }
1322 
1323  return(invmoves);
1324 
1325 ddUndoMovesOutOfMem:
1326  while (invmoves != NULL) {
1327  move = invmoves->next;
1328  cuddDeallocMove(table, invmoves);
1329  invmoves = move;
1330  }
1331  return((Move *) CUDD_OUT_OF_MEM);
1332 
1333 } /* end of ddUndoMoves */
#define CUDD_OUT_OF_MEM
Definition: cudd.h:91
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
#define CUDD_INVERSE_TRANSFORM_MOVE
Definition: cuddLinear.c:73
FILE * err
Definition: cuddInt.h:424
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
#define CUDD_SWAP_MOVE
Definition: cuddLinear.c:71
#define CUDD_LINEAR_TRANSFORM_MOVE
Definition: cuddLinear.c:72
int cuddLinearInPlace(DdManager *table, int x, int y)
Definition: cuddLinear.c:360
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddReorder.c:405
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddReorder.c:760
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
int size
Definition: cuddInt.h:473

Variable Documentation

◆ DD_UNUSED

char rcsid [] DD_UNUSED = "$Id: cuddLinear.c,v 1.29 2012/02/05 01:07:19 fabio Exp $"
static

Definition at line 95 of file cuddLinear.c.

◆ entry

int* entry
static

Definition at line 98 of file cuddLinear.c.