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.
		
		
		
		
		
			
		
			
				
					
					
						
							1491 lines
						
					
					
						
							44 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							1491 lines
						
					
					
						
							44 KiB
						
					
					
				| /**CFile********************************************************************** | |
|  | |
|   FileName     [dddmpLoad.c] | |
|  | |
|   PackageName  [dddmp] | |
|  | |
|   Synopsis     [Functions to read in bdds to file] | |
|  | |
|   Description  [Functions to read in bdds to file.  BDDs | |
|     are represended on file either in text or binary format under the | |
|     following rules.  A file contains a forest of BDDs (a vector of | |
|     Boolean functions).  BDD nodes are numbered with contiguous numbers, | |
|     from 1 to NNodes (total number of nodes on a file). 0 is not used to | |
|     allow negative node indexes for complemented edges.  A file contains | |
|     a header, including information about variables and roots to BDD | |
|     functions, followed by the list of nodes.  BDD nodes are listed | |
|     according to their numbering, and in the present implementation | |
|     numbering follows a post-order strategy, in such a way that a node | |
|     is never listed before its Then/Else children. | |
|   ] | |
|  | |
|   Author       [Gianpiero Cabodi and Stefano Quer] | |
|  | |
|   Copyright    [ | |
|     Copyright (c) 2004 by Politecnico di Torino. | |
|     All Rights Reserved. This software is for educational purposes only. | |
|     Permission is given to academic institutions to use, copy, and modify | |
|     this software and its documentation provided that this introductory | |
|     message is not removed, that this software and its documentation is | |
|     used for the institutions' internal research and educational purposes, | |
|     and that no monies are exchanged. No guarantee is expressed or implied | |
|     by the distribution of this code. | |
|     Send bug-reports and/or questions to: | |
|     {gianpiero.cabodi,stefano.quer}@polito.it. | |
|     ] | |
|  | |
| ******************************************************************************/ | |
| 
 | |
| #include "dddmpInt.h" | |
|  | |
| /*---------------------------------------------------------------------------*/ | |
| /* Stucture declarations                                                     */ | |
| /*---------------------------------------------------------------------------*/ | |
| 
 | |
| /*---------------------------------------------------------------------------*/ | |
| /* Type declarations                                                         */ | |
| /*---------------------------------------------------------------------------*/ | |
| 
 | |
| /*---------------------------------------------------------------------------*/ | |
| /* Variable declarations                                                     */ | |
| /*---------------------------------------------------------------------------*/ | |
| 
 | |
| /*---------------------------------------------------------------------------*/ | |
| /* Macro declarations                                                        */ | |
| /*---------------------------------------------------------------------------*/ | |
| 
 | |
| #define matchkeywd(str,key) (strncmp(str,key,strlen(key))==0) | |
|  | |
| /**AutomaticStart*************************************************************/ | |
| 
 | |
| /*---------------------------------------------------------------------------*/ | |
| /* Static function prototypes                                                */ | |
| /*---------------------------------------------------------------------------*/ | |
| 
 | |
| static int DddmpCuddDdArrayLoad(Dddmp_DecompType ddType, DdManager *ddMgr, Dddmp_RootMatchType rootMatchMode, char **rootmatchnames, Dddmp_VarMatchType varMatchMode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***pproots); | |
| static Dddmp_Hdr_t * DddmpBddReadHeader(char *file, FILE *fp); | |
| static void DddmpFreeHeader(Dddmp_Hdr_t *Hdr); | |
| 
 | |
| /**AutomaticEnd***************************************************************/ | |
| 
 | |
| /*---------------------------------------------------------------------------*/ | |
| /* Definition of exported functions                                          */ | |
| /*---------------------------------------------------------------------------*/ | |
| 
 | |
| /**Function******************************************************************** | |
|  | |
|   Synopsis     [Reads a dump file representing the argument BDD.] | |
|  | |
|   Description  [Reads a dump file representing the argument BDD. | |
|     Dddmp_cuddBddArrayLoad is used through a dummy array (see this | |
|     function's description for more details). | |
|     Mode, the requested input file format, is checked against  | |
|     the file format. | |
|     The loaded BDDs is referenced before returning it. | |
|     ] | |
|  | |
|   SideEffects  [A vector of pointers to DD nodes is allocated and freed.] | |
|  | |
|   SeeAlso      [Dddmp_cuddBddStore, Dddmp_cuddBddArrayLoad] | |
|  | |
| ******************************************************************************/ | |
| 
 | |
| DdNode * | |
| Dddmp_cuddBddLoad ( | |
|   DdManager *ddMgr                /* IN: DD Manager */, | |
|   Dddmp_VarMatchType varMatchMode /* IN: storing mode selector */, | |
|   char **varmatchnames            /* IN: array of variable names - by IDs */, | |
|   int *varmatchauxids             /* IN: array of variable auxids - by IDs */, | |
|   int *varcomposeids              /* IN: array of new ids accessed - by IDs */, | |
|   int mode                        /* IN: requested input file format */, | |
|   char *file                      /* IN: file name */, | |
|   FILE *fp                        /* IN: file pointer */ | |
|   ) | |
| { | |
|   DdNode *f , **tmpArray; | |
|   int i, nRoots; | |
| 
 | |
|   nRoots = Dddmp_cuddBddArrayLoad(ddMgr,DDDMP_ROOT_MATCHLIST,NULL, | |
|     varMatchMode,varmatchnames,varmatchauxids,varcomposeids, | |
|     mode,file,fp,&tmpArray); | |
| 
 | |
|   if (nRoots == 0) { | |
|     return (NULL); | |
|   } else { | |
|     f = tmpArray[0]; | |
|     if (nRoots > 1) { | |
|       fprintf (stderr, | |
|         "Warning: %d BDD roots found in file. Only first retrieved.\n", | |
|          nRoots); | |
|       for (i=1; i<nRoots; i++) { | |
|         Cudd_RecursiveDeref (ddMgr, tmpArray[i]); | |
|       }  | |
|     }  | |
|     DDDMP_FREE (tmpArray); | |
|     return (f); | |
|   } | |
| } | |
| 
 | |
| /**Function******************************************************************** | |
|  | |
|   Synopsis    [Reads a dump file representing the argument BDDs.] | |
|  | |
|   Description [Reads a dump file representing the argument BDDs. The header is | |
|     common to both text and binary mode. The node list is either  | |
|     in text or binary format. A dynamic vector of DD pointers  | |
|     is allocated to support conversion from DD indexes to pointers. | |
|     Several criteria are supported for variable match between file | |
|     and dd manager. Several changes/permutations/compositions are allowed | |
|     for variables while loading DDs. Variable of the dd manager are allowed  | |
|     to match with variables on file on ids, permids, varnames,  | |
|     varauxids; also direct composition between ids and  | |
|     composeids is supported. More in detail: | |
|     <ol> | |
|     <li> varMatchMode=DDDMP_VAR_MATCHIDS <p> | |
|     allows the loading of a DD keeping variable IDs unchanged | |
|     (regardless of the variable ordering of the reading manager); this | |
|     is useful, for example, when swapping DDs to file and restoring them | |
|     later from file, after possible variable reordering activations. | |
|      | |
|     <li> varMatchMode=DDDMP_VAR_MATCHPERMIDS <p> | |
|     is used to allow variable match according to the position in the | |
|     ordering. | |
|      | |
|     <li> varMatchMode=DDDMP_VAR_MATCHNAMES <p> | |
|     requires a non NULL varmatchnames parameter; this is a vector of | |
|     strings in one-to-one correspondence with variable IDs of the | |
|     reading manager. Variables in the DD file read are matched with | |
|     manager variables according to their name (a non NULL varnames | |
|     parameter was required while storing the DD file). | |
|      | |
|     <li> varMatchMode=DDDMP_VAR_MATCHIDS <p> | |
|     has a meaning similar to DDDMP_VAR_MATCHNAMES, but integer auxiliary | |
|     IDs are used instead of strings; the additional non NULL | |
|     varmatchauxids parameter is needed. | |
|      | |
|     <li> varMatchMode=DDDMP_VAR_COMPOSEIDS <p> | |
|     uses the additional varcomposeids parameter is used as array of | |
|     variable ids to be composed with ids stored in file. | |
|     </ol> | |
|      | |
|     In the present implementation, the array varnames (3), varauxids (4) | |
|     and composeids (5) need to have one entry for each variable in the  | |
|     DD manager (NULL pointers are allowed for unused variables | |
|     in varnames). Hence variables need to be already present in the  | |
|     manager. All arrays are sorted according to IDs. | |
|  | |
|     All the loaded BDDs are referenced before returning them. | |
|     ] | |
|  | |
|   SideEffects [A vector of pointers to DD nodes is allocated and freed.] | |
|  | |
|   SeeAlso     [Dddmp_cuddBddArrayStore] | |
|  | |
| ******************************************************************************/ | |
| 
 | |
