/**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
  • varMatchMode=DDDMP_VAR_MATCHIDS

    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.

  • varMatchMode=DDDMP_VAR_MATCHPERMIDS

    is used to allow variable match according to the position in the ordering.

  • varMatchMode=DDDMP_VAR_MATCHNAMES

    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).

  • varMatchMode=DDDMP_VAR_MATCHIDS

    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.

  • varMatchMode=DDDMP_VAR_COMPOSEIDS

    uses the additional varcomposeids parameter is used as array of variable ids to be composed with ids stored in file. 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; innodes==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:

    1. varMatchMode=DDDMP_VAR_MATCHIDS

      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.

    2. varMatchMode=DDDMP_VAR_MATCHPERMIDS

      is used to allow variable match according to the position in the ordering.

    3. varMatchMode=DDDMP_VAR_MATCHNAMES

      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).

    4. varMatchMode=DDDMP_VAR_MATCHIDS

      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.

    5. varMatchMode=DDDMP_VAR_COMPOSEIDS

      uses the additional varcomposeids parameter is used as array of variable ids to be composed with ids stored in file.

    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; insuppvars; 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; insuppvars; i++) { convertids[permsupport[i]] = Hdr->ids[i]; } break; case DDDMP_VAR_MATCHPERMIDS: for (i=0; insuppvars; 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; imaxaux) { 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; insuppvars; i++) { invauxids[varmatchauxids[Hdr->ids[i]]] = Hdr->ids[i]; } /* generate convertids array */ for (i=0; insuppvars; 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; insuppvars; i++) { invauxids[i] = -1; } for (i=0; insuppvars)) >=0) { Dddmp_Assert (jnsuppvars, "jnsuppvars"); invauxids[j] = i; } } /* generate convertids array */ for (i=0; insuppvars; i++) { Dddmp_Assert (Hdr->suppVarNames[i]!=NULL, "Hdr->suppVarNames[i] != NULL"); j=FindVarname(Hdr->suppVarNames[i],sortedvarnames,Hdr->nsuppvars); Dddmp_Assert ((j>=0) && (jnsuppvars), "(j>=0) && (jnsuppvars)"); 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; insuppvars; i++) { convertids[permsupport[i]] = varcomposeids[Hdr->ids[i]]; } break; } maxv = (-1); for (i=0; insuppvars; 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; insuppvars; 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 (idTnsuppvars; 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 (idEnsuppvars; 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 = (vTnsuppvars, "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; irootnames[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; }