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;
|
|
}
|
|
|
|
|
|
|