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.
		
		
		
		
		
			
		
			
				
					
					
						
							537 lines
						
					
					
						
							16 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							537 lines
						
					
					
						
							16 KiB
						
					
					
				
								/**
							 | 
						|
								  @file
							 | 
						|
								
							 | 
						|
								  @ingroup cudd
							 | 
						|
								
							 | 
						|
								  @brief Functions to read in a matrix
							 | 
						|
								
							 | 
						|
								  @see cudd_addHarwell.c
							 | 
						|
								
							 | 
						|
								  @author Fabio Somenzi
							 | 
						|
								
							 | 
						|
								  @copyright@parblock
							 | 
						|
								  Copyright (c) 1995-2015, Regents of the University of Colorado
							 | 
						|
								
							 | 
						|
								  All rights reserved.
							 | 
						|
								
							 | 
						|
								  Redistribution and use in source and binary forms, with or without
							 | 
						|
								  modification, are permitted provided that the following conditions
							 | 
						|
								  are met:
							 | 
						|
								
							 | 
						|
								  Redistributions of source code must retain the above copyright
							 | 
						|
								  notice, this list of conditions and the following disclaimer.
							 | 
						|
								
							 | 
						|
								  Redistributions in binary form must reproduce the above copyright
							 | 
						|
								  notice, this list of conditions and the following disclaimer in the
							 | 
						|
								  documentation and/or other materials provided with the distribution.
							 | 
						|
								
							 | 
						|
								  Neither the name of the University of Colorado nor the names of its
							 | 
						|
								  contributors may be used to endorse or promote products derived from
							 | 
						|
								  this software without specific prior written permission.
							 | 
						|
								
							 | 
						|
								  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
							 | 
						|
								  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
							 | 
						|
								  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
							 | 
						|
								  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
							 | 
						|
								  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
							 | 
						|
								  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
							 | 
						|
								  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
							 | 
						|
								  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
							 | 
						|
								  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
							 | 
						|
								  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
							 | 
						|
								  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
							 | 
						|
								  POSSIBILITY OF SUCH DAMAGE.
							 | 
						|
								  @endparblock
							 | 
						|
								
							 | 
						|
								*/
							 | 
						|
								
							 | 
						|
								#include "util.h"
							 | 
						|
								#include "cuddInt.h"
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Constant declarations                                                     */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Stucture declarations                                                     */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Type declarations                                                         */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Variable declarations                                                     */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Macro declarations                                                        */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								/** \cond */
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Static function prototypes                                                */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								/** \endcond */
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Definition of exported functions                                          */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								  @brief Reads in a sparse matrix.
							 | 
						|
								
							 | 
						|
								  @details Reads in a sparse matrix specified in a simple format.
							 | 
						|
								  The first line of the input contains the numbers of rows and columns.
							 | 
						|
								  The remaining lines contain the elements of the matrix, one per line.
							 | 
						|
								  Given a background value
							 | 
						|
								  (specified by the background field of the manager), only the values
							 | 
						|
								  different from it are explicitly listed.  Each foreground element is
							 | 
						|
								  described by two integers, i.e., the row and column number, and a
							 | 
						|
								  real number, i.e., the value.<p>
							 | 
						|
								  Cudd_addRead produces an %ADD that depends on two sets of variables: x
							 | 
						|
								  and y.  The x variables (x\[0\] ... x\[nx-1\]) encode the row index and
							 | 
						|
								  the y variables (y\[0\] ... y\[ny-1\]) encode the column index.
							 | 
						|
								  x\[0\] and y\[0\] are the most significant bits in the indices.
							 | 
						|
								  The variables may already exist or may be created by the function.
							 | 
						|
								  The index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy.<p>
							 | 
						|
								  On input, nx and ny hold the numbers
							 | 
						|
								  of row and column variables already in existence. On output, they
							 | 
						|
								  hold the numbers of row and column variables actually used by the
							 | 
						|
								  matrix. When Cudd_addRead creates the variable arrays,
							 | 
						|
								  the index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy.
							 | 
						|
								  When some variables already exist Cudd_addRead expects the indices
							 | 
						|
								  of the existing x variables to be bx+i*sx, and the indices of the
							 | 
						|
								  existing y variables to be by+i*sy.<p>
							 | 
						|
								  m and n are set to the numbers of rows and columns of the
							 | 
						|
								  matrix.  Their values on input are immaterial.
							 | 
						|
								  The %ADD for the sparse matrix is returned in E, and its reference
							 | 
						|
								  count is > 0.
							 | 
						|
								
							 | 
						|
								  @return 1 in case of success; 0 otherwise.
							 | 
						|
								
							 | 
						|
								  @sideeffect nx and ny are set to the numbers of row and column
							 | 
						|
								  variables. m and n are set to the numbers of rows and columns. x and y
							 | 
						|
								  are possibly extended to represent the array of row and column
							 | 
						|
								  variables. Similarly for xn and yn_, which hold on return from
							 | 
						|
								  Cudd_addRead the complements of the row and column variables.
							 | 
						|
								
							 | 
						|
								  @see Cudd_addHarwell Cudd_bddRead
							 | 
						|
								
							 | 
						|
								*/
							 | 
						|
								int
							 | 
						|
								Cudd_addRead(
							 | 
						|
								  FILE * fp /**< input file pointer */,
							 | 
						|
								  DdManager * dd /**< %DD manager */,
							 | 
						|
								  DdNode ** E /**< characteristic function of the graph */,
							 | 
						|
								  DdNode *** x /**< array of row variables */,
							 | 
						|
								  DdNode *** y /**< array of column variables */,
							 | 
						|
								  DdNode *** xn /**< array of complemented row variables */,
							 | 
						|
								  DdNode *** yn_ /**< array of complemented column variables */,
							 | 
						|
								  int * nx /**< number or row variables */,
							 | 
						|
								  int * ny /**< number or column variables */,
							 | 
						|
								  int * m /**< number of rows */,
							 | 
						|
								  int * n /**< number of columns */,
							 | 
						|
								  int  bx /**< first index of row variables */,
							 | 
						|
								  int  sx /**< step of row variables */,
							 | 
						|
								  int  by /**< first index of column variables */,
							 | 
						|
								  int  sy /**< step of column variables */)
							 | 
						|
								{
							 | 
						|
								    DdNode *one, *zero;
							 | 
						|
								    DdNode *w, *neW;
							 | 
						|
								    DdNode *minterm1;
							 | 
						|
								    int u, v, err, i, nv;
							 | 
						|
								    int lnx, lny;
							 | 
						|
								    CUDD_VALUE_TYPE val;
							 | 
						|
								    DdNode **lx, **ly, **lxn, **lyn;
							 | 
						|
								
							 | 
						|
								    one = DD_ONE(dd);
							 | 
						|
								    zero = DD_ZERO(dd);
							 | 
						|
								
							 | 
						|
								    err = fscanf(fp, "%d %d", &u, &v);
							 | 
						|
								    if (err == EOF) {
							 | 
						|
									return(0);
							 | 
						|
								    } else if (err != 2) {
							 | 
						|
									return(0);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    *m = u;
							 | 
						|
								    /* Compute the number of x variables. */
							 | 
						|
								    lx = *x; lxn = *xn;
							 | 
						|
								    u--; 	/* row and column numbers start from 0 */
							 | 
						|
								    for (lnx=0; u > 0; lnx++) {
							 | 
						|
									u >>= 1;
							 | 
						|
								    }
							 | 
						|
								    /* Here we rely on the fact that REALLOC of a null pointer is
							 | 
						|
								    ** translates to an ALLOC.
							 | 
						|
								    */
							 | 
						|
								    if (lnx > *nx) {
							 | 
						|
									*x = lx = REALLOC(DdNode *, *x, lnx);
							 | 
						|
									if (lx == NULL) {
							 | 
						|
									    dd->errorCode = CUDD_MEMORY_OUT;
							 | 
						|
									    return(0);
							 | 
						|
									}
							 | 
						|
									*xn = lxn =  REALLOC(DdNode *, *xn, lnx);
							 | 
						|
									if (lxn == NULL) {
							 | 
						|
									    dd->errorCode = CUDD_MEMORY_OUT;
							 | 
						|
									    return(0);
							 | 
						|
									}
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    *n = v;
							 | 
						|
								    /* Compute the number of y variables. */
							 | 
						|
								    ly = *y; lyn = *yn_;
							 | 
						|
								    v--; 	/* row and column numbers start from 0 */
							 | 
						|
								    for (lny=0; v > 0; lny++) {
							 | 
						|
									v >>= 1;
							 | 
						|
								    }
							 | 
						|
								    /* Here we rely on the fact that REALLOC of a null pointer is
							 | 
						|
								    ** translates to an ALLOC.
							 | 
						|
								    */
							 | 
						|
								    if (lny > *ny) {
							 | 
						|
									*y = ly = REALLOC(DdNode *, *y, lny);
							 | 
						|
									if (ly == NULL) {
							 | 
						|
									    dd->errorCode = CUDD_MEMORY_OUT;
							 | 
						|
									    return(0);
							 | 
						|
									}
							 | 
						|
									*yn_ = lyn =  REALLOC(DdNode *, *yn_, lny);
							 | 
						|
									if (lyn == NULL) {
							 | 
						|
									    dd->errorCode = CUDD_MEMORY_OUT;
							 | 
						|
									    return(0);
							 | 
						|
									}
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /* Create all new variables. */
							 | 
						|
								    for (i = *nx, nv = bx + (*nx) * sx; i < lnx; i++, nv += sx) {
							 | 
						|
									do {
							 | 
						|
									    dd->reordered = 0;
							 | 
						|
									    lx[i] = cuddUniqueInter(dd, nv, one, zero);
							 | 
						|
									} while (dd->reordered == 1);
							 | 
						|
									if (lx[i] == NULL) {
							 | 
						|
								            if (dd->errorCode == CUDD_TIMEOUT_EXPIRED && dd->timeoutHandler) {
							 | 
						|
								                dd->timeoutHandler(dd, dd->tohArg);
							 | 
						|
								            }
							 | 
						|
								            return(0);
							 | 
						|
								        }
							 | 
						|
								        cuddRef(lx[i]);
							 | 
						|
									do {
							 | 
						|
									    dd->reordered = 0;
							 | 
						|
									    lxn[i] = cuddUniqueInter(dd, nv, zero, one);
							 | 
						|
									} while (dd->reordered == 1);
							 | 
						|
									if (lxn[i] == NULL) {
							 | 
						|
								            if (dd->errorCode == CUDD_TIMEOUT_EXPIRED && dd->timeoutHandler) {
							 | 
						|
								                dd->timeoutHandler(dd, dd->tohArg);
							 | 
						|
								            }
							 | 
						|
								            return(0);
							 | 
						|
								        }
							 | 
						|
								        cuddRef(lxn[i]);
							 | 
						|
								    }
							 | 
						|
								    for (i = *ny, nv = by + (*ny) * sy; i < lny; i++, nv += sy) {
							 | 
						|
									do {
							 | 
						|
									    dd->reordered = 0;
							 | 
						|
									    ly[i] = cuddUniqueInter(dd, nv, one, zero);
							 | 
						|
									} while (dd->reordered == 1);
							 | 
						|
									if (ly[i] == NULL) {
							 | 
						|
								            if (dd->errorCode == CUDD_TIMEOUT_EXPIRED && dd->timeoutHandler) {
							 | 
						|
								                dd->timeoutHandler(dd, dd->tohArg);
							 | 
						|
								            }
							 | 
						|
								            return(0);
							 | 
						|
								        }
							 | 
						|
									cuddRef(ly[i]);
							 | 
						|
									do {
							 | 
						|
									    dd->reordered = 0;
							 | 
						|
									    lyn[i] = cuddUniqueInter(dd, nv, zero, one);
							 | 
						|
									} while (dd->reordered == 1);
							 | 
						|
									if (lyn[i] == NULL) {
							 | 
						|
								            if (dd->errorCode == CUDD_TIMEOUT_EXPIRED && dd->timeoutHandler) {
							 | 
						|
								                dd->timeoutHandler(dd, dd->tohArg);
							 | 
						|
								            }
							 | 
						|
								            return(0);
							 | 
						|
								        }
							 | 
						|
									cuddRef(lyn[i]);
							 | 
						|
								    }
							 | 
						|
								    *nx = lnx;
							 | 
						|
								    *ny = lny;
							 | 
						|
								
							 | 
						|
								    *E = dd->background; /* this call will never cause reordering */
							 | 
						|
								    cuddRef(*E);
							 | 
						|
								
							 | 
						|
								    while (! feof(fp)) {
							 | 
						|
									err = fscanf(fp, "%d %d %lf", &u, &v, &val);
							 | 
						|
									if (err == EOF) {
							 | 
						|
									    break;
							 | 
						|
									} else if (err != 3) {
							 | 
						|
									    return(0);
							 | 
						|
									} else if (u >= *m || v >= *n || u < 0 || v < 0) {
							 | 
						|
									    return(0);
							 | 
						|
									}
							 | 
						|
								 
							 | 
						|
									minterm1 = one; cuddRef(minterm1);
							 | 
						|
								
							 | 
						|
									/* Build minterm1 corresponding to this arc */
							 | 
						|
									for (i = lnx - 1; i>=0; i--) {
							 | 
						|
									    if (u & 1) {
							 | 
						|
										w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lx[i]);
							 | 
						|
									    } else {
							 | 
						|
										w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lxn[i]);
							 | 
						|
									    }
							 | 
						|
									    if (w == NULL) {
							 | 
						|
										Cudd_RecursiveDeref(dd, minterm1);
							 | 
						|
										return(0);
							 | 
						|
									    }
							 | 
						|
									    cuddRef(w);
							 | 
						|
									    Cudd_RecursiveDeref(dd, minterm1);
							 | 
						|
									    minterm1 = w;
							 | 
						|
									    u >>= 1;
							 | 
						|
									}
							 | 
						|
									for (i = lny - 1; i>=0; i--) {
							 | 
						|
									    if (v & 1) {
							 | 
						|
										w = Cudd_addApply(dd, Cudd_addTimes, minterm1, ly[i]);
							 | 
						|
									    } else {
							 | 
						|
										w = Cudd_addApply(dd, Cudd_addTimes, minterm1, lyn[i]);
							 | 
						|
									    }
							 | 
						|
									    if (w == NULL) {
							 | 
						|
										Cudd_RecursiveDeref(dd, minterm1);
							 | 
						|
										return(0);
							 | 
						|
									    }
							 | 
						|
									    cuddRef(w);
							 | 
						|
									    Cudd_RecursiveDeref(dd, minterm1);
							 | 
						|
									    minterm1 = w;
							 | 
						|
									    v >>= 1;
							 | 
						|
									}
							 | 
						|
									/* Create new constant node if necessary.
							 | 
						|
									** This call will never cause reordering.
							 | 
						|
									*/
							 | 
						|
									neW = cuddUniqueConst(dd, val);
							 | 
						|
									if (neW == NULL) {
							 | 
						|
									    Cudd_RecursiveDeref(dd, minterm1);
							 | 
						|
									    return(0);
							 | 
						|
									}
							 | 
						|
								    	cuddRef(neW);
							 | 
						|
								
							 | 
						|
									w = Cudd_addIte(dd, minterm1, neW, *E);
							 | 
						|
									if (w == NULL) {
							 | 
						|
									    Cudd_RecursiveDeref(dd, minterm1);
							 | 
						|
									    Cudd_RecursiveDeref(dd, neW);
							 | 
						|
									    return(0);
							 | 
						|
									}
							 | 
						|
									cuddRef(w);
							 | 
						|
									Cudd_RecursiveDeref(dd, minterm1);
							 | 
						|
									Cudd_RecursiveDeref(dd, neW);
							 | 
						|
									Cudd_RecursiveDeref(dd, *E);
							 | 
						|
									*E = w;
							 | 
						|
								    }
							 | 
						|
								    return(1);
							 | 
						|
								
							 | 
						|
								} /* end of Cudd_addRead */
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								  @brief Reads in a graph (without labels) given as a list of arcs.
							 | 
						|
								
							 | 
						|
								  @details Reads in a graph (without labels) given as an adjacency
							 | 
						|
								  matrix.  The first line of the input contains the numbers of rows and
							 | 
						|
								  columns of the adjacency matrix. The remaining lines contain the arcs
							 | 
						|
								  of the graph, one per line. Each arc is described by two integers,
							 | 
						|
								  i.e., the row and column number, or the indices of the two endpoints.
							 | 
						|
								  Cudd_bddRead produces a %BDD that depends on two sets of variables: x
							 | 
						|
								  and y.  The x variables (x\[0\] ... x\[nx-1\]) encode
							 | 
						|
								  the row index and the y variables (y\[0\] ... y\[ny-1\]) encode the
							 | 
						|
								  column index. x\[0\] and y\[0\] are the most significant bits in the
							 | 
						|
								  indices.
							 | 
						|
								  The variables may already exist or may be created by the function.
							 | 
						|
								  The index of x\[i\] is bx+i*sx, and the index of y\[i\] is by+i*sy.<p>
							 | 
						|
								  On input, nx and ny hold the numbers of row and column variables already
							 | 
						|
								  in existence. On output, they hold the numbers of row and column
							 | 
						|
								  variables actually used by the matrix. When Cudd_bddRead creates the
							 | 
						|
								  variable arrays, the index of x\[i\] is bx+i*sx, and the index of
							 | 
						|
								  y\[i\] is by+i*sy. When some variables already exist, Cudd_bddRead
							 | 
						|
								  expects the indices of the existing x variables to be bx+i*sx, and the
							 | 
						|
								  indices of the existing y variables to be by+i*sy.<p>
							 | 
						|
								  m and n are set to the numbers of rows and columns of the
							 | 
						|
								  matrix.  Their values on input are immaterial.  The %BDD for the graph
							 | 
						|
								  is returned in E, and its reference count is > 0.
							 | 
						|
								
							 | 
						|
								  @return 1 in case of success; 0 otherwise.
							 | 
						|
								
							 | 
						|
								  @sideeffect nx and ny are set to the numbers of row and column
							 | 
						|
								  variables. m and n are set to the numbers of rows and columns. x and y
							 | 
						|
								  are possibly extended to represent the array of row and column
							 | 
						|
								  variables.
							 | 
						|
								
							 | 
						|
								  @see Cudd_addHarwell Cudd_addRead
							 | 
						|
								
							 | 
						|
								*/
							 | 
						|
								int
							 | 
						|
								Cudd_bddRead(
							 | 
						|
								  FILE * fp /**< input file pointer */,
							 | 
						|
								  DdManager * dd /**< DD manager */,
							 | 
						|
								  DdNode ** E /**< characteristic function of the graph */,
							 | 
						|
								  DdNode *** x /**< array of row variables */,
							 | 
						|
								  DdNode *** y /**< array of column variables */,
							 | 
						|
								  int * nx /**< number or row variables */,
							 | 
						|
								  int * ny /**< number or column variables */,
							 | 
						|
								  int * m /**< number of rows */,
							 | 
						|
								  int * n /**< number of columns */,
							 | 
						|
								  int  bx /**< first index of row variables */,
							 | 
						|
								  int  sx /**< step of row variables */,
							 | 
						|
								  int  by /**< first index of column variables */,
							 | 
						|
								  int  sy /**< step of column variables */)
							 | 
						|
								{
							 | 
						|
								    DdNode *one, *zero;
							 | 
						|
								    DdNode *w;
							 | 
						|
								    DdNode *minterm1;
							 | 
						|
								    int u, v, err, i, nv;
							 | 
						|
								    int lnx, lny;
							 | 
						|
								    DdNode **lx, **ly;
							 | 
						|
								
							 | 
						|
								    one = DD_ONE(dd);
							 | 
						|
								    zero = Cudd_Not(one);
							 | 
						|
								
							 | 
						|
								    err = fscanf(fp, "%d %d", &u, &v);
							 | 
						|
								    if (err == EOF) {
							 | 
						|
									return(0);
							 | 
						|
								    } else if (err != 2) {
							 | 
						|
									return(0);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    *m = u;
							 | 
						|
								    /* Compute the number of x variables. */
							 | 
						|
								    lx = *x;
							 | 
						|
								    u--; 	/* row and column numbers start from 0 */
							 | 
						|
								    for (lnx=0; u > 0; lnx++) {
							 | 
						|
									u >>= 1;
							 | 
						|
								    }
							 | 
						|
								    if (lnx > *nx) {
							 | 
						|
									*x = lx = REALLOC(DdNode *, *x, lnx);
							 | 
						|
									if (lx == NULL) {
							 | 
						|
									    dd->errorCode = CUDD_MEMORY_OUT;
							 | 
						|
									    return(0);
							 | 
						|
									}
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    *n = v;
							 | 
						|
								    /* Compute the number of y variables. */
							 | 
						|
								    ly = *y;
							 | 
						|
								    v--; 	/* row and column numbers start from 0 */
							 | 
						|
								    for (lny=0; v > 0; lny++) {
							 | 
						|
									v >>= 1;
							 | 
						|
								    }
							 | 
						|
								    if (lny > *ny) {
							 | 
						|
									*y = ly = REALLOC(DdNode *, *y, lny);
							 | 
						|
									if (ly == NULL) {
							 | 
						|
									    dd->errorCode = CUDD_MEMORY_OUT;
							 | 
						|
									    return(0);
							 | 
						|
									}
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /* Create all new variables. */
							 | 
						|
								    for (i = *nx, nv = bx + (*nx) * sx; i < lnx; i++, nv += sx) {
							 | 
						|
									do {
							 | 
						|
									    dd->reordered = 0;
							 | 
						|
									    lx[i] = cuddUniqueInter(dd, nv, one, zero);
							 | 
						|
									} while (dd->reordered == 1);
							 | 
						|
									if (lx[i] == NULL) {
							 | 
						|
								            if (dd->errorCode == CUDD_TIMEOUT_EXPIRED && dd->timeoutHandler) {
							 | 
						|
								                dd->timeoutHandler(dd, dd->tohArg);
							 | 
						|
								            }
							 | 
						|
								            return(0);
							 | 
						|
								        }
							 | 
						|
								        cuddRef(lx[i]);
							 | 
						|
								    }
							 | 
						|
								    for (i = *ny, nv = by + (*ny) * sy; i < lny; i++, nv += sy) {
							 | 
						|
									do {
							 | 
						|
									    dd->reordered = 0;
							 | 
						|
									    ly[i] = cuddUniqueInter(dd, nv, one, zero);
							 | 
						|
									} while (dd->reordered == 1);
							 | 
						|
									if (ly[i] == NULL) {
							 | 
						|
								            if (dd->errorCode == CUDD_TIMEOUT_EXPIRED && dd->timeoutHandler) {
							 | 
						|
								                dd->timeoutHandler(dd, dd->tohArg);
							 | 
						|
								            }
							 | 
						|
								            return(0);
							 | 
						|
								        }
							 | 
						|
									cuddRef(ly[i]);
							 | 
						|
								    }
							 | 
						|
								    *nx = lnx;
							 | 
						|
								    *ny = lny;
							 | 
						|
								
							 | 
						|
								    *E = zero; /* this call will never cause reordering */
							 | 
						|
								    cuddRef(*E);
							 | 
						|
								
							 | 
						|
								    while (! feof(fp)) {
							 | 
						|
									err = fscanf(fp, "%d %d", &u, &v);
							 | 
						|
									if (err == EOF) {
							 | 
						|
									    break;
							 | 
						|
									} else if (err != 2) {
							 | 
						|
									    return(0);
							 | 
						|
									} else if (u >= *m || v >= *n || u < 0 || v < 0) {
							 | 
						|
									    return(0);
							 | 
						|
									}
							 | 
						|
								 
							 | 
						|
									minterm1 = one; cuddRef(minterm1);
							 | 
						|
								
							 | 
						|
									/* Build minterm1 corresponding to this arc. */
							 | 
						|
									for (i = lnx - 1; i>=0; i--) {
							 | 
						|
									    if (u & 1) {
							 | 
						|
										w = Cudd_bddAnd(dd, minterm1, lx[i]);
							 | 
						|
									    } else {
							 | 
						|
										w = Cudd_bddAnd(dd, minterm1, Cudd_Not(lx[i]));
							 | 
						|
									    }
							 | 
						|
									    if (w == NULL) {
							 | 
						|
										Cudd_RecursiveDeref(dd, minterm1);
							 | 
						|
										return(0);
							 | 
						|
									    }
							 | 
						|
									    cuddRef(w);
							 | 
						|
									    Cudd_RecursiveDeref(dd,minterm1);
							 | 
						|
									    minterm1 = w;
							 | 
						|
									    u >>= 1;
							 | 
						|
									}
							 | 
						|
									for (i = lny - 1; i>=0; i--) {
							 | 
						|
									    if (v & 1) {
							 | 
						|
										w = Cudd_bddAnd(dd, minterm1, ly[i]);
							 | 
						|
									    } else {
							 | 
						|
										w = Cudd_bddAnd(dd, minterm1, Cudd_Not(ly[i]));
							 | 
						|
									    }
							 | 
						|
									    if (w == NULL) {
							 | 
						|
										Cudd_RecursiveDeref(dd, minterm1);
							 | 
						|
										return(0);
							 | 
						|
									    }
							 | 
						|
									    cuddRef(w);
							 | 
						|
									    Cudd_RecursiveDeref(dd, minterm1);
							 | 
						|
									    minterm1 = w;
							 | 
						|
									    v >>= 1;
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									w = Cudd_bddAnd(dd, Cudd_Not(minterm1), Cudd_Not(*E));
							 | 
						|
									if (w == NULL) {
							 | 
						|
									    Cudd_RecursiveDeref(dd, minterm1);
							 | 
						|
									    return(0);
							 | 
						|
									}
							 | 
						|
									w = Cudd_Not(w);
							 | 
						|
									cuddRef(w);
							 | 
						|
									Cudd_RecursiveDeref(dd, minterm1);
							 | 
						|
									Cudd_RecursiveDeref(dd, *E);
							 | 
						|
									*E = w;
							 | 
						|
								    }
							 | 
						|
								    return(1);
							 | 
						|
								
							 | 
						|
								} /* end of Cudd_bddRead */
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Definition of internal functions                                          */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								/* Definition of static functions                                            */
							 | 
						|
								/*---------------------------------------------------------------------------*/
							 | 
						|
								
							 |