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.
		
		
		
		
		
			
		
			
				
					
					
						
							1583 lines
						
					
					
						
							47 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							1583 lines
						
					
					
						
							47 KiB
						
					
					
				
								/**CFile**********************************************************************
							 | 
						|
								
							 | 
						|
								  FileName     [dddmpStoreCnf.c]
							 | 
						|
								
							 | 
						|
								  PackageName  [dddmp]
							 | 
						|
								
							 | 
						|
								  Synopsis     [Functions to write out BDDs to file in a CNF format]
							 | 
						|
								
							 | 
						|
								  Description  [Functions to write out BDDs to file in a CNF format.]
							 | 
						|
								
							 | 
						|
								  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 <limits.h>
							 | 
						|
								#include "dddmpInt.h"
							 | 
						|
								
							 | 
						|
								/*-------------------------------1--------------------------------------------*/
							 | 
						|
								/* Stucture declarations                                                     */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Type declarations                                                         */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Variable declarations                                                     */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								#define DDDMP_DEBUG_CNF   0
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Macro declarations                                                        */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								#define GET_MAX(x,y) (x>y?x:y)
							 | 
						|
								
							 | 
						|
								/**AutomaticStart*************************************************************/
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Static function prototypes                                                */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								static int DddmpCuddBddArrayStoreCnf(DdManager *ddMgr, DdNode **f, int rootN, Dddmp_DecompCnfStoreType mode, int noHeader, char **varNames, int *bddIds, int *bddAuxIds, int *cnfIds, int idInitial, int edgeInTh, int pathLengthTh, char *fname, FILE *fp, int *clauseNPtr, int *varNewNPtr);
							 | 
						|
								static int StoreCnfNodeByNode(DdManager *ddMgr, DdNode **f, int rootN, int *bddIds, int *cnfIds, FILE *fp, int *clauseN, int *varMax, int *rootStartLine);
							 | 
						|
								static int StoreCnfNodeByNodeRecur(DdManager *ddMgr, DdNode *f, int *bddIds, int *cnfIds, FILE *fp, int *clauseN, int *varMax);
							 | 
						|
								static int StoreCnfOneNode(DdNode *f, int idf, int vf, int idT, int idE, FILE *fp, int *clauseN, int *varMax);
							 | 
						|
								static int StoreCnfMaxtermByMaxterm(DdManager *ddMgr, DdNode **f, int rootN, int *bddIds, int *cnfIds, int idInitial, FILE *fp, int *varMax, int *clauseN, int *rootStartLine);
							 | 
						|
								static int StoreCnfBest(DdManager *ddMgr, DdNode **f, int rootN, int *bddIds, int *cnfIds, int idInitial, FILE *fp, int *varMax, int *clauseN, int *rootStartLine);
							 | 
						|
								static void StoreCnfMaxtermByMaxtermRecur(DdManager *ddMgr, DdNode *node, int *bddIds, int *cnfIds, FILE *fp, int *list, int *clauseN, int *varMax);
							 | 
						|
								static int StoreCnfBestNotSharedRecur(DdManager *ddMgr, DdNode *node, int idf, int *bddIds, int *cnfIds, FILE *fp, int *list, int *clauseN, int *varMax);
							 | 
						|
								static int StoreCnfBestSharedRecur(DdManager *ddMgr, DdNode *node, int *bddIds, int *cnfIds, FILE *fp, int *list, int *clauseN, int *varMax);
							 | 
						|
								static int printCubeCnf(DdManager *ddMgr, DdNode *node, int *cnfIds, FILE *fp, int *list, int *varMax);
							 | 
						|
								
							 | 
						|
								/**AutomaticEnd***************************************************************/
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Definition of exported functions                                          */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Writes a dump file representing the argument BDD in
							 | 
						|
								    a CNF format.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  Description  [Dumps the argument BDD to file.
							 | 
						|
								    This task is performed by calling the function
							 | 
						|
								    Dddmp_cuddBddArrayStoreCnf.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects  [Nodes are temporarily removed from unique hash. They are
							 | 
						|
								    re-linked after the store operation in a modified order.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SeeAlso      [Dddmp_cuddBddArrayStoreCnf]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								int
							 | 
						|
								Dddmp_cuddBddStoreCnf (
							 | 
						|
								  DdManager *ddMgr              /* IN: DD Manager */,
							 | 
						|
								  DdNode *f                     /* IN: BDD root to be stored */,
							 | 
						|
								  Dddmp_DecompCnfStoreType mode /* IN: format selection */,
							 | 
						|
								  int noHeader                  /* IN: do not store header iff 1 */,
							 | 
						|
								  char **varNames               /* IN: array of variable names (or NULL) */,
							 | 
						|
								  int *bddIds                   /* IN: array of var ids */,
							 | 
						|
								  int *bddAuxIds                /* IN: array of BDD node Auxiliary Ids */,
							 | 
						|
								  int *cnfIds                   /* IN: array of CNF var ids */,
							 | 
						|
								  int idInitial                 /* IN: starting id for cutting variables */,
							 | 
						|
								  int edgeInTh                  /* IN: Max # Incoming Edges */,
							 | 
						|
								  int pathLengthTh              /* IN: Max Path Length */,
							 | 
						|
								  char *fname                   /* IN: file name */,
							 | 
						|
								  FILE *fp                      /* IN: pointer to the store file */,
							 | 
						|
								  int *clauseNPtr               /* OUT: number of clause stored */, 
							 | 
						|
								  int *varNewNPtr               /* OUT: number of new variable created */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  int retValue;
							 | 
						|
								  DdNode *tmpArray[1];
							 | 
						|
								
							 | 
						|
								  tmpArray[0] = f;
							 | 
						|
								
							 | 
						|
								  retValue = Dddmp_cuddBddArrayStoreCnf (ddMgr, tmpArray, 1, mode,
							 | 
						|
								    noHeader, varNames, bddIds, bddAuxIds, cnfIds, idInitial, edgeInTh,
							 | 
						|
								    pathLengthTh, fname, fp, clauseNPtr, varNewNPtr);
							 | 
						|
								
							 | 
						|
								  Dddmp_CheckAndReturn (retValue==DDDMP_FAILURE, "Failure.");
							 | 
						|
								
							 | 
						|
								  return (DDDMP_SUCCESS);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Writes a dump file representing the argument array of BDDs
							 | 
						|
								    in CNF format.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  Description  [Dumps the argument array of BDDs to file.]
							 | 
						|
								
							 | 
						|
								  SideEffects  [Nodes are temporarily removed from the unique hash
							 | 
						|
								    table. They are re-linked after the store operation in a 
							 | 
						|
								    modified order.
							 | 
						|
								    Three methods are allowed:
							 | 
						|
								    * NodeByNode method: Insert a cut-point for each BDD node (but the
							 | 
						|
								                         terminal nodes)
							 | 
						|
								    * MaxtermByMaxterm method: Insert no cut-points, i.e. the off-set of
							 | 
						|
								                               trhe function is stored
							 | 
						|
								    * Best method: Tradeoff between the previous two methods.
							 | 
						|
								      Auxiliary variables, i.e., cut points are inserted following these
							 | 
						|
								      criterias:
							 | 
						|
								      * edgeInTh
							 | 
						|
								        indicates the maximum number of incoming edges up to which
							 | 
						|
								        no cut point (auxiliary variable) is inserted.
							 | 
						|
								        If edgeInTh:
							 | 
						|
								        * is equal to -1 no cut point due to incoming edges are inserted
							 | 
						|
								          (MaxtermByMaxterm method.)
							 | 
						|
									* is equal to 0 a cut point is inserted for each node with a single
							 | 
						|
								          incoming edge, i.e., each node, (NodeByNode method).
							 | 
						|
									* is equal to n a cut point is inserted for each node with (n+1)
							 | 
						|
								          incoming edges.
							 | 
						|
								      * pathLengthTh
							 | 
						|
								        indicates the maximum length path up to which no cut points
							 | 
						|
								        (auxiliary variable) is inserted.
							 | 
						|
								        If the path length between two nodes exceeds this value, a cut point
							 | 
						|
								        is inserted.
							 | 
						|
								        If pathLengthTh:
							 | 
						|
								        * is equal to -1 no cut point due path length are inserted
							 | 
						|
								          (MaxtermByMaxterm method.)
							 | 
						|
									* is equal to 0 a cut point is inserted for each node (NodeByNode
							 | 
						|
								          method).
							 | 
						|
									* is equal to n a cut point is inserted on path whose length is
							 | 
						|
								          equal to (n+1).
							 | 
						|
								        Notice that the maximum number of literals in a clause is equal
							 | 
						|
								        to (pathLengthTh + 2), i.e., for each path we have to keep into
							 | 
						|
								        account a CNF variable for each node plus 2 added variables for
							 | 
						|
								        the bottom and top-path cut points.
							 | 
						|
								    The stored file can contain a file header or not depending on the
							 | 
						|
								    noHeader parameter (IFF 0, usual setting, the header is usually stored.
							 | 
						|
								    This option can be useful in storing multiple BDDs, as separate BDDs,
							 | 
						|
								    on the same file leaving the opening of the file to the caller. 
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SeeAlso      []
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								int
							 | 
						|
								Dddmp_cuddBddArrayStoreCnf (
							 | 
						|
								  DdManager *ddMgr              /* IN: DD Manager */,
							 | 
						|
								  DdNode **f                    /* IN: array of BDD roots to be stored */,
							 | 
						|
								  int rootN                     /* IN: # output BDD roots to be stored */,
							 | 
						|
								  Dddmp_DecompCnfStoreType mode /* IN: format selection */,
							 | 
						|
								  int noHeader                  /* IN: do not store header iff 1 */,
							 | 
						|
								  char **varNames               /* IN: array of variable names (or NULL) */,
							 | 
						|
								  int *bddIds                   /* IN: array of converted var IDs */,
							 | 
						|
								  int *bddAuxIds                /* IN: array of BDD node Auxiliary Ids */,
							 | 
						|
								  int *cnfIds                   /* IN: array of converted var IDs */,
							 | 
						|
								  int idInitial                 /* IN: starting id for cutting variables */,
							 | 
						|
								  int edgeInTh                  /* IN: Max # Incoming Edges */,
							 | 
						|
								  int pathLengthTh              /* IN: Max Path Length */,
							 | 
						|
								  char *fname                   /* IN: file name */,
							 | 
						|
								  FILE *fp                      /* IN: pointer to the store file */,
							 | 
						|
								  int *clauseNPtr               /* OUT: number of clause stored */, 
							 | 
						|
								  int *varNewNPtr               /* OUT: number of new variable created */ 
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  int retValue2;
							 | 
						|
								
							 | 
						|
								#if 0
							 | 
						|
								#ifdef DDDMP_DEBUG
							 | 
						|
								#ifndef __alpha__  
							 | 
						|
								  int retValue1;
							 | 
						|
								
							 | 
						|
								  retValue1 = Cudd_DebugCheck (ddMgr);
							 | 
						|
								  Dddmp_CheckAndReturn (retValue1==1,
							 | 
						|
								    "Inconsistency Found During CNF Store.");
							 | 
						|
								  Dddmp_CheckAndReturn (retValue1==CUDD_OUT_OF_MEM,
							 | 
						|
								    "Out of Memory During CNF Store.");
							 | 
						|
								#endif
							 | 
						|
								#endif
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								  retValue2 = DddmpCuddBddArrayStoreCnf (ddMgr, f, rootN, mode, noHeader,
							 | 
						|
								    varNames, bddIds, bddAuxIds, cnfIds, idInitial, edgeInTh, pathLengthTh,
							 | 
						|
								    fname, fp, clauseNPtr, varNewNPtr);
							 | 
						|
								
							 | 
						|
								#if 0
							 | 
						|
								#ifdef DDDMP_DEBUG
							 | 
						|
								#ifndef __alpha__  
							 | 
						|
								  retValue1 = Cudd_DebugCheck (ddMgr);
							 | 
						|
								  Dddmp_CheckAndReturn (retValue1==1,
							 | 
						|
								    "Inconsistency Found During CNF Store.");
							 | 
						|
								  Dddmp_CheckAndReturn (retValue1==CUDD_OUT_OF_MEM,
							 | 
						|
								    "Out of Memory During CNF Store.");
							 | 
						|
								#endif
							 | 
						|
								#endif
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								  return (retValue2);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Definition of internal functions                                          */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Writes a dump file representing the argument Array of
							 | 
						|
								    BDDs in the CNF standard format.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  Description  [Dumps the argument array of BDDs/ADDs to file in CNF format.
							 | 
						|
								    The following arrays: varNames, bddIds, bddAuxIds, and cnfIds 
							 | 
						|
								    fix the correspondence among variable names, BDD ids, BDD 
							 | 
						|
								    auxiliary ids and the ids used to store the CNF problem.
							 | 
						|
								    All these arrays are automatically created iff NULL.
							 | 
						|
								    Auxiliary variable, iff necessary, are created starting from value
							 | 
						|
								    idInitial.
							 | 
						|
								    Iff idInitial is <= 0 its value is selected as the number of internal
							 | 
						|
								    CUDD variable + 2.
							 | 
						|
								    Auxiliary variables, i.e., cut points are inserted following these
							 | 
						|
								    criterias:
							 | 
						|
								    * edgeInTh
							 | 
						|
								      indicates the maximum number of incoming edges up to which
							 | 
						|
								      no cut point (auxiliary variable) is inserted.
							 | 
						|
								      If edgeInTh:
							 | 
						|
								      * is equal to -1 no cut point due to incoming edges are inserted
							 | 
						|
								        (MaxtermByMaxterm method.)
							 | 
						|
									* is equal to 0 a cut point is inserted for each node with a single
							 | 
						|
								        incoming edge, i.e., each node, (NodeByNode method).
							 | 
						|
									* is equal to n a cut point is inserted for each node with (n+1)
							 | 
						|
								        incoming edges.
							 | 
						|
								    * pathLengthTh
							 | 
						|
								      indicates the maximum length path up to which no cut points
							 | 
						|
								      (auxiliary variable) is inserted.
							 | 
						|
								      If the path length between two nodes exceeds this value, a cut point
							 | 
						|
								      is inserted.
							 | 
						|
								      If pathLengthTh:
							 | 
						|
								      * is equal to -1 no cut point due path length are inserted
							 | 
						|
								        (MaxtermByMaxterm method.)
							 | 
						|
									* is equal to 0 a cut point is inserted for each node (NodeByNode
							 | 
						|
								        method).
							 | 
						|
									* is equal to n a cut point is inserted on path whose length is
							 | 
						|
								        equal to (n+1).
							 | 
						|
								      Notice that the maximum number of literals in a clause is equal
							 | 
						|
								      to (pathLengthTh + 2), i.e., for each path we have to keep into
							 | 
						|
								      account a CNF variable for each node plus 2 added variables for
							 | 
						|
								      the bottom and top-path cut points.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects  [Nodes are temporarily removed from the unique hash table. 
							 | 
						|
								    They are re-linked after the store operation in a modified 
							 | 
						|
								    order.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SeeAlso      [Dddmp_cuddBddStore]
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static int
							 | 
						|
								DddmpCuddBddArrayStoreCnf (
							 | 
						|
								  DdManager *ddMgr               /* IN: DD Manager */,
							 | 
						|
								  DdNode **f                     /* IN: array of BDD roots to be stored */,
							 | 
						|
								  int rootN                      /* IN: # of output BDD roots to be stored */,
							 | 
						|
								  Dddmp_DecompCnfStoreType mode  /* IN: format selection */,
							 | 
						|
								  int noHeader                   /* IN: do not store header iff 1 */,
							 | 
						|
								  char **varNames                /* IN: array of variable names (or NULL) */,
							 | 
						|
								  int *bddIds                    /* IN: array of BDD node Ids (or NULL) */,
							 | 
						|
								  int *bddAuxIds                 /* IN: array of BDD Aux Ids (or NULL) */,
							 | 
						|
								  int *cnfIds                    /* IN: array of CNF ids (or NULL) */,
							 | 
						|
								  int idInitial                  /* IN: starting id for cutting variables */,
							 | 
						|
								  int edgeInTh                   /* IN: Max # Incoming Edges */,
							 | 
						|
								  int pathLengthTh               /* IN: Max Path Length */,
							 | 
						|
								  char *fname                    /* IN: file name */,
							 | 
						|
								  FILE *fp                       /* IN: pointer to the store file */,
							 | 
						|
								  int *clauseNPtr                /* OUT: number of clause stored */,
							 | 
						|
								  int *varNewNPtr                /* OUT: number of new variable created */ 
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  DdNode *support = NULL;
							 | 
						|
								  DdNode *scan = NULL;
							 | 
						|
								  int *bddIdsInSupport = NULL;
							 | 
						|
								  int *permIdsInSupport = NULL;
							 | 
						|
								  int *rootStartLine = NULL;
							 | 
						|
								  int nVar, nVarInSupport, retValue, i, j, fileToClose;
							 | 
						|
								  int varMax, clauseN, flagVar, intStringLength;
							 | 
						|
								  int bddIdsToFree = 0;
							 | 
						|
								  int bddAuxIdsToFree = 0;
							 | 
						|
								  int cnfIdsToFree = 0;
							 | 
						|
								  int varNamesToFree = 0;
							 | 
						|
								  char intString[DDDMP_MAXSTRLEN];
							 | 
						|
								  char tmpString[DDDMP_MAXSTRLEN];
							 | 
						|
								  fpos_t posFile1, posFile2;
							 | 
						|
								
							 | 
						|
								  /*---------------------------- Set Initial Values -------------------------*/
							 | 
						|
								
							 | 
						|
								  support = scan = NULL;
							 | 
						|
								  bddIdsInSupport = permIdsInSupport = rootStartLine = NULL;
							 | 
						|
								  nVar = ddMgr->size;
							 | 
						|
								  fileToClose = 0;
							 | 
						|
								  sprintf (intString, "%d", INT_MAX);
							 | 
						|
								  intStringLength = strlen (intString);
							 | 
						|
								
							 | 
						|
								  /*---------- Check if File needs to be opened in the proper mode ----------*/
							 | 
						|
								
							 | 
						|
								  if (fp == NULL) {
							 | 
						|
								    fp = fopen (fname, "w");
							 | 
						|
								    Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.",
							 | 
						|
								      failure);
							 | 
						|
								    fileToClose = 1;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*--------- Generate Bdd LOCAL IDs and Perm IDs and count them ------------*/
							 | 
						|
								
							 | 
						|
								  /* BDD Ids */
							 | 
						|
								  bddIdsInSupport = DDDMP_ALLOC (int, nVar);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (bddIdsInSupport==NULL, "Error allocating memory.",
							 | 
						|
								    failure);
							 | 
						|
								  /* BDD PermIds */
							 | 
						|
								  permIdsInSupport = DDDMP_ALLOC (int, nVar);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (permIdsInSupport==NULL, "Error allocating memory.",
							 | 
						|
								    failure);
							 | 
						|
								  /* Support Size (Number of BDD Ids-PermIds */
							 | 
						|
								  nVarInSupport = 0;
							 | 
						|
								
							 | 
						|
								  for (i=0; i<nVar; i++) {
							 | 
						|
								    bddIdsInSupport[i] = permIdsInSupport[i] = (-1);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* 
							 | 
						|
								   *  Take the union of the supports of each output function.
							 | 
						|
								   *  Skip NULL functions.
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								  for (i=0; i<rootN; i++) {
							 | 
						|
								    if (f[i] == NULL) {
							 | 
						|
								      continue;
							 | 
						|
								    }
							 | 
						|
								    support = Cudd_Support (ddMgr, f[i]);
							 | 
						|
								    Dddmp_CheckAndGotoLabel (support==NULL, "NULL support returned.",
							 | 
						|
								      failure);
							 | 
						|
								    cuddRef (support);
							 | 
						|
								    scan = support;
							 | 
						|
								    while (!cuddIsConstant(scan)) {
							 | 
						|
								      /* Count Number of Variable in the Support */
							 | 
						|
								      nVarInSupport++;
							 | 
						|
								      /* Set Ids and Perm-Ids */
							 | 
						|
								      bddIdsInSupport[scan->index] = scan->index;
							 | 
						|
								      permIdsInSupport[scan->index] = ddMgr->perm[scan->index];
							 | 
						|
								      scan = cuddT (scan);
							 | 
						|
								    }
							 | 
						|
								    Cudd_RecursiveDeref (ddMgr, support);
							 | 
						|
								  }
							 | 
						|
								  /* so that we do not try to free it in case of failure */
							 | 
						|
								  support = NULL;
							 | 
						|
								
							 | 
						|
								  /*---------------------------- Start HEADER -------------------------------*/
							 | 
						|
								
							 | 
						|
								  if (noHeader==0) {
							 | 
						|
								
							 | 
						|
								    retValue = fprintf (fp,
							 | 
						|
								      "c # BDD stored by the DDDMP tool in CNF format\n");
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing on file.",
							 | 
						|
								      failure);
							 | 
						|
								    fprintf (fp, "c #\n");
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*-------------------- Generate Bdd IDs IFF necessary ---------------------*/
							 | 
						|
								
							 | 
						|
								  if (bddIds == NULL) {
							 | 
						|
								    if (noHeader==0) {
							 | 
						|
								      fprintf (fp, "c # Warning: BDD IDs missing ... evaluating them.\n");
							 | 
						|
								      fprintf (fp, "c # \n");
							 | 
						|
								      fflush (fp);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    bddIdsToFree = 1;
							 | 
						|
								    bddIds = DDDMP_ALLOC (int, nVar);
							 | 
						|
								    Dddmp_CheckAndGotoLabel (bddIds==NULL, "Error allocating memory.",
							 | 
						|
								      failure);
							 | 
						|
								
							 | 
						|
								    /* Get BDD-IDs Directly from Cudd Manager */
							 | 
						|
								    for (i=0; i<nVar; i++) {
							 | 
						|
								      bddIds[i] = i;
							 | 
						|
								    }   
							 | 
						|
								  } /* end if bddIds == NULL */
							 | 
						|
								
							 | 
						|
								  /*------------------ Generate AUX BDD IDs IF necessary --------------------*/
							 | 
						|
								
							 | 
						|
								  if (bddAuxIds == NULL) {
							 | 
						|
								    if (noHeader==0) {
							 | 
						|
								      fprintf (fp, "c # Warning: AUX IDs missing ... equal to BDD IDs.\n");
							 | 
						|
								      fprintf (fp, "c #\n");
							 | 
						|
								      fflush (fp);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    bddAuxIdsToFree = 1;
							 | 
						|
								    bddAuxIds = DDDMP_ALLOC (int, nVar);
							 | 
						|
								    Dddmp_CheckAndGotoLabel (bddAuxIds==NULL, "Error allocating memory.",
							 | 
						|
								      failure);
							 | 
						|
								
							 | 
						|
								    for (i=0; i<nVar; i++) {
							 | 
						|
								      bddAuxIds[i] = bddIds[i];
							 | 
						|
								    }
							 | 
						|
								  } /* end if cnfIds == NULL */
							 | 
						|
								
							 | 
						|
								  /*------------------- Generate CNF IDs IF necessary -----------------------*/
							 | 
						|
								
							 | 
						|
								  if (cnfIds == NULL) {
							 | 
						|
								    if (noHeader==0) {
							 | 
						|
								      fprintf (fp, "c # Warning: CNF IDs missing ... equal to BDD IDs.\n");
							 | 
						|
								      fprintf (fp, "c #\n");
							 | 
						|
								      fflush (fp);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    cnfIdsToFree = 1;
							 | 
						|
								    cnfIds = DDDMP_ALLOC (int, nVar);
							 | 
						|
								    Dddmp_CheckAndGotoLabel (cnfIds==NULL, "Error allocating memory.",
							 | 
						|
								      failure);
							 | 
						|
								
							 | 
						|
								    for (i=0; i<nVar; i++) {
							 | 
						|
								      cnfIds[i] = bddIds[i] + 1;
							 | 
						|
								    }
							 | 
						|
								  } /* end if cnfIds == NULL */
							 | 
						|
								
							 | 
						|
								  /*------------------ Generate Var Names IF necessary ----------------------*/
							 | 
						|
								
							 | 
						|
								  flagVar = 0;
							 | 
						|
								  if (varNames == NULL) {
							 | 
						|
								    if (noHeader==0) {
							 | 
						|
								      fprintf (fp,
							 | 
						|
								        "c # Warning: null variable names ... create DUMMY names.\n");
							 | 
						|
								      fprintf (fp, "c #\n");
							 | 
						|
								      fflush (stderr);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    varNamesToFree = 1;
							 | 
						|
								    varNames = DDDMP_ALLOC (char *, nVar);
							 | 
						|
								    for (i=0; i<nVar; i++) {
							 | 
						|
								       varNames[i] = NULL;       
							 | 
						|
								    }
							 | 
						|
								    Dddmp_CheckAndGotoLabel (varNames==NULL, "Error allocating memory.",
							 | 
						|
								      failure);
							 | 
						|
								
							 | 
						|
								    flagVar = 1;
							 | 
						|
								  } else {
							 | 
						|
								    /* Protect the user also from partially loaded varNames array !!! */
							 | 
						|
								    for (i=0; i<nVar && flagVar==0; i++) {
							 | 
						|
								      if (varNames[i] == NULL) {
							 | 
						|
								        flagVar = 1;
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  if (flagVar == 1) {
							 | 
						|
								    for (i=0; i<nVar; i++) {
							 | 
						|
								      if (varNames[i] == NULL) {
							 | 
						|
								        sprintf (tmpString, "DUMMY%d", bddIds[i]);
							 | 
						|
								        varNames[i] = DDDMP_ALLOC (char, (strlen (tmpString)+1));
							 | 
						|
								        strcpy (varNames[i], tmpString);
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*----------------------- Set Initial ID  IF necessary --------------------*/
							 | 
						|
								
							 | 
						|
								  if (idInitial <= 0) {
							 | 
						|
								    idInitial = nVar + 1;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*--------------------------- Continue HEADER -----------------------------*/
							 | 
						|
								
							 | 
						|
								  if (noHeader==0) {
							 | 
						|
								    fprintf (fp, "c .ver %s\n", DDDMP_VERSION);
							 | 
						|
								    fprintf (fp, "c .nnodes %d\n", Cudd_SharingSize (f, rootN));
							 | 
						|
								    fprintf (fp, "c .nvars %d\n", nVar);
							 | 
						|
								    fprintf (fp, "c .nsuppvars %d\n", nVarInSupport);
							 | 
						|
								
							 | 
						|
								    /* Support Variable Names */
							 | 
						|
								    if (varNames != NULL) {
							 | 
						|
								      fprintf (fp, "c .suppvarnames");
							 | 
						|
								      for (i=0; i<nVar; i++) {
							 | 
						|
								        if (bddIdsInSupport[i] >= 0) {
							 | 
						|
								          fprintf (fp, " %s", varNames[i]);
							 | 
						|
								        }
							 | 
						|
								      }
							 | 
						|
								      fprintf (fp, "\n");
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /* Ordered Variable Names */
							 | 
						|
								    if (varNames != NULL) {
							 | 
						|
								      fprintf (fp, "c .orderedvarnames");
							 | 
						|
								      for (i=0; i<nVar; i++) {
							 | 
						|
								        fprintf (fp, " %s", varNames[i]);
							 | 
						|
								      }
							 | 
						|
								      fprintf (fp, "\n");
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /* BDD Variable Ids */
							 | 
						|
								    fprintf (fp, "c .ids ");
							 | 
						|
								    for (i=0; i<nVar; i++) {
							 | 
						|
								      if (bddIdsInSupport[i] >= 0) {
							 | 
						|
								        fprintf (fp, " %d", bddIdsInSupport[i]);
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								    fprintf (fp, "\n");
							 | 
						|
								
							 | 
						|
								    /* BDD Variable Permutation Ids */
							 | 
						|
								    fprintf (fp, "c .permids ");
							 | 
						|
								    for (i=0; i<nVar; i++) {
							 | 
						|
								      if (bddIdsInSupport[i] >= 0) {
							 | 
						|
								        fprintf (fp, " %d", permIdsInSupport[i]);
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								    fprintf (fp, "\n");
							 | 
						|
								
							 | 
						|
								    /* BDD Variable Auxiliary Ids */
							 | 
						|
								    fprintf (fp, "c .auxids ");
							 | 
						|
								    for (i=0; i<nVar; i++) {
							 | 
						|
								      if (bddIdsInSupport[i] >= 0) {
							 | 
						|
								        fprintf (fp, " %d", bddAuxIds[i]);
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								    fprintf (fp, "\n");
							 | 
						|
								
							 | 
						|
								    /* CNF Ids */
							 | 
						|
								    fprintf (fp, "c .cnfids ");
							 | 
						|
								    for (i=0; i<nVar; i++) {
							 | 
						|
								      if (bddIdsInSupport[i] >= 0) {
							 | 
						|
								        fprintf (fp, " %d", cnfIds[i]);
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								    fprintf (fp, "\n");
							 | 
						|
								
							 | 
						|
								    /* Number of Roots */
							 | 
						|
								    fprintf (fp, "c .nroots %d", rootN);
							 | 
						|
								    fprintf (fp, "\n");
							 | 
						|
								
							 | 
						|
								    /* Root Starting Line */
							 | 
						|
								    fgetpos (fp, &posFile1);
							 | 
						|
								    fprintf (fp, "c .rootids");
							 | 
						|
								    for (i=0; i<rootN; i++) {
							 | 
						|
								      for (j=0; j<intStringLength+1; j++) {
							 | 
						|
								        retValue = fprintf (fp, " ");
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								    retValue = fprintf (fp, "\n");
							 | 
						|
								    fflush (fp);
							 | 
						|
								
							 | 
						|
								  } /* End of noHeader check */
							 | 
						|
								
							 | 
						|
								  /*------------ Select Mode and Print Number of Tmp Var Created ------------*/
							 | 
						|
								
							 | 
						|
								  switch (mode) {
							 | 
						|
								    case DDDMP_CNF_MODE_NODE:
							 | 
						|
								      *varNewNPtr = idInitial;
							 | 
						|
								      *varNewNPtr = DddmpNumberDdNodesCnf (ddMgr, f, rootN, cnfIds, idInitial)
							 | 
						|
								        - *varNewNPtr;
							 | 
						|
								      break;
							 | 
						|
								    case DDDMP_CNF_MODE_MAXTERM:
							 | 
						|
								      *varNewNPtr = 0;
							 | 
						|
								      break;
							 | 
						|
								    default:
							 | 
						|
								      Dddmp_Warning (1, "Wrong DDDMP Store Mode. Force DDDMP_MODE_BEST.");
							 | 
						|
								    case DDDMP_CNF_MODE_BEST:
							 | 
						|
								      *varNewNPtr = idInitial;
							 | 
						|
								      *varNewNPtr = DddmpDdNodesCountEdgesAndNumber (ddMgr, f, rootN,
							 | 
						|
								        edgeInTh, pathLengthTh, cnfIds, idInitial) - *varNewNPtr;
							 | 
						|
								      break;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*------------ Print Space for Number of Variable and Clauses -------------*/
							 | 
						|
								
							 | 
						|
								  if (noHeader==0) {
							 | 
						|
								    fprintf (fp, "c .nAddedCnfVar %d\n", *varNewNPtr);
							 | 
						|
								    fprintf (fp, "c #\n");
							 | 
						|
								    fprintf (fp, "c # Init CNF Clauses\n");
							 | 
						|
								    fprintf (fp, "c #\n");
							 | 
						|
								    fgetpos (fp, &posFile2);
							 | 
						|
								    retValue = fprintf (fp, "p cnf");
							 | 
						|
								    for (j=0; j<2*(intStringLength+1); j++) {
							 | 
						|
								      retValue = fprintf (fp, " ");
							 | 
						|
								    }
							 | 
						|
								    retValue = fprintf (fp, "\n");
							 | 
						|
								    fflush (fp);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*---------------------- Select Mode and Do the Job -----------------------*/
							 | 
						|
								
							 | 
						|
								  clauseN = 0;
							 | 
						|
								  varMax = -1;
							 | 
						|
								  rootStartLine = DDDMP_ALLOC (int, rootN);
							 | 
						|
								  Dddmp_CheckAndGotoLabel (rootStartLine==NULL, "Error allocating memory.",
							 | 
						|
								    failure);
							 | 
						|
								  for (i=0; i<rootN; i++) {
							 | 
						|
								    rootStartLine[i] = (-1);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  switch (mode) {
							 | 
						|
								    case DDDMP_CNF_MODE_NODE:
							 | 
						|
								      StoreCnfNodeByNode (ddMgr, f, rootN, bddIds, cnfIds, fp, &clauseN,
							 | 
						|
								        &varMax, rootStartLine);
							 | 
						|
								      DddmpUnnumberDdNodesCnf (ddMgr, f, rootN);
							 | 
						|
								      break;
							 | 
						|
								    case DDDMP_CNF_MODE_MAXTERM:
							 | 
						|
								      StoreCnfMaxtermByMaxterm (ddMgr, f, rootN, bddIds, cnfIds, idInitial,
							 | 
						|
								        fp, &varMax, &clauseN, rootStartLine);
							 | 
						|
								      break;
							 | 
						|
								    default:
							 | 
						|
								      Dddmp_Warning (1, "Wrong DDDMP Store Mode. Force DDDMP_MODE_BEST.");
							 | 
						|
								    case DDDMP_CNF_MODE_BEST:
							 | 
						|
								      StoreCnfBest (ddMgr, f, rootN, bddIds, cnfIds, idInitial,
							 | 
						|
								        fp, &varMax, &clauseN, rootStartLine);
							 | 
						|
								      DddmpUnnumberDdNodesCnf (ddMgr, f, rootN);
							 | 
						|
								      break;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*------------------------------ Write trailer ----------------------------*/
							 | 
						|
								
							 | 
						|
								  if (noHeader==0) {
							 | 
						|
								    retValue = fprintf (fp, "c # End of Cnf From dddmp-2.0\n");
							 | 
						|
								    Dddmp_CheckAndGotoLabel (retValue==EOF, "Error writing to file.",
							 | 
						|
								      failure);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  Write Root Starting Line
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  if (noHeader==0) {
							 | 
						|
								    fsetpos (fp, &posFile1);
							 | 
						|
								    fprintf (fp, "c .rootids");
							 | 
						|
								    for (i=0; i<rootN; i++) {
							 | 
						|
								      Dddmp_Warning (rootStartLine[i]==(-1),
							 | 
						|
								        "Init Line for CNF file = (-1) {[(Stored one or zero BDD)]}.");
							 | 
						|
								      sprintf (tmpString, " %d", rootStartLine[i]);
							 | 
						|
								      for (j=strlen(tmpString); j<intStringLength+1; j++) {
							 | 
						|
								        strcat (tmpString, " ");
							 | 
						|
								      }
							 | 
						|
								      retValue = fprintf (fp, "%s", tmpString);
							 | 
						|
								    }
							 | 
						|
								    retValue = fprintf (fp, "\n");
							 | 
						|
								    fflush (fp);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  Write Number of clauses and variable in the header 
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  *clauseNPtr = clauseN;
							 | 
						|
								
							 | 
						|
								  if (noHeader==0) {
							 | 
						|
								    fsetpos (fp, &posFile2);
							 | 
						|
								    retValue = fprintf (fp, "p cnf");
							 | 
						|
								    sprintf (tmpString, " %d %d", varMax, clauseN);
							 | 
						|
								    for (j=strlen(tmpString); j<2*(intStringLength+1); j++) {
							 | 
						|
								      strcat (tmpString, " ");
							 | 
						|
								    }
							 | 
						|
								    retValue = fprintf (fp, "%s\n", tmpString);
							 | 
						|
								    fflush (fp);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*-------------------------- Close file and return ------------------------*/
							 | 
						|
								
							 | 
						|
								  if (fileToClose) {
							 | 
						|
								    fclose (fp);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  DDDMP_FREE (bddIdsInSupport);
							 | 
						|
								  DDDMP_FREE (permIdsInSupport);
							 | 
						|
								  DDDMP_FREE (rootStartLine);
							 | 
						|
								  if (bddIdsToFree == 1) {
							 | 
						|
								    DDDMP_FREE (bddIds);
							 | 
						|
								  }
							 | 
						|
								  if (bddAuxIdsToFree == 1) {
							 | 
						|
								    DDDMP_FREE (bddAuxIds);
							 | 
						|
								  }
							 | 
						|
								  if (cnfIdsToFree == 1) {
							 | 
						|
								    DDDMP_FREE (cnfIds);
							 | 
						|
								  }
							 | 
						|
								  if (varNamesToFree == 1) {
							 | 
						|
								    for (i=0; i<nVar; i++) {
							 | 
						|
								      DDDMP_FREE (varNames[i]);
							 | 
						|
								    }
							 | 
						|
								    DDDMP_FREE (varNames);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  return (DDDMP_SUCCESS);
							 | 
						|
								
							 | 
						|
								  failure:
							 | 
						|
								
							 | 
						|
								    if (support != NULL) {
							 | 
						|
								      Cudd_RecursiveDeref (ddMgr, support);
							 | 
						|
								    }
							 | 
						|
								    DDDMP_FREE (bddIdsInSupport);
							 | 
						|
								    DDDMP_FREE (permIdsInSupport);
							 | 
						|
								    DDDMP_FREE (rootStartLine);
							 | 
						|
								    if (bddIdsToFree == 1) {
							 | 
						|
								      DDDMP_FREE (bddIds);
							 | 
						|
								    }
							 | 
						|
								    if (bddAuxIdsToFree == 1) {
							 | 
						|
								      DDDMP_FREE (bddAuxIds);
							 | 
						|
								    }
							 | 
						|
								    if (cnfIdsToFree == 1) {
							 | 
						|
								      DDDMP_FREE (cnfIds);
							 | 
						|
								    }
							 | 
						|
								    if (varNamesToFree == 1) {
							 | 
						|
								      for (i=0; i<nVar; i++) {
							 | 
						|
								        DDDMP_FREE (varNames[i]);
							 | 
						|
								      }
							 | 
						|
								      DDDMP_FREE (varNames);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    return (DDDMP_FAILURE);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Definition of static functions                                            */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Store the BDD as CNF clauses.]
							 | 
						|
								
							 | 
						|
								  Description  [Store the BDD as CNF clauses.
							 | 
						|
								    Use a multiplexer description for each BDD node.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects  [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso      []
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static int
							 | 
						|
								StoreCnfNodeByNode (
							 | 
						|
								  DdManager *ddMgr      /* IN: DD Manager */,
							 | 
						|
								  DdNode **f            /* IN: BDD array to be stored */,
							 | 
						|
								  int rootN             /* IN: number of BDDs in the array */,
							 | 
						|
								  int *bddIds           /* IN: BDD ids for variables */,
							 | 
						|
								  int *cnfIds           /* IN: CNF ids for variables */,
							 | 
						|
								  FILE *fp              /* IN: store file */,
							 | 
						|
								  int *clauseN      /* IN/OUT: number of clauses written in the CNF file */,
							 | 
						|
								  int *varMax       /* IN/OUT: maximum value of id written in the CNF file */,
							 | 
						|
								  int *rootStartLine   /* OUT: CNF line where root starts */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  int retValue = 0;
							 | 
						|
								  int i, idf;
							 | 
						|
								
							 | 
						|
								  for (i=0; i<rootN; i++) {
							 | 
						|
								    if (f[i] != NULL) {
							 | 
						|
								      if (!cuddIsConstant(Cudd_Regular (f[i]))) {
							 | 
						|
								        /*
							 | 
						|
								         *  Set Starting Line for this Root
							 | 
						|
								         */
							 | 
						|
								
							 | 
						|
								        rootStartLine[i] = *clauseN + 1;
							 | 
						|
								
							 | 
						|
								        /*
							 | 
						|
								         *  Store the BDD
							 | 
						|
								         */
							 | 
						|
								
							 | 
						|
								        retValue = StoreCnfNodeByNodeRecur (ddMgr, Cudd_Regular(f[i]),
							 | 
						|
								          bddIds, cnfIds, fp, clauseN, varMax);
							 | 
						|
								        if (retValue == 0) {
							 | 
						|
								          (void) fprintf (stderr,
							 | 
						|
								            "DdStoreCnf: Error in recursive node store\n");
							 | 
						|
								          fflush (stderr);
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /*
							 | 
						|
								         *  Store CNF for the root if necessary
							 | 
						|
								         */
							 | 
						|
								
							 | 
						|
								        idf = DddmpReadNodeIndexCnf (Cudd_Regular (f[i]));
							 | 
						|
								#if DDDMP_DEBUG_CNF
							 | 
						|
								        retValue = fprintf (fp, "root %d --> \n", i);
							 | 
						|
								#endif
							 | 
						|
								        if (Cudd_IsComplement (f[i])) {
							 | 
						|
								          retValue = fprintf (fp, "-%d 0\n", idf);
							 | 
						|
								        } else {
							 | 
						|
								          retValue = fprintf (fp, "%d 0\n", idf);
							 | 
						|
								        } 
							 | 
						|
								        *varMax = GET_MAX (*varMax, idf);
							 | 
						|
								        *clauseN = *clauseN + 1;
							 | 
						|
								
							 | 
						|
								        if (retValue == EOF) {
							 | 
						|
								          (void) fprintf (stderr,
							 | 
						|
								            "DdStoreCnf: Error in recursive node store\n");
							 | 
						|
								          fflush (stderr);
							 | 
						|
								        }
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  return (retValue);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Performs the recursive step of Dddmp_bddStore.]
							 | 
						|
								
							 | 
						|
								  Description  [Performs the recursive step of Dddmp_bddStore.
							 | 
						|
								    Traverse the BDD and store a CNF formula for each "terminal" node.
							 | 
						|
								    ]
							 | 
						|
								
							 | 
						|
								  SideEffects  [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso      []
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static int
							 | 
						|
								StoreCnfNodeByNodeRecur (
							 | 
						|
								  DdManager *ddMgr   /* IN: DD Manager */,
							 | 
						|
								  DdNode *f          /* IN: BDD node to be stored */,
							 | 
						|
								  int *bddIds        /* IN: BDD ids for variables */,
							 | 
						|
								  int *cnfIds        /* IN: CNF ids for variables */,
							 | 
						|
								  FILE *fp           /* IN: store file */,
							 | 
						|
								  int *clauseN      /* OUT: number of clauses written in the CNF file */,
							 | 
						|
								  int *varMax       /* OUT: maximum value of id written in the CNF file */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  DdNode *T, *E;
							 | 
						|
								  int idf, idT, idE, vf;
							 | 
						|
								  int retValue;
							 | 
						|
								
							 | 
						|
								#ifdef DDDMP_DEBUG
							 | 
						|
								  assert(!Cudd_IsComplement(f));
							 | 
						|
								  assert(f!=NULL);
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								  /* If constant, nothing to do. */
							 | 
						|
								  if (Cudd_IsConstant(f)) {
							 | 
						|
								    return (1);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* If already visited, nothing to do. */
							 | 
						|
								  if (DddmpVisitedCnf (f)) {
							 | 
						|
								    return (1);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Mark node as visited. */
							 | 
						|
								  DddmpSetVisitedCnf (f);
							 | 
						|
								
							 | 
						|
								  /*------------------ Non Terminal Node -------------------------------*/
							 | 
						|
								
							 | 
						|
								#ifdef DDDMP_DEBUG
							 | 
						|
								  /* BDDs! Only one constant supported */
							 | 
						|
								  assert (!cuddIsConstant(f));
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								  /* 
							 | 
						|
								   *  Recursive call for Then edge
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  T = cuddT (f);
							 | 
						|
								#ifdef DDDMP_DEBUG
							 | 
						|
								  /* ROBDDs! No complemented Then edge */
							 | 
						|
								  assert (!Cudd_IsComplement(T)); 
							 | 
						|
								#endif
							 | 
						|
								  /* recur */
							 | 
						|
								  retValue = StoreCnfNodeByNodeRecur (ddMgr, T, bddIds, cnfIds, fp,
							 | 
						|
								    clauseN, varMax);
							 | 
						|
								  if (retValue != 1) {
							 | 
						|
								    return(retValue);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* 
							 | 
						|
								   *  Recursive call for Else edge
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  E = Cudd_Regular (cuddE (f));
							 | 
						|
								  retValue = StoreCnfNodeByNodeRecur (ddMgr, E, bddIds, cnfIds, fp,
							 | 
						|
								    clauseN, varMax);
							 | 
						|
								  if (retValue != 1) {
							 | 
						|
								    return (retValue);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* 
							 | 
						|
								   *  Obtain nodeids and variable ids of f, T, E 
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  idf = DddmpReadNodeIndexCnf (f);
							 | 
						|
								  vf = f->index;
							 | 
						|
								
							 | 
						|
								  if (bddIds[vf] != vf) {
							 | 
						|
								    (void) fprintf (stderr, "DdStoreCnf: Error writing to file\n");
							 | 
						|
								    fflush (stderr);
							 | 
						|
								    return (0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  idT = DddmpReadNodeIndexCnf (T);
							 | 
						|
								
							 | 
						|
								  idE = DddmpReadNodeIndexCnf (E);
							 | 
						|
								  if (Cudd_IsComplement (cuddE (f))) {
							 | 
						|
								    idE = -idE;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  retValue = StoreCnfOneNode (f, idf, cnfIds[vf], idT, idE, fp,
							 | 
						|
								   clauseN, varMax);
							 | 
						|
								
							 | 
						|
								  if (retValue == EOF) {
							 | 
						|
								    return (0);
							 | 
						|
								  } else {
							 | 
						|
								    return (1);
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								
							 | 
						|
								  Synopsis     [Store One Single BDD Node.]
							 | 
						|
								
							 | 
						|
								  Description  [Store One Single BDD Node translating it as a multiplexer.]
							 | 
						|
								
							 | 
						|
								  SideEffects  [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso      []
							 | 
						|
								
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static int
							 | 
						|
								StoreCnfOneNode (
							 | 
						|
								  DdNode *f       /* IN: node to be stored */,
							 | 
						|
								  int idf         /* IN: node CNF Index  */,
							 | 
						|
								  int vf          /* IN: node BDD Index */,
							 | 
						|
								  int idT         /* IN: Then CNF Index with sign = inverted edge */,
							 | 
						|
								  int idE         /* IN: Else CNF Index with sign = inverted edge */,
							 | 
						|
								  FILE *fp        /* IN: store file */,
							 | 
						|
								  int *clauseN   /* OUT: number of clauses */,
							 | 
						|
								  int *varMax    /* OUT: maximun Index of variable stored */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  int retValue = 0;
							 | 
						|
								  int idfAbs, idTAbs, idEAbs;
							 | 
						|
								
							 | 
						|
								  idfAbs = abs (idf);
							 | 
						|
								  idTAbs = abs (idT);
							 | 
						|
								  idEAbs = abs (idE);
							 | 
						|
								
							 | 
						|
								  /*----------------------------- Check for Constant ------------------------*/
							 | 
						|
								
							 | 
						|
								  assert(!Cudd_IsConstant(f));
							 | 
						|
								
							 | 
						|
								  /*------------------------- Check for terminal nodes ----------------------*/
							 | 
						|
								
							 | 
						|
								  if ((idTAbs==1) && (idEAbs==1)) { 
							 | 
						|
								    return (1);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*------------------------------ Internal Node ----------------------------*/
							 | 
						|
								
							 | 
						|
								#if DDDMP_DEBUG_CNF
							 | 
						|
								  retValue = fprintf (fp, "id=%d var=%d idT=%d idE=%d\n",
							 | 
						|
								    idf, vf, idT, idE);
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  Then to terminal
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  if ((idTAbs==1) && (idEAbs!=1)) {
							 | 
						|
								#if DDDMP_DEBUG_CNF
							 | 
						|
								    retValue = fprintf (fp, "CASE 1 -->\n");
							 | 
						|
								#endif
							 | 
						|
								    retValue = fprintf (fp, "%d %d 0\n",
							 | 
						|
								      idf, -vf);
							 | 
						|
								    retValue = fprintf (fp, "%d %d 0\n",
							 | 
						|
								      idf, -idE);
							 | 
						|
								    retValue = fprintf (fp, "%d %d %d 0\n",
							 | 
						|
								      -idf, vf, idE);
							 | 
						|
								    *clauseN = *clauseN + 3;
							 | 
						|
								
							 | 
						|
								    *varMax = GET_MAX (*varMax, idfAbs);
							 | 
						|
								    *varMax = GET_MAX (*varMax, vf);
							 | 
						|
								    *varMax = GET_MAX (*varMax, idEAbs);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  Else to terminal
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  if ((idTAbs!=1) && (idEAbs==1)) {
							 | 
						|
								    if (idE == 1) {
							 | 
						|
								#if DDDMP_DEBUG_CNF
							 | 
						|
								      retValue = fprintf (fp, "CASE 2 -->\n");
							 | 
						|
								#endif
							 | 
						|
								      retValue = fprintf (fp, "%d %d 0\n",
							 | 
						|
								        idf, vf);
							 | 
						|
								      retValue = fprintf (fp, "%d %d 0\n",
							 | 
						|
								        idf, -idT);
							 | 
						|
								      retValue = fprintf (fp, "%d %d %d 0\n",
							 | 
						|
								        -idf, -vf, idT);
							 | 
						|
								    } else {
							 | 
						|
								#if DDDMP_DEBUG_CNF
							 | 
						|
								      retValue = fprintf (fp, "CASE 3 -->\n");
							 | 
						|
								#endif
							 | 
						|
								      retValue = fprintf (fp, "%d %d 0\n",
							 | 
						|
								        -idf, vf);
							 | 
						|
								      retValue = fprintf (fp, "%d %d 0\n",
							 | 
						|
								        -idf, idT);
							 | 
						|
								      retValue = fprintf (fp, "%d %d %d 0\n",
							 | 
						|
								        idf, -vf, -idT);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    *varMax = GET_MAX (*varMax, idfAbs);
							 | 
						|
								    *varMax = GET_MAX (*varMax, vf);
							 | 
						|
								    *varMax = GET_MAX (*varMax, idTAbs);
							 | 
						|
								
							 | 
						|
								    *clauseN = *clauseN + 3;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  Nor Then or Else to terminal
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  if ((idTAbs!=1) && (idEAbs!=1)) {
							 | 
						|
								#if DDDMP_DEBUG_CNF
							 | 
						|
								    retValue = fprintf (fp, "CASE 4 -->\n");
							 | 
						|
								#endif
							 | 
						|
								    retValue = fprintf (fp, "%d %d %d 0\n",
							 | 
						|
								      idf, vf, -idE);
							 | 
						|
								    retValue = fprintf (fp, "%d %d %d 0\n",
							 | 
						|
								      -idf, vf, idE);
							 | 
						|
								    retValue = fprintf (fp, "%d %d %d 0\n",
							 | 
						|
								      idf, -vf, -idT);
							 | 
						|
								    retValue = fprintf (fp, "%d %d %d 0\n",
							 | 
						|
								      -idf, -vf, idT);
							 | 
						|
								
							 | 
						|
								    *varMax = GET_MAX (*varMax, idfAbs);
							 | 
						|
								    *varMax = GET_MAX (*varMax, vf);
							 | 
						|
								    *varMax = GET_MAX (*varMax, idTAbs);
							 | 
						|
								    *varMax = GET_MAX (*varMax, idEAbs);
							 | 
						|
								
							 | 
						|
								    *clauseN = *clauseN + 4;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  return (retValue);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								 
							 | 
						|
								  Synopsis    [Prints a disjoint sum of products.]
							 | 
						|
								 
							 | 
						|
								  Description [Prints a disjoint sum of product cover for the function
							 | 
						|
								    rooted at node. Each product corresponds to a path from node a 
							 | 
						|
								    leaf node different from the logical zero, and different from 
							 | 
						|
								    the background value. Uses the standard output.  Returns 1 if 
							 | 
						|
								    successful, 0 otherwise.
							 | 
						|
								    ]
							 | 
						|
								 
							 | 
						|
								  SideEffects [None]
							 | 
						|
								 
							 | 
						|
								  SeeAlso     [StoreCnfBest]
							 | 
						|
								 
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static int
							 | 
						|
								StoreCnfMaxtermByMaxterm (
							 | 
						|
								  DdManager *ddMgr    /* IN: DD Manager */,
							 | 
						|
								  DdNode **f          /* IN: array of BDDs to store */,
							 | 
						|
								  int rootN           /* IN: number of BDDs in the array */,
							 | 
						|
								  int *bddIds         /* IN: BDD Identifiers */,
							 | 
						|
								  int *cnfIds         /* IN: corresponding CNF Identifiers */,
							 | 
						|
								  int idInitial       /* IN: initial value for numbering new CNF variables */,
							 | 
						|
								  FILE *fp            /* IN: file pointer */,
							 | 
						|
								  int *varMax        /* OUT: maximum identifier of the variables created */,
							 | 
						|
								  int *clauseN       /* OUT: number of stored clauses */,
							 | 
						|
								  int *rootStartLine /* OUT: line where root starts */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  int i, j, *list;
							 | 
						|
								
							 | 
						|
								  list = DDDMP_ALLOC (int, ddMgr->size);
							 | 
						|
								  if (list == NULL) {
							 | 
						|
								    ddMgr->errorCode = CUDD_MEMORY_OUT;
							 | 
						|
								    return (DDDMP_FAILURE);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  for (i=0; i<rootN; i++) {
							 | 
						|
								    if (f[i] != NULL) {
							 | 
						|
								      if (!cuddIsConstant(Cudd_Regular (f[i]))) {
							 | 
						|
								        for (j=0; j<ddMgr->size; j++) {
							 | 
						|
								          list[j] = 2;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /*
							 | 
						|
								         *  Set Starting Line for this Root
							 | 
						|
								         */
							 | 
						|
								
							 | 
						|
								        rootStartLine[i] = *clauseN + 1;
							 | 
						|
								
							 | 
						|
								        StoreCnfMaxtermByMaxtermRecur (ddMgr, f[i], bddIds, cnfIds, fp,
							 | 
						|
								          list, clauseN, varMax);
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  FREE (list);
							 | 
						|
								
							 | 
						|
								  return (1);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								 
							 | 
						|
								  Synopsis    [Prints a disjoint sum of products with intermediate
							 | 
						|
								    cutting points.]
							 | 
						|
								 
							 | 
						|
								  Description [Prints a disjoint sum of product cover for the function
							 | 
						|
								    rooted at node intorducing cutting points whenever necessary.
							 | 
						|
								    Each product corresponds to a path from node a leaf
							 | 
						|
								    node different from the logical zero, and different from the
							 | 
						|
								    background value. Uses the standard output.  Returns 1 if 
							 | 
						|
								    successful, 0 otherwise.
							 | 
						|
								    ]
							 | 
						|
								 
							 | 
						|
								  SideEffects [None]
							 | 
						|
								 
							 | 
						|
								  SeeAlso     [StoreCnfMaxtermByMaxterm]
							 | 
						|
								 
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static int
							 | 
						|
								StoreCnfBest (
							 | 
						|
								  DdManager *ddMgr    /* IN: DD Manager */,
							 | 
						|
								  DdNode **f          /* IN: array of BDDs to store */,
							 | 
						|
								  int rootN           /* IN: number of BDD in the array */,
							 | 
						|
								  int *bddIds         /* IN: BDD identifiers */,
							 | 
						|
								  int *cnfIds         /* IN: corresponding CNF identifiers */,
							 | 
						|
								  int idInitial       /* IN: initial value for numbering new CNF variables */,
							 | 
						|
								  FILE *fp            /* IN: file pointer */,
							 | 
						|
								  int *varMax        /* OUT: maximum identifier of the variables created */,
							 | 
						|
								  int *clauseN       /* OUT: number of stored clauses */,
							 | 
						|
								  int *rootStartLine /* OUT: line where root starts */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  int i, j, *list;
							 | 
						|
								
							 | 
						|
								  list = DDDMP_ALLOC (int, ddMgr->size);
							 | 
						|
								  if (list == NULL) {
							 | 
						|
								    ddMgr->errorCode = CUDD_MEMORY_OUT;
							 | 
						|
								    return (DDDMP_FAILURE);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  for (i=0; i<rootN; i++) {
							 | 
						|
								    if (f[i] != NULL) {
							 | 
						|
								      if (!cuddIsConstant(Cudd_Regular (f[i]))) {
							 | 
						|
								        for (j=0; j<ddMgr->size; j++) {
							 | 
						|
								          list[j] = 2;
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /*
							 | 
						|
								         *  Set Starting Line for this Root
							 | 
						|
								         */
							 | 
						|
								
							 | 
						|
								        rootStartLine[i] = *clauseN + 1;
							 | 
						|
								
							 | 
						|
								#if DDDMP_DEBUG_CNF
							 | 
						|
								        fprintf (fp, "root NOT shared BDDs %d --> \n", i);
							 | 
						|
								#endif
							 | 
						|
								        StoreCnfBestNotSharedRecur (ddMgr, f[i], 0, bddIds, cnfIds, fp, list,
							 | 
						|
								          clauseN, varMax);
							 | 
						|
								
							 | 
						|
								#if DDDMP_DEBUG_CNF
							 | 
						|
								        fprintf (fp, "root SHARED BDDs %d --> \n", i);
							 | 
						|
								#endif
							 | 
						|
								        StoreCnfBestSharedRecur (ddMgr, Cudd_Regular (f[i]), bddIds, cnfIds,
							 | 
						|
								          fp, list, clauseN, varMax);
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								#if DDDMP_DEBUG_CNF
							 | 
						|
								  fprintf (stdout, "###---> BDDs After the Storing Process:\n");
							 | 
						|
								  DddmpPrintBddAndNext (ddMgr, f, rootN);
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								  FREE (list);
							 | 
						|
								
							 | 
						|
								  return (DDDMP_SUCCESS);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								 
							 | 
						|
								  Synopsis    [Performs the recursive step of Print Maxterm.]
							 | 
						|
								 
							 | 
						|
								  Description [Performs the recursive step of Print Maxterm.
							 | 
						|
								    Traverse a BDD a print out a cube in CNF format each time a terminal
							 | 
						|
								    node is reached.
							 | 
						|
								    ]
							 | 
						|
								 
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso     []
							 | 
						|
								 
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static void
							 | 
						|
								StoreCnfMaxtermByMaxtermRecur (
							 | 
						|
								  DdManager *ddMgr  /* IN: DD Manager */,
							 | 
						|
								  DdNode *node      /* IN: BDD to store */,
							 | 
						|
								  int *bddIds       /* IN: BDD identifiers */,
							 | 
						|
								  int *cnfIds       /* IN: corresponding CNF identifiers */,
							 | 
						|
								  FILE *fp          /* IN: file pointer */,
							 | 
						|
								  int *list         /* IN: temporary array to store cubes */,
							 | 
						|
								  int *clauseN     /* OUT: number of stored clauses */,
							 | 
						|
								  int *varMax      /* OUT: maximum identifier of the variables created */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  DdNode *N, *Nv, *Nnv;
							 | 
						|
								  int retValue, index;
							 | 
						|
								 
							 | 
						|
								  N = Cudd_Regular (node);
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  Terminal case: Print one cube based on the current recursion
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  if (cuddIsConstant (N)) {
							 | 
						|
								    retValue = printCubeCnf (ddMgr, node, cnfIds, fp, list, varMax);
							 | 
						|
								    if (retValue == DDDMP_SUCCESS) {
							 | 
						|
								      fprintf (fp, "0\n");
							 | 
						|
								      *clauseN = *clauseN + 1;
							 | 
						|
								    }
							 | 
						|
								    return;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  NON Terminal case: Recur
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  Nv  = cuddT (N);
							 | 
						|
								  Nnv = cuddE (N);
							 | 
						|
								  if (Cudd_IsComplement (node)) {
							 | 
						|
								    Nv  = Cudd_Not (Nv);
							 | 
						|
								    Nnv = Cudd_Not (Nnv);
							 | 
						|
								  }
							 | 
						|
								  index = N->index;
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  StQ 06.05.2003
							 | 
						|
								   *  Perform the optimization:
							 | 
						|
								   *  f = (a + b)' = (a') ^ (a + b') = (a') ^ (b')
							 | 
						|
								   *  i.e., if the THEN node is the constant ZERO then that variable
							 | 
						|
								   *  can be forgotten (list[index] = 2) for subsequent ELSE cubes
							 | 
						|
								   */
							 | 
						|
								  if (cuddIsConstant (Cudd_Regular (Nv)) &&  Nv != ddMgr->one) {
							 | 
						|
								    list[index] = 2;
							 | 
						|
								  } else {
							 | 
						|
								    list[index] = 0;
							 | 
						|
								  }
							 | 
						|
								  StoreCnfMaxtermByMaxtermRecur (ddMgr, Nnv, bddIds, cnfIds, fp, list,
							 | 
						|
								    clauseN, varMax);
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  StQ 06.05.2003
							 | 
						|
								   *  Perform the optimization:
							 | 
						|
								   *  f = a ^ b = (a) ^ (a' + b) = (a) ^ (b)
							 | 
						|
								   *  i.e., if the ELSE node is the constant ZERO then that variable
							 | 
						|
								   *  can be forgotten (list[index] = 2) for subsequent THEN cubes
							 | 
						|
								   */
							 | 
						|
								  if (cuddIsConstant (Cudd_Regular (Nnv)) &&  Nnv != ddMgr->one) {
							 | 
						|
								    list[index] = 2;
							 | 
						|
								  } else {
							 | 
						|
								    list[index] = 1;
							 | 
						|
								  }
							 | 
						|
								  StoreCnfMaxtermByMaxtermRecur (ddMgr, Nv, bddIds, cnfIds, fp, list,
							 | 
						|
								    clauseN, varMax);
							 | 
						|
								  list[index] = 2;
							 | 
						|
								
							 | 
						|
								  return;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								 
							 | 
						|
								  Synopsis    [Performs the recursive step of Print Best on Not Shared
							 | 
						|
								    sub-BDDs.]
							 | 
						|
								 
							 | 
						|
								  Description [Performs the recursive step of Print Best on Not Shared
							 | 
						|
								    sub-BDDs, i.e., print out information for the nodes belonging to
							 | 
						|
								    BDDs not shared (whose root has just one incoming edge).
							 | 
						|
								    ]
							 | 
						|
								 
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso     []
							 | 
						|
								 
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static int
							 | 
						|
								StoreCnfBestNotSharedRecur (
							 | 
						|
								  DdManager *ddMgr   /* IN: DD Manager */,
							 | 
						|
								  DdNode *node       /* IN: BDD to store */,
							 | 
						|
								  int idf            /* IN: Id to store */,
							 | 
						|
								  int *bddIds        /* IN: BDD identifiers */,
							 | 
						|
								  int *cnfIds        /* IN: corresponding CNF identifiers */,
							 | 
						|
								  FILE *fp           /* IN: file pointer */,
							 | 
						|
								  int *list          /* IN: temporary array to store cubes */,
							 | 
						|
								  int *clauseN      /* OUT: number of stored clauses */,
							 | 
						|
								  int *varMax       /* OUT: maximum identifier of the variables created */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  DdNode *N, *Nv, *Nnv;
							 | 
						|
								  int index, retValue;
							 | 
						|
								  DdNode *one;
							 | 
						|
								    
							 | 
						|
								  one = ddMgr->one;
							 | 
						|
								 
							 | 
						|
								  N = Cudd_Regular (node);
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  Terminal case or Already Visited:
							 | 
						|
								   *    Print one cube based on the current recursion
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  if (cuddIsConstant (N)) {
							 | 
						|
								    retValue = printCubeCnf (ddMgr, node, cnfIds, fp, list, varMax);
							 | 
						|
								    if (retValue == DDDMP_SUCCESS) {
							 | 
						|
								      if (idf != 0) {
							 | 
						|
								         fprintf (fp, "%d ", idf);
							 | 
						|
								      }
							 | 
						|
								      fprintf (fp, "0\n");
							 | 
						|
								      *varMax = GET_MAX (*varMax, abs(idf));
							 | 
						|
								      *clauseN = *clauseN + 1;
							 | 
						|
								    }
							 | 
						|
								    return (DDDMP_SUCCESS);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  Shared Sub-Tree: Print Cube
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  index = DddmpReadNodeIndexCnf (N);
							 | 
						|
								  if (index > 0) {
							 | 
						|
								    if (idf != 0) {
							 | 
						|
								      fprintf (fp, "%d ", idf);
							 | 
						|
								    }
							 | 
						|
								    if (Cudd_IsComplement (node)) {
							 | 
						|
								      retValue = fprintf (fp, "-%d ", index);
							 | 
						|
								    } else {
							 | 
						|
								      retValue = fprintf (fp, "%d ", index);
							 | 
						|
								    }
							 | 
						|
								    retValue = printCubeCnf (ddMgr, node, cnfIds, fp, list, varMax);
							 | 
						|
								    fprintf (fp, "0\n");
							 | 
						|
								    *varMax = GET_MAX (*varMax, abs(index));
							 | 
						|
								    *clauseN = *clauseN + 1;
							 | 
						|
								    return (DDDMP_SUCCESS);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  NON Terminal case: Recur
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  Nv  = cuddT (N);
							 | 
						|
								  Nnv = cuddE (N);
							 | 
						|
								  if (Cudd_IsComplement (node)) {
							 | 
						|
								    Nv  = Cudd_Not (Nv);
							 | 
						|
								    Nnv = Cudd_Not (Nnv);
							 | 
						|
								  }
							 | 
						|
								  index = N->index;
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  StQ 06.05.2003
							 | 
						|
								   *  Perform the optimization:
							 | 
						|
								   *  f = (a + b)' = (a') ^ (a + b') = (a') ^ (b')
							 | 
						|
								   *  i.e., if the THEN node is the constant ZERO then that variable
							 | 
						|
								   *  can be forgotten (list[index] = 2) for subsequent ELSE cubes
							 | 
						|
								   */
							 | 
						|
								  if (cuddIsConstant (Cudd_Regular (Nv)) &&  Nv != ddMgr->one) {
							 | 
						|
								    list[index] = 2;
							 | 
						|
								  } else {
							 | 
						|
								    list[index] = 0;
							 | 
						|
								  }
							 | 
						|
								  StoreCnfBestNotSharedRecur (ddMgr, Nnv, idf, bddIds, cnfIds, fp, list,
							 | 
						|
								    clauseN, varMax);
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  StQ 06.05.2003
							 | 
						|
								   *  Perform the optimization:
							 | 
						|
								   *  f = a ^ b = (a) ^ (a' + b) = (a) ^ (b)
							 | 
						|
								   *  i.e., if the ELSE node is the constant ZERO then that variable
							 | 
						|
								   *  can be forgotten (list[index] = 2) for subsequent THEN cubes
							 | 
						|
								   */
							 | 
						|
								  if (cuddIsConstant (Cudd_Regular (Nnv)) &&  Nnv != ddMgr->one) {
							 | 
						|
								    list[index] = 2;
							 | 
						|
								  } else {
							 | 
						|
								    list[index] = 1;
							 | 
						|
								  }
							 | 
						|
								  StoreCnfBestNotSharedRecur (ddMgr, Nv, idf, bddIds, cnfIds, fp, list,
							 | 
						|
								    clauseN, varMax);
							 | 
						|
								  list[index] = 2;
							 | 
						|
								
							 | 
						|
								  return (DDDMP_SUCCESS);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								 
							 | 
						|
								  Synopsis    [Performs the recursive step of Print Best on Shared
							 | 
						|
								    sub-BDDs.
							 | 
						|
								    ]
							 | 
						|
								 
							 | 
						|
								  Description [Performs the recursive step of Print Best on Not Shared
							 | 
						|
								    sub-BDDs, i.e., print out information for the nodes belonging to
							 | 
						|
								    BDDs not shared (whose root has just one incoming edge).
							 | 
						|
								    ]
							 | 
						|
								 
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso      []
							 | 
						|
								 
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static int
							 | 
						|
								StoreCnfBestSharedRecur (
							 | 
						|
								  DdManager *ddMgr  /* IN: DD Manager */,
							 | 
						|
								  DdNode *node      /* IN: BDD to store */,
							 | 
						|
								  int *bddIds       /* IN: BDD identifiers */,
							 | 
						|
								  int *cnfIds       /* IN: corresponding CNF identifiers */,
							 | 
						|
								  FILE *fp          /* IN: file pointer */,
							 | 
						|
								  int *list         /* IN: temporary array to store cubes */,
							 | 
						|
								  int *clauseN     /* OUT: number of stored clauses */,
							 | 
						|
								  int *varMax      /* OUT: maximum identifier of the variables created */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  DdNode *nodeThen, *nodeElse;
							 | 
						|
								  int i, idf, index;
							 | 
						|
								  DdNode *one;
							 | 
						|
								    
							 | 
						|
								  one = ddMgr->one;
							 | 
						|
								
							 | 
						|
								  Dddmp_Assert (node==Cudd_Regular(node),
							 | 
						|
								    "Inverted Edge during Shared Printing.");
							 | 
						|
								
							 | 
						|
								  /* If constant, nothing to do. */
							 | 
						|
								  if (cuddIsConstant (node)) {
							 | 
						|
								    return (DDDMP_SUCCESS);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* If already visited, nothing to do. */
							 | 
						|
								  if (DddmpVisitedCnf (node)) {
							 | 
						|
								    return (DDDMP_SUCCESS);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  Shared Sub-Tree: Print Cube
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  idf = DddmpReadNodeIndexCnf (node);
							 | 
						|
								  if (idf > 0) {
							 | 
						|
								    /* Cheat the Recur Function about the Index of the Current Node */
							 | 
						|
								    DddmpWriteNodeIndexCnf (node, 0);
							 | 
						|
								
							 | 
						|
								#if DDDMP_DEBUG_CNF
							 | 
						|
								    fprintf (fp, "Else of XNOR\n");
							 | 
						|
								#endif
							 | 
						|
								    for (i=0; i<ddMgr->size; i++) {
							 | 
						|
								      list[i] = 2;
							 | 
						|
								    }
							 | 
						|
								    StoreCnfBestNotSharedRecur (ddMgr, Cudd_Not (node), idf, bddIds, cnfIds,
							 | 
						|
								      fp, list, clauseN, varMax);
							 | 
						|
								
							 | 
						|
								#if DDDMP_DEBUG_CNF
							 | 
						|
								    fprintf (fp, "Then of XNOR\n");
							 | 
						|
								#endif
							 | 
						|
								    for (i=0; i<ddMgr->size; i++) {
							 | 
						|
								      list[i] = 2;
							 | 
						|
								    }
							 | 
						|
								    StoreCnfBestNotSharedRecur (ddMgr, node, -idf, bddIds, cnfIds,
							 | 
						|
								      fp, list, clauseN, varMax);
							 | 
						|
								
							 | 
						|
								    /* Set Back Index of Current Node */
							 | 
						|
								    DddmpWriteNodeIndexCnf (node, idf);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /* Mark node as visited. */
							 | 
						|
								  DddmpSetVisitedCnf (node);
							 | 
						|
								
							 | 
						|
								  /*
							 | 
						|
								   *  Recur
							 | 
						|
								   */
							 | 
						|
								
							 | 
						|
								  nodeThen  = cuddT (node);
							 | 
						|
								  nodeElse = cuddE (node);
							 | 
						|
								  index = node->index;
							 | 
						|
								
							 | 
						|
								  StoreCnfBestSharedRecur (ddMgr, Cudd_Regular (nodeThen), bddIds, cnfIds,
							 | 
						|
								    fp, list, clauseN, varMax);
							 | 
						|
								  StoreCnfBestSharedRecur (ddMgr, Cudd_Regular (nodeElse), bddIds, cnfIds,
							 | 
						|
								    fp, list, clauseN, varMax);
							 | 
						|
								
							 | 
						|
								  return (DDDMP_SUCCESS);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**Function********************************************************************
							 | 
						|
								 
							 | 
						|
								  Synopsis    [Print One Cube in CNF Format.]
							 | 
						|
								 
							 | 
						|
								  Description [Print One Cube in CNF Format.
							 | 
						|
								    Return DDDMP_SUCCESS if something is printed out, DDDMP_FAILURE
							 | 
						|
								    is nothing is printed out.
							 | 
						|
								    ]
							 | 
						|
								 
							 | 
						|
								  SideEffects [None]
							 | 
						|
								
							 | 
						|
								  SeeAlso      []
							 | 
						|
								 
							 | 
						|
								******************************************************************************/
							 | 
						|
								
							 | 
						|
								static int
							 | 
						|
								printCubeCnf (
							 | 
						|
								  DdManager *ddMgr /* IN: DD Manager */,
							 | 
						|
								  DdNode *node     /* IN: BDD to store */,
							 | 
						|
								  int *cnfIds      /* IN: CNF identifiers */,
							 | 
						|
								  FILE *fp         /* IN: file pointer */,
							 | 
						|
								  int *list        /* IN: temporary array to store cubes */,
							 | 
						|
								  int *varMax      /* OUT: maximum identifier of the variables created */
							 | 
						|
								  )
							 | 
						|
								{
							 | 
						|
								  int i, retValue;
							 | 
						|
								  DdNode *one;
							 | 
						|
								    
							 | 
						|
								  retValue = DDDMP_FAILURE;
							 | 
						|
								  one = ddMgr->one;
							 | 
						|
								
							 | 
						|
								  if (node != one) {
							 | 
						|
								    for (i=0; i<ddMgr->size; i++) {
							 | 
						|
								      if (list[i] == 0) {
							 | 
						|
								        retValue = DDDMP_SUCCESS;
							 | 
						|
								        (void) fprintf (fp, "%d ", cnfIds[i]);
							 | 
						|
									*varMax = GET_MAX(*varMax, cnfIds[i]);
							 | 
						|
								      } else {
							 | 
						|
								        if (list[i] == 1) {
							 | 
						|
								          retValue = DDDMP_SUCCESS;
							 | 
						|
								          (void) fprintf (fp, "-%d ", cnfIds[i]);
							 | 
						|
								  	  *varMax = GET_MAX(*varMax, cnfIds[i]);
							 | 
						|
								        }
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  return (retValue);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								
							 |