blob: 9bea8ef7f96d612f748f5003619a9956adf3d698 [file] [log] [blame]
/**CFile****************************************************************
FileName [giaSat.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Scalable AIG package.]
Synopsis [New constraint-propagation procedures.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: giaSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "gia.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define GIA_LIMIT 10
typedef struct Gia_ManSat_t_ Gia_ManSat_t;
struct Gia_ManSat_t_
{
Aig_MmFlex_t * pMem;
};
typedef struct Gia_ObjSat1_t_ Gia_ObjSat1_t;
struct Gia_ObjSat1_t_
{
char nFans;
char nOffset;
char PathsH;
char PathsV;
};
typedef struct Gia_ObjSat2_t_ Gia_ObjSat2_t;
struct Gia_ObjSat2_t_
{
unsigned fTerm : 1;
unsigned iLit : 31;
};
typedef struct Gia_ObjSat_t_ Gia_ObjSat_t;
struct Gia_ObjSat_t_
{
union {
Gia_ObjSat1_t Obj1;
Gia_ObjSat2_t Obj2;
};
};
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Gia_ManSat_t * Gia_ManSatStart()
{
Gia_ManSat_t * p;
p = ABC_CALLOC( Gia_ManSat_t, 1 );
p->pMem = Aig_MmFlexStart();
return p;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManSatStop( Gia_ManSat_t * p )
{
Aig_MmFlexStop( p->pMem, 0 );
ABC_FREE( p );
}
/**Function*************************************************************
Synopsis [Collects the supergate rooted at this ]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManSatPartCollectSuper( Gia_Man_t * p, Gia_Obj_t * pObj, int * pLits, int * pnLits )
{
Gia_Obj_t * pFanin;
assert( Gia_ObjIsAnd(pObj) );
assert( pObj->fMark0 == 0 );
pFanin = Gia_ObjFanin0(pObj);
if ( pFanin->fMark0 || Gia_ObjFaninC0(pObj) )
pLits[(*pnLits)++] = Gia_Var2Lit(Gia_ObjId(p, pFanin), Gia_ObjFaninC0(pObj));
else
Gia_ManSatPartCollectSuper(p, pFanin, pLits, pnLits);
pFanin = Gia_ObjFanin1(pObj);
if ( pFanin->fMark0 || Gia_ObjFaninC1(pObj) )
pLits[(*pnLits)++] = Gia_Var2Lit(Gia_ObjId(p, pFanin), Gia_ObjFaninC1(pObj));
else
Gia_ManSatPartCollectSuper(p, pFanin, pLits, pnLits);
}
/**Function*************************************************************
Synopsis [Returns the number of words used.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Gia_ManSatPartCreate_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int * pObjPlace, int * pStore )
{
Gia_Obj_t * pFanin;
int i, nWordsUsed, nSuperSize = 0, Super[2*GIA_LIMIT];
// make sure this is a valid node
assert( Gia_ObjIsAnd(pObj) );
assert( pObj->fMark0 == 0 );
// collect inputs to the supergate
Gia_ManSatPartCollectSuper( p, pObj, Super, &nSuperSize );
assert( nSuperSize <= 2*GIA_LIMIT );
// create the root entry
*pObjPlace = 0;
((Gia_ObjSat1_t *)pObjPlace)->nFans = Gia_Var2Lit( nSuperSize, 0 );
((Gia_ObjSat1_t *)pObjPlace)->nOffset = pStore - pObjPlace;
nWordsUsed = nSuperSize;
for ( i = 0; i < nSuperSize; i++ )
{
pFanin = Gia_ManObj( p, Gia_Lit2Var(Super[i]) );
if ( pFanin->fMark0 )
{
((Gia_ObjSat2_t *)(pStore + i))->fTerm = 1;
((Gia_ObjSat2_t *)(pStore + i))->iLit = Super[i];
}
else
{
assert( Gia_LitIsCompl(Super[i]) );
nWordsUsed += Gia_ManSatPartCreate_rec( p, pFanin, pStore + i, pStore + nWordsUsed );
}
}
return nWordsUsed;
}
/**Function*************************************************************
Synopsis [Creates part and returns the number of words used.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Gia_ManSatPartCreate( Gia_Man_t * p, Gia_Obj_t * pObj, int * pStore )
{
return 1 + Gia_ManSatPartCreate_rec( p, pObj, pStore, pStore + 1 );
}
/**Function*************************************************************
Synopsis [Count the number of internal nodes in the leaf-DAG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManSatPartCountClauses( Gia_Man_t * p, Gia_Obj_t * pObj, int * pnOnset, int * pnOffset )
{
Gia_Obj_t * pFanin;
int nOnset0, nOnset1, nOffset0, nOffset1;
assert( Gia_ObjIsAnd(pObj) );
pFanin = Gia_ObjFanin0(pObj);
if ( pFanin->fMark0 )
nOnset0 = 1, nOffset0 = 1;
else
{
Gia_ManSatPartCountClauses(p, pFanin, &nOnset0, &nOffset0);
if ( Gia_ObjFaninC0(pObj) )
{
int Temp = nOnset0;
nOnset0 = nOffset0;
nOffset0 = Temp;
}
}
pFanin = Gia_ObjFanin1(pObj);
if ( pFanin->fMark0 )
nOnset1 = 1, nOffset1 = 1;
else
{
Gia_ManSatPartCountClauses(p, pFanin, &nOnset1, &nOffset1);
if ( Gia_ObjFaninC1(pObj) )
{
int Temp = nOnset1;
nOnset1 = nOffset1;
nOffset1 = Temp;
}
}
*pnOnset = nOnset0 * nOnset1;
*pnOffset = nOffset0 + nOffset1;
}
/**Function*************************************************************
Synopsis [Count the number of internal nodes in the leaf-DAG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Gia_ManSatPartCount( Gia_Man_t * p, Gia_Obj_t * pObj, int * pnLeaves, int * pnNodes )
{
Gia_Obj_t * pFanin;
int Level0 = 0, Level1 = 0;
assert( Gia_ObjIsAnd(pObj) );
assert( pObj->fMark0 == 0 );
(*pnNodes)++;
pFanin = Gia_ObjFanin0(pObj);
if ( pFanin->fMark0 )
(*pnLeaves)++;
else
Level0 = Gia_ManSatPartCount(p, pFanin, pnLeaves, pnNodes) + Gia_ObjFaninC0(pObj);
pFanin = Gia_ObjFanin1(pObj);
if ( pFanin->fMark0 )
(*pnLeaves)++;
else
Level1 = Gia_ManSatPartCount(p, pFanin, pnLeaves, pnNodes) + Gia_ObjFaninC1(pObj);
return Abc_MaxInt( Level0, Level1 );
}
/**Function*************************************************************
Synopsis [Count the number of internal nodes in the leaf-DAG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Gia_ManSatPartCountNodes( Gia_Man_t * p, Gia_Obj_t * pObj )
{
Gia_Obj_t * pFanin;
int nNodes0 = 0, nNodes1 = 0;
assert( Gia_ObjIsAnd(pObj) );
assert( pObj->fMark0 == 0 );
pFanin = Gia_ObjFanin0(pObj);
if ( !(pFanin->fMark0) )
nNodes0 = Gia_ManSatPartCountNodes(p, pFanin);
pFanin = Gia_ObjFanin1(pObj);
if ( !(pFanin->fMark0) )
nNodes1 = Gia_ManSatPartCountNodes(p, pFanin);
return nNodes0 + nNodes1 + 1;
}
/**Function*************************************************************
Synopsis [Count the number of internal nodes in the leaf-DAG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManSatPartPrint( Gia_Man_t * p, Gia_Obj_t * pObj, int Step )
{
Gia_Obj_t * pFanin;
assert( Gia_ObjIsAnd(pObj) );
assert( pObj->fMark0 == 0 );
pFanin = Gia_ObjFanin0(pObj);
if ( pFanin->fMark0 )
printf( "%s%d", Gia_ObjFaninC0(pObj)?"!":"", Gia_ObjId(p,pFanin) );
else
{
if ( Gia_ObjFaninC0(pObj) )
printf( "(" );
Gia_ManSatPartPrint(p, pFanin, Step + Gia_ObjFaninC0(pObj));
if ( Gia_ObjFaninC0(pObj) )
printf( ")" );
}
printf( "%s", (Step & 1)? " + " : "*" );
pFanin = Gia_ObjFanin1(pObj);
if ( pFanin->fMark0 )
printf( "%s%d", Gia_ObjFaninC1(pObj)?"!":"", Gia_ObjId(p,pFanin) );
else
{
if ( Gia_ObjFaninC1(pObj) )
printf( "(" );
Gia_ManSatPartPrint(p, pFanin, Step + Gia_ObjFaninC1(pObj));
if ( Gia_ObjFaninC1(pObj) )
printf( ")" );
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManSatExperiment( Gia_Man_t * p )
{
int nStored, Storage[1000], * pStart;
Gia_ManSat_t * pMan;
Gia_Obj_t * pObj;
int i, nLevels, nLeaves, nNodes, nCount[2*GIA_LIMIT+2] = {0}, nCountAll = 0;
int Num0 = 0, Num1 = 0;
clock_t clk = clock();
int nWords = 0, nWords2 = 0;
pMan = Gia_ManSatStart();
// mark the nodes to become roots of leaf-DAGs
Gia_ManCreateValueRefs( p );
Gia_ManForEachObj( p, pObj, i )
{
pObj->fMark0 = 0;
if ( Gia_ObjIsCo(pObj) )
Gia_ObjFanin0(pObj)->fMark0 = 1;
else if ( Gia_ObjIsCi(pObj) )
pObj->fMark0 = 1;
else if ( Gia_ObjIsAnd(pObj) )
{
if ( pObj->Value > 1 || Gia_ManSatPartCountNodes(p,pObj) >= GIA_LIMIT )
pObj->fMark0 = 1;
}
pObj->Value = 0;
}
// compute the sizes of leaf-DAGs
Gia_ManForEachAnd( p, pObj, i )
{
if ( pObj->fMark0 == 0 )
continue;
pObj->fMark0 = 0;
nCountAll++;
nStored = Gia_ManSatPartCreate( p, pObj, Storage );
nWords2 += nStored;
assert( nStored < 500 );
pStart = (int *)Aig_MmFlexEntryFetch( pMan->pMem, sizeof(int) * nStored );
memcpy( pStart, Storage, sizeof(int) * nStored );
nLeaves = nNodes = 0;
nLevels = 1+Gia_ManSatPartCount( p, pObj, &nLeaves, &nNodes );
nWords += nLeaves + nNodes;
if ( nNodes <= 2*GIA_LIMIT )
nCount[nNodes]++;
else
nCount[2*GIA_LIMIT+1]++;
// if ( nNodes > 10 && i % 100 == 0 )
// if ( nNodes > 5 )
if ( 0 )
{
Gia_ManSatPartCountClauses( p, pObj, &Num0, &Num1 );
printf( "%8d : And = %3d. Lev = %2d. Clauses = %3d. (%3d + %3d).\n", i, nNodes, nLevels, Num0+Num1, Num0, Num1 );
Gia_ManSatPartPrint( p, pObj, 0 );
printf( "\n" );
}
pObj->fMark0 = 1;
}
printf( "\n" );
Gia_ManForEachObj( p, pObj, i )
pObj->fMark0 = 0;
Gia_ManSatStop( pMan );
for ( i = 0; i < 2*GIA_LIMIT+2; i++ )
printf( "%2d=%6d %7.2f %% %7.2f %%\n", i, nCount[i], 100.0*nCount[i]/nCountAll, 100.0*i*nCount[i]/Gia_ManAndNum(p) );
ABC_PRMn( "MemoryEst", 4*nWords );
ABC_PRMn( "MemoryReal", 4*nWords2 );
printf( "%5.2f bpn ", 4.0*nWords2/Gia_ManObjNum(p) );
ABC_PRT( "Time", clock() - clk );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END