You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							1114 lines
						
					
					
						
							32 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							1114 lines
						
					
					
						
							32 KiB
						
					
					
				
								/**CFile**********************************************************************
							 | 
						|
								
							 | 
						|
								  FileName     [dddmpStoreBdd.c]
							 | 
						|
								
							 | 
						|
								  PackageName  [dddmp]
							 | 
						|
								
							 | 
						|
								  Synopsis     [Functions to write BDDs to file.]
							 | 
						|
								
							 | 
						|
								  Description  [Functions to write BDDs to file.
							 | 
						|
								    BDDs are represended on file either in text or binary format under the
							 | 
						|
								    following rules.  A file contains a forest of BDDs (a vector of
							 | 
						|
								    Boolean functions).  BDD nodes are numbered with contiguous numbers,
							 | 
						|
								    from 1 to NNodes (total number of nodes on a file). 0 is not used to
							 | 
						|
								    allow negative node indexes for complemented edges.  A file contains
							 | 
						|
								    a header, including information about variables and roots to BDD
							 | 
						|
								    functions, followed by the list of nodes.  BDD nodes are listed
							 | 
						|
								    according to their numbering, and in the present implementation
							 | 
						|
								    numbering follows a post-order strategy, in such a way that a node
							 | 
						|
								    is never listed before its Then/Else children.
							 | 
						|
								  ]
							 | 
						|
								
							 | 
						|
								  Author       [Gianpiero Cabodi and Stefano Quer]
							 | 
						|
								
							 | 
						|
								  Copyright    [
							 | 
						|
								    Copyright (c) 2004 by Politecnico di Torino.
							 | 
						|
								    All Rights Reserved. This software is for educational purposes only.
							 | 
						|
								    Permission is given to academic institutions to use, copy, and modify
							 | 
						|
								    this software and its documentation provided that this introductory
							 | 
						|
								    message is not removed, that this software and its documentation is
							 | 
						|
								    used for the institutions' internal research and educational purposes,
							 | 
						|
								    and that no monies are exchanged. No guarantee is expressed or implied
							 | 
						|
								    by the distribution of this code.
							 | 
						|
								    Send bug-reports and/or questions to:
							 | 
						|
								    {gianpiero.cabodi,stefano.quer}@polito.it.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								#include "dddmpInt.h"
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Stucture declarations                                                     */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Type declarations                                                         */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Variable declarations                                                     */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Macro declarations                                                        */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								/**AutomaticStart*************************************************************/
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Static function prototypes                                                */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								static int NodeStoreRecurBdd(DdManager *ddMgr, DdNode *f, int mode, int *supportids, char **varnames, int *outids, FILE *fp);
							 | 
						|
								static int NodeTextStoreBdd(DdManager *ddMgr, DdNode *f, int mode, int *supportids, char **varnames, int *outids, FILE *fp, int idf, int vf, int idT, int idE);
							 | 
						|
								static int NodeBinaryStoreBdd(DdManager *ddMgr, DdNode *f, int mode, int *supportids, char **varnames, int *outids, FILE *fp, int idf, int vf, int idT, int idE, int vT, int vE, DdNode *T, DdNode *E);
							 | 
						|
								
							 | 
						|
								/**AutomaticEnd***************************************************************/
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Definition of exported functions                                          */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Writes a dump file representing the argument BDD.]
							 | 
						|
								
							 | 
						|
								  Description  [Dumps the argument BDD to file. Dumping is done through
							 | 
						|
								    Dddmp_cuddBddArrayStore. A dummy array of 1 BDD root is
							 | 
						|
								    used for this purpose.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects  [Nodes are temporarily removed from unique hash. They are
							 | 
						|
								    re-linked after the store operation in a modified order.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SeeAlso      [Dddmp_cuddBddLoad Dddmp_cuddBddArrayLoad]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								int
							 | 
						|
								Dddmp_cuddBddStore (
							 | 
						|
								  DdManager *ddMgr           /* IN: DD Manager */,
							 | 
						|
								  char *ddname               /* IN: DD name (or NULL) */,
							 | 
						|
								  DdNode *f                  /* IN: BDD root to be stored */,
							 | 
						|
								  char **varnames            /* IN: array of variable names (or NULL) */,
							 | 
						|
								  int *auxids                /* IN: array of converted var ids */,
							 | 
						|
								  int mode                   /* IN: storing mode selector */,
							 | 
						|
								  Dddmp_VarInfoType varinfo  /* IN: extra info for variables in text mode */,
							 | 
						|
								  char *fname                /* IN: File name */,
							 | 
						|
								  FILE *fp                   /* IN: File pointer to the store file */ 
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  int retValue;
							 | 
						|
								  DdNode *tmpArray[1];
							 | 
						|
								
							 | 
						|
								  tmpArray[0] = f;
							 | 
						|
								
							 | 
						|
								  retValue = Dddmp_cuddBddArrayStore (ddMgr,ddname,1,tmpArray,NULL,
							 | 
						|
								    varnames, auxids, mode, varinfo, fname, fp);
							 | 
						|
								
							 | 
						|
								  return (retValue);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Writes a dump file representing the argument Array of BDDs.]
							 | 
						|
								
							 | 
						|
								  Description  [Dumps the argument array of BDDs to file. Dumping is either 
							 | 
						|
								    in text or binary form.  BDDs are stored to the fp (already 
							 | 
						|
								    open) file if not NULL. Otherwise the file whose name is 
							 | 
						|
								    fname is opened in write mode. The header has the same format 
							 | 
						|
								    for both textual and binary dump. Names are allowed for input 
							 | 
						|
								    variables (vnames) and for represented functions (rnames). 
							 | 
						|
								    For sake of generality and because of dynamic variable 
							 | 
						|
								    ordering both variable IDs and permuted IDs are included. 
							 | 
						|
								    New IDs are also supported (auxids). Variables are identified 
							 | 
						|
								    with incremental numbers. according with their positiom in 
							 | 
						|
								    the support set. In text mode, an extra info may be added, 
							 | 
						|
								    chosen among the following options: name, ID, PermID, or an 
							 | 
						|
								    auxiliary id. Since conversion from DD pointers to integers 
							 | 
						|
								    is required, DD nodes are temporarily removed from the unique
							 | 
						|
								    hash table. This allows the use of the next field to store 
							 | 
						|
								    node IDs.
							 | 
						|
								   ]
							 | 
						|
								
							 | 
						|
								  SideEffects  [Nodes are temporarily removed from the unique hash
							 | 
						|
								    table. They are re-linked after the store operation in a 
							 | 
						|
								    modified order.
							 | 
						|
								    ] 
							 | 
						|
								
							 | 
						|
								  SeeAlso      [Dddmp_cuddBddStore, Dddmp_cuddBddLoad, 
							 | 
						|
								    Dddmp_cuddBddArrayLoad
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								int
							 | 
						|
								Dddmp_cuddBddArrayStore (
							 | 
						|
								  DdManager *ddMgr           /* IN: DD Manager */,
							 | 
						|
								  char *ddname               /* IN: dd name (or NULL) */,
							 | 
						|
								  int nRoots                 /* IN: number of output BDD roots to be stored */,
							 | 
						|
								  DdNode **f                 /* IN: array of BDD roots to be stored */,
							 | 
						|
								  char **rootnames           /* IN: array of root names (or NULL) */,
							 | 
						|
								  char **varnames            /* IN: array of variable names (or NULL) */,
							 | 
						|
								  int *auxids                /* IN: array of converted var IDs */,
							 | 
						|
								  int mode                   /* IN: storing mode selector */,
							 | 
						|
								  Dddmp_VarInfoType varinfo  /* IN: extra info for variables in text mode */,
							 | 
						|
								  char *fname                /* IN: File name */,
							 | 
						|
								  FILE *fp                   /* IN: File pointer to the store file */ 
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  int retValue;
							 | 
						|
								
							 | 
						|
								#ifdef DDDMP_DEBUG
							 | 
						|
								#ifndef __alpha__  
							 | 
						|
								  int retValueBis;
							 | 
						|
								
							 | 
						|
								  retValueBis = Cudd_DebugCheck (ddMgr);
							 | 
						|
								  if (retValueBis == 1) {
							 | 
						|
								    fprintf (stderr, "Inconsistency Found During BDD Store.\n");
							 | 
						|
								    fflush (stderr);
							 | 
						|
								  } else {
							 | 
						|
								    if (retValueBis == CUDD_OUT_OF_MEM) {
							 | 
						|
								      fprintf (stderr, "Out of Memory During BDD Store.\n");
							 | 
						|
								      fflush (stderr);
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								#endif
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								  retValue = DddmpCuddBddArrayStore (DDDMP_BDD, ddMgr, ddname, nRoots, f,
							 | 
						|
								    rootnames, varnames, auxids, mode, varinfo, fname, fp);
							 | 
						|
								
							 | 
						|
								#ifdef DDDMP_DEBUG
							 | 
						|
								#ifndef __alpha__  
							 | 
						|
								  retValueBis = Cudd_DebugCheck (ddMgr);
							 | 
						|
								  if (retValueBis == 1) {
							 | 
						|
								    fprintf (stderr, "Inconsistency Found During BDD Store.\n");
							 | 
						|
								    fflush (stderr);
							 | 
						|
								  } else {
							 | 
						|
								    if (retValueBis == CUDD_OUT_OF_MEM) {
							 | 
						|
								      fprintf (stderr, "Out of Memory During BDD Store.\n");
							 | 
						|
								      fflush (stderr);
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								#endif
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								  return (retValue);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Definition of internal functions                                          */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Writes a dump file representing the argument Array of
							 | 
						|
								    BDDs.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  Description  [Dumps the argument array of BDDs to file.
							 | 
						|
								    Internal function doing inner steps of store for BDDs.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects  [Nodes are temporarily removed from the unique hash
							 | 
						|
								    table. They are re-linked after the store operation in a 
							 | 
						|
								    modified order.
							 | 
						|
								    ]	
							 | 
						|
									
							 | 
						|
								  SeeAlso      [Dddmp_cuddBddStore, Dddmp_cuddBddLoad,
							 | 
						|
								    Dddmp_cuddBddArrayLoad
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								int
							 | 
						|
								DddmpCuddBddArrayStore (
							 | 
						|
								  Dddmp_DecompType ddType   /* IN: Selects the decomp type BDD */,
							 | 
						|
								  DdManager *ddMgr          /* IN: DD Manager */,
							 | 
						|
								  char *ddname              /* IN: DD name (or NULL) */,
							 | 
						|
								  int nRoots                /* IN: number of output BDD roots to be stored */,
							 | 
						|
								  DdNode **f                /* IN: array of DD roots to be stored */,
							 | 
						|
								  char **rootnames          /* IN: array of root names (or NULL) */,
							 | 
						|
								  char **varnames           /* IN: array of variable names (or NULL) */,
							 | 
						|
								  int *auxids               /* IN: array of converted var IDs */,
							 | 
						|
								  int mode                  /* IN: storing mode selector */,
							 | 
						|
								  Dddmp_VarInfoType varinfo /* IN: extra info for variables in text mode */,
							 | 
						|
								  char *fname               /* IN: File name */,
							 | 
						|
								  FILE *fp                  /* IN: File pointer to the store file */ 
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  DdNode *support = NULL;
							 | 
						|
								  DdNode *scan;
							 | 
						|
								  int *ids = NULL;
							 | 
						|
								  int *permids = NULL;
							 | 
						|
								  int *invpermids = NULL;
							 | 
						|
								  int *supportids = NULL;
							 | 
						|
								  int *outids = NULL;
							 | 
						|
								  char **outvarnames = NULL;
							 | 
						|
								  int nVars = ddMgr->size;
							 | 
						|
								  int nnodes;
							 | 
						|
								  int retValue;
							 | 
						|
								  int i, var;
							 | 
						|
								  int fileToClose = 0;
							 | 
						|
								
							 | 
						|
								  /* 
							 | 
						|
								   *  Check DD Type
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  Dddmp_CheckAndGotoLabel (ddType==DDDMP_ADD,
							 | 
						|
								    "Error writing to file: ADD Type.", failure);
							 | 
						|
								
							 | 
						|
								  /* 
							 | 
						|
								   *  Check if File needs to be opened in the proper mode.
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  if (fp == NULL) {
							 | 
						|
								    fp = fopen (fname, "w");
							 | 
						|
								    Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.",
							 | 
						|
								      failure);
							 | 
						|
								    fileToClose = 1;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* 
							 | 
						|
								   *  Force binary mode if automatic.
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  switch (mode) {
							 | 
						|
								    case DDDMP_MODE_TEXT:
							 | 
						|
								    case DDDMP_MODE_BINARY:
							 | 
						|
								      break;
							 | 
						|
								    case DDDMP_MODE_DEFAULT:
							 | 
						|
								      mode = DDDMP_MODE_BINARY;
							 | 
						|
								      break;
							 | 
						|
								    default:
							 | 
						|
								      mode = DDDMP_MODE_BINARY;
							 | 
						|
								      break;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* 
							 | 
						|
								   * Alloc vectors for variable IDs, perm IDs and support IDs.
							 | 
						|
								   *  +1 to include a slot for terminals.
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  ids = DDDMP_ALLOC (int, nVars);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (ids==NULL, "Error allocating memory.", failure);
							 | 
						|
								  permids = DDDMP_ALLOC (int, nVars);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (permids==NULL, "Error allocating memory.", failure);
							 | 
						|
								  invpermids = DDDMP_ALLOC (int, nVars);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (invpermids==NULL, "Error allocating memory.",
							 | 
						|
								    failure);
							 | 
						|
								  supportids = DDDMP_ALLOC (int, nVars+1);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (supportids==NULL, "Error allocating memory.",
							 | 
						|
								    failure);
							 | 
						|
								    
							 | 
						|
								  for (i=0; i<nVars; i++) {
							 | 
						|
								    ids[i] = permids[i] = invpermids[i] = supportids[i] = (-1);
							 | 
						|
								  }
							 | 
						|
								  /* StQ */
							 | 
						|
								  supportids[nVars] = -1;
							 | 
						|
								  
							 | 
						|
								  /* 
							 | 
						|
								   *  Take the union of the supports of each output function.
							 | 
						|
								   *  skip NULL functions.
							 | 
						|
								   *  Set permids and invpermids of support variables to the proper values.
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  for (i=0; i<nRoots; i++) {
							 | 
						|
								    if (f[i] == NULL) {
							 | 
						|
								      continue;
							 | 
						|
								    }
							 | 
						|
								    support = Cudd_Support (ddMgr, f[i]);
							 | 
						|
								    Dddmp_CheckAndGotoLabel (support==NULL, "NULL support returned.",
							 | 
						|
								      failure);
							 | 
						|
								    cuddRef (support);
							 | 
						|
								    scan = support;
							 | 
						|
								    while (!cuddIsConstant(scan)) {
							 | 
						|
								      ids[scan->index] = scan->index;
							 | 
						|
								      permids[scan->index] = ddMgr->perm[scan->index];
							 | 
						|
								      invpermids[ddMgr->perm[scan->index]] = scan->index;
							 | 
						|
								      scan = cuddT (scan);
							 | 
						|
								    }
							 | 
						|
								    Cudd_RecursiveDeref (ddMgr, support);
							 | 
						|
								  }
							 | 
						|
								  /* so that we do not try to free it in case of failure */
							 | 
						|
								  support = NULL;
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  Set supportids to incremental (shrinked) values following the ordering.
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  for (i=0, var=0; i<nVars; i++) {
							 | 
						|
								    if (invpermids[i] >= 0) {
							 | 
						|
								      supportids[invpermids[i]] = var++;
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								  /* set a dummy id for terminal nodes */
							 | 
						|
								  supportids[nVars] = var;
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  Select conversion array for extra var info
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  switch (mode) {
							 | 
						|
								    case DDDMP_MODE_TEXT:
							 | 
						|
								      switch (varinfo) {
							 | 
						|
								        case DDDMP_VARIDS:
							 | 
						|
								          outids = ids;
							 | 
						|
								          break;
							 | 
						|
								        case DDDMP_VARPERMIDS:
							 | 
						|
								          outids = permids;
							 | 
						|
								          break;
							 | 
						|
								        case DDDMP_VARAUXIDS:
							 | 
						|
								          outids = auxids;
							 | 
						|
								          break;
							 | 
						|
								        case DDDMP_VARNAMES:
							 | 
						|
								          outvarnames = varnames;
							 | 
						|
								          break;
							 | 
						|
								        case DDDMP_VARDEFAULT:
							 | 
						|
								          break;
							 | 
						|
								      }
							 | 
						|
								      break;
							 | 
						|
								    case DDDMP_MODE_BINARY:
							 | 
						|
								      outids = NULL;
							 | 
						|
								      break;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* 
							 | 
						|
								   *  Number dd nodes and count them (numbering is from 1 to nnodes)
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  nnodes = DddmpNumberBddNodes (ddMgr, f, nRoots);
							 | 
						|
								
							 | 
						|
								  /* 
							 | 
						|
								   * Start Header
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								#ifdef DDDMP_VERSION
							 | 
						|
								  retValue = fprintf (fp, ".ver %s\n", DDDMP_VERSION);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								    failure);
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								  retValue = fprintf (fp, ".mode %c\n", mode);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								    failure);
							 | 
						|
								
							 | 
						|
								  if (mode == DDDMP_MODE_TEXT) {
							 | 
						|
								    retValue = fprintf (fp, ".varinfo %d\n", varinfo);
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								      failure);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  if (ddname != NULL) {
							 | 
						|
								    retValue = fprintf (fp, ".dd %s\n",ddname);
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								      failure);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  retValue = fprintf (fp, ".nnodes %d\n", nnodes);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								    failure);
							 | 
						|
								
							 | 
						|
								  retValue = fprintf (fp, ".nvars %d\n", nVars);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								    failure);
							 | 
						|
								
							 | 
						|
								  retValue = fprintf (fp, ".nsuppvars %d\n", var);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								    failure);
							 | 
						|
								
							 | 
						|
								  /*------------  Write the Var Names by scanning the ids array -------------*/
							 | 
						|
								
							 | 
						|
								  if (varnames != NULL) {
							 | 
						|
								
							 | 
						|
								    retValue = fprintf (fp, ".suppvarnames");
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								      failure);
							 | 
						|
								
							 | 
						|
								    for (i=0; i<nVars; i++) {
							 | 
						|
								      if (ids[i] >= 0) {
							 | 
						|
								        if (varnames[ids[i]] == NULL) {
							 | 
						|
								          (void) fprintf (stderr,
							 | 
						|
								             "DdStore Warning: null variable name. DUMMY%d generated\n", i);
							 | 
						|
								          fflush (stderr);
							 | 
						|
								          varnames[ids[i]] = DDDMP_ALLOC (char, 10);
							 | 
						|
								          Dddmp_CheckAndGotoLabel (varnames[ids[i]] == NULL,
							 | 
						|
								            "Error allocating memory.", failure);
							 | 
						|
								          sprintf (varnames[ids[i]], "DUMMY%d", i);
							 | 
						|
								        }
							 | 
						|
								        retValue = fprintf (fp, " %s", varnames[ids[i]]);
							 | 
						|
								        Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								          failure);
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    retValue = fprintf (fp, "\n");
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								      failure);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*--------- Write the Var SUPPORT Names by scanning the ids array ---------*/
							 | 
						|
								
							 | 
						|
								  if (varnames != NULL) {
							 | 
						|
								    retValue = fprintf (fp, ".orderedvarnames");
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								      failure);
							 | 
						|
								
							 | 
						|
								    for (i=0; i<nVars; i++) {
							 | 
						|
								      if (varnames[ddMgr->invperm[i]] == NULL) {
							 | 
						|
								          (void) fprintf (stderr,
							 | 
						|
								           "DdStore Warning: null variable name. DUMMY%d generated\n", i);
							 | 
						|
								        fflush (stderr);
							 | 
						|
								        varnames[ddMgr->invperm[i]] = DDDMP_ALLOC (char, 10);
							 | 
						|
								        Dddmp_CheckAndGotoLabel (varnames[ddMgr->invperm[i]] == NULL,
							 | 
						|
								          "Error allocating memory.", failure);
							 | 
						|
								        sprintf (varnames[ddMgr->invperm[i]], "DUMMY%d", i);
							 | 
						|
								      }
							 | 
						|
								
							 | 
						|
								      retValue = fprintf (fp, " %s", varnames[ddMgr->invperm[i]]);
							 | 
						|
								      Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								        failure);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    retValue = fprintf (fp, "\n");
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								      failure);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*------------ Write the var ids by scanning the ids array ---------------*/
							 | 
						|
								
							 | 
						|
								  retValue = fprintf (fp, ".ids");
							 | 
						|
								  Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								    failure);
							 | 
						|
								
							 | 
						|
								  for (i=0; i<nVars; i++) {
							 | 
						|
								    if (ids[i] >= 0) {
							 | 
						|
								      retValue = fprintf (fp, " %d", i);
							 | 
						|
								      Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								        failure);
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								  retValue = fprintf (fp, "\n");
							 | 
						|
								  Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								    failure);
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  Write the var permids by scanning the permids array. 
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  retValue = fprintf (fp, ".permids");
							 | 
						|
								  Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								    failure);
							 | 
						|
								  for (i = 0; i < nVars; i++) {
							 | 
						|
								    if (permids[i] >= 0) {
							 | 
						|
								      retValue = fprintf (fp, " %d", permids[i]);
							 | 
						|
								      Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								        failure);
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  retValue = fprintf (fp, "\n");
							 | 
						|
								  Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								    failure);
							 | 
						|
								
							 | 
						|
								  if (auxids != NULL) {
							 | 
						|
								  
							 | 
						|
								    /*
							 | 
						|
								     * Write the var auxids by scanning the ids array. 
							 | 
						|
								     */
							 | 
						|
								
							 | 
						|
								    retValue = fprintf (fp, ".auxids");
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								      failure);
							 | 
						|
								    for (i = 0; i < nVars; i++) {
							 | 
						|
								      if (ids[i] >= 0) {
							 | 
						|
								        retValue = fprintf (fp, " %d", auxids[i]);
							 | 
						|
								        Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								          failure);
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								    retValue = fprintf (fp, "\n");
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								      failure);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* 
							 | 
						|
								   * Write the roots info. 
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  retValue = fprintf (fp, ".nroots %d\n", nRoots);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								    failure);
							 | 
						|
								
							 | 
						|
								  if (rootnames != NULL) {
							 | 
						|
								
							 | 
						|
								    /* 
							 | 
						|
								     * Write the root names. 
							 | 
						|
								     */
							 | 
						|
								
							 | 
						|
								    retValue = fprintf (fp, ".rootnames");
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								      failure);
							 | 
						|
								
							 | 
						|
								    for (i = 0; i < nRoots; i++) {
							 | 
						|
								      if (rootnames[i] == NULL) {
							 | 
						|
								        (void) fprintf (stderr,
							 | 
						|
								          "DdStore Warning: null variable name. ROOT%d generated\n",i);
							 | 
						|
								        fflush (stderr);
							 | 
						|
								        rootnames[i] = DDDMP_ALLOC(char,10);
							 | 
						|
								        Dddmp_CheckAndGotoLabel (rootnames[i]==NULL,
							 | 
						|
								          "Error writing to file.", failure);
							 | 
						|
								        sprintf(rootnames[ids[i]], "ROOT%d",i);
							 | 
						|
								      }
							 | 
						|
								      retValue = fprintf (fp, " %s", rootnames[i]);
							 | 
						|
								      Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								        failure);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    retValue = fprintf (fp, "\n");
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								      failure);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  retValue = fprintf (fp, ".rootids");
							 | 
						|
								  Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								    failure);
							 | 
						|
								
							 | 
						|
								  /* 
							 | 
						|
								   * Write BDD indexes of function roots.
							 | 
						|
								   * Use negative integers for complemented edges. 
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  for (i = 0; i < nRoots; i++) {
							 | 
						|
								    if (f[i] == NULL) {
							 | 
						|
								      (void) fprintf (stderr, "DdStore Warning: %d-th root is NULL\n",i);
							 | 
						|
								      fflush (stderr);
							 | 
						|
								      retValue = fprintf (fp, " 0");
							 | 
						|
								    }
							 | 
						|
								    if (Cudd_IsComplement(f[i])) {
							 | 
						|
								      retValue = fprintf (fp, " -%d",
							 | 
						|
								        DddmpReadNodeIndexBdd (Cudd_Regular (f[i])));
							 | 
						|
								    } else {
							 | 
						|
								      retValue = fprintf (fp, " %d",
							 | 
						|
								        DddmpReadNodeIndexBdd (Cudd_Regular (f[i])));
							 | 
						|
								    }
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								      failure);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  retValue = fprintf (fp, "\n");
							 | 
						|
								  Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								    failure);
							 | 
						|
								
							 | 
						|
								  retValue = fprintf (fp, ".nodes\n");
							 | 
						|
								  Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								    failure);
							 | 
						|
								
							 | 
						|
								  /* 
							 | 
						|
								   *  END HEADER
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  /* 
							 | 
						|
								   *  Call the function that really gets the job done.
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  for (i = 0; i < nRoots; i++) {
							 | 
						|
								    if (f[i] != NULL) {
							 | 
						|
								      retValue = NodeStoreRecurBdd (ddMgr, Cudd_Regular(f[i]),
							 | 
						|
								        mode, supportids, outvarnames, outids, fp);
							 | 
						|
								      Dddmp_CheckAndGotoLabel (retValue==DDDMP_FAILURE,
							 | 
						|
								        "Error writing to file.", failure);
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* 
							 | 
						|
								   *  Write trailer and return.
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  retValue = fprintf (fp, ".end\n");
							 | 
						|
								  Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								    failure);
							 | 
						|
								
							 | 
						|
								  if (fileToClose) {
							 | 
						|
								    fclose (fp);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  DddmpUnnumberBddNodes (ddMgr, f, nRoots);
							 | 
						|
								  DDDMP_FREE (ids);
							 | 
						|
								  DDDMP_FREE (permids);
							 | 
						|
								  DDDMP_FREE (invpermids);
							 | 
						|
								  DDDMP_FREE (supportids);
							 | 
						|
								
							 | 
						|
								  return (DDDMP_SUCCESS);
							 | 
						|
								
							 | 
						|
								  failure:
							 | 
						|
								
							 | 
						|
								    if (ids != NULL) {
							 | 
						|
								      DDDMP_FREE (ids);
							 | 
						|
								    }
							 | 
						|
								    if (permids != NULL) {
							 | 
						|
								      DDDMP_FREE (permids);
							 | 
						|
								    }
							 | 
						|
								    if (invpermids != NULL) {
							 | 
						|
								      DDDMP_FREE (invpermids);
							 | 
						|
								    }
							 | 
						|
								    if (supportids != NULL) {
							 | 
						|
								      DDDMP_FREE (supportids);
							 | 
						|
								    }
							 | 
						|
								    if (support != NULL) {
							 | 
						|
								      Cudd_RecursiveDeref (ddMgr, support);
							 | 
						|
								    }
							 | 
						|
								    
							 | 
						|
								    return (DDDMP_FAILURE);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Definition of static functions                                            */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Performs the recursive step of Dddmp_bddStore.]
							 | 
						|
								
							 | 
						|
								  Description  [Stores a node to file in either test or binary mode.<l>
							 | 
						|
								    In text mode a node is represented (on a text line basis) as
							 | 
						|
								    <UL>
							 | 
						|
								    <LI> node-index \[var-extrainfo\] var-index Then-index Else-index
							 | 
						|
								    </UL>
							 | 
						|
								    
							 | 
						|
								    where all indexes are integer numbers and var-extrainfo 
							 | 
						|
								    (optional redundant field) is either an integer or a string 
							 | 
						|
								    (variable name). Node-index is redundant (due to the node 
							 | 
						|
								    ordering) but we keep it for readability.<p>
							 | 
						|
								    
							 | 
						|
								    In binary mode nodes are represented as a sequence of bytes,
							 | 
						|
								    representing var-index, Then-index, and Else-index in an 
							 | 
						|
								    optimized way. Only the first byte (code) is mandatory. 
							 | 
						|
								    Integer indexes are represented in absolute or relative mode, 
							 | 
						|
								    where relative means offset wrt. a Then/Else node info. 
							 | 
						|
								    Suppose Var(NodeId), Then(NodeId) and Else(NodeId) represent 
							 | 
						|
								    infos about a given node.<p>
							 | 
						|
								    
							 | 
						|
								    The generic "NodeId" node is stored as 
							 | 
						|
								
							 | 
						|
								    <UL>
							 | 
						|
								    <LI> code-byte
							 | 
						|
								    <LI> \[var-info\]
							 | 
						|
								    <LI> \[Then-info\]
							 | 
						|
								    <LI> \[Else-info\]
							 | 
						|
								    </UL>
							 | 
						|
								
							 | 
						|
								    where code-byte contains bit fields
							 | 
						|
								
							 | 
						|
								    <UL>
							 | 
						|
								    <LI>Unused  : 1 bit
							 | 
						|
								    <LI>Variable: 2 bits, one of the following codes
							 | 
						|
								    <UL>
							 | 
						|
								    <LI>DDDMP_ABSOLUTE_ID   var-info = Var(NodeId) follows
							 | 
						|
								    <LI>DDDMP_RELATIVE_ID   Var(NodeId) is represented in relative form as
							 | 
						|
								        var-info = Min(Var(Then(NodeId)),Var(Else(NodeId))) -Var(NodeId)
							 | 
						|
								    <LI>DDDMP_RELATIVE_1    No var-info follows, because
							 | 
						|
								        Var(NodeId) = Min(Var(Then(NodeId)),Var(Else(NodeId)))-1
							 | 
						|
								    <LI>DDDMP_TERMINAL      Node is a terminal, no var info required
							 | 
						|
								    </UL>
							 | 
						|
								    <LI>T       : 2 bits, with codes similar to V
							 | 
						|
								    <UL>
							 | 
						|
								    <LI>DDDMP_ABSOLUTE_ID   Then-info = Then(NodeId) follows
							 | 
						|
								    <LI>DDDMP_RELATIVE_ID   Then(NodeId) is represented in relative form as
							 | 
						|
								          Then-info = Nodeid-Then(NodeId)
							 | 
						|
								    <LI>DDDMP_RELATIVE_1    No info on Then(NodeId) follows, because
							 | 
						|
								          Then(NodeId) = NodeId-1
							 | 
						|
								    <LI>DDDMP_TERMINAL Then Node is a terminal, no info required (for BDDs)
							 | 
						|
								    </UL>
							 | 
						|
								    <LI>Ecompl  : 1 bit, if 1 means complemented edge
							 | 
						|
								    <LI>E       : 2 bits, with codes and meanings as for the Then edge
							 | 
						|
								    </UL>
							 | 
						|
								    var-info, Then-info, Else-info (if required) are represented as unsigned 
							 | 
						|
								    integer values on a sufficient set of bytes (MSByte first).
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects  [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso      []
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static int
							 | 
						|
								NodeStoreRecurBdd (
							 | 
						|
								  DdManager *ddMgr  /* IN: DD Manager */,
							 | 
						|
								  DdNode *f         /* IN: DD node to be stored */,
							 | 
						|
								  int mode          /* IN: store mode */,
							 | 
						|
								  int *supportids   /* IN: internal ids for variables */,
							 | 
						|
								  char **varnames   /* IN: names of variables: to be stored with nodes */,
							 | 
						|
								  int *outids       /* IN: output ids for variables */,
							 | 
						|
								  FILE *fp          /* IN: store file */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  DdNode *T = NULL;
							 | 
						|
								  DdNode *E = NULL;
							 | 
						|
								  int idf = (-1);
							 | 
						|
								  int idT = (-1);
							 | 
						|
								  int idE = (-1);
							 | 
						|
								  int vf = (-1);
							 | 
						|
								  int vT = (-1);
							 | 
						|
								  int vE = (-1);
							 | 
						|
								  int retValue;
							 | 
						|
								  int nVars;
							 | 
						|
								
							 | 
						|
								  nVars = ddMgr->size;
							 | 
						|
								  T = E = NULL;
							 | 
						|
								  idf = idT =  idE = (-1);
							 | 
						|
								
							 | 
						|
								#ifdef DDDMP_DEBUG
							 | 
						|
								  assert(!Cudd_IsComplement(f));
							 | 
						|
								  assert(f!=NULL);
							 | 
						|
								  assert(supportids!=NULL);
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								  /* If already visited, nothing to do. */
							 | 
						|
								  if (DddmpVisitedBdd (f)) {
							 | 
						|
								    return (DDDMP_SUCCESS);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Mark node as visited. */
							 | 
						|
								  DddmpSetVisitedBdd (f);
							 | 
						|
								
							 | 
						|
								  if (Cudd_IsConstant(f)) {
							 | 
						|
								    /* Check for special case: don't recur */
							 | 
						|
								    idf = DddmpReadNodeIndexBdd (f);
							 | 
						|
								  } else {
							 | 
						|
								
							 | 
						|
								#ifdef DDDMP_DEBUG
							 | 
						|
								    /* BDDs! Only one constant supported */
							 | 
						|
								    assert (!cuddIsConstant(f));
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								    /* 
							 | 
						|
								     *  Recursive call for Then edge
							 | 
						|
								     */
							 | 
						|
								
							 | 
						|
								    T = cuddT(f);
							 | 
						|
								#ifdef DDDMP_DEBUG
							 | 
						|
								    /* ROBDDs! No complemented Then edge */
							 | 
						|
								    assert (!Cudd_IsComplement(T)); 
							 | 
						|
								#endif
							 | 
						|
								    /* recur */
							 | 
						|
								    retValue = NodeStoreRecurBdd (ddMgr, T, mode, supportids, varnames, outids,
							 | 
						|
								      fp);
							 | 
						|
								    if (retValue != DDDMP_SUCCESS) {
							 | 
						|
								      return (retValue);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /* 
							 | 
						|
								     *  Recursive call for Else edge
							 | 
						|
								     */
							 | 
						|
								
							 | 
						|
								    E = Cudd_Regular (cuddE (f));
							 | 
						|
								    retValue = NodeStoreRecurBdd (ddMgr, E, mode, supportids, varnames, outids,
							 | 
						|
								      fp);
							 | 
						|
								    if (retValue != DDDMP_SUCCESS) {
							 | 
						|
								      return (retValue);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /* 
							 | 
						|
								     *  Obtain nodeids and variable ids of f, T, E 
							 | 
						|
								     */
							 | 
						|
								
							 | 
						|
								    idf = DddmpReadNodeIndexBdd (f);
							 | 
						|
								    vf = f->index;
							 | 
						|
								
							 | 
						|
								    idT = DddmpReadNodeIndexBdd (T);
							 | 
						|
								    if (Cudd_IsConstant(T)) {
							 | 
						|
								      vT = nVars;
							 | 
						|
								    } else {
							 | 
						|
								      vT = T->index;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    idE = DddmpReadNodeIndexBdd (E);
							 | 
						|
								    if (Cudd_IsConstant(E)) {
							 | 
						|
								      vE = nVars;
							 | 
						|
								    } else {
							 | 
						|
								      vE = E->index;
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  switch (mode) {
							 | 
						|
								    case DDDMP_MODE_TEXT:
							 | 
						|
								      retValue = NodeTextStoreBdd (ddMgr, f, mode, supportids, varnames,
							 | 
						|
								        outids, fp, idf, vf, idT, idE);
							 | 
						|
								      break;
							 | 
						|
								    case DDDMP_MODE_BINARY:
							 | 
						|
								      retValue = NodeBinaryStoreBdd (ddMgr, f, mode, supportids, varnames,
							 | 
						|
								        outids, fp, idf, vf, idT, idE, vT, vE, T, E);
							 | 
						|
								      break;
							 | 
						|
								    default:
							 | 
						|
								      return (DDDMP_FAILURE);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  return (retValue);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Store One Single Node in Text Format.]
							 | 
						|
								
							 | 
						|
								  Description  [Store 1 0 0 for the terminal node.
							 | 
						|
								    Store id, left child pointer, right pointer for all the other nodes.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects  [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso      [NodeBinaryStoreBdd]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static int
							 | 
						|
								NodeTextStoreBdd (
							 | 
						|
								  DdManager *ddMgr  /* IN: DD Manager */,
							 | 
						|
								  DdNode *f         /* IN: DD node to be stored */,
							 | 
						|
								  int mode          /* IN: store mode */,
							 | 
						|
								  int *supportids   /* IN: internal ids for variables */,
							 | 
						|
								  char **varnames   /* IN: names of variables: to be stored with nodes */,
							 | 
						|
								  int *outids       /* IN: output ids for variables */,
							 | 
						|
								  FILE *fp          /* IN: Store file */,
							 | 
						|
								  int idf           /* IN: index of the current node */,
							 | 
						|
								  int vf            /* IN: variable of the current node */,
							 | 
						|
								  int idT           /* IN: index of the Then node */,
							 | 
						|
								  int idE           /* IN: index of the Else node */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  int retValue = EOF;
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  Check for Constant
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  if (Cudd_IsConstant(f)) {
							 | 
						|
								
							 | 
						|
								    if (f == Cudd_ReadOne(ddMgr)) {
							 | 
						|
								      if ((varnames != NULL) || (outids != NULL)) {
							 | 
						|
								        retValue = fprintf (fp, "%d T 1 0 0\n", idf);
							 | 
						|
								      } else {
							 | 
						|
								        retValue = fprintf (fp, "%d 1 0 0\n", idf);
							 | 
						|
								      }
							 | 
						|
								
							 | 
						|
								      if (retValue == EOF) {
							 | 
						|
								        return (DDDMP_FAILURE);
							 | 
						|
								      } else {
							 | 
						|
								        return (DDDMP_SUCCESS);
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    if (f == Cudd_ReadZero(ddMgr)) {
							 | 
						|
								      if ((varnames != NULL) || (outids != NULL)) {
							 | 
						|
								        retValue = fprintf (fp, "%d T 0 0 0\n", idf);
							 | 
						|
								      } else {
							 | 
						|
								        retValue = fprintf (fp, "%d 0 0 0\n", idf);
							 | 
						|
								      }
							 | 
						|
								
							 | 
						|
								      if (retValue == EOF) {
							 | 
						|
								        return (DDDMP_FAILURE);
							 | 
						|
								      } else {
							 | 
						|
								        return (DDDMP_SUCCESS);
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /*
							 | 
						|
								     *  A constant node different from 1: an ADD constant
							 | 
						|
								     */
							 | 
						|
								
							 | 
						|
								    Dddmp_CheckAndReturn (((varnames!=NULL)||(outids!=NULL)),
							 | 
						|
								      "Error writing to file: ADD Type.");
							 | 
						|
								
							 | 
						|
								    if (retValue == EOF) {
							 | 
						|
								      return (DDDMP_FAILURE);
							 | 
						|
								    } else {
							 | 
						|
								      return (DDDMP_SUCCESS);
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  ... Not A Constant
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  if (Cudd_IsComplement (cuddE(f))) {
							 | 
						|
								    idE = -idE;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  if (varnames != NULL) {   
							 | 
						|
								    retValue = fprintf (fp, "%d %s %d %d %d\n",
							 | 
						|
								       idf, varnames[vf], supportids[vf], idT, idE);
							 | 
						|
								
							 | 
						|
								    if (retValue == EOF) {
							 | 
						|
								      return (DDDMP_FAILURE);
							 | 
						|
								    } else {
							 | 
						|
								      return (DDDMP_SUCCESS);
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  if (outids != NULL) {   
							 | 
						|
								    retValue = fprintf (fp, "%d %d %d %d %d\n",
							 | 
						|
								       idf, outids[vf], supportids[vf], idT, idE);
							 | 
						|
								
							 | 
						|
								    if (retValue == EOF) {
							 | 
						|
								      return (DDDMP_FAILURE);
							 | 
						|
								    } else {
							 | 
						|
								      return (DDDMP_SUCCESS);
							 | 
						|
								    }
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								  retValue = fprintf (fp, "%d %d %d %d\n",
							 | 
						|
								    idf, supportids[vf], idT, idE);
							 | 
						|
								
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return (DDDMP_FAILURE);
							 | 
						|
								  } else {
							 | 
						|
								    return (DDDMP_SUCCESS);
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Store One Single Node in Binary Format.]
							 | 
						|
								
							 | 
						|
								  Description  [Store 1 0 0 for the terminal node.
							 | 
						|
								    Store id, left child pointer, right pointer for all the other nodes.
							 | 
						|
								    Store every information as coded binary values.]
							 | 
						|
								
							 | 
						|
								  SideEffects  [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso      [NodeTextStoreBdd]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static int
							 | 
						|
								NodeBinaryStoreBdd (
							 | 
						|
								  DdManager *ddMgr  /* IN: DD Manager */,
							 | 
						|
								  DdNode *f         /* IN: DD node to be stored */,
							 | 
						|
								  int mode          /* IN: store mode */,
							 | 
						|
								  int *supportids   /* IN: internal ids for variables */,
							 | 
						|
								  char **varnames   /* IN: names of variables: to be stored with nodes */,
							 | 
						|
								  int *outids       /* IN: output ids for variables */,
							 | 
						|
								  FILE *fp          /* IN: store file */,
							 | 
						|
								  int idf           /* IN: index of the node */,
							 | 
						|
								  int vf            /* IN: variable of the node */,
							 | 
						|
								  int idT           /* IN: index of the Then node */,
							 | 
						|
								  int idE           /* IN: index of the Else node */,
							 | 
						|
								  int vT            /* IN: variable of the Then node */,
							 | 
						|
								  int vE            /* IN: variable of the Else node */,
							 | 
						|
								  DdNode *T         /* IN: Then node */,
							 | 
						|
								  DdNode *E         /* IN: Else node */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  int retValue, diff, var;
							 | 
						|
								  struct binary_dd_code code;
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  Check for Constant
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  /* only integer ids used, varnames ignored */
							 | 
						|
								  /* Terminal one is coded as DDDMP_TERMINAL, all other fields are 0 */
							 | 
						|
								  if (Cudd_IsConstant(f)) {
							 | 
						|
								    code.Unused = 0;
							 | 
						|
								    code.V = DDDMP_TERMINAL;
							 | 
						|
								    code.T = 0;
							 | 
						|
								    code.E = 0;
							 | 
						|
								    code.Ecompl = 0;
							 | 
						|
								    retValue = DddmpWriteCode (fp,code);
							 | 
						|
								    if (retValue == EOF) {
							 | 
						|
								      return (DDDMP_FAILURE);
							 | 
						|
								    } else {
							 | 
						|
								      return (DDDMP_SUCCESS);
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   * Non terminal: output variable id
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  var = supportids[vf];
							 | 
						|
								  diff = (supportids[vT]<supportids[vE]) ? 
							 | 
						|
								    (supportids[vT]-var) : (supportids[vE]-var);
							 | 
						|
								  code.V = DDDMP_ABSOLUTE_ID;
							 | 
						|
								
							 | 
						|
								  if (diff <= var) {
							 | 
						|
								    if (diff == 1) {
							 | 
						|
								      code.V = DDDMP_RELATIVE_1;
							 | 
						|
								    } else {
							 | 
						|
								      code.V = DDDMP_RELATIVE_ID;
							 | 
						|
								      var = diff;
							 | 
						|
								    } 
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  if (T == DD_ONE(ddMgr)) {
							 | 
						|
								    code.T = DDDMP_TERMINAL;
							 | 
						|
								  } else {
							 | 
						|
								    /* compute displacement */
							 | 
						|
								    diff = idf - idT;
							 | 
						|
								    code.T = DDDMP_ABSOLUTE_ID;
							 | 
						|
								    if (diff <= idT) {
							 | 
						|
								      if (diff == 1) {
							 | 
						|
								         code.T = DDDMP_RELATIVE_1;
							 | 
						|
								      } else {
							 | 
						|
								         code.T = DDDMP_RELATIVE_ID;
							 | 
						|
									 idT = diff;
							 | 
						|
								      } 
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  if (E == DD_ONE(ddMgr)) {
							 | 
						|
								    code.E = DDDMP_TERMINAL;
							 | 
						|
								  } else {
							 | 
						|
								    /* compute displacement */
							 | 
						|
								    diff = idf - idE;
							 | 
						|
								    code.E = DDDMP_ABSOLUTE_ID;
							 | 
						|
								    if (diff <= idE) {
							 | 
						|
								      if (diff == 1) {
							 | 
						|
								        code.E = DDDMP_RELATIVE_1;
							 | 
						|
								      } else {
							 | 
						|
								        code.E = DDDMP_RELATIVE_ID;
							 | 
						|
									idE = diff;
							 | 
						|
								      } 
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  if (Cudd_IsComplement(cuddE(f))) {
							 | 
						|
								    code.Ecompl = 1;
							 | 
						|
								  } else {
							 | 
						|
								    code.Ecompl = 0;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  retValue = DddmpWriteCode (fp,code);
							 | 
						|
								  
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return (DDDMP_FAILURE);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  if ((code.V == DDDMP_ABSOLUTE_ID) || (code.V == DDDMP_RELATIVE_ID)) { 
							 | 
						|
								    retValue = DddmpWriteInt (fp, var);
							 | 
						|
								    if (retValue == EOF) {
							 | 
						|
								      return (DDDMP_FAILURE);
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  if ((code.T == DDDMP_ABSOLUTE_ID) || (code.T == DDDMP_RELATIVE_ID)) { 
							 | 
						|
								    retValue = DddmpWriteInt(fp,idT);
							 | 
						|
								    if (retValue == EOF) {
							 | 
						|
								      return (DDDMP_FAILURE);
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  if ((code.E == DDDMP_ABSOLUTE_ID) || (code.E == DDDMP_RELATIVE_ID)) { 
							 | 
						|
								    retValue = DddmpWriteInt(fp,idE);
							 | 
						|
								    if (retValue == EOF) {
							 | 
						|
								      return (DDDMP_FAILURE);
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  return (retValue);
							 | 
						|
								}
							 | 
						|
								
							 |