| int | |
| Dddmp_cuddBddArrayLoad ( | |
|   DdManager *ddMgr                  /* IN: DD Manager */, | |
|   Dddmp_RootMatchType rootMatchMode /* IN: storing mode selector */, | |
|   char **rootmatchnames             /* IN: sorted names for loaded roots */, | |
|   Dddmp_VarMatchType varMatchMode   /* IN: storing mode selector */, | |
|   char **varmatchnames              /* IN: array of variable names, by ids */, | |
|   int *varmatchauxids               /* IN: array of variable auxids, by ids */, | |
|   int *varcomposeids                /* IN: array of new ids, by ids */, | |
|   int mode                          /* IN: requested input file format */, | |
|   char *file                        /* IN: file name */, | |
|   FILE *fp                          /* IN: file pointer */, | |
|   DdNode ***pproots                 /* OUT: array of returned BDD roots */ | |
|   ) | |
| { | |
|   int retValue; | |
| 
 | |
| #ifdef DDDMP_DEBUG | |
| #ifndef __alpha__   | |
|   int retValueBis; | |
| 
 | |
|   retValueBis = Cudd_DebugCheck (ddMgr); | |
|   if (retValueBis == 1) { | |
|     fprintf (stderr, "Inconsistency Found During BDD Load.\n"); | |
|     fflush (stderr); | |
|   } else { | |
|     if (retValueBis == CUDD_OUT_OF_MEM) { | |
|       fprintf (stderr, "Out of Memory During BDD Load.\n"); | |
|       fflush (stderr); | |
|     } | |
|   } | |
| #endif | |
| #endif | |
|  | |
|   retValue = DddmpCuddDdArrayLoad (DDDMP_BDD, ddMgr, rootMatchMode, | |
|      rootmatchnames, varMatchMode, varmatchnames, varmatchauxids, | |
|      varcomposeids, mode, file, fp, pproots); | |
| 
 | |
| #ifdef DDDMP_DEBUG | |
| #ifndef __alpha__   | |
|   retValueBis = Cudd_DebugCheck (ddMgr); | |
|   if (retValueBis == 1) { | |
|     fprintf (stderr, "Inconsistency Found During BDD Load.\n"); | |
|     fflush (stderr); | |
|   } else { | |
|     if (retValueBis == CUDD_OUT_OF_MEM) { | |
|       fprintf (stderr, "Out of Memory During BDD Load.\n"); | |
|       fflush (stderr); | |
|     } | |
|   } | |
| #endif | |
| #endif | |
|  | |
|   return (retValue); | |
| } | |
| 
 | |
| /**Function******************************************************************** | |
|  | |
|   Synopsis    [Reads a dump file representing the argument ADD.] | |
|  | |
|   Description [Reads a dump file representing the argument ADD. | |
|     Dddmp_cuddAddArrayLoad is used through a dummy array. | |
|     ] | |
|  | |
|   SideEffects [A vector of pointers to DD nodes is allocated and freed.] | |
|  | |
|   SeeAlso     [Dddmp_cuddAddStore, Dddmp_cuddAddArrayLoad] | |
|  | |
| ******************************************************************************/ | |
| 
 | |
| DdNode * | |
| Dddmp_cuddAddLoad ( | |
|   DdManager *ddMgr                /* IN: Manager */, | |
|   Dddmp_VarMatchType varMatchMode /* IN: storing mode selector */, | |
|   char **varmatchnames            /* IN: array of variable names by IDs */, | |
|   int  *varmatchauxids            /* IN: array of variable auxids by IDs */, | |
|   int  *varcomposeids             /* IN: array of new ids by IDs */, | |
|   int mode                        /* IN: requested input file format */, | |
|   char *file                      /* IN: file name */, | |
|   FILE *fp                        /* IN: file pointer */ | |
|   ) | |
| { | |
|   DdNode *f , **tmpArray; | |
|   int i, nRoots; | |
| 
 | |
|   nRoots = Dddmp_cuddAddArrayLoad (ddMgr, DDDMP_ROOT_MATCHLIST,NULL, | |
|     varMatchMode, varmatchnames, varmatchauxids, varcomposeids, | |
|     mode, file, fp, &tmpArray); | |
| 
 | |
|   if (nRoots == 0) { | |
|     return (NULL); | |
|   } else { | |
|     f = tmpArray[0]; | |
|     if (nRoots > 1) { | |
|       fprintf (stderr, | |
|         "Warning: %d BDD roots found in file. Only first retrieved.\n", | |
|         nRoots); | |
|       for (i=1; i<nRoots; i++) { | |
|         Cudd_RecursiveDeref (ddMgr, tmpArray[i]); | |
|       }  | |
|     }  | |
|     DDDMP_FREE (tmpArray); | |
|     return (f); | |
|   } | |
| } | |
| 
 | |
| /**Function******************************************************************** | |
|  | |
|   Synopsis    [Reads a dump file representing the argument ADDs.] | |
|  | |
|   Description [Reads a dump file representing the argument ADDs. See  | |
|     BDD load functions for detailed explanation. | |
|     ] | |
|  | |
|   SideEffects [A vector of pointers to DD nodes is allocated and freed.] | |
|  | |
|   SeeAlso     [Dddmp_cuddBddArrayStore] | |
|  | |
| ******************************************************************************/ | |
| 
 | |
| int | |
| Dddmp_cuddAddArrayLoad ( | |
|   DdManager *ddMgr                  /* IN: DD Manager */, | |
|   Dddmp_RootMatchType rootMatchMode /* IN: storing mode selector */, | |
|   char **rootmatchnames             /* IN: sorted names for loaded roots */, | |
|   Dddmp_VarMatchType varMatchMode   /* IN: storing mode selector */, | |
|   char **varmatchnames              /* IN: array of variable names, by ids */, | |
|   int *varmatchauxids               /* IN: array of variable auxids, by ids */, | |
|   int *varcomposeids                /* IN: array of new ids, by ids */, | |
|   int mode                          /* IN: requested input file format */, | |
|   char *file                        /* IN: file name */, | |
|   FILE *fp                          /* IN: file pointer */, | |
|   DdNode ***pproots                 /* OUT: array of returned BDD roots */ | |
|   ) | |
| { | |
| 
 | |
|   int retValue; | |
| 
 | |
| #if 0 | |
| #ifdef DDDMP_DEBUG | |
| #ifndef __alpha__   | |
|   int retValueBis; | |
|  | |
|   retValueBis = Cudd_DebugCheck (ddMgr); | |
|   if (retValueBis == 1) { | |
|     fprintf (stderr, "Inconsistency Found During ADD Load.\n"); | |
|     fflush (stderr); | |
|   } else { | |
|     if (retValueBis == CUDD_OUT_OF_MEM) { | |
|       fprintf (stderr, "Out of Memory During ADD Load.\n"); | |
|       fflush (stderr); | |
|     } | |
|   } | |
| #endif | |
| #endif | |
| #endif | |
|  | |
|   retValue = DddmpCuddDdArrayLoad (DDDMP_ADD, ddMgr, rootMatchMode, | |
|     rootmatchnames, varMatchMode, varmatchnames, varmatchauxids, | |
|     varcomposeids, mode, file, fp, pproots); | |
| 
 | |
| #if 0 | |
| #ifdef DDDMP_DEBUG | |
| #ifndef __alpha__   | |
|   retValueBis = Cudd_DebugCheck (ddMgr); | |
|   if (retValueBis == 1) { | |
|     fprintf (stderr, "Inconsistency Found During ADD Load.\n"); | |
|     fflush (stderr); | |
|   } else { | |
|     if (retValueBis == CUDD_OUT_OF_MEM) { | |
|       fprintf (stderr, "Out of Memory During ADD Load.\n"); | |
|       fflush (stderr); | |
|     } | |
|   } | |
| #endif | |
| #endif | |
| #endif | |
|  | |
|   return (retValue); | |
| } | |
| 
 | |
