summaryrefslogtreecommitdiffstats
path: root/src/opt
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2006-07-23 08:01:00 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2006-07-23 08:01:00 -0700
commit7e8e03206c56e7cd9d0d9fbb447c785c400ff3ee (patch)
tree9d31935cf6c27b36c3ceb57cb5cffe2577a569a7 /src/opt
parent616bb095f10c24f1f720efe89b7f39c670d114a3 (diff)
downloadabc-7e8e03206c56e7cd9d0d9fbb447c785c400ff3ee.tar.gz
abc-7e8e03206c56e7cd9d0d9fbb447c785c400ff3ee.tar.bz2
abc-7e8e03206c56e7cd9d0d9fbb447c785c400ff3ee.zip
Version abc60723
Diffstat (limited to 'src/opt')
-rw-r--r--src/opt/cut/Abc_NtkFindCi.c988
-rw-r--r--src/opt/cut/abcCut.c491
-rw-r--r--src/opt/cut/cut.h5
-rw-r--r--src/opt/cut/cutInt.h1
-rw-r--r--src/opt/cut/cutMan.c48
-rw-r--r--src/opt/cut/cutNode.c36
-rw-r--r--src/opt/cut/cutPre22.c2
-rw-r--r--src/opt/cut/vec.h66
-rw-r--r--src/opt/cut/vecInt.h753
-rw-r--r--src/opt/cut/vecPtr.h579
-rw-r--r--src/opt/cut/vecStr.h510
-rw-r--r--src/opt/cut/vecVec.h289
-rw-r--r--src/opt/dec/decAbc.c2
13 files changed, 2779 insertions, 991 deletions
diff --git a/src/opt/cut/Abc_NtkFindCi.c b/src/opt/cut/Abc_NtkFindCi.c
deleted file mode 100644
index 203f9e6f..00000000
--- a/src/opt/cut/Abc_NtkFindCi.c
+++ /dev/null
@@ -1,988 +0,0 @@
-/**CFile****************************************************************
-
- FileName [cutPre22.c]
-
- SystemName [ABC: Logic synthesis and verification system.]
-
- PackageName [Network and node package.]
-
- Synopsis [Precomputes truth tables for the 2x2 macro cell.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 1.0. Started - June 20, 2005.]
-
- Revision [$Id: cutPre22.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
-
-***********************************************************************/
-
-#include "cutInt.h"
-
-////////////////////////////////////////////////////////////////////////
-/// DECLARATIONS ///
-////////////////////////////////////////////////////////////////////////
-
-#define CUT_CELL_MVAR 9
-
-typedef struct Cut_Cell_t_ Cut_Cell_t;
-typedef struct Cut_CMan_t_ Cut_CMan_t;
-
-struct Cut_Cell_t_
-{
- Cut_Cell_t * pNext; // pointer to the next cell in the table
- Cut_Cell_t * pNextVar; // pointer to the next cell of this support size
- Cut_Cell_t * pParent; // pointer to the cell used to derive this one
- int nUsed; // the number of times the cell is used
- char Box[4]; // functions in the boxes
- unsigned nVars : 4; // the number of variables
- unsigned CrossBar0 : 4; // the variable set equal
- unsigned CrossBar1 : 4; // the variable set equal
- unsigned CrossBarPhase : 2; // the phase of the cross bar (0, 1, or 2)
- unsigned CanonPhase : 18; // the canonical phase
- char CanonPerm[CUT_CELL_MVAR+3]; // semicanonical permutation
- short Store[2*CUT_CELL_MVAR]; // minterm counts in the cofactors
- unsigned uTruth[1<<(CUT_CELL_MVAR-5)]; // the current truth table
-};
-
-struct Cut_CMan_t_
-{
- // storage for canonical cells
- Extra_MmFixed_t * pMem;
- st_table * tTable;
- Cut_Cell_t * pSameVar[CUT_CELL_MVAR+1];
- // elementary truth tables
- unsigned uInputs[CUT_CELL_MVAR][1<<(CUT_CELL_MVAR-5)];
- // temporary truth tables
- unsigned uTemp1[22][1<<(CUT_CELL_MVAR-5)];
- unsigned uTemp2[22][1<<(CUT_CELL_MVAR-5)];
- unsigned uTemp3[22][1<<(CUT_CELL_MVAR-5)];
- unsigned uFinal[1<<(CUT_CELL_MVAR-5)];
- unsigned puAux[1<<(CUT_CELL_MVAR-5)];
- // statistical variables
- int nTotal;
- int nGood;
- int nVarCounts[CUT_CELL_MVAR+1];
- int nSymGroups[CUT_CELL_MVAR+1];
- int nSymGroupsE[CUT_CELL_MVAR+1];
- int timeCanon;
- int timeSupp;
- int timeTable;
- int nCellFound;
- int nCellNotFound;
-};
-
-// NP-classes of functions of 3 variables (22)
-static char * s_NP3[22] = {
- " 0\n", // 00 const 0 // 0 vars
- " 1\n", // 01 const 1 // 0 vars
- "1 1\n", // 02 a // 1 vars
- "11 1\n", // 03 ab // 2 vars
- "11 0\n", // 04 (ab)' // 2 vars
- "10 1\n01 1\n", // 05 a<+>b // 2 vars
- "111 1\n", // 06 0s abc // 3 vars
- "111 0\n", // 07 (abc)' //
- "11- 1\n1-1 1\n", // 08 1p a(b+c) //
- "11- 0\n1-1 0\n", // 09 (a(b+c))' //
- "111 1\n100 1\n010 1\n001 1\n", // 10 2s a<+>b<+>c //
- "10- 0\n1-0 0\n011 0\n", // 11 3p a<+>bc //
- "101 1\n110 1\n", // 12 4p a(b<+>c) //
- "101 0\n110 0\n", // 13 (a(b<+>c))' //
- "11- 1\n1-1 1\n-11 1\n", // 14 5s ab+bc+ac //
- "111 1\n000 1\n", // 15 6s abc+a'b'c' //
- "111 0\n000 0\n", // 16 (abc+a'b'c')' //
- "11- 1\n-11 1\n0-1 1\n", // 17 7 ab+bc+a'c //
- "011 1\n101 1\n110 1\n", // 18 8s a'bc+ab'c+abc' //
- "011 0\n101 0\n110 0\n", // 19 (a'bc+ab'c+abc')' //
- "100 1\n-11 1\n", // 20 9p ab'c'+bc //
- "100 0\n-11 0\n" // 21 (ab'c'+bc)' //
-};
-
-// NP-classes of functions of 3 variables (22)
-static char * s_NP3Names[22] = {
- " const 0 ",
- " const 1 ",
- " a ",
- " ab ",
- " (ab)' ",
- " a<+>b ",
- "0s abc ",
- " (abc)' ",
- "1p a(b+c) ",
- " (a(b+c))' ",
- "2s a<+>b<+>c ",
- "3p a<+>bc ",
- "4p a(b<+>c) ",
- " (a(b<+>c))' ",
- "5s ab+bc+ac ",
- "6s abc+a'b'c' ",
- " (abc+a'b'c')' ",
- "7 ab+bc+a'c ",
- "8s a'bc+ab'c+abc' ",
- " (a'bc+ab'c+abc')' ",
- "9p ab'c'+bc ",
- " (ab'c'+bc)' "
-};
-
-// the number of variables in each function
-static int s_NP3VarNums[22] = { 0, 0, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
-
-// NPN classes of functions of exactly 3 inputs (10)
-static int s_NPNe3[10] = { 6, 8, 10, 11, 12, 14, 15, 17, 18, 20 };
-
-// NPN classes of functions of exactly 3 inputs that are symmetric (5)
-static int s_NPNe3s[10] = { 6, 10, 14, 15, 18 };
-
-// NPN classes of functions of exactly 3 inputs (4)
-static int s_NPNe3p[10] = { 8, 11, 12, 20 };
-
-static Cut_CMan_t * Cut_CManStart();
-static void Cut_CManStop( Cut_CMan_t * p );
-static void Cut_CellTruthElem( unsigned * InA, unsigned * InB, unsigned * InC, unsigned * pOut, int nVars, int Type );
-static void Cut_CellCanonicize( Cut_CMan_t * p, Cut_Cell_t * pCell );
-static int Cut_CellTableLookup( Cut_CMan_t * p, Cut_Cell_t * pCell );
-static void Cut_CellSuppMin( Cut_Cell_t * pCell );
-static void Cut_CellCrossBar( Cut_Cell_t * pCell );
-
-
-static Cut_CMan_t * s_pCMan = NULL;
-
-////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFINITIONS ///
-////////////////////////////////////////////////////////////////////////
-
-/**Function*************************************************************
-
- Synopsis [Start the precomputation manager.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Cut_CellLoad()
-{
- FILE * pFile;
- char * pFileName = "cells22_daomap_iwls.txt";
- char pString[1000];
- Cut_CMan_t * p;
- Cut_Cell_t * pCell;
- int Length; //, i;
- pFile = fopen( pFileName, "r" );
- if ( pFile == NULL )
- {
- printf( "Cannot open file \"%s\".\n", pFileName );
- return;
- }
- // start the manager
- p = Cut_CManStart();
- // load truth tables
- while ( fgets(pString, 1000, pFile) )
- {
- Length = strlen(pString);
- pString[Length--] = 0;
- if ( Length == 0 )
- continue;
- // derive the cell
- pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
- memset( pCell, 0, sizeof(Cut_Cell_t) );
- pCell->nVars = Extra_Base2Log(Length*4);
- pCell->nUsed = 1;
-// Extra_TruthCopy( pCell->uTruth, pTruth, nVars );
- Extra_ReadHexadecimal( pCell->uTruth, pString, pCell->nVars );
- Cut_CellSuppMin( pCell );
-/*
- // set the elementary permutation
- for ( i = 0; i < (int)pCell->nVars; i++ )
- pCell->CanonPerm[i] = i;
- // canonicize
- pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
-*/
- // add to the table
- p->nTotal++;
-
-// Extra_PrintHexadecimal( stdout, pCell->uTruth, pCell->nVars ); printf( "\n" );
-// if ( p->nTotal == 500 )
-// break;
-
- if ( !Cut_CellTableLookup( p, pCell ) ) // new cell
- p->nGood++;
- }
- printf( "Read %d cells from file \"%s\". Added %d cells to the table.\n", p->nTotal, pFileName, p->nGood );
- fclose( pFile );
-// return p;
-}
-
-/**Function*************************************************************
-
- Synopsis [Precomputes truth tables for the 2x2 macro cell.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Cut_CellPrecompute()
-{
- Cut_CMan_t * p;
- Cut_Cell_t * pCell, * pTemp;
- int i1, i2, i3, i, j, k, c, clk = clock(), clk2 = clock();
-
- p = Cut_CManStart();
-
- // precompute truth tables
- for ( i = 0; i < 22; i++ )
- Cut_CellTruthElem( p->uInputs[0], p->uInputs[1], p->uInputs[2], p->uTemp1[i], 9, i );
- for ( i = 0; i < 22; i++ )
- Cut_CellTruthElem( p->uInputs[3], p->uInputs[4], p->uInputs[5], p->uTemp2[i], 9, i );
- for ( i = 0; i < 22; i++ )
- Cut_CellTruthElem( p->uInputs[6], p->uInputs[7], p->uInputs[8], p->uTemp3[i], 9, i );
-/*
- if ( k == 8 && ((i1 == 6 && i2 == 14 && i3 == 20) || (i1 == 20 && i2 == 6 && i3 == 14)) )
- {
- Extra_PrintBinary( stdout, &pCell->CanonPhase, pCell->nVars+1 ); printf( " : " );
- for ( i = 0; i < pCell->nVars; i++ )
- printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] );
- Extra_PrintHexadecimal( stdout, pCell->uTruth, pCell->nVars );
- printf( "\n" );
- }
-*/
-/*
- // go through symmetric roots
- for ( k = 0; k < 5; k++ )
- for ( i1 = 0; i1 < 22; i1++ )
- for ( i2 = i1; i2 < 22; i2++ )
- for ( i3 = i2; i3 < 22; i3++ )
- {
- // derive the cell
- pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
- memset( pCell, 0, sizeof(Cut_Cell_t) );
- pCell->nVars = 9;
- pCell->Box[0] = s_NPNe3s[k];
- pCell->Box[1] = i1;
- pCell->Box[2] = i2;
- pCell->Box[3] = i3;
- // fill in the truth table
- Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3s[k] );
- // canonicize
- Cut_CellCanonicize( pCell );
-
- // add to the table
- p->nTotal++;
- if ( Cut_CellTableLookup( p, pCell ) ) // already exists
- Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
- else
- p->nGood++;
- }
-
- // go through partially symmetric roots
- for ( k = 0; k < 4; k++ )
- for ( i1 = 0; i1 < 22; i1++ )
- for ( i2 = 0; i2 < 22; i2++ )
- for ( i3 = i2; i3 < 22; i3++ )
- {
- // derive the cell
- pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
- memset( pCell, 0, sizeof(Cut_Cell_t) );
- pCell->nVars = 9;
- pCell->Box[0] = s_NPNe3p[k];
- pCell->Box[1] = i1;
- pCell->Box[2] = i2;
- pCell->Box[3] = i3;
- // fill in the truth table
- Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3p[k] );
- // canonicize
- Cut_CellCanonicize( pCell );
-
- // add to the table
- p->nTotal++;
- if ( Cut_CellTableLookup( p, pCell ) ) // already exists
- Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
- else
- p->nGood++;
- }
-
- // go through non-symmetric functions
- for ( i1 = 0; i1 < 22; i1++ )
- for ( i2 = 0; i2 < 22; i2++ )
- for ( i3 = 0; i3 < 22; i3++ )
- {
- // derive the cell
- pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
- memset( pCell, 0, sizeof(Cut_Cell_t) );
- pCell->nVars = 9;
- pCell->Box[0] = 17;
- pCell->Box[1] = i1;
- pCell->Box[2] = i2;
- pCell->Box[3] = i3;
- // fill in the truth table
- Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, 17 );
- // canonicize
- Cut_CellCanonicize( pCell );
-
- // add to the table
- p->nTotal++;
- if ( Cut_CellTableLookup( p, pCell ) ) // already exists
- Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
- else
- p->nGood++;
- }
-*/
-
- // go through non-symmetric functions
- for ( k = 0; k < 10; k++ )
- for ( i1 = 0; i1 < 22; i1++ )
- for ( i2 = 0; i2 < 22; i2++ )
- for ( i3 = 0; i3 < 22; i3++ )
- {
- // derive the cell
- pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
- memset( pCell, 0, sizeof(Cut_Cell_t) );
- pCell->nVars = 9;
- pCell->Box[0] = s_NPNe3[k];
- pCell->Box[1] = i1;
- pCell->Box[2] = i2;
- pCell->Box[3] = i3;
- // set the elementary permutation
- for ( i = 0; i < (int)pCell->nVars; i++ )
- pCell->CanonPerm[i] = i;
- // fill in the truth table
- Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3[k] );
- // minimize the support
- Cut_CellSuppMin( pCell );
-
- // canonicize
- pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
-
- // add to the table
- p->nTotal++;
- if ( Cut_CellTableLookup( p, pCell ) ) // already exists
- Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
- else
- {
- p->nGood++;
- p->nVarCounts[pCell->nVars]++;
-
- if ( pCell->nVars )
- for ( i = 0; i < (int)pCell->nVars-1; i++ )
- {
- if ( pCell->Store[2*i] != pCell->Store[2*(i+1)] ) // i and i+1 cannot be symmetric
- continue;
- // i and i+1 can be symmetric
- // find the end of this group
- for ( j = i+1; j < (int)pCell->nVars; j++ )
- if ( pCell->Store[2*i] != pCell->Store[2*j] )
- break;
-
- if ( pCell->Store[2*i] == pCell->Store[2*i+1] )
- p->nSymGroupsE[j-i]++;
- else
- p->nSymGroups[j-i]++;
- i = j - 1;
- }
-/*
- if ( pCell->nVars == 3 )
- {
- Extra_PrintBinary( stdout, pCell->uTruth, 32 ); printf( "\n" );
- for ( i = 0; i < (int)pCell->nVars; i++ )
- printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] );
- printf( "\n" );
- }
-*/
- }
- }
-
- printf( "BASIC: Total = %d. Good = %d. Entry = %d. ", p->nTotal, p->nGood, sizeof(Cut_Cell_t) );
- PRT( "Time", clock() - clk );
- printf( "Cells: " );
- for ( i = 0; i <= 9; i++ )
- printf( "%d=%d ", i, p->nVarCounts[i] );
- printf( "\nDiffs: " );
- for ( i = 0; i <= 9; i++ )
- printf( "%d=%d ", i, p->nSymGroups[i] );
- printf( "\nEquals: " );
- for ( i = 0; i <= 9; i++ )
- printf( "%d=%d ", i, p->nSymGroupsE[i] );
- printf( "\n" );
-
- // continue adding new cells using support
- for ( k = CUT_CELL_MVAR; k > 3; k-- )
- {
- for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar )
- for ( i1 = 0; i1 < k; i1++ )
- for ( i2 = i1+1; i2 < k; i2++ )
- for ( c = 0; c < 3; c++ )
- {
- // derive the cell
- pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
- memset( pCell, 0, sizeof(Cut_Cell_t) );
- pCell->nVars = pTemp->nVars;
- pCell->pParent = pTemp;
- // set the elementary permutation
- for ( i = 0; i < (int)pCell->nVars; i++ )
- pCell->CanonPerm[i] = i;
- // fill in the truth table
- Extra_TruthCopy( pCell->uTruth, pTemp->uTruth, pTemp->nVars );
- // create the cross-bar
- pCell->CrossBar0 = i1;
- pCell->CrossBar1 = i2;
- pCell->CrossBarPhase = c;
- Cut_CellCrossBar( pCell );
- // minimize the support
-//clk2 = clock();
- Cut_CellSuppMin( pCell );
-//p->timeSupp += clock() - clk2;
- // canonicize
-//clk2 = clock();
- pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
-//p->timeCanon += clock() - clk2;
-
- // add to the table
-//clk2 = clock();
- p->nTotal++;
- if ( Cut_CellTableLookup( p, pCell ) ) // already exists
- Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
- else
- {
- p->nGood++;
- p->nVarCounts[pCell->nVars]++;
-
- for ( i = 0; i < (int)pCell->nVars-1; i++ )
- {
- if ( pCell->Store[2*i] != pCell->Store[2*(i+1)] ) // i and i+1 cannot be symmetric
- continue;
- // i and i+1 can be symmetric
- // find the end of this group
- for ( j = i+1; j < (int)pCell->nVars; j++ )
- if ( pCell->Store[2*i] != pCell->Store[2*j] )
- break;
-
- if ( pCell->Store[2*i] == pCell->Store[2*i+1] )
- p->nSymGroupsE[j-i]++;
- else
- p->nSymGroups[j-i]++;
- i = j - 1;
- }
-/*
- if ( pCell->nVars == 3 )
- {
- Extra_PrintBinary( stdout, pCell->uTruth, 32 ); printf( "\n" );
- for ( i = 0; i < (int)pCell->nVars; i++ )
- printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] );
- printf( "\n" );
- }
-*/
- }
-//p->timeTable += clock() - clk2;
- }
-
- printf( "VAR %d: Total = %d. Good = %d. Entry = %d. ", k, p->nTotal, p->nGood, sizeof(Cut_Cell_t) );
- PRT( "Time", clock() - clk );
- printf( "Cells: " );
- for ( i = 0; i <= 9; i++ )
- printf( "%d=%d ", i, p->nVarCounts[i] );
- printf( "\nDiffs: " );
- for ( i = 0; i <= 9; i++ )
- printf( "%d=%d ", i, p->nSymGroups[i] );
- printf( "\nEquals: " );
- for ( i = 0; i <= 9; i++ )
- printf( "%d=%d ", i, p->nSymGroupsE[i] );
- printf( "\n" );
- }
-// printf( "\n" );
- PRT( "Supp ", p->timeSupp );
- PRT( "Canon", p->timeCanon );
- PRT( "Table", p->timeTable );
-// Cut_CManStop( p );
-}
-
-/**Function*************************************************************
-
- Synopsis [Check the table.]
-
- Description [Returns 1 if such a truth table already exists.]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Cut_CellTableLookup( Cut_CMan_t * p, Cut_Cell_t * pCell )
-{
- Cut_Cell_t ** pSlot, * pTemp;
- unsigned Hash;
- Hash = Extra_TruthHash( pCell->uTruth, Extra_TruthWordNum( pCell->nVars ) );
- if ( !st_find_or_add( p->tTable, (char *)Hash, (char ***)&pSlot ) )
- *pSlot = NULL;
- for ( pTemp = *pSlot; pTemp; pTemp = pTemp->pNext )
- {
- if ( pTemp->nVars != pCell->nVars )
- continue;
- if ( Extra_TruthIsEqual(pTemp->uTruth, pCell->uTruth, pCell->nVars) )
- return 1;
- }
- // the entry is new
- pCell->pNext = *pSlot;
- *pSlot = pCell;
- // add it to the variable support list
- pCell->pNextVar = p->pSameVar[pCell->nVars];
- p->pSameVar[pCell->nVars] = pCell;
- return 0;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Cut_CellSuppMin( Cut_Cell_t * pCell )
-{
- static unsigned uTemp[1<<(CUT_CELL_MVAR-5)];
- unsigned * pIn, * pOut, * pTemp;
- int i, k, Counter, Temp;
-
- // go backward through the support variables and remove redundant
- for ( k = pCell->nVars - 1; k >= 0; k-- )
- if ( !Extra_TruthVarInSupport(pCell->uTruth, pCell->nVars, k) )
- {
- // shift all the variables above this one
- Counter = 0;
- pIn = pCell->uTruth; pOut = uTemp;
- for ( i = k; i < (int)pCell->nVars - 1; i++ )
- {
- Extra_TruthSwapAdjacentVars( pOut, pIn, pCell->nVars, i );
- pTemp = pIn; pIn = pOut; pOut = pTemp;
- // swap the support vars
- Temp = pCell->CanonPerm[i];
- pCell->CanonPerm[i] = pCell->CanonPerm[i+1];
- pCell->CanonPerm[i+1] = Temp;
- Counter++;
- }
- // return the function back into its place
- if ( Counter & 1 )
- Extra_TruthCopy( pOut, pIn, pCell->nVars );
- // remove one variable
- pCell->nVars--;
-// Extra_PrintBinary( stdout, pCell->uTruth, (1<<pCell->nVars) ); printf( "\n" );
- }
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Cut_CellCrossBar( Cut_Cell_t * pCell )
-{
- static unsigned uTemp0[1<<(CUT_CELL_MVAR-5)];
- static unsigned uTemp1[1<<(CUT_CELL_MVAR-5)];
- Extra_TruthCopy( uTemp0, pCell->uTruth, pCell->nVars );
- Extra_TruthCopy( uTemp1, pCell->uTruth, pCell->nVars );
- if ( pCell->CanonPhase == 0 )
- {
- Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar0 );
- Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar1 );
- Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar0 );
- Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar1 );
- }
- else if ( pCell->CanonPhase == 1 )
- {
- Extra_TruthCofactor1( uTemp0, pCell->nVars, pCell->CrossBar0 );
- Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar1 );
- Extra_TruthCofactor0( uTemp1, pCell->nVars, pCell->CrossBar0 );
- Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar1 );
- }
- else if ( pCell->CanonPhase == 2 )
- {
- Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar0 );
- Extra_TruthCofactor1( uTemp0, pCell->nVars, pCell->CrossBar1 );
- Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar0 );
- Extra_TruthCofactor0( uTemp1, pCell->nVars, pCell->CrossBar1 );
- }
- else assert( 0 );
- Extra_TruthCombine( pCell->uTruth, uTemp0, uTemp1, pCell->nVars, pCell->CrossBar0 );
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Cut_CellTruthElem( unsigned * InA, unsigned * InB, unsigned * InC, unsigned * pOut, int nVars, int Type )
-{
- int nWords = Extra_TruthWordNum( nVars );
- int i;
-
- assert( Type < 22 );
- switch ( Type )
- {
- // " 0\n", // 00 const 0
- case 0:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = 0;
- return;
- // " 1\n", // 01 const 1
- case 1:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = 0xFFFFFFFF;
- return;
- // "1 1\n", // 02 a
- case 2:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = InA[i];
- return;
- // "11 1\n", // 03 ab
- case 3:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = InA[i] & InB[i];
- return;
- // "11 0\n", // 04 (ab)'
- case 4:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = ~(InA[i] & InB[i]);
- return;
- // "10 1\n01 1\n", // 05 a<+>b
- case 5:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = InA[i] ^ InB[i];
- return;
- // "111 1\n", // 06 + abc
- case 6:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = InA[i] & InB[i] & InC[i];
- return;
- // "111 0\n", // 07 (abc)'
- case 7:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = ~(InA[i] & InB[i] & InC[i]);
- return;
- // "11- 1\n1-1 1\n", // 08 + a(b+c)
- case 8:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = InA[i] & (InB[i] | InC[i]);
- return;
- // "11- 0\n1-1 0\n", // 09 (a(b+c))'
- case 9:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = ~(InA[i] & (InB[i] | InC[i]));
- return;
- // "111 1\n100 1\n010 1\n001 1\n", // 10 + a<+>b<+>c
- case 10:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = InA[i] ^ InB[i] ^ InC[i];
- return;
- // "10- 0\n1-0 0\n011 0\n", // 11 + a<+>bc
- case 11:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = InA[i] ^ (InB[i] & InC[i]);
- return;
- // "101 1\n110 1\n", // 12 + a(b<+>c)
- case 12:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = InA[i] & (InB[i] ^ InC[i]);
- return;
- // "101 0\n110 0\n", // 13 (a(b<+>c))'
- case 13:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = ~(InA[i] & (InB[i] ^ InC[i]));
- return;
- // "11- 1\n1-1 1\n-11 1\n", // 14 + ab+bc+ac
- case 14:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = (InA[i] & InB[i]) | (InB[i] & InC[i]) | (InA[i] & InC[i]);
- return;
- // "111 1\n000 1\n", // 15 + abc+a'b'c'
- case 15:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = (InA[i] & InB[i] & InC[i]) | (~InA[i] & ~InB[i] & ~InC[i]);
- return;
- // "111 0\n000 0\n", // 16 (abc+a'b'c')'
- case 16:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = ~((InA[i] & InB[i] & InC[i]) | (~InA[i] & ~InB[i] & ~InC[i]));
- return;
- // "11- 1\n-11 1\n0-1 1\n", // 17 + ab+bc+a'c
- case 17:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = (InA[i] & InB[i]) | (InB[i] & InC[i]) | (~InA[i] & InC[i]);
- return;
- // "011 1\n101 1\n110 1\n", // 18 + a'bc+ab'c+abc'
- case 18:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = (~InA[i] & InB[i] & InC[i]) | (InA[i] & ~InB[i] & InC[i]) | (InA[i] & InB[i] & ~InC[i]);
- return;
- // "011 0\n101 0\n110 0\n", // 19 (a'bc+ab'c+abc')'
- case 19:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = ~((~InA[i] & InB[i] & InC[i]) | (InA[i] & ~InB[i] & InC[i]) | (InA[i] & InB[i] & ~InC[i]));
- return;
- // "100 1\n-11 1\n", // 20 + ab'c'+bc
- case 20:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = (InA[i] & ~InB[i] & ~InC[i]) | (InB[i] & InC[i]);
- return;
- // "100 0\n-11 0\n" // 21 (ab'c'+bc)'
- case 21:
- for ( i = 0; i < nWords; i++ )
- pOut[i] = ~((InA[i] & ~InB[i] & ~InC[i]) | (InB[i] & InC[i]));
- return;
- }
-}
-
-
-/**Function*************************************************************
-
- Synopsis [Start the precomputation manager.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Cut_CMan_t * Cut_CManStart()
-{
- Cut_CMan_t * p;
- int i, k;
- // start the manager
- assert( sizeof(unsigned) == 4 );
- p = ALLOC( Cut_CMan_t, 1 );
- memset( p, 0, sizeof(Cut_CMan_t) );
- // start the table and the memory manager
- p->tTable = st_init_table(st_ptrcmp,st_ptrhash);
- p->pMem = Extra_MmFixedStart( sizeof(Cut_Cell_t) );
- // set elementary truth tables
- for ( k = 0; k < CUT_CELL_MVAR; k++ )
- for ( i = 0; i < (1<<CUT_CELL_MVAR); i++ )
- if ( i & (1 << k) )
- p->uInputs[k][i>>5] |= (1 << (i&31));
- s_pCMan = p;
- return p;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Cut_CManStop( Cut_CMan_t * p )
-{
- st_free_table( p->tTable );
- Extra_MmFixedStop( p->pMem, 0 );
- free( p );
-}
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Cut_CellIsRunning()
-{
- return s_pCMan != NULL;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Cut_CellDumpToFile()
-{
- FILE * pFile;
- Cut_CMan_t * p = s_pCMan;
- Cut_Cell_t * pTemp;
- char * pFileName = "celllib22.txt";
- int NumUsed[10][5] = {{0}};
- int BoxUsed[22][5] = {{0}};
- int i, k, Counter;
- int clk = clock();
-
- if ( p == NULL )
- {
- printf( "Cut_CellDumpToFile: Cell manager is not defined.\n" );
- return;
- }
-
- // count the number of cells used
- for ( k = CUT_CELL_MVAR; k >= 0; k-- )
- {
- for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar )
- {
- if ( pTemp->nUsed == 0 )
- NumUsed[k][0]++;
- else if ( pTemp->nUsed < 10 )
- NumUsed[k][1]++;
- else if ( pTemp->nUsed < 100 )
- NumUsed[k][2]++;
- else if ( pTemp->nUsed < 1000 )
- NumUsed[k][3]++;
- else
- NumUsed[k][4]++;
-
- for ( i = 0; i < 4; i++ )
- if ( pTemp->nUsed == 0 )
- BoxUsed[ pTemp->Box[i] ][0]++;
- else if ( pTemp->nUsed < 10 )
- BoxUsed[ pTemp->Box[i] ][1]++;
- else if ( pTemp->nUsed < 100 )
- BoxUsed[ pTemp->Box[i] ][2]++;
- else if ( pTemp->nUsed < 1000 )
- BoxUsed[ pTemp->Box[i] ][3]++;
- else
- BoxUsed[ pTemp->Box[i] ][4]++;
- }
- }
-
- printf( "Functions found = %10d. Functions not found = %10d.\n", p->nCellFound, p->nCellNotFound );
- for ( k = 0; k <= CUT_CELL_MVAR; k++ )
- {
- printf( "%3d : ", k );
- for ( i = 0; i < 5; i++ )
- printf( "%8d ", NumUsed[k][i] );
- printf( "\n" );
- }
- printf( "Box usage:\n" );
- for ( k = 0; k < 22; k++ )
- {
- printf( "%3d : ", k );
- for ( i = 0; i < 5; i++ )
- printf( "%8d ", BoxUsed[k][i] );
- printf( " %s", s_NP3Names[k] );
- printf( "\n" );
- }
-
- pFile = fopen( pFileName, "w" );
- if ( pFile == NULL )
- {
- printf( "Cut_CellDumpToFile: Cannout open output file.\n" );
- return;
- }
-
- Counter = 0;
- for ( k = 0; k <= CUT_CELL_MVAR; k++ )
- {
- for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar )
- if ( pTemp->nUsed > 0 )
- {
- Extra_PrintHexadecimal( pFile, pTemp->uTruth, (k <= 5? 5 : k) );
- fprintf( pFile, "\n" );
- Counter++;
- }
- fprintf( pFile, "\n" );
- }
- fclose( pFile );
-
- printf( "Library composed of %d functions is written into file \"%s\". ", Counter, pFileName );
-
- PRT( "Time", clock() - clk );
-}
-
-
-/**Function*************************************************************
-
- Synopsis [Looks up if the given function exists in the hash table.]
-
- Description [If the function exists, returns 1, meaning that it can be
- implemented using two levels of 3-input LUTs. If the function does not
- exist, return 0.]
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Cut_CellTruthLookup( unsigned * pTruth, int nVars )
-{
- Cut_CMan_t * p = s_pCMan;
- Cut_Cell_t * pTemp;
- Cut_Cell_t Cell, * pCell = &Cell;
- unsigned Hash;
- int i;
-
- // cell manager is not defined
- if ( p == NULL )
- {
- printf( "Cut_CellTruthLookup: Cell manager is not defined.\n" );
- return 0;
- }
-
- // canonicize
- memset( pCell, 0, sizeof(Cut_Cell_t) );
- pCell->nVars = nVars;
- Extra_TruthCopy( pCell->uTruth, pTruth, nVars );
- Cut_CellSuppMin( pCell );
- // set the elementary permutation
- for ( i = 0; i < (int)pCell->nVars; i++ )
- pCell->CanonPerm[i] = i;
- // canonicize
- pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
-
-
- // check if the cell exists
- Hash = Extra_TruthHash( pCell->uTruth, Extra_TruthWordNum(pCell->nVars) );
- if ( st_lookup( p->tTable, (char *)Hash, (char **)&pTemp ) )
- {
- for ( ; pTemp; pTemp = pTemp->pNext )
- {
- if ( pTemp->nVars != pCell->nVars )
- continue;
- if ( Extra_TruthIsEqual(pTemp->uTruth, pCell->uTruth, pCell->nVars) )
- {
- pTemp->nUsed++;
- p->nCellFound++;
- return 1;
- }
- }
- }
- p->nCellNotFound++;
- return 0;
-}
-
-
-////////////////////////////////////////////////////////////////////////
-/// END OF FILE ///
-////////////////////////////////////////////////////////////////////////
-
-
diff --git a/src/opt/cut/abcCut.c b/src/opt/cut/abcCut.c
new file mode 100644
index 00000000..b4b879a3
--- /dev/null
+++ b/src/opt/cut/abcCut.c
@@ -0,0 +1,491 @@
+/**CFile****************************************************************
+
+ FileName [abcCut.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Interface to cut computation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcCut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "cut.h"
+#include "seqInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static void Abc_NtkPrintCuts( void * p, Abc_Ntk_t * pNtk, int fSeq );
+static void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq );
+
+
+extern int nTotal, nGood, nEqual;
+
+// temporary
+//Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk ) { return NULL; }
+Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk )
+{
+ Vec_Int_t * vAttrs = Vec_IntStart( Abc_NtkObjNumMax(pNtk) + 1 );
+ int i;
+ Abc_Obj_t * pObj;
+
+// Abc_NtkForEachCi( pNtk, pObj, i )
+// Vec_IntWriteEntry( vAttrs, pObj->Id, 1 );
+
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ {
+// if ( Abc_ObjIsNode(pObj) && (rand() % 4 == 0) )
+ if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj) && (rand() % 3 == 0) )
+ Vec_IntWriteEntry( vAttrs, pObj->Id, 1 );
+ }
+ return vAttrs;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Computes the cuts for the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
+{
+ ProgressBar * pProgress;
+ Cut_Man_t * p;
+ Abc_Obj_t * pObj, * pNode;
+ Vec_Ptr_t * vNodes;
+ Vec_Int_t * vChoices;
+ int i;
+ int clk = clock();
+
+ extern void Abc_NtkBalanceAttach( Abc_Ntk_t * pNtk );
+ extern void Abc_NtkBalanceDetach( Abc_Ntk_t * pNtk );
+
+ nTotal = nGood = nEqual = 0;
+
+ assert( Abc_NtkIsStrash(pNtk) );
+ // start the manager
+ pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
+ p = Cut_ManStart( pParams );
+ // compute node attributes if local or global cuts are requested
+ if ( pParams->fGlobal || pParams->fLocal )
+ {
+ extern Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk );
+ Cut_ManSetNodeAttrs( p, Abc_NtkGetNodeAttributes(pNtk) );
+ }
+ // prepare for cut dropping
+ if ( pParams->fDrop )
+ Cut_ManSetFanoutCounts( p, Abc_NtkFanoutCounts(pNtk) );
+ // set cuts for PIs
+ Abc_NtkForEachCi( pNtk, pObj, i )
+ if ( Abc_ObjFanoutNum(pObj) > 0 )
+ Cut_NodeSetTriv( p, pObj->Id );
+ // compute cuts for internal nodes
+ vNodes = Abc_AigDfs( pNtk, 0, 1 ); // collects POs
+ vChoices = Vec_IntAlloc( 100 );
+ pProgress = Extra_ProgressBarStart( stdout, Vec_PtrSize(vNodes) );
+ Vec_PtrForEachEntry( vNodes, pObj, i )
+ {
+ // when we reached a CO, it is time to deallocate the cuts
+ if ( Abc_ObjIsCo(pObj) )
+ {
+ if ( pParams->fDrop )
+ Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
+ continue;
+ }
+ // skip constant node, it has no cuts
+ if ( Abc_NodeIsConst(pObj) )
+ continue;
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ // compute the cuts to the internal node
+ Abc_NodeGetCuts( p, pObj, pParams->fDag, pParams->fTree );
+ // consider dropping the fanins cuts
+ if ( pParams->fDrop )
+ {
+ Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
+ Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId1(pObj) );
+ }
+ // add cuts due to choices
+ if ( Abc_NodeIsAigChoice(pObj) )
+ {
+ Vec_IntClear( vChoices );
+ for ( pNode = pObj; pNode; pNode = pNode->pData )
+ Vec_IntPush( vChoices, pNode->Id );
+ Cut_NodeUnionCuts( p, vChoices );
+ }
+ }
+ Extra_ProgressBarStop( pProgress );
+ Vec_PtrFree( vNodes );
+ Vec_IntFree( vChoices );
+PRT( "Total", clock() - clk );
+//Abc_NtkPrintCuts( p, pNtk, 0 );
+// Cut_ManPrintStatsToFile( p, pNtk->pSpec, clock() - clk );
+
+ // temporary printout of stats
+ if ( nTotal )
+ printf( "Total cuts = %d. Good cuts = %d. Ratio = %5.2f\n", nTotal, nGood, ((double)nGood)/nTotal );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Cut computation using the oracle.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkCutsOracle( Abc_Ntk_t * pNtk, Cut_Oracle_t * p )
+{
+ Abc_Obj_t * pObj;
+ Vec_Ptr_t * vNodes;
+ int i, clk = clock();
+ int fDrop = Cut_OracleReadDrop(p);
+
+ assert( Abc_NtkIsStrash(pNtk) );
+
+ // prepare cut droppping
+ if ( fDrop )
+ Cut_OracleSetFanoutCounts( p, Abc_NtkFanoutCounts(pNtk) );
+
+ // set cuts for PIs
+ Abc_NtkForEachCi( pNtk, pObj, i )
+ if ( Abc_ObjFanoutNum(pObj) > 0 )
+ Cut_OracleNodeSetTriv( p, pObj->Id );
+
+ // compute cuts for internal nodes
+ vNodes = Abc_AigDfs( pNtk, 0, 1 ); // collects POs
+ Vec_PtrForEachEntry( vNodes, pObj, i )
+ {
+ // when we reached a CO, it is time to deallocate the cuts
+ if ( Abc_ObjIsCo(pObj) )
+ {
+ if ( fDrop )
+ Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
+ continue;
+ }
+ // skip constant node, it has no cuts
+ if ( Abc_NodeIsConst(pObj) )
+ continue;
+ // compute the cuts to the internal node
+ Cut_OracleComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
+ Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
+ // consider dropping the fanins cuts
+ if ( fDrop )
+ {
+ Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
+ Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId1(pObj) );
+ }
+ }
+ Vec_PtrFree( vNodes );
+//PRT( "Total", clock() - clk );
+//Abc_NtkPrintCuts_( p, pNtk, 0 );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes the cuts for the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
+{
+ Cut_Man_t * p;
+ Abc_Obj_t * pObj, * pNode;
+ int i, nIters, fStatus;
+ Vec_Int_t * vChoices;
+ int clk = clock();
+
+ assert( Abc_NtkIsSeq(pNtk) );
+ assert( pParams->fSeq );
+// assert( Abc_NtkIsDfsOrdered(pNtk) );
+
+ // start the manager
+ pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
+ pParams->nCutSet = Abc_NtkCutSetNodeNum( pNtk );
+ p = Cut_ManStart( pParams );
+
+ // set cuts for the constant node and the PIs
+ pObj = Abc_NtkConst1(pNtk);
+ if ( Abc_ObjFanoutNum(pObj) > 0 )
+ Cut_NodeSetTriv( p, pObj->Id );
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ {
+//printf( "Setting trivial cut %d.\n", pObj->Id );
+ Cut_NodeSetTriv( p, pObj->Id );
+ }
+ // label the cutset nodes and set their number in the array
+ // assign the elementary cuts to the cutset nodes
+ Abc_SeqForEachCutsetNode( pNtk, pObj, i )
+ {
+ assert( pObj->fMarkC == 0 );
+ pObj->fMarkC = 1;
+ pObj->pCopy = (Abc_Obj_t *)i;
+ Cut_NodeSetTriv( p, pObj->Id );
+//printf( "Setting trivial cut %d.\n", pObj->Id );
+ }
+
+ // process the nodes
+ vChoices = Vec_IntAlloc( 100 );
+ for ( nIters = 0; nIters < 10; nIters++ )
+ {
+//printf( "ITERATION %d:\n", nIters );
+ // compute the cuts for the internal nodes
+ Abc_AigForEachAnd( pNtk, pObj, i )
+ {
+ Abc_NodeGetCutsSeq( p, pObj, nIters==0 );
+ // add cuts due to choices
+ if ( Abc_NodeIsAigChoice(pObj) )
+ {
+ Vec_IntClear( vChoices );
+ for ( pNode = pObj; pNode; pNode = pNode->pData )
+ Vec_IntPush( vChoices, pNode->Id );
+ Cut_NodeUnionCutsSeq( p, vChoices, (pObj->fMarkC ? (int)pObj->pCopy : -1), nIters==0 );
+ }
+ }
+ // merge the new cuts with the old cuts
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ Cut_NodeNewMergeWithOld( p, pObj->Id );
+ Abc_AigForEachAnd( pNtk, pObj, i )
+ Cut_NodeNewMergeWithOld( p, pObj->Id );
+ // for the cutset, transfer temp cuts to new cuts
+ fStatus = 0;
+ Abc_SeqForEachCutsetNode( pNtk, pObj, i )
+ fStatus |= Cut_NodeTempTransferToNew( p, pObj->Id, i );
+ if ( fStatus == 0 )
+ break;
+ }
+ Vec_IntFree( vChoices );
+
+ // if the status is not finished, transfer new to old for the cutset
+ Abc_SeqForEachCutsetNode( pNtk, pObj, i )
+ Cut_NodeNewMergeWithOld( p, pObj->Id );
+
+ // transfer the old cuts to the new positions
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ Cut_NodeOldTransferToNew( p, pObj->Id );
+
+ // unlabel the cutset nodes
+ Abc_SeqForEachCutsetNode( pNtk, pObj, i )
+ pObj->fMarkC = 0;
+if ( pParams->fVerbose )
+{
+PRT( "Total", clock() - clk );
+printf( "Converged after %d iterations.\n", nIters );
+}
+//Abc_NtkPrintCuts( p, pNtk, 1 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the cuts for the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj, int fDag, int fTree )
+{
+ void * pList;
+ if ( pList = Abc_NodeReadCuts( p, pObj ) )
+ return pList;
+ Abc_NodeGetCutsRecursive( p, Abc_ObjFanin0(pObj), fDag, fTree );
+ Abc_NodeGetCutsRecursive( p, Abc_ObjFanin1(pObj), fDag, fTree );
+ return Abc_NodeGetCuts( p, pObj, fDag, fTree );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the cuts for the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fDag, int fTree )
+{
+ Abc_Obj_t * pFanin;
+ int fDagNode, fTriv, TreeCode = 0;
+// assert( Abc_NtkIsStrash(pObj->pNtk) );
+ assert( Abc_ObjFaninNum(pObj) == 2 );
+
+
+ // check if the node is a DAG node
+ fDagNode = (Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj));
+ // increment the counter of DAG nodes
+ if ( fDagNode ) Cut_ManIncrementDagNodes( p );
+ // add the trivial cut if the node is a DAG node, or if we compute all cuts
+ fTriv = fDagNode || !fDag;
+ // check if fanins are DAG nodes
+ if ( fTree )
+ {
+ pFanin = Abc_ObjFanin0(pObj);
+ TreeCode |= (Abc_ObjFanoutNum(pFanin) > 1 && !Abc_NodeIsMuxControlType(pFanin));
+ pFanin = Abc_ObjFanin1(pObj);
+ TreeCode |= ((Abc_ObjFanoutNum(pFanin) > 1 && !Abc_NodeIsMuxControlType(pFanin)) << 1);
+ }
+
+
+ // changes due to the global/local cut computation
+ {
+ Cut_Params_t * pParams = Cut_ManReadParams(p);
+ if ( pParams->fLocal )
+ {
+ Vec_Int_t * vNodeAttrs = Cut_ManReadNodeAttrs(p);
+ fDagNode = Vec_IntEntry( vNodeAttrs, pObj->Id );
+ if ( fDagNode ) Cut_ManIncrementDagNodes( p );
+// fTriv = fDagNode || !pParams->fGlobal;
+ fTriv = !Vec_IntEntry( vNodeAttrs, pObj->Id );
+ TreeCode = 0;
+ pFanin = Abc_ObjFanin0(pObj);
+ TreeCode |= Vec_IntEntry( vNodeAttrs, pFanin->Id );
+ pFanin = Abc_ObjFanin1(pObj);
+ TreeCode |= (Vec_IntEntry( vNodeAttrs, pFanin->Id ) << 1);
+ }
+ }
+ return Cut_NodeComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
+ Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), fTriv, TreeCode );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the cuts for the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeGetCutsSeq( void * p, Abc_Obj_t * pObj, int fTriv )
+{
+ int CutSetNum;
+ assert( Abc_NtkIsSeq(pObj->pNtk) );
+ assert( Abc_ObjFaninNum(pObj) == 2 );
+ fTriv = pObj->fMarkC ? 0 : fTriv;
+ CutSetNum = pObj->fMarkC ? (int)pObj->pCopy : -1;
+ Cut_NodeComputeCutsSeq( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
+ Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), Seq_ObjFaninL0(pObj), Seq_ObjFaninL1(pObj), fTriv, CutSetNum );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the cuts for the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void * Abc_NodeReadCuts( void * p, Abc_Obj_t * pObj )
+{
+ return Cut_NodeReadCutsNew( p, pObj->Id );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the cuts for the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeFreeCuts( void * p, Abc_Obj_t * pObj )
+{
+ Cut_NodeFreeCuts( p, pObj->Id );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the cuts for the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkPrintCuts( void * p, Abc_Ntk_t * pNtk, int fSeq )
+{
+ Cut_Man_t * pMan = p;
+ Cut_Cut_t * pList;
+ Abc_Obj_t * pObj;
+ int i;
+ printf( "Cuts of the network:\n" );
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ {
+ pList = Abc_NodeReadCuts( p, pObj );
+ printf( "Node %s:\n", Abc_ObjName(pObj) );
+ Cut_CutPrintList( pList, fSeq );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the cuts for the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq )
+{
+ Cut_Man_t * pMan = p;
+ Cut_Cut_t * pList;
+ Abc_Obj_t * pObj;
+ pObj = Abc_NtkObj( pNtk, 2 * Abc_NtkObjNum(pNtk) / 3 );
+ pList = Abc_NodeReadCuts( p, pObj );
+ printf( "Node %s:\n", Abc_ObjName(pObj) );
+ Cut_CutPrintList( pList, fSeq );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/opt/cut/cut.h b/src/opt/cut/cut.h
index c2142c4f..4c5af98d 100644
--- a/src/opt/cut/cut.h
+++ b/src/opt/cut/cut.h
@@ -61,6 +61,8 @@ struct Cut_ParamsStruct_t_
int fDrop; // drop cuts on the fly
int fDag; // compute only DAG cuts
int fTree; // compute only tree cuts
+ int fGlobal; // compute only global cuts
+ int fLocal; // compute only local cuts
int fRecord; // record the cut computation flow
int fFancy; // perform fancy computations
int fVerbose; // the verbosiness flag
@@ -118,7 +120,10 @@ extern void Cut_ManStop( Cut_Man_t * p );
extern void Cut_ManPrintStats( Cut_Man_t * p );
extern void Cut_ManPrintStatsToFile( Cut_Man_t * p, char * pFileName, int TimeTotal );
extern void Cut_ManSetFanoutCounts( Cut_Man_t * p, Vec_Int_t * vFanCounts );
+extern void Cut_ManSetNodeAttrs( Cut_Man_t * p, Vec_Int_t * vFanCounts );
extern int Cut_ManReadVarsMax( Cut_Man_t * p );
+extern Cut_Params_t * Cut_ManReadParams( Cut_Man_t * p );
+extern Vec_Int_t * Cut_ManReadNodeAttrs( Cut_Man_t * p );
extern void Cut_ManIncrementDagNodes( Cut_Man_t * p );
/*=== cutNode.c ==========================================================*/
extern Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1, int fTriv, int TreeCode );
diff --git a/src/opt/cut/cutInt.h b/src/opt/cut/cutInt.h
index c6246ad7..2a0139d3 100644
--- a/src/opt/cut/cutInt.h
+++ b/src/opt/cut/cutInt.h
@@ -46,6 +46,7 @@ struct Cut_ManStruct_t_
// user preferences
Cut_Params_t * pParams; // computation parameters
Vec_Int_t * vFanCounts; // the array of fanout counters
+ Vec_Int_t * vNodeAttrs; // node attributes (1 = global; 0 = local)
// storage for cuts
Vec_Ptr_t * vCutsNew; // new cuts by node ID
Vec_Ptr_t * vCutsOld; // old cuts by node ID
diff --git a/src/opt/cut/cutMan.c b/src/opt/cut/cutMan.c
index 22ea1cb6..30e5fa38 100644
--- a/src/opt/cut/cutMan.c
+++ b/src/opt/cut/cutMan.c
@@ -233,6 +233,22 @@ void Cut_ManSetFanoutCounts( Cut_Man_t * p, Vec_Int_t * vFanCounts )
SeeAlso []
***********************************************************************/
+void Cut_ManSetNodeAttrs( Cut_Man_t * p, Vec_Int_t * vNodeAttrs )
+{
+ p->vNodeAttrs = vNodeAttrs;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Cut_ManReadVarsMax( Cut_Man_t * p )
{
return p->pParams->nVarsMax;
@@ -249,6 +265,38 @@ int Cut_ManReadVarsMax( Cut_Man_t * p )
SeeAlso []
***********************************************************************/
+Cut_Params_t * Cut_ManReadParams( Cut_Man_t * p )
+{
+ return p->pParams;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Cut_ManReadNodeAttrs( Cut_Man_t * p )
+{
+ return p->vNodeAttrs;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
void Cut_ManIncrementDagNodes( Cut_Man_t * p )
{
p->nNodesDag++;
diff --git a/src/opt/cut/cutNode.c b/src/opt/cut/cutNode.c
index 6f7777ad..fafa89f7 100644
--- a/src/opt/cut/cutNode.c
+++ b/src/opt/cut/cutNode.c
@@ -206,6 +206,32 @@ static inline int Cut_CutFilterOne( Cut_Man_t * p, Cut_List_t * pSuperList, Cut_
/**Function*************************************************************
+ Synopsis [Checks if the cut is local and can be removed.]
+
+ Description [Returns 1 if the cut is removed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cut_CutFilterGlobal( Cut_Man_t * p, Cut_Cut_t * pCut )
+{
+ int a;
+ if ( pCut->nLeaves == 1 )
+ return 0;
+ for ( a = 0; a < (int)pCut->nLeaves; a++ )
+ if ( Vec_IntEntry( p->vNodeAttrs, pCut->pLeaves[a] ) ) // global
+ return 0;
+ // there is no global nodes, the cut should be removed
+ p->nCutsFilter++;
+ Cut_CutRecycle( p, pCut );
+ return 1;
+}
+
+
+/**Function*************************************************************
+
Synopsis [Checks containment for one cut.]
Description [Returns 1 if the cut is removed.]
@@ -306,6 +332,14 @@ static inline int Cut_CutProcessTwo( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t
return 0;
}
}
+
+ if ( p->pParams->fGlobal )
+ {
+ assert( p->vNodeAttrs != NULL );
+ if ( Cut_CutFilterGlobal( p, pCut ) )
+ return 0;
+ }
+
// compute the truth table
if ( p->pParams->fTruth )
Cut_TruthCompute( p, pCut, pCut0, pCut1, p->fCompl0, p->fCompl1 );
@@ -395,7 +429,7 @@ void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fC
p->nNodeCuts++;
}
// get the cut lists of children
- if ( pList0 == NULL || pList1 == NULL )
+ if ( pList0 == NULL || pList1 == NULL || (p->pParams->fLocal && TreeCode) )
return;
// remember the old number of cuts
diff --git a/src/opt/cut/cutPre22.c b/src/opt/cut/cutPre22.c
index 203f9e6f..20c93c5f 100644
--- a/src/opt/cut/cutPre22.c
+++ b/src/opt/cut/cutPre22.c
@@ -617,7 +617,7 @@ void Cut_CellCrossBar( Cut_Cell_t * pCell )
Extra_TruthCofactor0( uTemp1, pCell->nVars, pCell->CrossBar1 );
}
else assert( 0 );
- Extra_TruthCombine( pCell->uTruth, uTemp0, uTemp1, pCell->nVars, pCell->CrossBar0 );
+ Extra_TruthMux( pCell->uTruth, uTemp0, uTemp1, pCell->nVars, pCell->CrossBar0 );
}
/**Function*************************************************************
diff --git a/src/opt/cut/vec.h b/src/opt/cut/vec.h
new file mode 100644
index 00000000..6ab23298
--- /dev/null
+++ b/src/opt/cut/vec.h
@@ -0,0 +1,66 @@
+/**CFile****************************************************************
+
+ FileName [vec.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Resizable arrays.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: vec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __VEC_H__
+#define __VEC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#ifdef _WIN32
+#define inline __inline // compatible with MS VS 6.0
+#endif
+
+#include "vecInt.h"
+#include "vecStr.h"
+#include "vecPtr.h"
+#include "vecVec.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/opt/cut/vecInt.h b/src/opt/cut/vecInt.h
new file mode 100644
index 00000000..4f193cf2
--- /dev/null
+++ b/src/opt/cut/vecInt.h
@@ -0,0 +1,753 @@
+/**CFile****************************************************************
+
+ FileName [vecInt.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Resizable arrays.]
+
+ Synopsis [Resizable arrays of integers.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: vecInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __VEC_INT_H__
+#define __VEC_INT_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include "extra.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Vec_Int_t_ Vec_Int_t;
+struct Vec_Int_t_
+{
+ int nCap;
+ int nSize;
+ int * pArray;
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define Vec_IntForEachEntry( vVec, Entry, i ) \
+ for ( i = 0; (i < Vec_IntSize(vVec)) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ )
+#define Vec_IntForEachEntryStart( vVec, Entry, i, Start ) \
+ for ( i = Start; (i < Vec_IntSize(vVec)) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ )
+#define Vec_IntForEachEntryStartStop( vVec, Entry, i, Start, Stop ) \
+ for ( i = Start; (i < Stop) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ )
+#define Vec_IntForEachEntryReverse( vVec, pEntry, i ) \
+ for ( i = Vec_IntSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_IntEntry(vVec, i)), 1); i-- )
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Int_t * Vec_IntAlloc( int nCap )
+{
+ Vec_Int_t * p;
+ p = ALLOC( Vec_Int_t, 1 );
+ if ( nCap > 0 && nCap < 16 )
+ nCap = 16;
+ p->nSize = 0;
+ p->nCap = nCap;
+ p->pArray = p->nCap? ALLOC( int, p->nCap ) : NULL;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given size and cleans it.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Int_t * Vec_IntStart( int nSize )
+{
+ Vec_Int_t * p;
+ p = Vec_IntAlloc( nSize );
+ p->nSize = nSize;
+ memset( p->pArray, 0, sizeof(int) * nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the vector from an integer array of the given size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Int_t * Vec_IntAllocArray( int * pArray, int nSize )
+{
+ Vec_Int_t * p;
+ p = ALLOC( Vec_Int_t, 1 );
+ p->nSize = nSize;
+ p->nCap = nSize;
+ p->pArray = pArray;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the vector from an integer array of the given size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Int_t * Vec_IntAllocArrayCopy( int * pArray, int nSize )
+{
+ Vec_Int_t * p;
+ p = ALLOC( Vec_Int_t, 1 );
+ p->nSize = nSize;
+ p->nCap = nSize;
+ p->pArray = ALLOC( int, nSize );
+ memcpy( p->pArray, pArray, sizeof(int) * nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the integer array.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Int_t * Vec_IntDup( Vec_Int_t * pVec )
+{
+ Vec_Int_t * p;
+ p = ALLOC( Vec_Int_t, 1 );
+ p->nSize = pVec->nSize;
+ p->nCap = pVec->nCap;
+ p->pArray = p->nCap? ALLOC( int, p->nCap ) : NULL;
+ memcpy( p->pArray, pVec->pArray, sizeof(int) * pVec->nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transfers the array into another vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Int_t * Vec_IntDupArray( Vec_Int_t * pVec )
+{
+ Vec_Int_t * p;
+ p = ALLOC( Vec_Int_t, 1 );
+ p->nSize = pVec->nSize;
+ p->nCap = pVec->nCap;
+ p->pArray = pVec->pArray;
+ pVec->nSize = 0;
+ pVec->nCap = 0;
+ pVec->pArray = NULL;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntFree( Vec_Int_t * p )
+{
+ FREE( p->pArray );
+ FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int * Vec_IntReleaseArray( Vec_Int_t * p )
+{
+ int * pArray = p->pArray;
+ p->nCap = 0;
+ p->nSize = 0;
+ p->pArray = NULL;
+ return pArray;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int * Vec_IntArray( Vec_Int_t * p )
+{
+ return p->pArray;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntSize( Vec_Int_t * p )
+{
+ return p->nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntEntry( Vec_Int_t * p, int i )
+{
+ assert( i >= 0 && i < p->nSize );
+ return p->pArray[i];
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntWriteEntry( Vec_Int_t * p, int i, int Entry )
+{
+ assert( i >= 0 && i < p->nSize );
+ p->pArray[i] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntAddToEntry( Vec_Int_t * p, int i, int Addition )
+{
+ assert( i >= 0 && i < p->nSize );
+ p->pArray[i] += Addition;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntEntryLast( Vec_Int_t * p )
+{
+ assert( p->nSize > 0 );
+ return p->pArray[p->nSize-1];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resizes the vector to the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntGrow( Vec_Int_t * p, int nCapMin )
+{
+ if ( p->nCap >= nCapMin )
+ return;
+ p->pArray = REALLOC( int, p->pArray, nCapMin );
+ assert( p->pArray );
+ p->nCap = nCapMin;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Fills the vector with given number of entries.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntFill( Vec_Int_t * p, int nSize, int Entry )
+{
+ int i;
+ Vec_IntGrow( p, nSize );
+ for ( i = 0; i < nSize; i++ )
+ p->pArray[i] = Entry;
+ p->nSize = nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Fills the vector with given number of entries.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntFillExtra( Vec_Int_t * p, int nSize, int Entry )
+{
+ int i;
+ if ( p->nSize >= nSize )
+ return;
+ Vec_IntGrow( p, nSize );
+ for ( i = p->nSize; i < nSize; i++ )
+ p->pArray[i] = Entry;
+ p->nSize = nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntShrink( Vec_Int_t * p, int nSizeNew )
+{
+ assert( p->nSize >= nSizeNew );
+ p->nSize = nSizeNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntClear( Vec_Int_t * p )
+{
+ p->nSize = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntPush( Vec_Int_t * p, int Entry )
+{
+ if ( p->nSize == p->nCap )
+ {
+ if ( p->nCap < 16 )
+ Vec_IntGrow( p, 16 );
+ else
+ Vec_IntGrow( p, 2 * p->nCap );
+ }
+ p->pArray[p->nSize++] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntPushFirst( Vec_Int_t * p, int Entry )
+{
+ int i;
+ if ( p->nSize == p->nCap )
+ {
+ if ( p->nCap < 16 )
+ Vec_IntGrow( p, 16 );
+ else
+ Vec_IntGrow( p, 2 * p->nCap );
+ }
+ p->nSize++;
+ for ( i = p->nSize - 1; i >= 1; i-- )
+ p->pArray[i] = p->pArray[i-1];
+ p->pArray[0] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntPushMem( Extra_MmStep_t * pMemMan, Vec_Int_t * p, int Entry )
+{
+ if ( p->nSize == p->nCap )
+ {
+ int * pArray;
+ int i;
+
+ if ( p->nSize == 0 )
+ p->nCap = 1;
+ pArray = (int *)Extra_MmStepEntryFetch( pMemMan, p->nCap * 8 );
+// pArray = ALLOC( int, p->nCap * 2 );
+ if ( p->pArray )
+ {
+ for ( i = 0; i < p->nSize; i++ )
+ pArray[i] = p->pArray[i];
+ Extra_MmStepEntryRecycle( pMemMan, (char *)p->pArray, p->nCap * 4 );
+// free( p->pArray );
+ }
+ p->nCap *= 2;
+ p->pArray = pArray;
+ }
+ p->pArray[p->nSize++] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Inserts the entry while preserving the increasing order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntPushOrder( Vec_Int_t * p, int Entry )
+{
+ int i;
+ if ( p->nSize == p->nCap )
+ {
+ if ( p->nCap < 16 )
+ Vec_IntGrow( p, 16 );
+ else
+ Vec_IntGrow( p, 2 * p->nCap );
+ }
+ p->nSize++;
+ for ( i = p->nSize-2; i >= 0; i-- )
+ if ( p->pArray[i] > Entry )
+ p->pArray[i+1] = p->pArray[i];
+ else
+ break;
+ p->pArray[i+1] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Inserts the entry while preserving the increasing order.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntPushUniqueOrder( Vec_Int_t * p, int Entry )
+{
+ int i;
+ for ( i = 0; i < p->nSize; i++ )
+ if ( p->pArray[i] == Entry )
+ return 1;
+ Vec_IntPushOrder( p, Entry );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntPushUnique( Vec_Int_t * p, int Entry )
+{
+ int i;
+ for ( i = 0; i < p->nSize; i++ )
+ if ( p->pArray[i] == Entry )
+ return 1;
+ Vec_IntPush( p, Entry );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the last entry and removes it from the list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntPop( Vec_Int_t * p )
+{
+ assert( p->nSize > 0 );
+ return p->pArray[--p->nSize];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find entry.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntFind( Vec_Int_t * p, int Entry )
+{
+ int i;
+ for ( i = 0; i < p->nSize; i++ )
+ if ( p->pArray[i] == Entry )
+ return i;
+ return -1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntRemove( Vec_Int_t * p, int Entry )
+{
+ int i;
+ for ( i = 0; i < p->nSize; i++ )
+ if ( p->pArray[i] == Entry )
+ break;
+ if ( i == p->nSize )
+ return 0;
+ assert( i < p->nSize );
+ for ( i++; i < p->nSize; i++ )
+ p->pArray[i-1] = p->pArray[i];
+ p->nSize--;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Comparison procedure for two integers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntSortCompare1( int * pp1, int * pp2 )
+{
+ // for some reason commenting out lines (as shown) led to crashing of the release version
+ if ( *pp1 < *pp2 )
+ return -1;
+ if ( *pp1 > *pp2 ) //
+ return 1;
+ return 0; //
+}
+
+/**Function*************************************************************
+
+ Synopsis [Comparison procedure for two integers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntSortCompare2( int * pp1, int * pp2 )
+{
+ // for some reason commenting out lines (as shown) led to crashing of the release version
+ if ( *pp1 > *pp2 )
+ return -1;
+ if ( *pp1 < *pp2 ) //
+ return 1;
+ return 0; //
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sorting the entries by their integer value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntSort( Vec_Int_t * p, int fReverse )
+{
+ if ( fReverse )
+ qsort( (void *)p->pArray, p->nSize, sizeof(int),
+ (int (*)(const void *, const void *)) Vec_IntSortCompare2 );
+ else
+ qsort( (void *)p->pArray, p->nSize, sizeof(int),
+ (int (*)(const void *, const void *)) Vec_IntSortCompare1 );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Comparison procedure for two integers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_IntSortCompareUnsigned( unsigned * pp1, unsigned * pp2 )
+{
+ if ( *pp1 < *pp2 )
+ return -1;
+ if ( *pp1 > *pp2 )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sorting the entries by their integer value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntSortUnsigned( Vec_Int_t * p )
+{
+ qsort( (void *)p->pArray, p->nSize, sizeof(int),
+ (int (*)(const void *, const void *)) Vec_IntSortCompareUnsigned );
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/opt/cut/vecPtr.h b/src/opt/cut/vecPtr.h
new file mode 100644
index 00000000..f2413703
--- /dev/null
+++ b/src/opt/cut/vecPtr.h
@@ -0,0 +1,579 @@
+/**CFile****************************************************************
+
+ FileName [vecPtr.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Resizable arrays.]
+
+ Synopsis [Resizable arrays of generic pointers.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: vecPtr.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __VEC_PTR_H__
+#define __VEC_PTR_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include "extra.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Vec_Ptr_t_ Vec_Ptr_t;
+struct Vec_Ptr_t_
+{
+ int nCap;
+ int nSize;
+ void ** pArray;
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// iterators through entries
+#define Vec_PtrForEachEntry( vVec, pEntry, i ) \
+ for ( i = 0; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
+#define Vec_PtrForEachEntryStart( vVec, pEntry, i, Start ) \
+ for ( i = Start; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
+#define Vec_PtrForEachEntryStop( vVec, pEntry, i, Stop ) \
+ for ( i = 0; (i < Stop) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
+#define Vec_PtrForEachEntryStartStop( vVec, pEntry, i, Start, Stop ) \
+ for ( i = Start; (i < Stop) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ )
+#define Vec_PtrForEachEntryReverse( vVec, pEntry, i ) \
+ for ( i = Vec_PtrSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i-- )
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Ptr_t * Vec_PtrAlloc( int nCap )
+{
+ Vec_Ptr_t * p;
+ p = ALLOC( Vec_Ptr_t, 1 );
+ if ( nCap > 0 && nCap < 8 )
+ nCap = 8;
+ p->nSize = 0;
+ p->nCap = nCap;
+ p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given size and cleans it.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Ptr_t * Vec_PtrStart( int nSize )
+{
+ Vec_Ptr_t * p;
+ p = Vec_PtrAlloc( nSize );
+ p->nSize = nSize;
+ memset( p->pArray, 0, sizeof(void *) * nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the vector from an integer array of the given size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Ptr_t * Vec_PtrAllocArray( void ** pArray, int nSize )
+{
+ Vec_Ptr_t * p;
+ p = ALLOC( Vec_Ptr_t, 1 );
+ p->nSize = nSize;
+ p->nCap = nSize;
+ p->pArray = pArray;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the vector from an integer array of the given size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Ptr_t * Vec_PtrAllocArrayCopy( void ** pArray, int nSize )
+{
+ Vec_Ptr_t * p;
+ p = ALLOC( Vec_Ptr_t, 1 );
+ p->nSize = nSize;
+ p->nCap = nSize;
+ p->pArray = ALLOC( void *, nSize );
+ memcpy( p->pArray, pArray, sizeof(void *) * nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the integer array.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Ptr_t * Vec_PtrDup( Vec_Ptr_t * pVec )
+{
+ Vec_Ptr_t * p;
+ p = ALLOC( Vec_Ptr_t, 1 );
+ p->nSize = pVec->nSize;
+ p->nCap = pVec->nCap;
+ p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL;
+ memcpy( p->pArray, pVec->pArray, sizeof(void *) * pVec->nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transfers the array into another vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Ptr_t * Vec_PtrDupArray( Vec_Ptr_t * pVec )
+{
+ Vec_Ptr_t * p;
+ p = ALLOC( Vec_Ptr_t, 1 );
+ p->nSize = pVec->nSize;
+ p->nCap = pVec->nCap;
+ p->pArray = pVec->pArray;
+ pVec->nSize = 0;
+ pVec->nCap = 0;
+ pVec->pArray = NULL;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrFree( Vec_Ptr_t * p )
+{
+ FREE( p->pArray );
+ FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void ** Vec_PtrReleaseArray( Vec_Ptr_t * p )
+{
+ void ** pArray = p->pArray;
+ p->nCap = 0;
+ p->nSize = 0;
+ p->pArray = NULL;
+ return pArray;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void ** Vec_PtrArray( Vec_Ptr_t * p )
+{
+ return p->pArray;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_PtrSize( Vec_Ptr_t * p )
+{
+ return p->nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void * Vec_PtrEntry( Vec_Ptr_t * p, int i )
+{
+ assert( i >= 0 && i < p->nSize );
+ return p->pArray[i];
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void ** Vec_PtrEntryP( Vec_Ptr_t * p, int i )
+{
+ assert( i >= 0 && i < p->nSize );
+ return p->pArray + i;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrWriteEntry( Vec_Ptr_t * p, int i, void * Entry )
+{
+ assert( i >= 0 && i < p->nSize );
+ p->pArray[i] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void * Vec_PtrEntryLast( Vec_Ptr_t * p )
+{
+ assert( p->nSize > 0 );
+ return p->pArray[p->nSize-1];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resizes the vector to the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrGrow( Vec_Ptr_t * p, int nCapMin )
+{
+ if ( p->nCap >= nCapMin )
+ return;
+ p->pArray = REALLOC( void *, p->pArray, nCapMin );
+ p->nCap = nCapMin;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Fills the vector with given number of entries.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrFill( Vec_Ptr_t * p, int nSize, void * Entry )
+{
+ int i;
+ Vec_PtrGrow( p, nSize );
+ for ( i = 0; i < nSize; i++ )
+ p->pArray[i] = Entry;
+ p->nSize = nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Fills the vector with given number of entries.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrFillExtra( Vec_Ptr_t * p, int nSize, void * Entry )
+{
+ int i;
+ if ( p->nSize >= nSize )
+ return;
+ if ( p->nSize < 2 * nSize )
+ Vec_PtrGrow( p, 2 * nSize );
+ else
+ Vec_PtrGrow( p, p->nSize );
+ for ( i = p->nSize; i < nSize; i++ )
+ p->pArray[i] = Entry;
+ p->nSize = nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrShrink( Vec_Ptr_t * p, int nSizeNew )
+{
+ assert( p->nSize >= nSizeNew );
+ p->nSize = nSizeNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrClear( Vec_Ptr_t * p )
+{
+ p->nSize = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrPush( Vec_Ptr_t * p, void * Entry )
+{
+ if ( p->nSize == p->nCap )
+ {
+ if ( p->nCap < 16 )
+ Vec_PtrGrow( p, 16 );
+ else
+ Vec_PtrGrow( p, 2 * p->nCap );
+ }
+ p->pArray[p->nSize++] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_PtrPushUnique( Vec_Ptr_t * p, void * Entry )
+{
+ int i;
+ for ( i = 0; i < p->nSize; i++ )
+ if ( p->pArray[i] == Entry )
+ return 1;
+ Vec_PtrPush( p, Entry );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the last entry and removes it from the list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void * Vec_PtrPop( Vec_Ptr_t * p )
+{
+ assert( p->nSize > 0 );
+ return p->pArray[--p->nSize];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find entry.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_PtrFind( Vec_Ptr_t * p, void * Entry )
+{
+ int i;
+ for ( i = 0; i < p->nSize; i++ )
+ if ( p->pArray[i] == Entry )
+ return i;
+ return -1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrRemove( Vec_Ptr_t * p, void * Entry )
+{
+ int i;
+ for ( i = 0; i < p->nSize; i++ )
+ if ( p->pArray[i] == Entry )
+ break;
+ assert( i < p->nSize );
+ for ( i++; i < p->nSize; i++ )
+ p->pArray[i-1] = p->pArray[i];
+ p->nSize--;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Moves the first nItems to the end.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrReorder( Vec_Ptr_t * p, int nItems )
+{
+ assert( nItems < p->nSize );
+ Vec_PtrGrow( p, nItems + p->nSize );
+ memmove( (char **)p->pArray + p->nSize, p->pArray, nItems * sizeof(void*) );
+ memmove( p->pArray, (char **)p->pArray + nItems, p->nSize * sizeof(void*) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sorting the entries by their integer value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrSort( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)() )
+{
+ qsort( (void *)p->pArray, p->nSize, sizeof(void *),
+ (int (*)(const void *, const void *)) Vec_PtrSortCompare );
+}
+
+#endif
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/opt/cut/vecStr.h b/src/opt/cut/vecStr.h
new file mode 100644
index 00000000..eb6aa41d
--- /dev/null
+++ b/src/opt/cut/vecStr.h
@@ -0,0 +1,510 @@
+/**CFile****************************************************************
+
+ FileName [vecStr.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Resizable arrays.]
+
+ Synopsis [Resizable arrays of characters.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: vecStr.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __VEC_STR_H__
+#define __VEC_STR_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include "extra.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Vec_Str_t_ Vec_Str_t;
+struct Vec_Str_t_
+{
+ int nCap;
+ int nSize;
+ char * pArray;
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define Vec_StrForEachEntry( vVec, Entry, i ) \
+ for ( i = 0; (i < Vec_StrSize(vVec)) && (((Entry) = Vec_StrEntry(vVec, i)), 1); i++ )
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Str_t * Vec_StrAlloc( int nCap )
+{
+ Vec_Str_t * p;
+ p = ALLOC( Vec_Str_t, 1 );
+ if ( nCap > 0 && nCap < 16 )
+ nCap = 16;
+ p->nSize = 0;
+ p->nCap = nCap;
+ p->pArray = p->nCap? ALLOC( char, p->nCap ) : NULL;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given size and cleans it.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Str_t * Vec_StrStart( int nSize )
+{
+ Vec_Str_t * p;
+ p = Vec_StrAlloc( nSize );
+ p->nSize = nSize;
+ memset( p->pArray, 0, sizeof(char) * nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the vector from an integer array of the given size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Str_t * Vec_StrAllocArray( char * pArray, int nSize )
+{
+ Vec_Str_t * p;
+ p = ALLOC( Vec_Str_t, 1 );
+ p->nSize = nSize;
+ p->nCap = nSize;
+ p->pArray = pArray;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the vector from an integer array of the given size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Str_t * Vec_StrAllocArrayCopy( char * pArray, int nSize )
+{
+ Vec_Str_t * p;
+ p = ALLOC( Vec_Str_t, 1 );
+ p->nSize = nSize;
+ p->nCap = nSize;
+ p->pArray = ALLOC( char, nSize );
+ memcpy( p->pArray, pArray, sizeof(char) * nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the integer array.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Str_t * Vec_StrDup( Vec_Str_t * pVec )
+{
+ Vec_Str_t * p;
+ p = ALLOC( Vec_Str_t, 1 );
+ p->nSize = pVec->nSize;
+ p->nCap = pVec->nCap;
+ p->pArray = p->nCap? ALLOC( char, p->nCap ) : NULL;
+ memcpy( p->pArray, pVec->pArray, sizeof(char) * pVec->nSize );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transfers the array into another vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Str_t * Vec_StrDupArray( Vec_Str_t * pVec )
+{
+ Vec_Str_t * p;
+ p = ALLOC( Vec_Str_t, 1 );
+ p->nSize = pVec->nSize;
+ p->nCap = pVec->nCap;
+ p->pArray = pVec->pArray;
+ pVec->nSize = 0;
+ pVec->nCap = 0;
+ pVec->pArray = NULL;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_StrFree( Vec_Str_t * p )
+{
+ FREE( p->pArray );
+ FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline char * Vec_StrReleaseArray( Vec_Str_t * p )
+{
+ char * pArray = p->pArray;
+ p->nCap = 0;
+ p->nSize = 0;
+ p->pArray = NULL;
+ return pArray;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline char * Vec_StrArray( Vec_Str_t * p )
+{
+ return p->pArray;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_StrSize( Vec_Str_t * p )
+{
+ return p->nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline char Vec_StrEntry( Vec_Str_t * p, int i )
+{
+ assert( i >= 0 && i < p->nSize );
+ return p->pArray[i];
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_StrWriteEntry( Vec_Str_t * p, int i, char Entry )
+{
+ assert( i >= 0 && i < p->nSize );
+ p->pArray[i] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline char Vec_StrEntryLast( Vec_Str_t * p )
+{
+ assert( p->nSize > 0 );
+ return p->pArray[p->nSize-1];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resizes the vector to the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_StrGrow( Vec_Str_t * p, int nCapMin )
+{
+ if ( p->nCap >= nCapMin )
+ return;
+ p->pArray = REALLOC( char, p->pArray, 2 * nCapMin );
+ p->nCap = 2 * nCapMin;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Fills the vector with given number of entries.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_StrFill( Vec_Str_t * p, int nSize, char Entry )
+{
+ int i;
+ Vec_StrGrow( p, nSize );
+ p->nSize = nSize;
+ for ( i = 0; i < p->nSize; i++ )
+ p->pArray[i] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_StrShrink( Vec_Str_t * p, int nSizeNew )
+{
+ assert( p->nSize >= nSizeNew );
+ p->nSize = nSizeNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_StrClear( Vec_Str_t * p )
+{
+ p->nSize = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_StrPush( Vec_Str_t * p, char Entry )
+{
+ if ( p->nSize == p->nCap )
+ {
+ if ( p->nCap < 16 )
+ Vec_StrGrow( p, 16 );
+ else
+ Vec_StrGrow( p, 2 * p->nCap );
+ }
+ p->pArray[p->nSize++] = Entry;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Appends the string to the char vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_StrAppend( Vec_Str_t * p, char * pString )
+{
+ int i, nLength = strlen(pString);
+ Vec_StrGrow( p, p->nSize + nLength );
+ for ( i = 0; i < nLength; i++ )
+ p->pArray[p->nSize + i] = pString[i];
+ p->nSize += nLength;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the last entry and removes it from the list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline char Vec_StrPop( Vec_Str_t * p )
+{
+ assert( p->nSize > 0 );
+ return p->pArray[--p->nSize];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Comparison procedure for two clauses.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_StrSortCompare1( char * pp1, char * pp2 )
+{
+ // for some reason commenting out lines (as shown) led to crashing of the release version
+ if ( *pp1 < *pp2 )
+ return -1;
+ if ( *pp1 > *pp2 ) //
+ return 1;
+ return 0; //
+}
+
+/**Function*************************************************************
+
+ Synopsis [Comparison procedure for two clauses.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_StrSortCompare2( char * pp1, char * pp2 )
+{
+ // for some reason commenting out lines (as shown) led to crashing of the release version
+ if ( *pp1 > *pp2 )
+ return -1;
+ if ( *pp1 < *pp2 ) //
+ return 1;
+ return 0; //
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sorting the entries by their integer value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_StrSort( Vec_Str_t * p, int fReverse )
+{
+ if ( fReverse )
+ qsort( (void *)p->pArray, p->nSize, sizeof(char),
+ (int (*)(const void *, const void *)) Vec_StrSortCompare2 );
+ else
+ qsort( (void *)p->pArray, p->nSize, sizeof(char),
+ (int (*)(const void *, const void *)) Vec_StrSortCompare1 );
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/opt/cut/vecVec.h b/src/opt/cut/vecVec.h
new file mode 100644
index 00000000..5b725354
--- /dev/null
+++ b/src/opt/cut/vecVec.h
@@ -0,0 +1,289 @@
+/**CFile****************************************************************
+
+ FileName [vecVec.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Resizable arrays.]
+
+ Synopsis [Resizable vector of resizable vectors.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: vecVec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __VEC_VEC_H__
+#define __VEC_VEC_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include "extra.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Vec_Vec_t_ Vec_Vec_t;
+struct Vec_Vec_t_
+{
+ int nCap;
+ int nSize;
+ void ** pArray;
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// iterators through levels
+#define Vec_VecForEachLevel( vGlob, vVec, i ) \
+ for ( i = 0; (i < Vec_VecSize(vGlob)) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ )
+#define Vec_VecForEachLevelStart( vGlob, vVec, i, LevelStart ) \
+ for ( i = LevelStart; (i < Vec_VecSize(vGlob)) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ )
+#define Vec_VecForEachLevelStartStop( vGlob, vVec, i, LevelStart, LevelStop ) \
+ for ( i = LevelStart; (i <= LevelStop) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ )
+#define Vec_VecForEachLevelReverse( vGlob, vVec, i ) \
+ for ( i = Vec_VecSize(vGlob) - 1; (i >= 0) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i-- )
+
+// iteratores through entries
+#define Vec_VecForEachEntry( vGlob, pEntry, i, k ) \
+ for ( i = 0; i < Vec_VecSize(vGlob); i++ ) \
+ Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
+#define Vec_VecForEachEntryStart( vGlob, pEntry, i, k, LevelStart ) \
+ for ( i = LevelStart; i < Vec_VecSize(vGlob); i++ ) \
+ Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
+#define Vec_VecForEachEntryStartStop( vGlob, pEntry, i, k, LevelStart, LevelStop ) \
+ for ( i = LevelStart; i <= LevelStop; i++ ) \
+ Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )
+#define Vec_VecForEachEntryReverse( vGlob, pEntry, i, k ) \
+ for ( i = 0; i < Vec_VecSize(vGlob); i++ ) \
+ Vec_PtrForEachEntryReverse( Vec_VecEntry(vGlob, i), pEntry, k )
+#define Vec_VecForEachEntryReverseReverse( vGlob, pEntry, i, k ) \
+ for ( i = Vec_VecSize(vGlob) - 1; i >= 0; i-- ) \
+ Vec_PtrForEachEntryReverse( Vec_VecEntry(vGlob, i), pEntry, k )
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Vec_t * Vec_VecAlloc( int nCap )
+{
+ Vec_Vec_t * p;
+ p = ALLOC( Vec_Vec_t, 1 );
+ if ( nCap > 0 && nCap < 8 )
+ nCap = 8;
+ p->nSize = 0;
+ p->nCap = nCap;
+ p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Vec_Vec_t * Vec_VecStart( int nSize )
+{
+ Vec_Vec_t * p;
+ int i;
+ p = Vec_VecAlloc( nSize );
+ for ( i = 0; i < nSize; i++ )
+ p->pArray[i] = Vec_PtrAlloc( 0 );
+ p->nSize = nSize;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a vector with the given capacity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_VecExpand( Vec_Vec_t * p, int Level )
+{
+ int i;
+ if ( p->nSize >= Level + 1 )
+ return;
+ Vec_PtrGrow( (Vec_Ptr_t *)p, Level + 1 );
+ for ( i = p->nSize; i <= Level; i++ )
+ p->pArray[i] = Vec_PtrAlloc( 0 );
+ p->nSize = Level + 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_VecSize( Vec_Vec_t * p )
+{
+ return p->nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void * Vec_VecEntry( Vec_Vec_t * p, int i )
+{
+ assert( i >= 0 && i < p->nSize );
+ return p->pArray[i];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_VecFree( Vec_Vec_t * p )
+{
+ Vec_Ptr_t * vVec;
+ int i;
+ Vec_VecForEachLevel( p, vVec, i )
+ Vec_PtrFree( vVec );
+ Vec_PtrFree( (Vec_Ptr_t *)p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the vector of vectors.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Vec_VecSizeSize( Vec_Vec_t * p )
+{
+ Vec_Ptr_t * vVec;
+ int i, Counter = 0;
+ Vec_VecForEachLevel( p, vVec, i )
+ Counter += vVec->nSize;
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_VecClear( Vec_Vec_t * p )
+{
+ Vec_Ptr_t * vVec;
+ int i;
+ Vec_VecForEachLevel( p, vVec, i )
+ Vec_PtrClear( vVec );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_VecPush( Vec_Vec_t * p, int Level, void * Entry )
+{
+ if ( p->nSize < Level + 1 )
+ {
+ int i;
+ Vec_PtrGrow( (Vec_Ptr_t *)p, Level + 1 );
+ for ( i = p->nSize; i < Level + 1; i++ )
+ p->pArray[i] = Vec_PtrAlloc( 0 );
+ p->nSize = Level + 1;
+ }
+ Vec_PtrPush( (Vec_Ptr_t*)p->pArray[Level], Entry );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_VecPushUnique( Vec_Vec_t * p, int Level, void * Entry )
+{
+ if ( p->nSize < Level + 1 )
+ Vec_VecPush( p, Level, Entry );
+ else
+ Vec_PtrPushUnique( (Vec_Ptr_t*)p->pArray[Level], Entry );
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/opt/dec/decAbc.c b/src/opt/dec/decAbc.c
index 1b23bb53..5311cec6 100644
--- a/src/opt/dec/decAbc.c
+++ b/src/opt/dec/decAbc.c
@@ -267,7 +267,7 @@ Ivy_Obj_t * Dec_GraphToNetworkIvy( Ivy_Man_t * pMan, Dec_Graph_t * pGraph )
{
pAnd0 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl );
pAnd1 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl );
- pNode->pFunc = Ivy_And( pAnd0, pAnd1 );
+ pNode->pFunc = Ivy_And( pMan, pAnd0, pAnd1 );
}
// complement the result if necessary
return Ivy_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) );