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.
 
 
 
 
 
 

1084 lines
29 KiB

/**CFile**********************************************************************
FileName [dddmpLoadCnf.c]
PackageName [dddmp]
Synopsis [Functions to read in CNF from file as BDDs.]
Description [Functions to read in CNF from file as BDDs.
]
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"
/*---------------------------------------------------------------------------*/
/* Constant declarations */
/*---------------------------------------------------------------------------*/
#define DDDMP_MAX_CNF_ROW_LENGTH 1000
#define DDDMP_DEBUG_CNF 0
/*---------------------------------------------------------------------------*/
/* Stucture declarations */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* Type declarations */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* Variable declarations */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* Macro declarations */
/*---------------------------------------------------------------------------*/
#define matchkeywd(str,key) (strncmp(str,key,strlen(key))==0)
/**AutomaticStart*************************************************************/
/*---------------------------------------------------------------------------*/
/* Static function prototypes */
/*---------------------------------------------------------------------------*/
static int DddmpCuddDdArrayLoadCnf(DdManager *ddMgr, Dddmp_RootMatchType rootmatchmode, char **rootmatchnames, Dddmp_VarMatchType varmatchmode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***rootsPtrPtr, int *nRoots);
static Dddmp_Hdr_t * DddmpBddReadHeaderCnf(char *file, FILE *fp);
static void DddmpFreeHeaderCnf(Dddmp_Hdr_t *Hdr);
static int DddmpReadCnfClauses(Dddmp_Hdr_t *Hdr, int ***cnfTable, FILE *fp);
static int DddmpCnfClauses2Bdd(Dddmp_Hdr_t *Hdr, DdManager *ddMgr, int **cnfTable, int mode, DdNode ***rootsPtrPtr);
/**AutomaticEnd***************************************************************/
/*---------------------------------------------------------------------------*/
/* Definition of exported functions */
/*---------------------------------------------------------------------------*/
/**Function********************************************************************
Synopsis [Reads a dump file in a CNF format.]
Description [Reads a dump file representing the argument BDD in a
CNF formula.
Dddmp_cuddBddArrayLoadCnf is used through a dummy array.
The results is returned in different formats depending on the
mode selection:
IFF mode == 0 Return the Clauses without Conjunction
IFF mode == 1 Return the sets of BDDs without Quantification
IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification
]
SideEffects [A vector of pointers to DD nodes is allocated and freed.]
SeeAlso [Dddmp_cuddBddLoad, Dddmp_cuddBddArrayLoad]
******************************************************************************/
int
Dddmp_cuddBddLoadCnf (
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: computation mode */,
char *file /* IN: file name */,
FILE *fp /* IN: file pointer */,
DdNode ***rootsPtrPtr /* OUT: array of returned BDD roots */,
int *nRoots /* OUT: number of BDDs returned */
)
{
int i, retValue;
retValue = Dddmp_cuddBddArrayLoadCnf (ddMgr, DDDMP_ROOT_MATCHLIST, NULL,
varmatchmode, varmatchnames, varmatchauxids, varcomposeids, mode,
file, fp, rootsPtrPtr, nRoots);
if (retValue == DDDMP_FAILURE) {
return (DDDMP_FAILURE);
}
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, *rootsPtrPtr[i]);
}
}
return (DDDMP_SUCCESS);
}
/**Function********************************************************************
Synopsis [Reads a dump file in a CNF format.]
Description [Reads a dump file representing the argument BDD in a
CNF formula.
]
SideEffects [A vector of pointers to DD nodes is allocated and freed.]
SeeAlso [Dddmp_cuddBddArrayLoad]
******************************************************************************/
int
Dddmp_cuddBddArrayLoadCnf (
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: computation Mode */,
char *file /* IN: file name */,
FILE *fp /* IN: file pointer */,
DdNode ***rootsPtrPtr /* OUT: array of returned BDD roots */,
int *nRoots /* OUT: number of BDDs returned */
)
{
int retValue;
#ifdef DDDMP_DEBUG
#ifndef __alpha__
int retValueBis;
retValueBis = Cudd_DebugCheck (ddMgr);
if (retValueBis == 1) {
fprintf (stderr, "Inconsistency Found During CNF Load.\n");
fflush (stderr);
} else {
if (retValueBis == CUDD_OUT_OF_MEM) {
fprintf (stderr, "Out of Memory During CNF Load.\n");
fflush (stderr);
}
}
#endif
#endif
retValue = DddmpCuddDdArrayLoadCnf (ddMgr, rootmatchmode,
rootmatchnames, varmatchmode, varmatchnames, varmatchauxids,
varcomposeids, mode, file, fp, rootsPtrPtr, nRoots);
#ifdef DDDMP_DEBUG
#ifndef __alpha__
retValueBis = Cudd_DebugCheck (ddMgr);
if (retValueBis == 1) {
fprintf (stderr, "Inconsistency Found During CNF Load.\n");
fflush (stderr);
} else {
if (retValueBis == CUDD_OUT_OF_MEM) {
fprintf (stderr, "Out of Memory During CNF Load.\n");
fflush (stderr);
}
}
#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_cuddHeaderLoadCnf (
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;
char **tmpOrderedVarNames = NULL;
char **tmpSuppVarNames = NULL;
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 = DddmpBddReadHeaderCnf (NULL, fp);
Dddmp_CheckAndGotoLabel (Hdr->nnodes==0, "Zero number of nodes.",
failure);
/*
* Number of variables (tot and support)
*/
*nVars = Hdr->nVars;
*nsuppvars = Hdr->nsuppvars;
/*
* Support Varnames
*/
if (Hdr->suppVarNames != NULL) {
tmpSuppVarNames = DDDMP_ALLOC (char *, *nsuppvars);
Dddmp_CheckAndGotoLabel (tmpSuppVarNames==NULL, "Error allocating memory.",
failure);
for (i=0; i<*nsuppvars; i++) {
tmpSuppVarNames[i] = DDDMP_ALLOC (char,
(strlen (Hdr->suppVarNames[i]) + 1));
Dddmp_CheckAndGotoLabel (Hdr->suppVarNames[i]==NULL,
"Support Variable Name Missing in File.", failure);
strcpy (tmpSuppVarNames[i], Hdr->suppVarNames[i]);
}
*suppVarNames = tmpSuppVarNames;
} else {
*suppVarNames = NULL;
}
/*
* Ordered Varnames
*/
if (Hdr->orderedVarNames != NULL) {
tmpOrderedVarNames = DDDMP_ALLOC (char *, *nVars);
Dddmp_CheckAndGotoLabel (tmpOrderedVarNames==NULL,
"Error allocating memory.", failure);
for (i=0; i<*nVars; i++) {
tmpOrderedVarNames[i] = DDDMP_ALLOC (char,
(strlen (Hdr->orderedVarNames[i]) + 1));
Dddmp_CheckAndGotoLabel (Hdr->orderedVarNames[i]==NULL,
"Support Variable Name Missing in File.", failure);
strcpy (tmpOrderedVarNames[i], Hdr->orderedVarNames[i]);
}
*orderedVarNames = tmpOrderedVarNames;
} 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);
}
DddmpFreeHeaderCnf (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 in CNF
format.
]
Description [Reads a dump file representing the argument BDDs in CNF
format.
IFF mode == 0 Return the Clauses without Conjunction
IFF mode == 1 Return the sets of BDDs without Quantification
IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification
]
SideEffects [A vector of pointers to DD nodes is allocated and freed.]
SeeAlso [Dddmp_cuddBddArrayLoad]
******************************************************************************/
static int
DddmpCuddDdArrayLoadCnf (
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: computation mode */,
char *file /* IN: file name */,
FILE *fp /* IN: file pointer */,
DdNode ***rootsPtrPtr /* OUT: array of BDD roots */,
int *nRoots /* OUT: number of BDDs returned */
)
{
Dddmp_Hdr_t *Hdr = NULL;
int **cnfTable = NULL;
int fileToClose = 0;
int retValue, i;
(void) rootmatchmode; /* avoid warning */
(void) rootmatchnames; /* avoid warning */
(void) varmatchmode; /* avoid warning */
(void) varmatchnames; /* avoid warning */
(void) varmatchauxids; /* avoid warning */
(void) varcomposeids; /* avoid warning */
fileToClose = 0;
*rootsPtrPtr = NULL;
if (fp == NULL) {
fp = fopen (file, "r");
Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.",
failure);
fileToClose = 1;
}
/*--------------------------- Read the Header -----------------------------*/
Hdr = DddmpBddReadHeaderCnf (NULL, fp);
Dddmp_CheckAndGotoLabel (Hdr->nnodes==0, "Zero number of nodes.",
failure);
/*------------------------ Read the CNF Clauses ---------------------------*/
retValue = DddmpReadCnfClauses (Hdr, &cnfTable, fp);
Dddmp_CheckAndGotoLabel (retValue==DDDMP_FAILURE,
"Read CNF Clauses Failure.", failure);
/*------------------------- From Clauses to BDDs --------------------------*/
retValue = DddmpCnfClauses2Bdd (Hdr, ddMgr, cnfTable, mode, rootsPtrPtr);
Dddmp_CheckAndGotoLabel (retValue==DDDMP_FAILURE,
"CNF Clauses To BDDs Failure.", failure);
*nRoots = Hdr->nRoots;
if (fileToClose) {
fclose (fp);
}
for (i=0; i<Hdr->nClausesCnf; i++) {
DDDMP_FREE (cnfTable[i]);
}
DDDMP_FREE (cnfTable);
DddmpFreeHeaderCnf (Hdr);
return (DDDMP_SUCCESS);
/*
* Failure Condition
*/
failure:
if (fileToClose) {
fclose (fp);
}
for (i=0; i<Hdr->nClausesCnf; i++) {
DDDMP_FREE (cnfTable[i]);
}
DDDMP_FREE (cnfTable);
DddmpFreeHeaderCnf (Hdr);
/* return 0 on error ! */
nRoots = 0;
return (DDDMP_FAILURE);
}
/**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 *
DddmpBddReadHeaderCnf (
char *file /* IN: file name */,
FILE *fp /* IN: file pointer */
)
{
Dddmp_Hdr_t *Hdr = NULL;
char buf[DDDMP_MAXSTRLEN];
int nv, nc, retValue, fileToClose = 0;
char *fgetsRet;
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_CNF;
Hdr->varinfo = DDDMP_VARIDS;
Hdr->dd = NULL;
Hdr->nnodes = 0;
Hdr->nVars = 0;
Hdr->nsuppvars = 0;
Hdr->orderedVarNames = NULL;
Hdr->suppVarNames = 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) {
/* Init Problem Line */
if (buf[0] == 'p') {
retValue = fscanf (fp, "%*s %d %d", &nv, &nc);
Dddmp_CheckAndGotoLabel (retValue!=2, "Error reading problem line.",
failure);
Hdr->nVarsCnf = nv;
Hdr->nClausesCnf = nc;
break;
}
/* CNF Comment Line */
if (buf[0] == 'c') {
if (fscanf (fp, "%s", buf) == EOF) {
break;
}
}
/* Skip Comment? */
if (buf[0] != '.') {
fgetsRet = fgets (buf, DDDMP_MAXSTRLEN, fp);
Dddmp_CheckAndGotoLabel (!fgetsRet, "Error reading comment.", failure);
continue;
}
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, ".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->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, ".cnfids")) {
Hdr->cnfids = DddmpIntArrayRead (fp, Hdr->nsuppvars);
Dddmp_CheckAndGotoLabel (Hdr->cnfids==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, ".nAddedCnfVar")) {
retValue = fscanf (fp, "%d", &(Hdr->nAddedCnfVar));
Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.",
failure);
continue;
}
}
/* END HEADER */
return (Hdr);
failure:
if (fileToClose == 1) {
fclose (fp);
}
DddmpFreeHeaderCnf (Hdr);
return (NULL);
}
/**Function********************************************************************
Synopsis [Frees the internal header structure.]
Description [Frees the internal header structure by freeing all internal
fields first.
]
SideEffects []
SeeAlso []
******************************************************************************/
static void
DddmpFreeHeaderCnf (
Dddmp_Hdr_t *Hdr /* IN: pointer to header */
)
{
if (Hdr==NULL) {
return;
}
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->cnfids);
DDDMP_FREE (Hdr->rootids);
DddmpStrArrayFree (Hdr->rootnames, Hdr->nRoots);
DDDMP_FREE (Hdr);
return;
}
/**Function********************************************************************
Synopsis [Read the CNF clauses from the file in the standard DIMACS
format.
]
Description [Read the CNF clauses from the file in the standard DIMACS
format. Store all the clauses in an internal structure for
future transformation into BDDs.
]
SideEffects []
SeeAlso []
******************************************************************************/
static int
DddmpReadCnfClauses (
Dddmp_Hdr_t *Hdr /* IN: file header */,
int ***cnfTable /* OUT: CNF table for clauses */,
FILE *fp /* IN: source file */
)
{
char word[DDDMP_MAX_CNF_ROW_LENGTH];
int i, j, var;
int **cnfTableLocal = NULL;
int *clause = NULL;
char *fgetsRet;
cnfTableLocal = DDDMP_ALLOC (int *, Hdr->nClausesCnf);
clause = DDDMP_ALLOC (int, 2*Hdr->nVarsCnf+1);
for (i=0; i<Hdr->nClausesCnf; i++) {
cnfTableLocal[i] = NULL;
}
for (i=0; i<=2*Hdr->nVarsCnf; i++) {
clause[i] = 0;
}
i = j = 0;
do {
if (fscanf(fp, "%s", word)==EOF) {
if (j>0) {
/* force last zero */
strcpy(word,"0");
}
else break;
}
/* Check for Comment */
if (word[0] == 'c') {
/* Comment Found: Skip line */
fgetsRet = fgets (word, DDDMP_MAX_CNF_ROW_LENGTH-1, fp);
if (!fgetsRet) return (DDDMP_FAILURE);
break;
}
var = atoi (word);
Dddmp_Assert ((var>=(-Hdr->nVarsCnf))&&(var<=Hdr->nVarsCnf),
"Wrong num found");
clause[j++] = var;
if (var == 0) {
cnfTableLocal[i] = DDDMP_ALLOC (int, j);
while (--j >=0) {
cnfTableLocal[i][j] = clause[j];
}
i++;
j=0;
}
} while (!feof(fp));
Dddmp_Assert (i==Hdr->nClausesCnf,
"Wrong number of clauses in file");
#if DDDMP_DEBUG_CNF
for (i=0; i<Hdr->nClausesCnf; i++) {
fprintf (stdout, "[%4d] ", i);
j=0;
while ((var = cnfTableLocal[i][j++]) != 0) {
fprintf (stdout, "%d ", var);
}
fprintf (stdout, "0\n");
}
#endif
DDDMP_FREE (clause);
*cnfTable = cnfTableLocal;
return (DDDMP_SUCCESS);
}
/**Function********************************************************************
Synopsis [Transforms CNF clauses into BDDs.]
Description [Transforms CNF clauses into BDDs. Clauses are stored in an
internal structure previously read. The results can be given in
different format according to the mode selection:
IFF mode == 0 Return the Clauses without Conjunction
IFF mode == 1 Return the sets of BDDs without Quantification
IFF mode == 2 Return the sets of BDDs AFTER Existential Quantification
]
SideEffects []
SeeAlso []
******************************************************************************/
static int
DddmpCnfClauses2Bdd (
Dddmp_Hdr_t *Hdr /* IN: file header */,
DdManager *ddMgr /* IN: DD Manager */,
int **cnfTable /* IN: CNF table for clauses */,
int mode /* IN: computation mode */,
DdNode ***rootsPtrPtr /* OUT: array of returned BDD roots (by reference) */
)
{
DdNode **rel = NULL;
DdNode *lit = NULL;
DdNode *tmp1 = NULL;
DdNode *tmp2 = NULL;
DdNode **rootsPtr = NULL;
DdNode *cubeAllVar = NULL;
DdNode *cubeBddVar = NULL;
DdNode *cubeCnfVar = NULL;
int i, j, k, n, var1, var2, fromLine, toLine;
rootsPtr = NULL;
*rootsPtrPtr = NULL;
/*-------------------------- Read The Clauses -----------------------------*/
rel = DDDMP_ALLOC (DdNode *, Hdr->nClausesCnf);
cubeBddVar = Cudd_ReadOne (ddMgr);
cubeCnfVar = Cudd_ReadOne (ddMgr);
cubeAllVar = Cudd_ReadOne (ddMgr);
Cudd_Ref (cubeBddVar);
Cudd_Ref (cubeCnfVar);
Cudd_Ref (cubeAllVar);
for (i=0; i<Hdr->nClausesCnf; i++) {
rel[i] = Cudd_Not (Cudd_ReadOne (ddMgr));
Cudd_Ref (rel[i]);
j=0;
while ((var1 = cnfTable[i][j++]) != 0) {
/* Deal with the Literal */
var2 = abs (var1);
n = (-1);
for (k=0; k<Hdr->nsuppvars; k++) {
if (Hdr->cnfids[k] == var2) {
n = k;
break;
}
}
if (n == (-1)) {
lit = Cudd_bddIthVar (ddMgr, var2);
/* Create the cubes of CNF Variables */
tmp1 = Cudd_bddAnd (ddMgr, cubeCnfVar, lit);
Cudd_Ref (tmp1);
Cudd_RecursiveDeref (ddMgr, cubeCnfVar);
cubeCnfVar = tmp1;
} else {
lit = Cudd_bddIthVar (ddMgr, Hdr->ids[n]);
/* Create the cubes of BDD Variables */
tmp1 = Cudd_bddAnd (ddMgr, cubeBddVar, lit);
Cudd_Ref (tmp1);
Cudd_RecursiveDeref (ddMgr, cubeBddVar);
cubeBddVar = tmp1;
}
/* Create the cubes of ALL Variables */
tmp1 = Cudd_bddAnd (ddMgr, cubeAllVar, lit);
Cudd_Ref (tmp1);
Cudd_RecursiveDeref (ddMgr, cubeAllVar);
cubeAllVar = tmp1;
/* Deal with Relations */
if (var1<0) {
lit = Cudd_Not (lit);
}
tmp1 = Cudd_bddOr (ddMgr, rel[i], lit);
Cudd_Ref (tmp1);
Cudd_RecursiveDeref (ddMgr, rel[i]);
rel[i] = tmp1;
}
}
/*
* Mode == 0 Return the Clauses without Conjunction
*/
if (mode == 0) {
return (DDDMP_SUCCESS);
}
rootsPtr = DDDMP_ALLOC (DdNode *, Hdr->nRoots);
Dddmp_CheckAndGotoLabel (rootsPtr==NULL, "Error allocating memory.",
failure);
for (i=0; i<Hdr->nRoots; i++) {
if (i == (Hdr->nRoots-1)) {
fromLine = Hdr->rootids[i] - 1;
toLine = Hdr->nClausesCnf;
} else {
fromLine = Hdr->rootids[i] - 1;
toLine = Hdr->rootids[i+1];
}
tmp1 = Cudd_ReadOne (ddMgr);
Cudd_Ref (tmp1);
for (j=fromLine; j<toLine; j++) {
tmp2 = Cudd_bddAnd (ddMgr, rel[j], tmp1);
Cudd_Ref (tmp2);
Cudd_RecursiveDeref (ddMgr, tmp1);
Cudd_RecursiveDeref (ddMgr, rel[j]);
tmp1 = tmp2;
}
rootsPtr[i] = tmp1;
}
DDDMP_FREE (rel);
/*
* Mode == 1 Return the sets of BDDs without Quantification
*/
if (mode == 1) {
*rootsPtrPtr = rootsPtr;
return (DDDMP_SUCCESS);
}
/*
* Mode == 2 Return the sets of BDDs AFTER Existential Quantification
*/
#if DDDMP_DEBUG_CNF
cubeBddVar = Cudd_ReadOne (ddMgr);
Cudd_Ref (cubeBddVar);
for (i=0; i<Hdr->nsuppvars; i++) {
lit = Cudd_bddIthVar (ddMgr, Hdr->ids[i]);
tmp1 = Cudd_bddAnd (ddMgr, cubeBddVar, lit);
Cudd_Ref (tmp1);
Cudd_RecursiveDeref (ddMgr, cubeBddVar);
cubeBddVar = tmp1;
}
cubeCnfVar = Cudd_bddExistAbstract (ddMgr, cubeAllVar, cubeBddVar);
#endif
for (i=0; i<Hdr->nRoots; i++) {
#if DDDMP_DEBUG_CNF
fprintf (stdout, "rootsPtr Before Exist:\n");
Cudd_PrintDebug (ddMgr, rootsPtr[i], 0, 3);
#endif
tmp1 = Cudd_bddExistAbstract (ddMgr, rootsPtr[i], cubeCnfVar);
Cudd_RecursiveDeref (ddMgr, rootsPtr[i]);
rootsPtr[i] = tmp1;
#if DDDMP_DEBUG_CNF
fprintf (stdout, "rootsPtr After Exist:\n");
Cudd_PrintDebug (ddMgr, rootsPtr[i], 0, 3);
#endif
}
#if DDDMP_DEBUG_CNF
fprintf (stdout, "cubeAllVar:\n");
Cudd_PrintDebug (ddMgr, cubeAllVar, 0, 3);
fprintf (stdout, "cubeBddVar:\n");
Cudd_PrintDebug (ddMgr, cubeBddVar, 0, 3);
fprintf (stdout, "cubeCnfVar:\n");
Cudd_PrintDebug (ddMgr, cubeCnfVar, 0, 3);
#endif
Cudd_RecursiveDeref (ddMgr, cubeAllVar);
Cudd_RecursiveDeref (ddMgr, cubeBddVar);
Cudd_RecursiveDeref (ddMgr, cubeCnfVar);
*rootsPtrPtr = rootsPtr;
return (DDDMP_SUCCESS);
/*
* Failure Condition
*/
failure:
DDDMP_FREE (rel);
DDDMP_FREE (rootsPtrPtr);
return (DDDMP_FAILURE);
}