| /**Function******************************************************************** | |
|  | |
|   Synopsis    [Reads the header of a dump file representing the argument BDDs] | |
|  | |
|   Description [Reads the header of a dump file representing the argument BDDs. | |
|     Returns main information regarding DD type stored in the file, | |
|     the variable ordering used, the number of variables, etc. | |
|     It reads only the header of the file NOT the BDD/ADD section.  | |
|     ] | |
|  | |
|   SideEffects [] | |
|  | |
|   SeeAlso     [Dddmp_cuddBddArrayLoad] | |
|  | |
| ******************************************************************************/ | |
| 
 | |
| int | |
| Dddmp_cuddHeaderLoad ( | |
|   Dddmp_DecompType *ddType  /* OUT: selects the proper decomp type */, | |
|   int *nVars                /* OUT: number of DD variables */, | |
|   int *nsuppvars            /* OUT: number of support variables */, | |
|   char ***suppVarNames      /* OUT: array of support variable names */, | |
|   char ***orderedVarNames   /* OUT: array of variable names */, | |
|   int **varIds              /* OUT: array of variable ids */, | |
|   int **varComposeIds       /* OUT: array of permids ids */, | |
|   int **varAuxIds           /* OUT: array of variable aux ids */, | |
|   int *nRoots               /* OUT: number of root in the file */, | |
|   char *file                 /* IN: file name */, | |
|   FILE *fp                   /* IN: file pointer */ | |
|   ) | |
| { | |
|   Dddmp_Hdr_t *Hdr; | |
|   int i, fileToClose; | |
|   int *tmpVarIds = NULL; | |
|   int *tmpVarComposeIds = NULL; | |
|   int *tmpVarAuxIds = NULL;  | |
| 
 | |
|   fileToClose = 0; | |
|   if (fp == NULL) { | |
|     fp = fopen (file, "r"); | |
|     Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", | |
|       failure); | |
|     fileToClose = 1; | |
|   } | |
| 
 | |
|   Hdr = DddmpBddReadHeader (NULL, fp); | |
| 
 | |
|   Dddmp_CheckAndGotoLabel (Hdr->nnodes==0, "Zero number of nodes.", | |
|     failure); | |
| 
 | |
|   /* | |
|    *  Type, number of variables (tot and support) | |
|    */ | |
| 
 | |
|   *ddType = Hdr->ddType; | |
|   *nVars = Hdr->nVars; | |
|   *nsuppvars = Hdr->nsuppvars; | |
| 
 | |
|   /* | |
|    *  Support Varnames | |
|    */ | |
| 
 | |
|   if (Hdr->suppVarNames != NULL) { | |
|     *suppVarNames = DDDMP_ALLOC (char *, *nsuppvars); | |
|     Dddmp_CheckAndGotoLabel (*suppVarNames==NULL, | |
|       "Error allocating memory.", failure); | |
| 
 | |
|     for (i=0; i<*nsuppvars; i++) { | |
|       (*suppVarNames)[i] = DDDMP_ALLOC (char, | |
|         (strlen (Hdr->suppVarNames[i]) + 1)); | |
|       Dddmp_CheckAndGotoLabel (Hdr->suppVarNames[i]==NULL, | |
|         "Support Variable Name Missing in File.", failure); | |
|       strcpy ((*suppVarNames)[i], Hdr->suppVarNames[i]); | |
|     } | |
|   } else { | |
|     *suppVarNames = NULL; | |
|   } | |
| 
 | |
|   /* | |
|    *  Ordered Varnames | |
|    */ | |
| 
 | |
|   if (Hdr->orderedVarNames != NULL) { | |
|     *orderedVarNames = DDDMP_ALLOC (char *, *nVars); | |
|     Dddmp_CheckAndGotoLabel (*orderedVarNames==NULL, | |
|       "Error allocating memory.", failure); | |
| 
 | |
|     for (i=0; i<*nVars; i++) { | |
|       (*orderedVarNames)[i]  = DDDMP_ALLOC (char, | |
|         (strlen (Hdr->orderedVarNames[i]) + 1)); | |
|       Dddmp_CheckAndGotoLabel (Hdr->orderedVarNames[i]==NULL, | |
|         "Support Variable Name Missing in File.", failure); | |
|       strcpy ((*orderedVarNames)[i], Hdr->orderedVarNames[i]); | |
|     } | |
|   } else { | |
|     *orderedVarNames = NULL; | |
|   } | |
| 
 | |
|   /* | |
|    *  Variable Ids | |
|    */ | |
| 
 | |
|   if (Hdr->ids != NULL) { | |
|     tmpVarIds = DDDMP_ALLOC (int, *nsuppvars); | |
|     Dddmp_CheckAndGotoLabel (tmpVarIds==NULL, "Error allocating memory.", | |
|       failure); | |
|     for (i=0; i<*nsuppvars; i++) { | |
|       tmpVarIds[i] = Hdr->ids[i]; | |
|     } | |
| 
 | |
|     *varIds = tmpVarIds;  | |
|   } else { | |
|     *varIds = NULL; | |
|   } | |
| 
 | |
|   /* | |
|    *  Variable Compose Ids | |
|    */ | |
| 
 | |
|   if (Hdr->permids != NULL) { | |
|     tmpVarComposeIds = DDDMP_ALLOC (int, *nsuppvars); | |
|     Dddmp_CheckAndGotoLabel (tmpVarComposeIds==NULL, | |
|       "Error allocating memory.", failure); | |
|     for (i=0; i<*nsuppvars; i++) { | |
|       tmpVarComposeIds[i] = Hdr->permids[i]; | |
|     } | |
| 
 | |
|     *varComposeIds = tmpVarComposeIds;  | |
|   } else { | |
|     *varComposeIds = NULL; | |
|   } | |
| 
 | |
|   /* | |
|    *  Variable Auxiliary Ids | |
|    */ | |
| 
 | |
|   if (Hdr->auxids != NULL) { | |
|     tmpVarAuxIds = DDDMP_ALLOC (int, *nsuppvars); | |
|     Dddmp_CheckAndGotoLabel (tmpVarAuxIds==NULL, | |
|       "Error allocating memory.", failure); | |
|     for (i=0; i<*nsuppvars; i++) { | |
|       tmpVarAuxIds[i] = Hdr->auxids[i]; | |
|     } | |
| 
 | |
|     *varAuxIds = tmpVarAuxIds;  | |
|   } else { | |
|     *varAuxIds = NULL; | |
|   } | |
| 
 | |
|   /* | |
|    *  Number of roots | |
|    */ | |
| 
 | |
|   *nRoots = Hdr->nRoots; | |
|   | |
|  /* | |
|    *  Free and Return | |
|    */ | |
| 
 | |
|   if (fileToClose == 1) { | |
|     fclose (fp); | |
|   } | |
| 	 | |
|   DddmpFreeHeader(Hdr); | |
| 
 | |
|   return (DDDMP_SUCCESS); | |
| 
 | |
|   failure: | |
|     return (DDDMP_FAILURE); | |
| } | |
| 
 | |
| 
 | |
| /*---------------------------------------------------------------------------*/ | |
| /* Definition of internal functions                                          */ | |
| /*---------------------------------------------------------------------------*/ | |
| 
 | |
