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.
		
		
		
		
		
			
		
			
				
					
					
						
							1641 lines
						
					
					
						
							48 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							1641 lines
						
					
					
						
							48 KiB
						
					
					
				
								/**CFile**********************************************************************
							 | 
						|
								
							 | 
						|
								  FileName     [dddmpStoreMisc.c]
							 | 
						|
								
							 | 
						|
								  PackageName  [dddmp]
							 | 
						|
								
							 | 
						|
								  Synopsis     [Functions to write out bdds to file in prefixed
							 | 
						|
								    and in Blif form.]
							 | 
						|
								
							 | 
						|
								  Description  [Functions to write out bdds to file. 
							 | 
						|
								    BDDs are represended on file in text format.
							 | 
						|
								    Each node is stored as a multiplexer in a prefix notation format for
							 | 
						|
								    the prefix notation file or in PLA format for the blif file.
							 | 
						|
								  ]
							 | 
						|
								
							 | 
						|
								  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 DddmpCuddDdArrayStorePrefix(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, char *modelName, FILE *fp);
							 | 
						|
								static int DddmpCuddDdArrayStorePrefixBody(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, FILE *fp);
							 | 
						|
								static int DddmpCuddDdArrayStorePrefixStep(DdManager * ddMgr, DdNode * f, FILE * fp, st_table * visited, char ** names);
							 | 
						|
								static int DddmpCuddDdArrayStoreBlif(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, char *modelName, FILE *fp);
							 | 
						|
								static int DddmpCuddDdArrayStoreBlifBody(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, FILE *fp);
							 | 
						|
								static int DddmpCuddDdArrayStoreBlifStep(DdManager *ddMgr, DdNode *f, FILE *fp, st_table *visited, char **names);
							 | 
						|
								static int DddmpCuddDdArrayStoreSmv(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, char *modelName, FILE *fp);
							 | 
						|
								static int DddmpCuddDdArrayStoreSmvBody(DdManager *ddMgr, int n, DdNode **f, char **inputNames, char **outputNames, FILE *fp);
							 | 
						|
								static int DddmpCuddDdArrayStoreSmvStep(DdManager * ddMgr, DdNode * f, FILE * fp, st_table * visited, char ** names);
							 | 
						|
								
							 | 
						|
								/**AutomaticEnd***************************************************************/
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Definition of exported functions                                          */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Writes a dump file representing the argument BDD in
							 | 
						|
								    a prefix notation.]
							 | 
						|
								
							 | 
						|
								  Description  [Dumps the argument BDD to file.
							 | 
						|
								    Dumping is done through Dddmp_cuddBddArrayStorePrefix.
							 | 
						|
								    A dummy array of 1 BDD root is used for this purpose.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects  []
							 | 
						|
								
							 | 
						|
								  SeeAlso      [Dddmp_cuddBddStore]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								int
							 | 
						|
								Dddmp_cuddBddStorePrefix (
							 | 
						|
								  DdManager *ddMgr     /* IN: DD Manager */,
							 | 
						|
								  int nRoots           /* IN: Number of BDD roots */,
							 | 
						|
								  DdNode *f            /* IN: BDD root to be stored */,
							 | 
						|
								  char **inputNames    /* IN: Array of variable names */,
							 | 
						|
								  char **outputNames   /* IN: Array of root names */,
							 | 
						|
								  char *modelName      /* IN: Model Name */,
							 | 
						|
								  char *fileName       /* IN: File name */,
							 | 
						|
								  FILE *fp             /* IN: File pointer to the store file */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  int retValue;
							 | 
						|
								  DdNode *tmpArray[1];
							 | 
						|
								
							 | 
						|
								  tmpArray[0] = f;
							 | 
						|
								
							 | 
						|
								  retValue = Dddmp_cuddBddArrayStorePrefix (ddMgr, 1, tmpArray,
							 | 
						|
								    inputNames, outputNames, modelName, fileName, fp);
							 | 
						|
								
							 | 
						|
								  return (retValue);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Writes a dump file representing the argument BDD in
							 | 
						|
								    a prefix notation.]
							 | 
						|
								
							 | 
						|
								  Description  [Dumps the argument BDD to file.
							 | 
						|
								    Dumping is done through Dddmp_cuddBddArrayStorePrefix.
							 | 
						|
								    A dummy array of 1 BDD root is used for this purpose.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects  []
							 | 
						|
								
							 | 
						|
								  SeeAlso      [Dddmp_cuddBddArrayStore]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								int
							 | 
						|
								Dddmp_cuddBddArrayStorePrefix (
							 | 
						|
								  DdManager *ddMgr       /* IN: DD Manager */,
							 | 
						|
								  int nroots             /* IN: number of output BDD roots to be stored */,
							 | 
						|
								  DdNode **f             /* IN: array of BDD roots to be stored */,
							 | 
						|
								  char **inputNames      /* IN: array of variable names (or NULL) */,
							 | 
						|
								  char **outputNames     /* IN: array of root names (or NULL) */,
							 | 
						|
								  char *modelName        /* IN: Model Name */,
							 | 
						|
								  char *fname            /* IN: File name */,
							 | 
						|
								  FILE *fp               /* IN: File pointer to the store file */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  int retValue;
							 | 
						|
								  int fileToClose = 0;
							 | 
						|
								
							 | 
						|
								#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
							 | 
						|
								
							 | 
						|
								  /* 
							 | 
						|
								   *  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;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  retValue = DddmpCuddDdArrayStorePrefix (ddMgr, nroots, f,
							 | 
						|
								    inputNames, outputNames, modelName, fp);
							 | 
						|
								
							 | 
						|
								  if (fileToClose) {
							 | 
						|
								    fclose (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);
							 | 
						|
								
							 | 
						|
								  failure:
							 | 
						|
								    return (DDDMP_FAILURE);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Writes a dump file representing the argument BDD in
							 | 
						|
								    a Blif/Exlif notation.]
							 | 
						|
								
							 | 
						|
								  Description  [Dumps the argument BDD to file.
							 | 
						|
								    Dumping is done through Dddmp_cuddBddArrayStoreBlif.
							 | 
						|
								    A dummy array of 1 BDD root is used for this purpose.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects  []
							 | 
						|
								
							 | 
						|
								  SeeAlso      [Dddmp_cuddBddStorePrefix]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								int
							 | 
						|
								Dddmp_cuddBddStoreBlif (
							 | 
						|
								  DdManager *ddMgr     /* IN: DD Manager */,
							 | 
						|
								  int nRoots           /* IN: Number of BDD roots */,
							 | 
						|
								  DdNode *f            /* IN: BDD root to be stored */,
							 | 
						|
								  char **inputNames    /* IN: Array of variable names */,
							 | 
						|
								  char **outputNames   /* IN: Array of root names */,
							 | 
						|
								  char *modelName      /* IN: Model Name */,
							 | 
						|
								  char *fileName       /* IN: File name */,
							 | 
						|
								  FILE *fp             /* IN: File pointer to the store file */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  int retValue;
							 | 
						|
								  DdNode *tmpArray[1];
							 | 
						|
								
							 | 
						|
								  tmpArray[0] = f;
							 | 
						|
								
							 | 
						|
								  retValue = Dddmp_cuddBddArrayStoreBlif (ddMgr, 1, tmpArray,
							 | 
						|
								    inputNames, outputNames, modelName, fileName, fp);
							 | 
						|
								
							 | 
						|
								  return (retValue);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Writes a dump file representing the argument BDD in
							 | 
						|
								    a Blif/Exlif notation.]
							 | 
						|
								
							 | 
						|
								  Description  [Dumps the argument BDD to file.
							 | 
						|
								    Dumping is done through Dddmp_cuddBddArrayStoreBLif.
							 | 
						|
								    A dummy array of 1 BDD root is used for this purpose.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects  []
							 | 
						|
								
							 | 
						|
								  SeeAlso      [Dddmp_cuddBddArrayStorePrefix]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								int
							 | 
						|
								Dddmp_cuddBddArrayStoreBlif (
							 | 
						|
								  DdManager *ddMgr       /* IN: DD Manager */,
							 | 
						|
								  int nroots             /* IN: number of output BDD roots to be stored */,
							 | 
						|
								  DdNode **f             /* IN: array of BDD roots to be stored */,
							 | 
						|
								  char **inputNames      /* IN: array of variable names (or NULL) */,
							 | 
						|
								  char **outputNames     /* IN: array of root names (or NULL) */,
							 | 
						|
								  char *modelName        /* IN: Model Name */,
							 | 
						|
								  char *fname            /* IN: File name */,
							 | 
						|
								  FILE *fp               /* IN: File pointer to the store file */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  int retValue;
							 | 
						|
								  int fileToClose = 0;
							 | 
						|
								
							 | 
						|
								#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
							 | 
						|
								
							 | 
						|
								  /* 
							 | 
						|
								   *  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;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  retValue = DddmpCuddDdArrayStoreBlif (ddMgr, nroots, f,
							 | 
						|
								    inputNames, outputNames, modelName, fp);
							 | 
						|
								
							 | 
						|
								  if (fileToClose) {
							 | 
						|
								    fclose (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);
							 | 
						|
								
							 | 
						|
								  failure:
							 | 
						|
								    return (DDDMP_FAILURE);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Writes a dump file representing the argument BDD in
							 | 
						|
								    a prefix notation.]
							 | 
						|
								
							 | 
						|
								  Description  [Dumps the argument BDD to file.
							 | 
						|
								    Dumping is done through Dddmp_cuddBddArrayStorePrefix.
							 | 
						|
								    A dummy array of 1 BDD root is used for this purpose.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects  []
							 | 
						|
								
							 | 
						|
								  SeeAlso      [Dddmp_cuddBddStore]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								int
							 | 
						|
								Dddmp_cuddBddStoreSmv (
							 | 
						|
								  DdManager *ddMgr     /* IN: DD Manager */,
							 | 
						|
								  int nRoots           /* IN: Number of BDD roots */,
							 | 
						|
								  DdNode *f            /* IN: BDD root to be stored */,
							 | 
						|
								  char **inputNames    /* IN: Array of variable names */,
							 | 
						|
								  char **outputNames   /* IN: Array of root names */,
							 | 
						|
								  char *modelName      /* IN: Model Name */,
							 | 
						|
								  char *fileName       /* IN: File name */,
							 | 
						|
								  FILE *fp             /* IN: File pointer to the store file */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  int retValue;
							 | 
						|
								  DdNode *tmpArray[1];
							 | 
						|
								
							 | 
						|
								  tmpArray[0] = f;
							 | 
						|
								
							 | 
						|
								  retValue = Dddmp_cuddBddArrayStoreSmv (ddMgr, 1, tmpArray,
							 | 
						|
								    inputNames, outputNames, modelName, fileName, fp);
							 | 
						|
								
							 | 
						|
								  return (retValue);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Writes a dump file representing the argument BDD in
							 | 
						|
								    a prefix notation.]
							 | 
						|
								
							 | 
						|
								  Description  [Dumps the argument BDD to file.
							 | 
						|
								    Dumping is done through Dddmp_cuddBddArrayStorePrefix.
							 | 
						|
								    A dummy array of 1 BDD root is used for this purpose.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects  []
							 | 
						|
								
							 | 
						|
								  SeeAlso      [Dddmp_cuddBddArrayStore]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								int
							 | 
						|
								Dddmp_cuddBddArrayStoreSmv (
							 | 
						|
								  DdManager *ddMgr       /* IN: DD Manager */,
							 | 
						|
								  int nroots             /* IN: number of output BDD roots to be stored */,
							 | 
						|
								  DdNode **f             /* IN: array of BDD roots to be stored */,
							 | 
						|
								  char **inputNames      /* IN: array of variable names (or NULL) */,
							 | 
						|
								  char **outputNames     /* IN: array of root names (or NULL) */,
							 | 
						|
								  char *modelName        /* IN: Model Name */,
							 | 
						|
								  char *fname            /* IN: File name */,
							 | 
						|
								  FILE *fp               /* IN: File pointer to the store file */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  int retValue;
							 | 
						|
								  int fileToClose = 0;
							 | 
						|
								
							 | 
						|
								#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
							 | 
						|
								
							 | 
						|
								  /* 
							 | 
						|
								   *  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;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  retValue = DddmpCuddDdArrayStoreSmv (ddMgr, nroots, f,
							 | 
						|
								    inputNames, outputNames, modelName, fp);
							 | 
						|
								
							 | 
						|
								  if (fileToClose) {
							 | 
						|
								    fclose (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);
							 | 
						|
								
							 | 
						|
								  failure:
							 | 
						|
								    return (DDDMP_FAILURE);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Definition of static functions                                            */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Internal function to writes a dump file representing the
							 | 
						|
								    argument BDD in a prefix notation.]
							 | 
						|
								
							 | 
						|
								  Description  [One multiplexer is written for each BDD node.
							 | 
						|
								    It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file
							 | 
						|
								    system full, or an ADD with constants different from 0 and 1).
							 | 
						|
								    It does not close the file: This is the caller responsibility.
							 | 
						|
								    It uses a minimal unique subset of the hexadecimal address of a node as
							 | 
						|
								    name for it.
							 | 
						|
								    If the argument inputNames is non-null, it is assumed to hold the
							 | 
						|
								    pointers to the names of the inputs. Similarly for outputNames.
							 | 
						|
								    For each BDD node of function f, variable v, then child T, and else
							 | 
						|
								    child E it stores:
							 | 
						|
								    f = v * T + v' * E
							 | 
						|
								    that is
							 | 
						|
								    (OR f (AND v T) (AND (NOT v) E))
							 | 
						|
								    If E is a complemented child this results in the following
							 | 
						|
								    (OR f (AND v T) (AND (NOT v) (NOT E)))
							 | 
						|
								    Comments (COMMENT) are added at the beginning of the description to
							 | 
						|
								    describe inputs and outputs of the design.
							 | 
						|
								    A buffer (BUF) is add on the output to cope with complemented functions.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso     [DddmpCuddDdArrayStoreBlif]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static int
							 | 
						|
								DddmpCuddDdArrayStorePrefix (
							 | 
						|
								  DdManager *ddMgr    /* IN: Manager */,
							 | 
						|
								  int n               /* IN: Number of output nodes to be dumped */,
							 | 
						|
								  DdNode **f          /* IN: Array of output nodes to be dumped */,
							 | 
						|
								  char **inputNames   /* IN: Array of input names (or NULL) */,
							 | 
						|
								  char **outputNames  /* IN: Array of output names (or NULL) */,
							 | 
						|
								  char *modelName     /* IN: Model name (or NULL) */,
							 | 
						|
								  FILE *fp            /* IN: Pointer to the dump file */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  DdNode *support = NULL;
							 | 
						|
								  DdNode *scan;
							 | 
						|
								  int *sorted = NULL;
							 | 
						|
								  int nVars = ddMgr->size;
							 | 
						|
								  int retValue;
							 | 
						|
								  int i;
							 | 
						|
								
							 | 
						|
								  /* Build a bit array with the support of f. */
							 | 
						|
								  sorted = ALLOC(int, nVars);
							 | 
						|
								  if (sorted == NULL) {
							 | 
						|
								    ddMgr->errorCode = CUDD_MEMORY_OUT;
							 | 
						|
								    Dddmp_CheckAndGotoLabel (1, "Allocation Error.", failure);
							 | 
						|
								  }
							 | 
						|
								  for (i = 0; i < nVars; i++) {
							 | 
						|
								    sorted[i] = 0;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Take the union of the supports of each output function. */
							 | 
						|
								  support = Cudd_VectorSupport(ddMgr,f,n);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (support==NULL,
							 | 
						|
								    "Error in function Cudd_VectorSupport.", failure);
							 | 
						|
								  cuddRef(support);
							 | 
						|
								  scan = support;
							 | 
						|
								  while (!cuddIsConstant(scan)) {
							 | 
						|
								    sorted[scan->index] = 1;
							 | 
						|
								    scan = cuddT(scan);
							 | 
						|
								  }
							 | 
						|
								  Cudd_RecursiveDeref(ddMgr,support);
							 | 
						|
								  /* so that we do not try to free it in case of failure */
							 | 
						|
								  support = NULL;
							 | 
						|
								
							 | 
						|
								  /* Write the header (.model .inputs .outputs). */
							 | 
						|
								  if (modelName == NULL) {
							 | 
						|
								    retValue = fprintf (fp, "(COMMENT - model name: Unknown )\n");
							 | 
						|
								  } else {
							 | 
						|
								    retValue = fprintf (fp, "(COMMENT - model name: %s )\n", modelName);
							 | 
						|
								  }
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  retValue = fprintf(fp, "(COMMENT - input names: ");
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								  /* Write the input list by scanning the support array. */
							 | 
						|
								  for (i = 0; i < nVars; i++) {
							 | 
						|
								    if (sorted[i]) {
							 | 
						|
								      if (inputNames == NULL) {
							 | 
						|
									retValue = fprintf(fp," inNode%d", i);
							 | 
						|
								      } else {
							 | 
						|
									retValue = fprintf(fp," %s", inputNames[i]);
							 | 
						|
								      }
							 | 
						|
								      Dddmp_CheckAndGotoLabel (retValue==EOF,
							 | 
						|
								        "Error during file store.", failure);
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								  FREE(sorted);
							 | 
						|
								  sorted = NULL;
							 | 
						|
								  retValue = fprintf(fp, " )\n");
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Write the .output line. */
							 | 
						|
								  retValue = fprintf(fp,"(COMMENT - output names: ");
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								  for (i = 0; i < n; i++) {
							 | 
						|
								    if (outputNames == NULL) {
							 | 
						|
								      retValue = fprintf (fp," outNode%d", i);
							 | 
						|
								    } else {
							 | 
						|
								      retValue = fprintf (fp," %s", outputNames[i]);
							 | 
						|
								    }
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==EOF,
							 | 
						|
								      "Error during file store.", failure);
							 | 
						|
								  } 
							 | 
						|
								  retValue = fprintf(fp, " )\n");
							 | 
						|
								  Dddmp_CheckAndGotoLabel (retValue==EOF,
							 | 
						|
								    "Error during file store.", failure);
							 | 
						|
								
							 | 
						|
								  retValue = DddmpCuddDdArrayStorePrefixBody (ddMgr, n, f, inputNames,
							 | 
						|
								    outputNames, fp);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (retValue==0,
							 | 
						|
								    "Error in function DddmpCuddDdArrayStorePrefixBody.", failure);
							 | 
						|
								
							 | 
						|
								  return(1);
							 | 
						|
								
							 | 
						|
								failure:
							 | 
						|
								    if (sorted != NULL) {
							 | 
						|
								      FREE(sorted);
							 | 
						|
								    }
							 | 
						|
								    if (support != NULL) {
							 | 
						|
								      Cudd_RecursiveDeref(ddMgr,support);
							 | 
						|
								    }
							 | 
						|
								    return(0);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Internal function to writes a dump file representing the
							 | 
						|
								    argument BDD in a prefix notation. Writes the body of the file.]
							 | 
						|
								
							 | 
						|
								  Description  [One multiplexer is written for each BDD node.
							 | 
						|
								    It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file
							 | 
						|
								    system full, or an ADD with constants different from 0 and 1).
							 | 
						|
								    It does not close the file: This is the caller responsibility.
							 | 
						|
								    It uses a minimal unique subset of the hexadecimal address of a node as
							 | 
						|
								    name for it.
							 | 
						|
								    If the argument inputNames is non-null, it is assumed to hold the
							 | 
						|
								    pointers to the names of the inputs. Similarly for outputNames.
							 | 
						|
								    For each BDD node of function f, variable v, then child T, and else
							 | 
						|
								    child E it stores:
							 | 
						|
								    f = v * T + v' * E
							 | 
						|
								    that is
							 | 
						|
								    (OR f (AND v T) (AND (NOT v) E))
							 | 
						|
								    If E is a complemented child this results in the following
							 | 
						|
								    (OR f (AND v T) (AND (NOT v) (NOT E)))
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso     [DddmpCuddDdArrayStoreBlif]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static int
							 | 
						|
								DddmpCuddDdArrayStorePrefixBody (
							 | 
						|
								  DdManager *ddMgr      /* IN: Manager */,
							 | 
						|
								  int n                 /* IN: Number of output nodes to be dumped */,
							 | 
						|
								  DdNode **f            /* IN: Array of output nodes to be dumped */,
							 | 
						|
								  char **inputNames     /* IN: Array of input names (or NULL) */,
							 | 
						|
								  char **outputNames    /* IN: Array of output names (or NULL) */,
							 | 
						|
								  FILE *fp              /* IN: Pointer to the dump file */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  st_table *visited = NULL;
							 | 
						|
								  int retValue;
							 | 
						|
								  int i;
							 | 
						|
								
							 | 
						|
								  /* Initialize symbol table for visited nodes. */
							 | 
						|
								  visited = st_init_table(st_ptrcmp, st_ptrhash);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (visited==NULL,
							 | 
						|
								    "Error if function st_init_table.", failure);
							 | 
						|
								
							 | 
						|
								  /* Call the function that really gets the job done. */
							 | 
						|
								  for (i = 0; i < n; i++) {
							 | 
						|
								    retValue = DddmpCuddDdArrayStorePrefixStep (ddMgr, Cudd_Regular(f[i]),
							 | 
						|
								      fp, visited, inputNames);
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==0,
							 | 
						|
								      "Error if function DddmpCuddDdArrayStorePrefixStep.", failure);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* To account for the possible complement on the root,
							 | 
						|
								   ** we put either a buffer or an inverter at the output of
							 | 
						|
								   ** the multiplexer representing the top node.
							 | 
						|
								   */
							 | 
						|
								  for (i=0; i<n; i++) {
							 | 
						|
								    if (outputNames == NULL) {
							 | 
						|
								      retValue = fprintf (fp,  "(BUF outNode%d ", i);
							 | 
						|
								    } else {
							 | 
						|
								      retValue = fprintf (fp,  "(BUF %s ", outputNames[i]);
							 | 
						|
								    }
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==EOF,
							 | 
						|
								      "Error during file store.", failure);
							 | 
						|
								
							 | 
						|
								    if (Cudd_IsComplement(f[i])) {
							 | 
						|
								#if SIZEOF_VOID_P == 8
							 | 
						|
								      retValue = fprintf (fp, "(NOT node%lx))\n",
							 | 
						|
								        (unsigned long) f[i] / (unsigned long) sizeof(DdNode));
							 | 
						|
								#else
							 | 
						|
								      retValue = fprintf (fp, "(NOT node%x))\n",
							 | 
						|
								        (unsigned) f[i] / (unsigned) sizeof(DdNode));
							 | 
						|
								#endif
							 | 
						|
								    } else {
							 | 
						|
								#if SIZEOF_VOID_P == 8
							 | 
						|
								      retValue = fprintf (fp, "node%lx)\n",
							 | 
						|
								        (unsigned long) f[i] / (unsigned long) sizeof(DdNode));
							 | 
						|
								#else
							 | 
						|
								      retValue = fprintf (fp, "node%x)\n",
							 | 
						|
								        (unsigned) f[i] / (unsigned) sizeof(DdNode));
							 | 
						|
								#endif
							 | 
						|
								    }
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==EOF,
							 | 
						|
								      "Error during file store.", failure);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  st_free_table (visited);
							 | 
						|
								
							 | 
						|
								  return(1);
							 | 
						|
								
							 | 
						|
								failure:
							 | 
						|
								    if (visited != NULL) st_free_table(visited);
							 | 
						|
								    return(0);
							 | 
						|
								
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis    [Performs the recursive step of
							 | 
						|
								    DddmpCuddDdArrayStorePrefixBody.]
							 | 
						|
								
							 | 
						|
								  Description [Performs the recursive step of
							 | 
						|
								    DddmpCuddDdArrayStorePrefixBody.
							 | 
						|
								    Traverses the BDD f and writes a multiplexer-network description to the
							 | 
						|
								    file pointed by fp.
							 | 
						|
								    For each BDD node of function f, variable v, then child T, and else
							 | 
						|
								    child E it stores:
							 | 
						|
								    f = v * T + v' * E
							 | 
						|
								    that is
							 | 
						|
								    (OR f (AND v T) (AND (NOT v) E))
							 | 
						|
								    If E is a complemented child this results in the following
							 | 
						|
								    (OR f (AND v T) (AND (NOT v) (NOT E)))
							 | 
						|
								    f is assumed to be a regular pointer and the function guarantees this
							 | 
						|
								    assumption in the recursive calls.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso     []
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static int
							 | 
						|
								DddmpCuddDdArrayStorePrefixStep (
							 | 
						|
								  DdManager * ddMgr,
							 | 
						|
								  DdNode * f,
							 | 
						|
								  FILE * fp,
							 | 
						|
								  st_table * visited,
							 | 
						|
								  char ** names
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  DdNode *T, *E;
							 | 
						|
								  int retValue;
							 | 
						|
								
							 | 
						|
								#ifdef DDDMP_DEBUG
							 | 
						|
								  assert(!Cudd_IsComplement(f));
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								  /* If already visited, nothing to do. */
							 | 
						|
								  if (st_is_member(visited, (char *) f) == 1) {
							 | 
						|
								    return(1);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Check for abnormal condition that should never happen. */
							 | 
						|
								  if (f == NULL) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Mark node as visited. */
							 | 
						|
								  if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Check for special case: If constant node, generate constant 1. */
							 | 
						|
								  if (f == DD_ONE (ddMgr)) {
							 | 
						|
								#if SIZEOF_VOID_P == 8
							 | 
						|
								    retValue = fprintf (fp,
							 | 
						|
								      "(OR node%lx vss vdd)\n",
							 | 
						|
								      (unsigned long) f / (unsigned long) sizeof(DdNode));
							 | 
						|
								#else
							 | 
						|
								    retValue = fprintf (fp,
							 | 
						|
								      "(OR node%x vss vdd)\n",
							 | 
						|
								      (unsigned) f / (unsigned) sizeof(DdNode));
							 | 
						|
								#endif
							 | 
						|
								    if (retValue == EOF) {
							 | 
						|
								       return(0);
							 | 
						|
								    } else {
							 | 
						|
								       return(1);
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  Check whether this is an ADD. We deal with 0-1 ADDs, but not
							 | 
						|
								   *  with the general case.
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  if (f == DD_ZERO(ddMgr)) {
							 | 
						|
								#if SIZEOF_VOID_P == 8
							 | 
						|
								    retValue = fprintf (fp,
							 | 
						|
								      "(AND node%lx vss vdd)\n",
							 | 
						|
								       (unsigned long) f / (unsigned long) sizeof(DdNode));
							 | 
						|
								#else
							 | 
						|
								    retValue = fprintf (fp,
							 | 
						|
								      "(AND node%x vss vdd)\n",
							 | 
						|
								      (unsigned) f / (unsigned) sizeof(DdNode));
							 | 
						|
								#endif
							 | 
						|
								   if (retValue == EOF) {
							 | 
						|
								     return(0);
							 | 
						|
								   } else {
							 | 
						|
								     return(1);
							 | 
						|
								   }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  if (cuddIsConstant(f)) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Recursive calls. */
							 | 
						|
								  T = cuddT(f);
							 | 
						|
								  retValue = DddmpCuddDdArrayStorePrefixStep (ddMgr,T,fp,visited,names);
							 | 
						|
								  if (retValue != 1) {
							 | 
						|
								    return(retValue);
							 | 
						|
								  }
							 | 
						|
								  E = Cudd_Regular(cuddE(f));
							 | 
						|
								  retValue = DddmpCuddDdArrayStorePrefixStep (ddMgr,E,fp,visited,names);
							 | 
						|
								  if (retValue != 1) {
							 | 
						|
								    return(retValue);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Write multiplexer taking complement arc into account. */
							 | 
						|
								#if SIZEOF_VOID_P == 8
							 | 
						|
								  retValue = fprintf (fp, "(OR node%lx (AND ",
							 | 
						|
								    (unsigned long) f / (unsigned long) sizeof(DdNode));
							 | 
						|
								#else
							 | 
						|
								  retValue = fprintf (fp, "(OR node%x (AND ",
							 | 
						|
								    (unsigned) f / (unsigned) sizeof(DdNode));
							 | 
						|
								#endif
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  if (names != NULL) {
							 | 
						|
								    retValue = fprintf(fp, "%s ", names[f->index]);
							 | 
						|
								  } else {
							 | 
						|
								    retValue = fprintf(fp, "inNode%d ", f->index);
							 | 
						|
								  }
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								#if SIZEOF_VOID_P == 8
							 | 
						|
								  retValue = fprintf (fp, "node%lx) (AND (NOT ",
							 | 
						|
								    (unsigned long) T / (unsigned long) sizeof(DdNode));
							 | 
						|
								#else
							 | 
						|
								  retValue = fprintf (fp, "node%x) (AND (NOT ",
							 | 
						|
								    (unsigned) T / (unsigned) sizeof(DdNode));
							 | 
						|
								#endif
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  if (names != NULL) {
							 | 
						|
								    retValue = fprintf (fp, "%s", names[f->index]);
							 | 
						|
								  } else {
							 | 
						|
								    retValue = fprintf (fp, "inNode%d", f->index);
							 | 
						|
								  }
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								#if SIZEOF_VOID_P == 8
							 | 
						|
								  if (Cudd_IsComplement(cuddE(f))) {
							 | 
						|
								    retValue = fprintf (fp, ") (NOT node%lx)))\n",
							 | 
						|
								      (unsigned long) E / (unsigned long) sizeof(DdNode));
							 | 
						|
								  } else {
							 | 
						|
								    retValue = fprintf (fp, ") node%lx))\n",
							 | 
						|
								      (unsigned long) E / (unsigned long) sizeof(DdNode));
							 | 
						|
								  }
							 | 
						|
								#else
							 | 
						|
								  if (Cudd_IsComplement(cuddE(f))) {
							 | 
						|
								    retValue = fprintf (fp, ") (NOT node%x)))\n",
							 | 
						|
								      (unsigned) E / (unsigned) sizeof(DdNode));
							 | 
						|
								  } else {
							 | 
						|
								    retValue = fprintf (fp, ") node%x))\n",
							 | 
						|
								      (unsigned) E / (unsigned) sizeof(DdNode));
							 | 
						|
								  }
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return(0);
							 | 
						|
								  } else {
							 | 
						|
								    return(1);
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis    [Writes a blif file representing the argument BDDs.]
							 | 
						|
								
							 | 
						|
								  Description [Writes a blif file representing the argument BDDs as a
							 | 
						|
								    network of multiplexers. One multiplexer is written for each BDD
							 | 
						|
								    node. It returns 1 in case of success; 0 otherwise (e.g.,
							 | 
						|
								    out-of-memory, file system full, or an ADD with constants different
							 | 
						|
								    from 0 and 1).
							 | 
						|
								    DddmpCuddDdArrayStoreBlif does not close the file: This is the
							 | 
						|
								    caller responsibility.
							 | 
						|
								    DddmpCuddDdArrayStoreBlif uses a minimal unique subset of
							 | 
						|
								    the hexadecimal address of a node as name for it.  If the argument
							 | 
						|
								    inames is non-null, it is assumed to hold the pointers to the names
							 | 
						|
								    of the inputs. Similarly for outputNames.
							 | 
						|
								    It prefixes the string "NODE" to each nome to have "regular" names
							 | 
						|
								    for each elements.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso     [DddmpCuddDdArrayStoreBlifBody,Cudd_DumpBlif]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static int
							 | 
						|
								DddmpCuddDdArrayStoreBlif (
							 | 
						|
								  DdManager *ddMgr    /* IN: Manager */,
							 | 
						|
								  int n               /* IN: Number of output nodes to be dumped */,
							 | 
						|
								  DdNode **f          /* IN: Array of output nodes to be dumped */,
							 | 
						|
								  char **inputNames   /* IN: Array of input names (or NULL) */,
							 | 
						|
								  char **outputNames  /* IN: Array of output names (or NULL) */,
							 | 
						|
								  char *modelName     /* IN: Model name (or NULL) */,
							 | 
						|
								  FILE *fp            /* IN: Pointer to the dump file */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  DdNode *support = NULL;
							 | 
						|
								  DdNode *scan;
							 | 
						|
								  int *sorted = NULL;
							 | 
						|
								  int nVars = ddMgr->size;
							 | 
						|
								  int retValue;
							 | 
						|
								  int i;
							 | 
						|
								
							 | 
						|
								  /* Build a bit array with the support of f. */
							 | 
						|
								  sorted = ALLOC (int, nVars);
							 | 
						|
								  if (sorted == NULL) {
							 | 
						|
								    ddMgr->errorCode = CUDD_MEMORY_OUT;
							 | 
						|
								    Dddmp_CheckAndGotoLabel (1, "Allocation Error.", failure);
							 | 
						|
								  }
							 | 
						|
								  for (i = 0; i < nVars; i++) {
							 | 
						|
								    sorted[i] = 0;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Take the union of the supports of each output function. */
							 | 
						|
								  support = Cudd_VectorSupport(ddMgr,f,n);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (support==NULL,
							 | 
						|
								    "Error in function Cudd_VectorSupport.", failure);
							 | 
						|
								  cuddRef(support);
							 | 
						|
								  scan = support;
							 | 
						|
								  while (!cuddIsConstant(scan)) {
							 | 
						|
								    sorted[scan->index] = 1;
							 | 
						|
								    scan = cuddT(scan);
							 | 
						|
								  }
							 | 
						|
								  Cudd_RecursiveDeref(ddMgr,support);
							 | 
						|
								  support = NULL;
							 | 
						|
								  /* so that we do not try to free it in case of failure */
							 | 
						|
								
							 | 
						|
								  /* Write the header (.model .inputs .outputs). */
							 | 
						|
								  if (modelName == NULL) {
							 | 
						|
								    retValue = fprintf(fp,".model DD\n.inputs");
							 | 
						|
								  } else {
							 | 
						|
								    retValue = fprintf(fp,".model %s\n.inputs", modelName);
							 | 
						|
								  }
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Write the input list by scanning the support array. */
							 | 
						|
								  for (i = 0; i < nVars; i++) {
							 | 
						|
								    if (sorted[i]) {
							 | 
						|
								      if (inputNames == NULL || (inputNames[i] == NULL)) {
							 | 
						|
									retValue = fprintf(fp," inNode%d", i);
							 | 
						|
								      } else {
							 | 
						|
									retValue = fprintf(fp," %s", inputNames[i]);
							 | 
						|
								      }
							 | 
						|
								      Dddmp_CheckAndGotoLabel (retValue==EOF,
							 | 
						|
								        "Error during file store.", failure);
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								  FREE(sorted);
							 | 
						|
								  sorted = NULL;
							 | 
						|
								
							 | 
						|
								  /* Write the .output line. */
							 | 
						|
								  retValue = fprintf(fp,"\n.outputs");
							 | 
						|
								  Dddmp_CheckAndGotoLabel (retValue==EOF,
							 | 
						|
								    "Error during file store.", failure);
							 | 
						|
								  for (i = 0; i < n; i++) {
							 | 
						|
								    if (outputNames == NULL || (outputNames[i] == NULL)) {
							 | 
						|
								      retValue = fprintf(fp," outNode%d", i);
							 | 
						|
								    } else {
							 | 
						|
								      retValue = fprintf(fp," %s", outputNames[i]);
							 | 
						|
								    }
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==EOF,
							 | 
						|
								      "Error during file store.", failure);
							 | 
						|
								  }
							 | 
						|
								  retValue = fprintf(fp,"\n");
							 | 
						|
								  Dddmp_CheckAndGotoLabel (retValue==EOF,
							 | 
						|
								    "Error during file store.", failure);
							 | 
						|
								
							 | 
						|
								  retValue = DddmpCuddDdArrayStoreBlifBody(ddMgr, n, f, inputNames,
							 | 
						|
								    outputNames, fp);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (retValue==0,
							 | 
						|
								    "Error if function DddmpCuddDdArrayStoreBlifBody.", failure);
							 | 
						|
								
							 | 
						|
								  /* Write trailer and return. */
							 | 
						|
								  retValue = fprintf (fp, ".end\n");
							 | 
						|
								  Dddmp_CheckAndGotoLabel (retValue==EOF,
							 | 
						|
								    "Error during file store.", failure);
							 | 
						|
								
							 | 
						|
								  return(1);
							 | 
						|
								
							 | 
						|
								failure:
							 | 
						|
								  if (sorted != NULL) {
							 | 
						|
								    FREE(sorted);
							 | 
						|
								  }
							 | 
						|
								  if (support != NULL) {
							 | 
						|
								    Cudd_RecursiveDeref(ddMgr,support);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  return(0);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis    [Writes a blif body representing the argument BDDs.]
							 | 
						|
								
							 | 
						|
								  Description [Writes a blif body representing the argument BDDs as a
							 | 
						|
								    network of multiplexers. One multiplexer is written for each BDD
							 | 
						|
								    node. It returns 1 in case of success; 0 otherwise (e.g.,
							 | 
						|
								    out-of-memory, file system full, or an ADD with constants different
							 | 
						|
								    from 0 and 1).
							 | 
						|
								    DddmpCuddDdArrayStoreBlif does not close the file: This is the
							 | 
						|
								    caller responsibility.
							 | 
						|
								    DddmpCuddDdArrayStoreBlif uses a minimal unique subset of
							 | 
						|
								    the hexadecimal address of a node as name for it.  If the argument
							 | 
						|
								    inputNames is non-null, it is assumed to hold the pointers to the names
							 | 
						|
								    of the inputs. Similarly for outputNames. This function prints out only
							 | 
						|
								    .names part.
							 | 
						|
								  ]
							 | 
						|
								
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso     []
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static int
							 | 
						|
								DddmpCuddDdArrayStoreBlifBody (
							 | 
						|
								  DdManager *ddMgr      /* IN: Manager */,
							 | 
						|
								  int n                 /* IN: Number of output nodes to be dumped */,
							 | 
						|
								  DdNode **f            /* IN: Array of output nodes to be dumped */,
							 | 
						|
								  char **inputNames     /* IN: Array of input names (or NULL) */,
							 | 
						|
								  char **outputNames    /* IN: Array of output names (or NULL) */,
							 | 
						|
								  FILE *fp              /* IN: Pointer to the dump file */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  st_table *visited = NULL;
							 | 
						|
								  int retValue;
							 | 
						|
								  int i;
							 | 
						|
								
							 | 
						|
								  /* Initialize symbol table for visited nodes. */
							 | 
						|
								  visited = st_init_table(st_ptrcmp, st_ptrhash);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (visited==NULL,
							 | 
						|
								    "Error if function st_init_table.", failure);
							 | 
						|
								
							 | 
						|
								  /* Call the function that really gets the job done. */
							 | 
						|
								  for (i = 0; i < n; i++) {
							 | 
						|
								    retValue = DddmpCuddDdArrayStoreBlifStep (ddMgr, Cudd_Regular(f[i]),
							 | 
						|
								      fp, visited, inputNames);
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==0,
							 | 
						|
								      "Error if function DddmpCuddDdArrayStoreBlifStep.", failure);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  To account for the possible complement on the root,
							 | 
						|
								   *  we put either a buffer or an inverter at the output of
							 | 
						|
								   *  the multiplexer representing the top node.
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  for (i = 0; i < n; i++) {
							 | 
						|
								    if (outputNames == NULL) {
							 | 
						|
								      retValue = fprintf(fp,
							 | 
						|
								#if SIZEOF_VOID_P == 8
							 | 
						|
								        ".names node%lx outNode%d\n",
							 | 
						|
								        (unsigned long) f[i] / (unsigned long) sizeof(DdNode), i);
							 | 
						|
								#else
							 | 
						|
									".names node%x outNode%d\n",
							 | 
						|
								        (unsigned) f[i] / (unsigned) sizeof(DdNode), i);
							 | 
						|
								#endif
							 | 
						|
								    } else {
							 | 
						|
								      retValue = fprintf(fp,
							 | 
						|
								#if SIZEOF_VOID_P == 8
							 | 
						|
								        ".names node%lx %s\n",
							 | 
						|
								        (unsigned long) f[i] / (unsigned long) sizeof(DdNode), outputNames[i]);
							 | 
						|
								#else
							 | 
						|
								        ".names node%x %s\n",
							 | 
						|
								        (unsigned) f[i] / (unsigned) sizeof(DdNode), outputNames[i]);
							 | 
						|
								#endif
							 | 
						|
								    }
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==EOF,
							 | 
						|
								      "Error during file store.", failure);
							 | 
						|
								    if (Cudd_IsComplement(f[i])) {
							 | 
						|
								      retValue = fprintf(fp,"0 1\n");
							 | 
						|
								    } else {
							 | 
						|
								      retValue = fprintf(fp,"1 1\n");
							 | 
						|
								    }
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==EOF,
							 | 
						|
								      "Error during file store.", failure);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  st_free_table(visited);
							 | 
						|
								  return(1);
							 | 
						|
								
							 | 
						|
								failure:
							 | 
						|
								  if (visited != NULL) {
							 | 
						|
								    st_free_table(visited);
							 | 
						|
								  }
							 | 
						|
								  return(0);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis    [Performs the recursive step of DddmpCuddDdArrayStoreBlif.]
							 | 
						|
								
							 | 
						|
								  Description [Performs the recursive step of DddmpCuddDdArrayStoreBlif.
							 | 
						|
								    Traverses the BDD f and writes a multiplexer-network description to
							 | 
						|
								    the file pointed by fp in blif format.
							 | 
						|
								    f is assumed to be a regular pointer and DddmpCuddDdArrayStoreBlifStep
							 | 
						|
								    guarantees this assumption in the recursive calls.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso     []
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static int
							 | 
						|
								DddmpCuddDdArrayStoreBlifStep (
							 | 
						|
								  DdManager *ddMgr,
							 | 
						|
								  DdNode *f,
							 | 
						|
								  FILE *fp,
							 | 
						|
								  st_table *visited,
							 | 
						|
								  char **names
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  DdNode *T, *E;
							 | 
						|
								  int retValue;
							 | 
						|
								
							 | 
						|
								#ifdef DDDMP_DEBUG
							 | 
						|
								  assert(!Cudd_IsComplement(f));
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								  /* If already visited, nothing to do. */
							 | 
						|
								  if (st_is_member(visited, (char *) f) == 1) {
							 | 
						|
								    return(1);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Check for abnormal condition that should never happen. */
							 | 
						|
								  if (f == NULL) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Mark node as visited. */
							 | 
						|
								  if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Check for special case: If constant node, generate constant 1. */
							 | 
						|
								  if (f == DD_ONE(ddMgr)) {
							 | 
						|
								#if SIZEOF_VOID_P == 8
							 | 
						|
								    retValue = fprintf(fp, ".names node%lx\n1\n",
							 | 
						|
								      (unsigned long) f / (unsigned long) sizeof(DdNode));
							 | 
						|
								#else
							 | 
						|
								    retValue = fprintf(fp, ".names node%x\n1\n",
							 | 
						|
								      (unsigned) f / (unsigned) sizeof(DdNode));
							 | 
						|
								#endif
							 | 
						|
								     if (retValue == EOF) {
							 | 
						|
								       return(0);
							 | 
						|
								     } else {
							 | 
						|
								       return(1);
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Check whether this is an ADD. We deal with 0-1 ADDs, but not
							 | 
						|
								  ** with the general case.
							 | 
						|
								  */
							 | 
						|
								  if (f == DD_ZERO(ddMgr)) {
							 | 
						|
								#if SIZEOF_VOID_P == 8
							 | 
						|
								    retValue = fprintf(fp, ".names node%lx\n",
							 | 
						|
								      (unsigned long) f / (unsigned long) sizeof(DdNode));
							 | 
						|
								#else
							 | 
						|
								    retValue = fprintf(fp, ".names node%x\n",
							 | 
						|
								      (unsigned) f / (unsigned) sizeof(DdNode));
							 | 
						|
								#endif
							 | 
						|
								    if (retValue == EOF) {
							 | 
						|
								      return(0);
							 | 
						|
								    } else {
							 | 
						|
								      return(1);
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								  if (cuddIsConstant(f)) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Recursive calls. */
							 | 
						|
								  T = cuddT(f);
							 | 
						|
								  retValue = DddmpCuddDdArrayStoreBlifStep(ddMgr,T,fp,visited,names);
							 | 
						|
								  if (retValue != 1) return(retValue);
							 | 
						|
								  E = Cudd_Regular(cuddE(f));
							 | 
						|
								  retValue = DddmpCuddDdArrayStoreBlifStep(ddMgr,E,fp,visited,names);
							 | 
						|
								  if (retValue != 1) return(retValue);
							 | 
						|
								
							 | 
						|
								  /* Write multiplexer taking complement arc into account. */
							 | 
						|
								  if (names != NULL) {
							 | 
						|
								    retValue = fprintf(fp,".names %s", names[f->index]);
							 | 
						|
								  } else {
							 | 
						|
								    retValue = fprintf(fp,".names inNode%d", f->index);
							 | 
						|
								  }
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								#if SIZEOF_VOID_P == 8
							 | 
						|
								  if (Cudd_IsComplement(cuddE(f))) {
							 | 
						|
								    retValue = fprintf(fp," node%lx node%lx node%lx\n11- 1\n0-0 1\n",
							 | 
						|
								      (unsigned long) T / (unsigned long) sizeof(DdNode),
							 | 
						|
								      (unsigned long) E / (unsigned long) sizeof(DdNode),
							 | 
						|
								      (unsigned long) f / (unsigned long) sizeof(DdNode));
							 | 
						|
								  } else {
							 | 
						|
								    retValue = fprintf(fp," node%lx node%lx node%lx\n11- 1\n0-1 1\n",
							 | 
						|
								      (unsigned long) T / (unsigned long) sizeof(DdNode),
							 | 
						|
								      (unsigned long) E / (unsigned long) sizeof(DdNode),
							 | 
						|
								      (unsigned long) f / (unsigned long) sizeof(DdNode));
							 | 
						|
								  }
							 | 
						|
								#else
							 | 
						|
								  if (Cudd_IsComplement(cuddE(f))) {
							 | 
						|
								    retValue = fprintf(fp," node%x node%x node%x\n11- 1\n0-0 1\n",
							 | 
						|
								      (unsigned) T / (unsigned) sizeof(DdNode),
							 | 
						|
								      (unsigned) E / (unsigned) sizeof(DdNode),
							 | 
						|
								      (unsigned) f / (unsigned) sizeof(DdNode));
							 | 
						|
								  } else {
							 | 
						|
								    retValue = fprintf(fp," node%x node%x node%x\n11- 1\n0-1 1\n",
							 | 
						|
								      (unsigned) T / (unsigned) sizeof(DdNode),
							 | 
						|
								      (unsigned) E / (unsigned) sizeof(DdNode),
							 | 
						|
								      (unsigned) f / (unsigned) sizeof(DdNode));
							 | 
						|
								  }
							 | 
						|
								#endif
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return(0);
							 | 
						|
								  } else {
							 | 
						|
								    return(1);
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Internal function to writes a dump file representing the
							 | 
						|
								    argument BDD in a SMV notation.]
							 | 
						|
								
							 | 
						|
								  Description  [One multiplexer is written for each BDD node.
							 | 
						|
								    It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file
							 | 
						|
								    system full, or an ADD with constants different from 0 and 1).
							 | 
						|
								    It does not close the file: This is the caller responsibility.
							 | 
						|
								    It uses a minimal unique subset of the hexadecimal address of a node as
							 | 
						|
								    name for it.
							 | 
						|
								    If the argument inputNames is non-null, it is assumed to hold the
							 | 
						|
								    pointers to the names of the inputs. Similarly for outputNames.
							 | 
						|
								    For each BDD node of function f, variable v, then child T, and else
							 | 
						|
								    child E it stores:
							 | 
						|
								    f = v * T + v' * E
							 | 
						|
								    that is
							 | 
						|
								    (OR f (AND v T) (AND (NOT v) E))
							 | 
						|
								    If E is a complemented child this results in the following
							 | 
						|
								    (OR f (AND v T) (AND (NOT v) (NOT E)))
							 | 
						|
								    Comments (COMMENT) are added at the beginning of the description to
							 | 
						|
								    describe inputs and outputs of the design.
							 | 
						|
								    A buffer (BUF) is add on the output to cope with complemented functions.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso     [DddmpCuddDdArrayStoreBlif]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static int
							 | 
						|
								DddmpCuddDdArrayStoreSmv (
							 | 
						|
								  DdManager *ddMgr    /* IN: Manager */,
							 | 
						|
								  int n               /* IN: Number of output nodes to be dumped */,
							 | 
						|
								  DdNode **f          /* IN: Array of output nodes to be dumped */,
							 | 
						|
								  char **inputNames   /* IN: Array of input names (or NULL) */,
							 | 
						|
								  char **outputNames  /* IN: Array of output names (or NULL) */,
							 | 
						|
								  char *modelName     /* IN: Model name (or NULL) */,
							 | 
						|
								  FILE *fp            /* IN: Pointer to the dump file */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  DdNode *support = NULL;
							 | 
						|
								  DdNode *scan;
							 | 
						|
								  int *sorted = NULL;
							 | 
						|
								  int nVars = ddMgr->size;
							 | 
						|
								  int retValue;
							 | 
						|
								  int i;
							 | 
						|
								
							 | 
						|
								  /* Build a bit array with the support of f. */
							 | 
						|
								  sorted = ALLOC(int, nVars);
							 | 
						|
								  if (sorted == NULL) {
							 | 
						|
								    ddMgr->errorCode = CUDD_MEMORY_OUT;
							 | 
						|
								    Dddmp_CheckAndGotoLabel (1, "Allocation Error.", failure);
							 | 
						|
								  }
							 | 
						|
								  for (i = 0; i < nVars; i++) {
							 | 
						|
								    sorted[i] = 0;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Take the union of the supports of each output function. */
							 | 
						|
								  support = Cudd_VectorSupport(ddMgr,f,n);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (support==NULL,
							 | 
						|
								    "Error in function Cudd_VectorSupport.", failure);
							 | 
						|
								  cuddRef(support);
							 | 
						|
								  scan = support;
							 | 
						|
								  while (!cuddIsConstant(scan)) {
							 | 
						|
								    sorted[scan->index] = 1;
							 | 
						|
								    scan = cuddT(scan);
							 | 
						|
								  }
							 | 
						|
								  Cudd_RecursiveDeref(ddMgr,support);
							 | 
						|
								  /* so that we do not try to free it in case of failure */
							 | 
						|
								  support = NULL;
							 | 
						|
								
							 | 
						|
								  /* Write the header */
							 | 
						|
								  if (modelName == NULL) {
							 | 
						|
								    retValue = fprintf (fp, "MODULE main -- Unknown\n");
							 | 
						|
								  } else {
							 | 
						|
								    retValue = fprintf (fp, "MODULE main -- %s\n", modelName);
							 | 
						|
								  }
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  retValue = fprintf(fp, "IVAR\n");
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Write the input list by scanning the support array. */
							 | 
						|
								  for (i=0; i<nVars; i++) {
							 | 
						|
								    if (sorted[i]) {
							 | 
						|
								      if (inputNames == NULL) {
							 | 
						|
									retValue = fprintf (fp, " inNode%d : boolean;\n", i);
							 | 
						|
								      } else {
							 | 
						|
									retValue = fprintf (fp, " %s : boolean;\n", inputNames[i]);
							 | 
						|
								      }
							 | 
						|
								      Dddmp_CheckAndGotoLabel (retValue==EOF,
							 | 
						|
								        "Error during file store.", failure);
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								  FREE(sorted);
							 | 
						|
								  sorted = NULL;
							 | 
						|
								
							 | 
						|
								  retValue = fprintf (fp, "\nDEFINE\n");
							 | 
						|
								
							 | 
						|
								  retValue = DddmpCuddDdArrayStoreSmvBody (ddMgr, n, f, inputNames,
							 | 
						|
								    outputNames, fp);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (retValue==0,
							 | 
						|
								    "Error in function DddmpCuddDdArrayStoreSmvBody.", failure);
							 | 
						|
								
							 | 
						|
								  return(1);
							 | 
						|
								
							 | 
						|
								failure:
							 | 
						|
								    if (sorted != NULL) {
							 | 
						|
								      FREE(sorted);
							 | 
						|
								    }
							 | 
						|
								    if (support != NULL) {
							 | 
						|
								      Cudd_RecursiveDeref(ddMgr,support);
							 | 
						|
								    }
							 | 
						|
								    return(0);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Internal function to writes a dump file representing the
							 | 
						|
								    argument BDD in a SMV notation. Writes the body of the file.]
							 | 
						|
								
							 | 
						|
								  Description  [One multiplexer is written for each BDD node.
							 | 
						|
								    It returns 1 in case of success; 0 otherwise (e.g., out-of-memory, file
							 | 
						|
								    system full, or an ADD with constants different from 0 and 1).
							 | 
						|
								    It does not close the file: This is the caller responsibility.
							 | 
						|
								    It uses a minimal unique subset of the hexadecimal address of a node as
							 | 
						|
								    name for it.
							 | 
						|
								    If the argument inputNames is non-null, it is assumed to hold the
							 | 
						|
								    pointers to the names of the inputs. Similarly for outputNames.
							 | 
						|
								    For each BDD node of function f, variable v, then child T, and else
							 | 
						|
								    child E it stores:
							 | 
						|
								    f = v * T + v' * E
							 | 
						|
								    that is
							 | 
						|
								    (OR f (AND v T) (AND (NOT v) E))
							 | 
						|
								    If E is a complemented child this results in the following
							 | 
						|
								    (OR f (AND v T) (AND (NOT v) (NOT E)))
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso     [DddmpCuddDdArrayStoreBlif]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static int
							 | 
						|
								DddmpCuddDdArrayStoreSmvBody (
							 | 
						|
								  DdManager *ddMgr      /* IN: Manager */,
							 | 
						|
								  int n                 /* IN: Number of output nodes to be dumped */,
							 | 
						|
								  DdNode **f            /* IN: Array of output nodes to be dumped */,
							 | 
						|
								  char **inputNames     /* IN: Array of input names (or NULL) */,
							 | 
						|
								  char **outputNames    /* IN: Array of output names (or NULL) */,
							 | 
						|
								  FILE *fp              /* IN: Pointer to the dump file */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  st_table *visited = NULL;
							 | 
						|
								  int retValue;
							 | 
						|
								  int i;
							 | 
						|
								
							 | 
						|
								  /* Initialize symbol table for visited nodes. */
							 | 
						|
								  visited = st_init_table(st_ptrcmp, st_ptrhash);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (visited==NULL,
							 | 
						|
								    "Error if function st_init_table.", failure);
							 | 
						|
								
							 | 
						|
								  /* Call the function that really gets the job done. */
							 | 
						|
								  for (i = 0; i < n; i++) {
							 | 
						|
								    retValue = DddmpCuddDdArrayStoreSmvStep (ddMgr, Cudd_Regular(f[i]),
							 | 
						|
								      fp, visited, inputNames);
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==0,
							 | 
						|
								      "Error if function DddmpCuddDdArrayStoreSmvStep.", failure);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  To account for the possible complement on the root,
							 | 
						|
								   *  we put either a buffer or an inverter at the output of
							 | 
						|
								   *  the multiplexer representing the top node.
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  for (i=0; i<n; i++) {
							 | 
						|
								    if (outputNames == NULL) {
							 | 
						|
								      retValue = fprintf (fp,  "outNode%d := ", i);
							 | 
						|
								    } else {
							 | 
						|
								      retValue = fprintf (fp,  "%s := ", outputNames[i]);
							 | 
						|
								    }
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==EOF,
							 | 
						|
								      "Error during file store.", failure);
							 | 
						|
								
							 | 
						|
								    if (Cudd_IsComplement(f[i])) {
							 | 
						|
								#if SIZEOF_VOID_P == 8
							 | 
						|
								      retValue = fprintf (fp, "!node%lx\n",
							 | 
						|
								        (unsigned long) f[i] / (unsigned long) sizeof(DdNode));
							 | 
						|
								#else
							 | 
						|
								      retValue = fprintf (fp, "!node%x\n",
							 | 
						|
								        (unsigned) f[i] / (unsigned) sizeof(DdNode));
							 | 
						|
								#endif
							 | 
						|
								    } else {
							 | 
						|
								#if SIZEOF_VOID_P == 8
							 | 
						|
								      retValue = fprintf (fp, "node%lx\n",
							 | 
						|
								        (unsigned long) f[i] / (unsigned long) sizeof(DdNode));
							 | 
						|
								#else
							 | 
						|
								      retValue = fprintf (fp, "node%x\n",
							 | 
						|
								        (unsigned) f[i] / (unsigned) sizeof(DdNode));
							 | 
						|
								#endif
							 | 
						|
								    }
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==EOF,
							 | 
						|
								      "Error during file store.", failure);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  st_free_table (visited);
							 | 
						|
								
							 | 
						|
								  return(1);
							 | 
						|
								
							 | 
						|
								failure:
							 | 
						|
								    if (visited != NULL) st_free_table(visited);
							 | 
						|
								    return(0);
							 | 
						|
								
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis    [Performs the recursive step of
							 | 
						|
								    DddmpCuddDdArrayStoreSmvBody.]
							 | 
						|
								
							 | 
						|
								  Description [Performs the recursive step of
							 | 
						|
								    DddmpCuddDdArrayStoreSmvBody.
							 | 
						|
								    Traverses the BDD f and writes a multiplexer-network description to the
							 | 
						|
								    file pointed by fp.
							 | 
						|
								    For each BDD node of function f, variable v, then child T, and else
							 | 
						|
								    child E it stores:
							 | 
						|
								    f = v * T + v' * E
							 | 
						|
								    that is
							 | 
						|
								    (OR f (AND v T) (AND (NOT v) E))
							 | 
						|
								    If E is a complemented child this results in the following
							 | 
						|
								    (OR f (AND v T) (AND (NOT v) (NOT E)))
							 | 
						|
								    f is assumed to be a regular pointer and the function guarantees this
							 | 
						|
								    assumption in the recursive calls.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso     []
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static int
							 | 
						|
								DddmpCuddDdArrayStoreSmvStep (
							 | 
						|
								  DdManager * ddMgr,
							 | 
						|
								  DdNode * f,
							 | 
						|
								  FILE * fp,
							 | 
						|
								  st_table * visited,
							 | 
						|
								  char ** names
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  DdNode *T, *E;
							 | 
						|
								  int retValue;
							 | 
						|
								
							 | 
						|
								#ifdef DDDMP_DEBUG
							 | 
						|
								  assert(!Cudd_IsComplement(f));
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								  /* If already visited, nothing to do. */
							 | 
						|
								  if (st_is_member(visited, (char *) f) == 1) {
							 | 
						|
								    return(1);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Check for abnormal condition that should never happen. */
							 | 
						|
								  if (f == NULL) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Mark node as visited. */
							 | 
						|
								  if (st_insert(visited, (char *) f, NULL) == ST_OUT_OF_MEM) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Check for special case: If constant node, generate constant 1. */
							 | 
						|
								  if (f == DD_ONE (ddMgr)) {
							 | 
						|
								#if SIZEOF_VOID_P == 8
							 | 
						|
								    retValue = fprintf (fp,
							 | 
						|
								      "node%lx := 1;\n",
							 | 
						|
								      (unsigned long) f / (unsigned long) sizeof(DdNode));
							 | 
						|
								#else
							 | 
						|
								    retValue = fprintf (fp,
							 | 
						|
								      "node%x := 1;\n",
							 | 
						|
								      (unsigned) f / (unsigned) sizeof(DdNode));
							 | 
						|
								#endif
							 | 
						|
								    if (retValue == EOF) {
							 | 
						|
								       return(0);
							 | 
						|
								    } else {
							 | 
						|
								       return(1);
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  Check whether this is an ADD. We deal with 0-1 ADDs, but not
							 | 
						|
								   *  with the general case.
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  if (f == DD_ZERO(ddMgr)) {
							 | 
						|
								#if SIZEOF_VOID_P == 8
							 | 
						|
								    retValue = fprintf (fp,
							 | 
						|
								      "node%lx := 0;\n",
							 | 
						|
								       (unsigned long) f / (unsigned long) sizeof(DdNode));
							 | 
						|
								#else
							 | 
						|
								    retValue = fprintf (fp,
							 | 
						|
								      "node%x := 0;\n",
							 | 
						|
								      (unsigned) f / (unsigned) sizeof(DdNode));
							 | 
						|
								#endif
							 | 
						|
								   if (retValue == EOF) {
							 | 
						|
								     return(0);
							 | 
						|
								   } else {
							 | 
						|
								     return(1);
							 | 
						|
								   }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  if (cuddIsConstant(f)) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Recursive calls. */
							 | 
						|
								  T = cuddT(f);
							 | 
						|
								  retValue = DddmpCuddDdArrayStoreSmvStep (ddMgr,T,fp,visited,names);
							 | 
						|
								  if (retValue != 1) {
							 | 
						|
								    return(retValue);
							 | 
						|
								  }
							 | 
						|
								  E = Cudd_Regular(cuddE(f));
							 | 
						|
								  retValue = DddmpCuddDdArrayStoreSmvStep (ddMgr,E,fp,visited,names);
							 | 
						|
								  if (retValue != 1) {
							 | 
						|
								    return(retValue);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Write multiplexer taking complement arc into account. */
							 | 
						|
								#if SIZEOF_VOID_P == 8
							 | 
						|
								  retValue = fprintf (fp, "node%lx := ",
							 | 
						|
								    (unsigned long) f / (unsigned long) sizeof(DdNode));
							 | 
						|
								#else
							 | 
						|
								  retValue = fprintf (fp, "node%x := ",
							 | 
						|
								    (unsigned) f / (unsigned) sizeof(DdNode));
							 | 
						|
								#endif
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  if (names != NULL) {
							 | 
						|
								    retValue = fprintf(fp, "%s ", names[f->index]);
							 | 
						|
								  } else {
							 | 
						|
								    retValue = fprintf(fp, "inNode%d ", f->index);
							 | 
						|
								  }
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								#if SIZEOF_VOID_P == 8
							 | 
						|
								  retValue = fprintf (fp, "& node%lx | ",
							 | 
						|
								    (unsigned long) T / (unsigned long) sizeof(DdNode));
							 | 
						|
								#else
							 | 
						|
								  retValue = fprintf (fp, "& node%x | ",
							 | 
						|
								    (unsigned) T / (unsigned) sizeof(DdNode));
							 | 
						|
								#endif
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  if (names != NULL) {
							 | 
						|
								    retValue = fprintf (fp, "!%s ", names[f->index]);
							 | 
						|
								  } else {
							 | 
						|
								    retValue = fprintf (fp, "!inNode%d ", f->index);
							 | 
						|
								  }
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								#if SIZEOF_VOID_P == 8
							 | 
						|
								  if (Cudd_IsComplement(cuddE(f))) {
							 | 
						|
								    retValue = fprintf (fp, "& !node%lx\n",
							 | 
						|
								      (unsigned long) E / (unsigned long) sizeof(DdNode));
							 | 
						|
								  } else {
							 | 
						|
								    retValue = fprintf (fp, "& node%lx\n",
							 | 
						|
								      (unsigned long) E / (unsigned long) sizeof(DdNode));
							 | 
						|
								  }
							 | 
						|
								#else
							 | 
						|
								  if (Cudd_IsComplement(cuddE(f))) {
							 | 
						|
								    retValue = fprintf (fp, "& !node%x\n",
							 | 
						|
								      (unsigned) E / (unsigned) sizeof(DdNode));
							 | 
						|
								  } else {
							 | 
						|
								    retValue = fprintf (fp, "& node%x\n",
							 | 
						|
								      (unsigned) E / (unsigned) sizeof(DdNode));
							 | 
						|
								  }
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return(0);
							 | 
						|
								  } else {
							 | 
						|
								    return(1);
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 |