/**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; 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; inClausesCnf; i++) { DDDMP_FREE (cnfTable[i]); } DDDMP_FREE (cnfTable); DddmpFreeHeaderCnf (Hdr); return (DDDMP_SUCCESS); /* * Failure Condition */ failure: if (fileToClose) { fclose (fp); } for (i=0; inClausesCnf; 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; 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') { fscanf (fp, "%*s %d %d", &nv, &nc); 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] != '.') { fgets (buf, DDDMP_MAXSTRLEN, fp); 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; cnfTableLocal = DDDMP_ALLOC (int *, Hdr->nClausesCnf); clause = DDDMP_ALLOC (int, 2*Hdr->nVarsCnf+1); for (i=0; inClausesCnf; 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 */ fgets (word, DDDMP_MAX_CNF_ROW_LENGTH-1, fp); 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; inClausesCnf; 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; inClausesCnf; 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; knsuppvars; 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; inRoots; 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; jnsuppvars; 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; inRoots; 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); }