| /*---------------------------------------------------------------------------*/ | |
| /* Definition of static functions                                            */ | |
| /*---------------------------------------------------------------------------*/ | |
| 
 | |
| /**Function******************************************************************** | |
|  | |
|   Synopsis    [Reads a dump file representing the argument BDDs.] | |
|  | |
|   Description [Reads a dump file representing the argument BDDs. The header is | |
|     common to both text and binary mode. The node list is either  | |
|     in text or binary format. A dynamic vector of DD pointers  | |
|     is allocated to support conversion from DD indexes to pointers. | |
|     Several criteria are supported for variable match between file | |
|     and dd manager. Several changes/permutations/compositions are allowed | |
|     for variables while loading DDs. Variable of the dd manager are allowed  | |
|     to match with variables on file on ids, permids, varnames,  | |
|     varauxids; also direct composition between ids and  | |
|     composeids is supported. More in detail: | |
|     <ol> | |
|     <li> varMatchMode=DDDMP_VAR_MATCHIDS <p> | |
|     allows the loading of a DD keeping variable IDs unchanged | |
|     (regardless of the variable ordering of the reading manager); this | |
|     is useful, for example, when swapping DDs to file and restoring them | |
|     later from file, after possible variable reordering activations. | |
|      | |
|     <li> varMatchMode=DDDMP_VAR_MATCHPERMIDS <p> | |
|     is used to allow variable match according to the position in the ordering. | |
|      | |
|     <li> varMatchMode=DDDMP_VAR_MATCHNAMES <p> | |
|     requires a non NULL varmatchnames parameter; this is a vector of | |
|     strings in one-to-one correspondence with variable IDs of the | |
|     reading manager. Variables in the DD file read are matched with | |
|     manager variables according to their name (a non NULL varnames | |
|     parameter was required while storing the DD file). | |
|      | |
|     <li> varMatchMode=DDDMP_VAR_MATCHIDS <p> | |
|     has a meaning similar to DDDMP_VAR_MATCHNAMES, but integer auxiliary | |
|     IDs are used instead of strings; the additional non NULL | |
|     varmatchauxids parameter is needed. | |
|      | |
|     <li> varMatchMode=DDDMP_VAR_COMPOSEIDS <p> | |
|     uses the additional varcomposeids parameter is used as array of | |
|     variable ids to be composed with ids stored in file. | |
|     </ol> | |
|      | |
|     In the present implementation, the array varnames (3), varauxids (4) | |
|     and composeids (5) need to have one entry for each variable in the  | |
|     DD manager (NULL pointers are allowed for unused variables | |
|     in varnames). Hence variables need to be already present in the  | |
|     manager. All arrays are sorted according to IDs. | |
|     ] | |
|  | |
|   SideEffects [A vector of pointers to DD nodes is allocated and freed.] | |
|  | |
|   SeeAlso     [Dddmp_cuddBddArrayStore] | |
|  | |
| ******************************************************************************/ | |
| 
 | |
| static int | |
| DddmpCuddDdArrayLoad ( | |
|   Dddmp_DecompType ddType           /* IN: Selects decomp type */, | |
|   DdManager *ddMgr                  /* IN: DD Manager */, | |
|   Dddmp_RootMatchType rootMatchMode /* IN: storing mode selector */, | |
|   char **rootmatchnames             /* IN: sorted names for loaded roots */, | |
|   Dddmp_VarMatchType varMatchMode   /* IN: storing mode selector */, | |
|   char **varmatchnames              /* IN: array of variable names, by ids */, | |
|   int *varmatchauxids               /* IN: array of variable auxids, by ids */, | |
|   int *varcomposeids                /* IN: array of new ids, by ids */, | |
|   int mode                          /* IN: requested input file format */, | |
|   char *file                        /* IN: file name */, | |
|   FILE *fp                          /* IN: file pointer */, | |
|   DdNode ***pproots                 /* OUT: array BDD roots (by reference) */ | |
|   ) | |
| { | |
|   Dddmp_Hdr_t *Hdr = NULL; | |
|   DdNode *f = NULL; | |
|   DdNode *T = NULL; | |
|   DdNode *E = NULL; | |
|   struct binary_dd_code code; | |
|   char buf[DDDMP_MAXSTRLEN]; | |
|   int retValue, id, size, maxv; | |
|   int i, j, k, maxaux, var, vT, vE, idT, idE; | |
|   double addConstant; | |
|   int *permsupport = NULL; | |
|   int *convertids = NULL; | |
|   int *invconvertids = NULL; | |
|   int *invauxids = NULL; | |
|   char **sortedvarnames = NULL; | |
|   int  nddvars, nRoots; | |
|   DdNode **pnodes = NULL; | |
|   unsigned char *pvars1byte = NULL; | |
|   unsigned short *pvars2byte = NULL; | |
|   DdNode **proots = NULL; | |
|   int fileToClose = 0; | |
|   char *retval; | |
| 
 | |
|   *pproots = NULL; | |
| 
 | |
|   if (fp == NULL) { | |
|     fp = fopen (file, "r"); | |
|     Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", | |
|       failure); | |
|     fileToClose = 1; | |
|   } | |
| 
 | |
|   nddvars = ddMgr->size; | |
| 
 | |
|   Hdr = DddmpBddReadHeader (NULL, fp); | |
| 
 | |
|   Dddmp_CheckAndGotoLabel (Hdr->nnodes==0, "Zero number of nodes.", | |
|     failure); | |
| 
 | |
|   nRoots = Hdr->nRoots; | |
| 
 | |
|   if (Hdr->ddType != ddType) { | |
|     (void) fprintf (stderr, "DdLoad Error: ddType mismatch\n"); | |
|   | |
|    if (Hdr->ddType == DDDMP_BDD) | |
|       (void) fprintf (stderr, "BDD found\n"); | |
|     if (Hdr->ddType == DDDMP_ADD) | |
|       (void) fprintf (stderr, "ADD found\n"); | |
|     if (ddType == DDDMP_BDD) | |
|       (void) fprintf (stderr, "when loading a BDD\n"); | |
|     if (ddType == DDDMP_ADD) | |
|       (void) fprintf (stderr, "when loading an ADD\n"); | |
| 
 | |
|     fflush (stderr); | |
|     goto failure; | |
|   } | |
| 
 | |
|   if (Hdr->mode != mode) { | |
|     Dddmp_CheckAndGotoLabel (mode!=DDDMP_MODE_DEFAULT, | |
|       "Mode Mismatch.", failure); | |
|     mode = Hdr->mode; | |
|   } | |
| 
 | |
|   /* | |
|    *  For each variable in the support | |
|    *  compute the relative position in the ordering | |
|    *  (within the support only) | |
|    */ | |
| 
 | |
|   permsupport = DDDMP_ALLOC (int, Hdr->nsuppvars); | |
|   Dddmp_CheckAndGotoLabel (permsupport==NULL, "Error allocating memory.", | |
|     failure); | |
|   for (i=0,k=0; i < Hdr->nVars; i++) {  | |
|     for (j=0; j < Hdr->nsuppvars; j++) {  | |
|       if (Hdr->permids[j] == i) { | |
|         permsupport[j] = k++; | |
|       } | |
|     } | |
|   } | |
|   Dddmp_Assert (k==Hdr->nsuppvars, "k==Hdr->nsuppvars"); | |
| 
 | |
|   if (Hdr->suppVarNames != NULL) { | |
|     /* | |
|      *  Varnames are sorted for binary search | |
|      */ | |
| 
 | |
|     sortedvarnames = DDDMP_ALLOC(char *, Hdr->nsuppvars); | |
|     Dddmp_CheckAndGotoLabel (sortedvarnames==NULL, "Error allocating memory.", | |
|       failure); | |
|     for (i=0; i<Hdr->nsuppvars; i++) { | |
|       Dddmp_CheckAndGotoLabel (Hdr->suppVarNames[i]==NULL, | |
|         "Support Variable Name Missing in File.", failure); | |
|       sortedvarnames[i] = Hdr->suppVarNames[i]; | |
|     }     | |
|      | |
|     qsort ((void *) sortedvarnames, Hdr->nsuppvars, | |
|       sizeof(char *), QsortStrcmp); | |
|      | |
|   } | |
| 
 | |
|   /* | |
|    *  Convertids is the array used to convert variable ids from positional | |
|    *  (shrinked) ids used within the DD file. | |
|    *  Positions in the file are from 0 to nsuppvars-1. | |
|    */  | |
| 
 | |
|   convertids = DDDMP_ALLOC (int, Hdr->nsuppvars); | |
|   Dddmp_CheckAndGotoLabel (convertids==NULL, "Error allocating memory.", | |
|     failure); | |
| 
 | |
|   again_matchmode: | |
|   switch (varMatchMode) { | |
|     case DDDMP_VAR_MATCHIDS: | |
|       for (i=0; i<Hdr->nsuppvars; i++) { | |
|         convertids[permsupport[i]] = Hdr->ids[i]; | |
|       } | |
|       break; | |
|     case DDDMP_VAR_MATCHPERMIDS: | |
|       for (i=0; i<Hdr->nsuppvars; i++) { | |
|         convertids[permsupport[i]] = Cudd_ReadInvPerm (ddMgr, | |
|           Hdr->permids[i]); | |
|       } | |
|       break; | |
|     case DDDMP_VAR_MATCHAUXIDS: | |
|       if (Hdr->auxids == NULL) { | |
|         (void) fprintf (stderr, | |
|            "DdLoad Error: variable auxids matching requested\n"); | |
|         (void) fprintf (stderr, "but .auxids not found in BDD file\n"); | |
|         (void) fprintf (stderr, "Matching IDs forced.\n"); | |
|         fflush (stderr); | |
|         varMatchMode = DDDMP_VAR_MATCHIDS; | |
|         goto again_matchmode; | |
|       } | |
|       /* find max auxid value to alloc invaux array */ | |
|       for (i=0,maxaux= -1; i<nddvars; i++) { | |
|         if (varmatchauxids[i]>maxaux) { | |
|           maxaux = varmatchauxids[i]; | |
|         } | |
|       } | |
|       /* generate invaux array */ | |
|       invauxids = DDDMP_ALLOC (int, maxaux+1); | |
|       Dddmp_CheckAndGotoLabel (invauxids==NULL, "Error allocating memory.", | |
|         failure); | |
| 
 | |
|       for (i=0; i<=maxaux; i++) { | |
|         invauxids[i] = -1; | |
|       } | |
| 
 | |
|       for (i=0; i<Hdr->nsuppvars; i++) { | |
|         invauxids[varmatchauxids[Hdr->ids[i]]] = Hdr->ids[i]; | |
|       } | |
| 
 | |
|       /* generate convertids array */ | |
|       for (i=0; i<Hdr->nsuppvars; i++) { | |
|         if ((Hdr->auxids[i]>maxaux) || (invauxids[Hdr->auxids[i]]<0)) { | |
|           (void) fprintf (stderr, | |
|             "DdLoad Error: auxid %d not found in DD manager.\n",  | |
|             Hdr->auxids[i]); | |
|           (void) fprintf (stderr, "ID matching forced (%d).\n", i); | |
|           (void) fprintf (stderr, | |
|             "Beware of possible overlappings with other variables\n");  | |
|           fflush (stderr); | |
|           convertids[permsupport[i]] = i; | |
|         } else { | |
|           convertids[permsupport[i]] = invauxids[Hdr->auxids[i]]; | |
|         } | |
|       } | |
|       break; | |
|     case DDDMP_VAR_MATCHNAMES: | |
|       if (Hdr->suppVarNames == NULL) { | |
|         (void) fprintf (stderr, | |
|           "DdLoad Error: variable names matching requested\n"); | |
|         (void) fprintf (stderr, "but .suppvarnames not found in BDD file\n"); | |
|         (void) fprintf (stderr, "Matching IDs forced.\n"); | |
|         fflush (stderr); | |
|         varMatchMode = DDDMP_VAR_MATCHIDS; | |
|         goto again_matchmode; | |
|       } | |
| 
 | |
|       /* generate invaux array */ | |
|       invauxids = DDDMP_ALLOC (int, Hdr->nsuppvars); | |
|       Dddmp_CheckAndGotoLabel (invauxids==NULL, "Error allocating memory.", | |
|         failure); | |
| 
 | |
|       for (i=0; i<Hdr->nsuppvars; i++) { | |
|         invauxids[i] = -1; | |
|       } | |
| 
 | |
|       for (i=0; i<nddvars; i++) { | |
|         if (varmatchnames[i]==NULL) { | |
|           (void) fprintf (stderr, | |
|             "DdLoad Warning: NULL match variable name (id: %d). Ignored.\n", | |
|             i); | |
|           fflush (stderr); | |
|         } | |
|         else | |
|           if ((j=FindVarname(varmatchnames[i],sortedvarnames,Hdr->nsuppvars)) | |
|                >=0) { | |
|             Dddmp_Assert (j<Hdr->nsuppvars, "j<Hdr->nsuppvars"); | |
|             invauxids[j] = i; | |
|           } | |
|       } | |
|       /* generate convertids array */ | |
|       for (i=0; i<Hdr->nsuppvars; i++) { | |
|         Dddmp_Assert (Hdr->suppVarNames[i]!=NULL, | |
|           "Hdr->suppVarNames[i] != NULL"); | |
|         j=FindVarname(Hdr->suppVarNames[i],sortedvarnames,Hdr->nsuppvars); | |
|         Dddmp_Assert ((j>=0) && (j<Hdr->nsuppvars), | |
|           "(j>=0) && (j<Hdr->nsuppvars)"); | |
|         if (invauxids[j]<0) { | |
|           fprintf (stderr, | |
|             "DdLoad Error: varname %s not found in DD manager.", | |
|              Hdr->suppVarNames[i]); | |
|           fprintf (stderr, "ID matching forced (%d)\n", i); | |
|           fflush (stderr); | |
|           convertids[permsupport[i]]=i; | |
|         } else { | |
|           convertids[permsupport[i]] = invauxids[j]; | |
|         } | |
|       } | |
|       break; | |
|     case DDDMP_VAR_COMPOSEIDS: | |
|       for (i=0; i<Hdr->nsuppvars; i++) { | |
|         convertids[permsupport[i]] = varcomposeids[Hdr->ids[i]]; | |
|       } | |
|       break; | |
|   } | |
| 
 | |
|   maxv = (-1); | |
|   for (i=0; i<Hdr->nsuppvars; i++) { | |
|     if (convertids[i] > maxv) { | |
|       maxv = convertids[i]; | |
|     } | |
|   } | |
|   | |
|   invconvertids = DDDMP_ALLOC (int, maxv+1); | |
|   Dddmp_CheckAndGotoLabel (invconvertids==NULL, "Error allocating memory.", | |
|     failure); | |
| 
 | |
|   for (i=0; i<=maxv; i++) { | |
|     invconvertids[i]= -1; | |
|   } | |
| 
 | |
|   for (i=0; i<Hdr->nsuppvars; i++) { | |
|     invconvertids[convertids[i]] = i; | |
|   } | |
| 
 | |
|   pnodes = DDDMP_ALLOC(DdNode *,(Hdr->nnodes+1)); | |
|   Dddmp_CheckAndGotoLabel (pnodes==NULL, "Error allocating memory.", | |
|     failure); | |
| 
 | |
|   if (Hdr->nsuppvars < 256) { | |
|     pvars1byte = DDDMP_ALLOC(unsigned char,(Hdr->nnodes+1)); | |
|     Dddmp_CheckAndGotoLabel (pvars1byte==NULL, "Error allocating memory.", | |
|       failure); | |
|   } | |
|   else if (Hdr->nsuppvars < 0xffff) { | |
|     pvars2byte = DDDMP_ALLOC(unsigned short,(Hdr->nnodes+1)); | |
|     Dddmp_CheckAndGotoLabel (pvars2byte==NULL, "Error allocating memory.", | |
|       failure); | |
|   } else { | |
|     (void) fprintf (stderr,  | |
|        "DdLoad Error: more than %d variables. Not supported.\n", 0xffff); | |
|     fflush (stderr); | |
|     goto failure; | |
|   } | |
| 
 | |
|   /*-------------- Deal With Nodes ... One Row File at a Time --------------*/ | |
|   | |
|   for (i=1; i<=Hdr->nnodes; i++) { | |
| 
 | |
|     Dddmp_CheckAndGotoLabel (feof(fp), | |
|       "Unexpected EOF While Reading DD Nodes.", failure); | |
| 
 | |
|     switch (mode) { | |
| 
 | |
|       /* | |
|        *  Text FORMAT | |
|        */ | |
| 
 | |
|       case DDDMP_MODE_TEXT: | |
| 
 | |
|         switch (Hdr->varinfo) { | |
|           case DDDMP_VARIDS: | |
|           case DDDMP_VARPERMIDS: | |
|           case DDDMP_VARAUXIDS: | |
|           case DDDMP_VARNAMES: | |
|             retValue = fscanf(fp, "%d %*s %s %d %d\n", &id, buf, &idT, &idE);  | |
|             Dddmp_CheckAndGotoLabel (retValue<4, | |
|               "Error Reading Nodes in Text Mode.", failure); | |
|             break; | |
|           case DDDMP_VARDEFAULT: | |
|             retValue = fscanf(fp, "%d %s %d %d\n", &id, buf, &idT, &idE); | |
|             Dddmp_CheckAndGotoLabel (retValue<4, | |
|               "Error Reading Nodes in Text Mode.", failure); | |
|             break; | |
|         } | |
| #ifdef DDDMP_DEBUG | |
|         Dddmp_Assert (id==i, "id == i"); | |
| #endif | |
|         if (idT==0 && idE==0) { | |
|           /* leaf node: a constant */ | |
|           if (strcmp(buf, "1") == 0) { | |
|             pnodes[i] = Cudd_ReadOne (ddMgr);        | |
|           } else { | |
|             /* this is an ADD constant ! */ | |
|             if (strcmp(buf, "0") == 0) { | |
|               pnodes[i] = Cudd_ReadZero (ddMgr);        | |
|             } else { | |
|               addConstant = atof(buf); | |
|               pnodes[i] = Cudd_addConst (ddMgr, | |
|                 (CUDD_VALUE_TYPE) addConstant); | |
|             } | |
|           } | |
| 
 | |
|           /* StQ 11.02.2004: | |
|              Bug fixed --> Reference All Nodes for ADD */ | |
|           Cudd_Ref (pnodes[i]);        | |
|           Dddmp_CheckAndGotoLabel (pnodes[i]==NULL, "NULL pnodes.", | |
|             failure); | |
|           continue; | |
|         } else { | |
| #ifdef DDDMP_DEBUG | |
|           Dddmp_Assert (idT>0, "id > 0"); | |
| #endif | |
|           var = atoi(buf); | |
|           T = pnodes[idT]; | |
|           if(idE<0) { | |
|             idE = -idE; | |
|             E = pnodes[idE]; | |
|             E = Cudd_Not(E); | |
|           } else { | |
|             E = pnodes[idE]; | |
|           } | |
|         } | |
| 
 | |
|         break; | |
| 
 | |
|       /* | |
|        *  Binary FORMAT | |
|        */ | |
| 
 | |
|       case DDDMP_MODE_BINARY: | |
| 
 | |
|         Dddmp_CheckAndGotoLabel (DddmpReadCode(fp,&code) == 0, | |
|           "Error Reading witn ReadCode.", failure); | |
| 
 | |
|         switch (code.V) { | |
|         case DDDMP_TERMINAL:      | |
|           /* only 1 terminal presently supported */     | |
|           pnodes[i] = Cudd_ReadOne (ddMgr);        | |
|           continue;  | |
|           break; | |
|         case DDDMP_RELATIVE_1: | |
|           break; | |
|         case DDDMP_RELATIVE_ID: | |
|         case DDDMP_ABSOLUTE_ID: | |
|           size = DddmpReadInt (fp, &var); | |
|           Dddmp_CheckAndGotoLabel (size==0, "Error reading size.", | |
|             failure); | |
|           break; | |
|         } | |
| 
 | |
|         switch (code.T) { | |
|         case DDDMP_TERMINAL:      | |
|           idT = 1; | |
|           break; | |
|         case DDDMP_RELATIVE_1: | |
|           idT = i-1; | |
|           break; | |
|         case DDDMP_RELATIVE_ID: | |
|           size = DddmpReadInt (fp, &id); | |
|           Dddmp_CheckAndGotoLabel (size==0, "Error reading size.", | |
|             failure); | |
|           idT = i-id; | |
|           break; | |
|         case DDDMP_ABSOLUTE_ID: | |
|           size = DddmpReadInt (fp, &idT); | |
|           Dddmp_CheckAndGotoLabel (size==0, "Error reading size.", | |
|             failure); | |
|           break; | |
|         } | |
| 
 | |
|         switch (code.E) { | |
|         case DDDMP_TERMINAL:      | |
|           idE = 1; | |
|           break; | |
|         case DDDMP_RELATIVE_1: | |
|           idE = i-1; | |
|           break; | |
|         case DDDMP_RELATIVE_ID: | |
|           size = DddmpReadInt (fp, &id); | |
|           Dddmp_CheckAndGotoLabel (size==0, "Error reading size.", | |
|             failure); | |
|           idE = i-id; | |
|           break; | |
|         case DDDMP_ABSOLUTE_ID: | |
|           size = DddmpReadInt (fp, &idE); | |
|           Dddmp_CheckAndGotoLabel (size==0, "Error reading size.", | |
|             failure); | |
|           break; | |
|         } | |
| 
 | |
| #ifdef DDDMP_DEBUG | |
|       Dddmp_Assert (idT<i, "id<i"); | |
| #endif | |
|       T = pnodes[idT]; | |
|       if (cuddIsConstant(T)) | |
|         vT = Hdr->nsuppvars; | |
|       else { | |
|         if (pvars1byte != NULL) | |
|           vT = pvars1byte[idT]; | |
|         else if (pvars2byte != NULL) | |
|           vT = pvars2byte[idT]; | |
|         else | |
|           vT = invconvertids[T->index]; | |
|       } | |
| #ifdef DDDMP_DEBUG | |
|       Dddmp_Assert (vT>0, "vT > 0"); | |
|       Dddmp_Assert (vT<=Hdr->nsuppvars, "vT <= Hdr->nsuppvars"); | |
| #endif | |
|  | |
| #ifdef DDDMP_DEBUG | |
|       Dddmp_Assert (idE<i, "idE < i"); | |
| #endif | |
|       E = pnodes[idE]; | |
|       if (cuddIsConstant(E)) | |
|         vE = Hdr->nsuppvars; | |
|       else { | |
|         if (pvars1byte != NULL) | |
|           vE = pvars1byte[idE]; | |
|         else if (pvars2byte != NULL) | |
|           vE = pvars2byte[idE]; | |
|         else | |
|           vE = invconvertids[E->index]; | |
|       } | |
| #ifdef DDDMP_DEBUG | |
|       Dddmp_Assert (vE>0, "vE > 0"); | |
|       Dddmp_Assert (vE<=Hdr->nsuppvars, "vE <= Hdr->nsuppvars"); | |
| #endif | |
|    | |
|       switch (code.V) { | |
|         case DDDMP_TERMINAL:      | |
|         case DDDMP_ABSOLUTE_ID: | |
|           break; | |
|         case DDDMP_RELATIVE_1: | |
|           var = (vT<vE) ? vT-1 : vE-1; | |
|           break; | |
|         case DDDMP_RELATIVE_ID: | |
|           var = (vT<vE) ? vT-var : vE-var; | |
|           break; | |
|       } | |
| 
 | |
|       if (code.Ecompl) { | |
|         E = Cudd_Not(E); | |
|       } | |
| 
 | |
| #ifdef DDDMP_DEBUG | |
|       Dddmp_Assert (var<Hdr->nsuppvars, "var < Hdr->nsuppvars"); | |
| #endif | |
|  | |
|       break; | |
|     } | |
| 
 | |
|     if (pvars1byte != NULL) { | |
|       pvars1byte[i] = (unsigned char) var; | |
|     } else { | |
|       if (pvars2byte != NULL) { | |
|         pvars2byte[i] = (unsigned short) var; | |
|       } | |
|     } | |
| 
 | |
|     var = convertids[var]; | |
|     switch (ddType) { | |
|       case DDDMP_BDD:  | |
|         pnodes[i] = Cudd_bddIte (ddMgr, Cudd_bddIthVar (ddMgr, var), | |
|           T, E); | |
|         break; | |
|       case DDDMP_ADD:  | |
|         {  | |
|         DdNode *tmp = Cudd_addIthVar (ddMgr, var); | |
|         Cudd_Ref (tmp); | |
|         pnodes[i] = Cudd_addIte (ddMgr, tmp, T, E); | |
|         Cudd_RecursiveDeref (ddMgr, tmp); | |
|         break; | |
|         } | |
|       case DDDMP_CNF: | |
|       case DDDMP_NONE: | |
|         Dddmp_Warning (1, "Wrong DD Type."); | |
|         break; | |
|      } | |
| 
 | |
|     cuddRef (pnodes[i]); | |
|   } | |
| 
 | |
|   /*------------------------ Deal With the File Tail -----------------------*/ | |
| 
 | |
|   retval = fgets (buf, DDDMP_MAXSTRLEN-1,fp); | |
|   Dddmp_CheckAndGotoLabel (!retval, "Error on reading file tail.", failure); | |
|   Dddmp_CheckAndGotoLabel (!matchkeywd(buf, ".end"), | |
|     "Error .end not found.", failure); | |
| 
 | |
|   /* Close File IFF Necessary */ | |
|   if (fileToClose) { | |
|     fclose (fp); | |
|   } | |
| 
 | |
|   /* BDD Roots */ | |
|   proots = DDDMP_ALLOC(DdNode *,nRoots); | |
|   Dddmp_CheckAndGotoLabel (proots==NULL, "Error allocating memory.", | |
|     failure); | |
| 
 | |
|   for(i=0; i<nRoots; ++i) { | |
|     switch (rootMatchMode) { | |
|       case DDDMP_ROOT_MATCHNAMES: | |
|         for (j=0; j<nRoots; j++) { | |
|           if (strcmp(rootmatchnames[i], Hdr->rootnames[j]) == 0) | |
|             break; | |
|         } | |
|         if (j>=nRoots) { | |
|           /* rootname not found */ | |
|           fprintf (stderr, "Warning: unable to match root name <%s>\n", | |
|             rootmatchnames[i]); | |
|         } | |
|         break;  | |
|       case DDDMP_ROOT_MATCHLIST: | |
|         j = i; | |
|         break; | |
|     } | |
| 
 | |
|     id = Hdr->rootids[i]; | |
|     if (id==0) { | |
|       (void) fprintf (stderr, "DdLoad Warning: NULL root found in file\n"); | |
|       fflush (stderr); | |
|       f = NULL; | |
|     } else { | |
|       if (id<0) { | |
|         f = Cudd_Not(pnodes[-id]); | |
|       } else { | |
|         f = pnodes[id]; | |
|       } | |
|     } | |
|     proots[i] = f; | |
| 
 | |
|     cuddRef (f); | |
|   } /* end for i = 0..nRoots */ | |
| 
 | |
|   /* | |
|    *  Decrease Reference for all Nodes | |
|    */ | |
| 
 | |
|   /* StQ 11.02.2004: | |
|      Bug fixed --> De-Reference All Nodes for ADD */ | |
|   for (i=1; i<=Hdr->nnodes; i++) { | |
|     f = pnodes[i]; | |
|     Cudd_RecursiveDeref (ddMgr, f); | |
|   } | |
| 
 | |
|   /* | |
|    *  Free Memory: load_end label | |
|    */ | |
| 
 | |
| load_end: | |
| 
 | |
|   DddmpFreeHeader(Hdr); | |
| 
 | |
|   DDDMP_FREE (pnodes); | |
|   DDDMP_FREE (pvars1byte); | |
|   DDDMP_FREE (pvars2byte); | |
| 
 | |
|   /* variable names are not freed because they were shared with varnames */ | |
|   DDDMP_FREE (sortedvarnames); | |
| 
 | |
|   DDDMP_FREE (permsupport); | |
|   DDDMP_FREE (convertids); | |
|   DDDMP_FREE (invconvertids); | |
|   DDDMP_FREE (invauxids); | |
| 
 | |
|   *pproots = proots; | |
|   return (nRoots); | |
| 
 | |
|   /* | |
|    *  Failure Condition | |
|    */ | |
| 
 | |
| failure: | |
| 
 | |
|   if (fileToClose) { | |
|     fclose (fp); | |
|   } | |
| 
 | |
|   nRoots = 0; /* return 0 on error ! */ | |
| 
 | |
|   DDDMP_FREE (proots); | |
| 
 | |
|   goto load_end; /* this is done to free memory */ | |
| } | |
| 
 | |
| /**Function******************************************************************** | |
|  | |
|   Synopsis    [Reads a the header of a dump file representing the | |
|     argument BDDs. | |
|     ] | |
|  | |
|   Description [Reads the header of a dump file. Builds a Dddmp_Hdr_t struct | |
|     containing all infos in the header, for next manipulations. | |
|     ] | |
|  | |
|   SideEffects [none] | |
|  | |
|   SeeAlso     [] | |
|  | |
| ******************************************************************************/ | |
| 
 | |
| static Dddmp_Hdr_t * | |
| DddmpBddReadHeader ( | |
|   char *file	    /* IN: file name */, | |
|   FILE *fp          /* IN: file pointer */ | |
|   ) | |
| { | |
|   Dddmp_Hdr_t *Hdr = NULL; | |
|   char buf[DDDMP_MAXSTRLEN]; | |
|   int retValue, fileToClose = 0; | |
|   char *retval; | |
| 
 | |
|   if (fp == NULL) { | |
|     fp = fopen (file, "r"); | |
|     Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.", | |
|       failure); | |
|     fileToClose = 1; | |
|   } | |
| 
 | |
|   /* START HEADER */ | |
| 
 | |
|   Hdr = DDDMP_ALLOC (Dddmp_Hdr_t,1); | |
|   if (Hdr == NULL) { | |
|     return NULL; | |
|   } | |
|   Hdr->ver = NULL; | |
|   Hdr->mode = 0; | |
|   Hdr->ddType = DDDMP_BDD; | |
|   Hdr->varinfo = DDDMP_VARIDS; | |
|   Hdr->dd = NULL; | |
|   Hdr->nnodes = 0; | |
|   Hdr->nVars = 0; | |
|   Hdr->nsuppvars = 0; | |
|   Hdr->suppVarNames = NULL; | |
|   Hdr->orderedVarNames = NULL; | |
|   Hdr->ids = NULL; | |
|   Hdr->permids = NULL; | |
|   Hdr->auxids = NULL; | |
|   Hdr->cnfids = NULL; | |
|   Hdr->nRoots = 0; | |
|   Hdr->rootids = NULL; | |
|   Hdr->rootnames = NULL; | |
|   Hdr->nAddedCnfVar = 0; | |
|   Hdr->nVarsCnf = 0; | |
|   Hdr->nClausesCnf = 0; | |
| 
 | |
|   while (fscanf(fp, "%s", buf)!=EOF) { | |
| 
 | |
|     /* comment */ | |
|     if (buf[0] == '#') { | |
|       retval = fgets(buf,DDDMP_MAXSTRLEN,fp); | |
|       Dddmp_CheckAndGotoLabel (!retval, "Error on reading comment.", failure); | |
|       continue; | |
|     } | |
| 
 | |
|     Dddmp_CheckAndGotoLabel (buf[0] != '.', | |
|       "Error; line must begin with '.' or '#'.", | |
|         failure); | |
| 
 | |
|     if (matchkeywd(buf, ".ver")) {     | |
|       /* this not checked so far: only read */ | |
|       retValue = fscanf (fp, "%s", buf); | |
|       Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading from file.", | |
|         failure); | |
| 
 | |
|       Hdr->ver=DddmpStrDup(buf); | |
|       Dddmp_CheckAndGotoLabel (Hdr->ver==NULL, | |
|         "Error allocating memory.", failure); | |
| 
 | |
|       continue; | |
|     } | |
| 
 | |
|     if (matchkeywd(buf, ".add")) {     | |
|       Hdr->ddType = DDDMP_ADD; | |
|       continue; | |
|     } | |
| 
 | |
|     if (matchkeywd(buf, ".bdd")) {     | |
|       Hdr->ddType = DDDMP_BDD; | |
|       continue; | |
|     } | |
| 
 | |
|     if (matchkeywd(buf, ".mode")) {     | |
|       retValue = fscanf (fp, "%s", buf); | |
|       Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading to file.", | |
|         failure); | |
| 
 | |
|       Hdr->mode = buf[0]; | |
|       continue; | |
|     } | |
| 
 | |
|     if (matchkeywd(buf, ".varinfo")) { | |
|       int readMe; | |
|       retValue = fscanf (fp, "%d", &readMe); | |
|       Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", | |
|         failure); | |
|       Hdr->varinfo = (Dddmp_VarInfoType) readMe; | |
| 
 | |
|       continue; | |
|     } | |
| 
 | |
|     if (matchkeywd(buf, ".dd")) {     | |
|       retValue = fscanf (fp, "%s", buf); | |
|       Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", | |
|         failure); | |
| 
 | |
|       Hdr->dd = DddmpStrDup (buf); | |
|       Dddmp_CheckAndGotoLabel (Hdr->dd==NULL, "Error allocating memory.", | |
|         failure); | |
| 
 | |
|       continue; | |
|     } | |
| 
 | |
|     if (matchkeywd(buf, ".nnodes")) { | |
|       retValue = fscanf (fp, "%d", &(Hdr->nnodes)); | |
|       Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", | |
|         failure); | |
| 
 | |
|       continue; | |
|     } | |
| 
 | |
|     if (matchkeywd(buf, ".nvars")) {    | |
|       retValue = fscanf (fp, "%d", &(Hdr->nVars)); | |
|       Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", | |
|         failure); | |
| 
 | |
|       continue; | |
|     } | |
| 
 | |
|     if (matchkeywd(buf, ".nsuppvars")) { | |
|       retValue = fscanf (fp, "%d", &(Hdr->nsuppvars)); | |
|       Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", | |
|         failure); | |
| 
 | |
|       continue; | |
|     } | |
| 
 | |
|     if (matchkeywd(buf, ".orderedvarnames")) { | |
|       Hdr->orderedVarNames = DddmpStrArrayRead (fp, Hdr->nVars); | |
|       Dddmp_CheckAndGotoLabel (Hdr->orderedVarNames==NULL, | |
|         "Error allocating memory.", failure); | |
| 
 | |
|       continue; | |
|     } | |
| 
 | |
|     if (matchkeywd(buf, ".suppvarnames") || | |
|       (Hdr->ver != NULL && (strcmp (Hdr->ver, "DDDMP-1.0") == 0) && | |
|       matchkeywd (buf, ".varnames"))) { | |
|       Hdr->suppVarNames = DddmpStrArrayRead (fp, Hdr->nsuppvars); | |
|       Dddmp_CheckAndGotoLabel (Hdr->suppVarNames==NULL, | |
|         "Error allocating memory.", failure); | |
| 
 | |
|       continue; | |
|     } | |
| 
 | |
|     if matchkeywd(buf, ".ids") { | |
|       Hdr->ids = DddmpIntArrayRead(fp,Hdr->nsuppvars); | |
|       Dddmp_CheckAndGotoLabel (Hdr->ids==NULL, | |
|         "Error allocating memory.", failure); | |
| 
 | |
|       continue; | |
|     } | |
| 
 | |
|     if (matchkeywd(buf, ".permids")) { | |
|       Hdr->permids = DddmpIntArrayRead(fp,Hdr->nsuppvars); | |
|       Dddmp_CheckAndGotoLabel (Hdr->permids==NULL, | |
|         "Error allocating memory.", failure); | |
| 
 | |
|       continue; | |
|     } | |
| 
 | |
|     if (matchkeywd(buf, ".auxids")) { | |
|       Hdr->auxids = DddmpIntArrayRead(fp,Hdr->nsuppvars); | |
|       Dddmp_CheckAndGotoLabel (Hdr->auxids==NULL, | |
|         "Error allocating memory.", failure); | |
| 
 | |
|       continue; | |
|     } | |
| 
 | |
|     if (matchkeywd(buf, ".nroots")) { | |
|       retValue = fscanf (fp, "%d", &(Hdr->nRoots)); | |
|       Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.", | |
|         failure); | |
| 
 | |
|       continue; | |
|     } | |
| 
 | |
|     if (matchkeywd(buf, ".rootids")) { | |
|       Hdr->rootids = DddmpIntArrayRead(fp,Hdr->nRoots); | |
|       Dddmp_CheckAndGotoLabel (Hdr->rootids==NULL, | |
|         "Error allocating memory.", failure); | |
| 
 | |
|       continue; | |
|     } | |
| 
 | |
|     if (matchkeywd(buf, ".rootnames")) { | |
|       Hdr->rootnames = DddmpStrArrayRead(fp,Hdr->nRoots); | |
|       Dddmp_CheckAndGotoLabel (Hdr->rootnames==NULL, | |
|         "Error allocating memory.", failure); | |
| 
 | |
|       continue; | |
|     } | |
| 
 | |
|     if (matchkeywd(buf, ".nodes")) { | |
|       retval = fgets(buf,DDDMP_MAXSTRLEN,fp); | |
|       Dddmp_CheckAndGotoLabel (!retval, "Error on reading nodes.", failure); | |
|       break; | |
|     } | |
| 
 | |
|   } | |
| 
 | |
|   /* END HEADER */ | |
| 
 | |
|   return (Hdr); | |
| 
 | |
| failure: | |
| 
 | |
|   if (fileToClose == 1) { | |
|     fclose (fp); | |
|   } | |
| 
 | |
|   DddmpFreeHeader(Hdr); | |
| 
 | |
|   return (NULL); | |
| } | |
| 
 | |
| 
 | |
| /**Function******************************************************************** | |
|  | |
|   Synopsis    [Frees the internal header structure.] | |
|  | |
|   Description [Frees the internal header structureby freeing all internal | |
|     fields first. | |
|     ] | |
|  | |
|   SideEffects [] | |
|  | |
|   SeeAlso     [] | |
|  | |
| ******************************************************************************/ | |
| 
 | |
| static void | |
| DddmpFreeHeader ( | |
|   Dddmp_Hdr_t *Hdr   /* IN: pointer to header */ | |
|   ) | |
| { | |
|   DDDMP_FREE (Hdr->ver); | |
|   DDDMP_FREE (Hdr->dd); | |
|   DddmpStrArrayFree (Hdr->orderedVarNames, Hdr->nVars); | |
|   DddmpStrArrayFree (Hdr->suppVarNames, Hdr->nsuppvars); | |
|   DDDMP_FREE (Hdr->ids); | |
|   DDDMP_FREE (Hdr->permids); | |
|   DDDMP_FREE (Hdr->auxids); | |
|   DDDMP_FREE (Hdr->rootids); | |
|   DddmpStrArrayFree (Hdr->rootnames, Hdr->nRoots); | |
| 
 | |
|   DDDMP_FREE (Hdr); | |
| 
 | |
|   return; | |
| } | |
| 
 | |
| 
 | |
| 
 |