Commit f03871ab by Mathias Soeken

Merged alanmi/abc into default

parents 28e8e7f3 b1907e90
......@@ -271,6 +271,10 @@ SOURCE=.\src\base\abci\abcDsd.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcEco.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcExact.c
# End Source File
# Begin Source File
......@@ -695,6 +699,10 @@ SOURCE=.\src\base\io\ioWriteVerilog.c
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\src\base\main\abcapis.h
# End Source File
# Begin Source File
SOURCE=.\src\base\main\libSupport.c
# End Source File
# Begin Source File
......
......@@ -37,7 +37,7 @@ struct Gli_Obj_t_
unsigned nFanins : 3; // the number of fanins
unsigned nFanouts : 25; // total number of fanouts
unsigned Handle; // ID of the node
unsigned uTruth[2]; // truth table of the node
word * pTruth; // truth table of the node
unsigned uSimInfo; // simulation info of the node
union
{
......@@ -333,7 +333,7 @@ static inline int Gli_NodeComputeValue( Gli_Obj_t * pNode )
int i, Phase = 0;
for ( i = 0; i < (int)pNode->nFanins; i++ )
Phase |= (Gli_ObjFanin(pNode, i)->fPhase << i);
return Abc_InfoHasBit( pNode->uTruth, Phase );
return Abc_InfoHasBit( (unsigned *)pNode->pTruth, Phase );
}
/**Function*************************************************************
......@@ -352,7 +352,7 @@ static inline int Gli_NodeComputeValue2( Gli_Obj_t * pNode )
int i, Phase = 0;
for ( i = 0; i < (int)pNode->nFanins; i++ )
Phase |= (Gli_ObjFanin(pNode, i)->fPhase2 << i);
return Abc_InfoHasBit( pNode->uTruth, Phase );
return Abc_InfoHasBit( (unsigned *)pNode->pTruth, Phase );
}
/**Function*************************************************************
......@@ -366,16 +366,15 @@ static inline int Gli_NodeComputeValue2( Gli_Obj_t * pNode )
SeeAlso []
***********************************************************************/
int Gli_ManCreateNode( Gli_Man_t * p, Vec_Int_t * vFanins, int nFanouts, unsigned * puTruth )
int Gli_ManCreateNode( Gli_Man_t * p, Vec_Int_t * vFanins, int nFanouts, word * pGateTruth )
{
Gli_Obj_t * pObj, * pFanin;
int i;
assert( Vec_IntSize(vFanins) <= 6 );
assert( Vec_IntSize(vFanins) <= 16 );
pObj = Gli_ObjAlloc( p, Vec_IntSize(vFanins), nFanouts );
Gli_ManForEachEntry( vFanins, p, pFanin, i )
Gli_ObjAddFanin( pObj, pFanin );
pObj->uTruth[0] = puTruth[0];
pObj->uTruth[1] = puTruth[Vec_IntSize(vFanins) == 6];
pObj->pTruth = pGateTruth;
pObj->fPhase = pObj->fPhase2 = Gli_NodeComputeValue( pObj );
return pObj->Handle;
}
......@@ -584,7 +583,7 @@ unsigned Gli_ManSimulateSeqNode( Gli_Man_t * p, Gli_Obj_t * pNode )
int nFanins = Gli_ObjFaninNum(pNode);
int i, k, Phase;
Gli_Obj_t * pFanin;
assert( nFanins <= 6 );
assert( nFanins <= 16 );
Gli_ObjForEachFanin( pNode, pFanin, i )
pSimInfos[i] = pFanin->uSimInfo;
for ( i = 0; i < 32; i++ )
......@@ -593,7 +592,7 @@ unsigned Gli_ManSimulateSeqNode( Gli_Man_t * p, Gli_Obj_t * pNode )
for ( k = 0; k < nFanins; k++ )
if ( (pSimInfos[k] >> i) & 1 )
Phase |= (1 << k);
if ( Abc_InfoHasBit( pNode->uTruth, Phase ) )
if ( Abc_InfoHasBit( (unsigned *)pNode->pTruth, Phase ) )
Result |= (1 << i);
}
return Result;
......@@ -772,7 +771,7 @@ void Gli_ManSwitchesAndGlitches( Gli_Man_t * p, int nPatterns, float PiTransProb
}
if ( fVerbose )
{
printf( "\nSimulated %d patterns. ", nPatterns );
printf( "Simulated %d patterns. Input transition probability %.2f. ", nPatterns, PiTransProb );
ABC_PRMn( "Memory", 4*p->nObjData );
ABC_PRT( "Time", Abc_Clock() - clk );
}
......
......@@ -825,6 +825,7 @@ extern ABC_DLL void Abc_NtkDontCareFree( Odc_Man_t * p );
extern ABC_DLL int Abc_NtkDontCareCompute( Odc_Man_t * p, Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, unsigned * puTruth );
/*=== abcPrint.c ==========================================================*/
extern ABC_DLL float Abc_NtkMfsTotalSwitching( Abc_Ntk_t * pNtk );
extern ABC_DLL float Abc_NtkMfsTotalGlitching( Abc_Ntk_t * pNtk, int nPats, int Prob, int fVerbose );
extern ABC_DLL void Abc_NtkPrintStats( Abc_Ntk_t * pNtk, int fFactored, int fSaveBest, int fDumpResult, int fUseLutLib, int fPrintMuxes, int fPower, int fGlitch, int fSkipBuf, int fSkipSmall, int fPrintMem );
extern ABC_DLL void Abc_NtkPrintIo( FILE * pFile, Abc_Ntk_t * pNtk, int fPrintFlops );
extern ABC_DLL void Abc_NtkPrintLatch( FILE * pFile, Abc_Ntk_t * pNtk );
......
/**CFile****************************************************************
FileName [abcEco.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Experimental procedures.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcEco.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "base/abc/abc.h"
#include "base/main/main.h"
#include "map/mio/mio.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkEco( char * pFileNames[3] )
{
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END
......@@ -923,9 +923,9 @@ void Abc_NtkPrintMiniMapping( int * pArray )
SeeAlso []
***********************************************************************/
int * Abc_NtkOutputMiniMapping( void * pAbc0 )
int * Abc_NtkOutputMiniMapping( Abc_Frame_t * pAbc )
{
Abc_Frame_t * pAbc = (Abc_Frame_t *)pAbc0;
//Abc_Frame_t * pAbc = (Abc_Frame_t *)pAbc0;
Abc_Ntk_t * pNtk;
Vec_Int_t * vMapping;
int * pArray;
......@@ -977,9 +977,9 @@ void Abc_NtkTestMiniMapping( Abc_Ntk_t * p )
SeeAlso []
***********************************************************************/
void Abc_NtkSetCiArrivalTime( void * pAbc0, int iCi, float Rise, float Fall )
void Abc_NtkSetCiArrivalTime( Abc_Frame_t * pAbc, int iCi, float Rise, float Fall )
{
Abc_Frame_t * pAbc = (Abc_Frame_t *)pAbc0;
//Abc_Frame_t * pAbc = (Abc_Frame_t *)pAbc0;
Abc_Ntk_t * pNtk;
Abc_Obj_t * pNode;
if ( pAbc == NULL )
......@@ -1001,9 +1001,9 @@ void Abc_NtkSetCiArrivalTime( void * pAbc0, int iCi, float Rise, float Fall )
pNode = Abc_NtkCi( pNtk, iCi );
Abc_NtkTimeSetArrival( pNtk, Abc_ObjId(pNode), Rise, Fall );
}
void Abc_NtkSetCoRequiredTime( void * pAbc0, int iCo, float Rise, float Fall )
void Abc_NtkSetCoRequiredTime( Abc_Frame_t * pAbc, int iCo, float Rise, float Fall )
{
Abc_Frame_t * pAbc = (Abc_Frame_t *)pAbc0;
//Abc_Frame_t * pAbc = (Abc_Frame_t *)pAbc0;
Abc_Ntk_t * pNtk;
Abc_Obj_t * pNode;
if ( pAbc == NULL )\
......@@ -1037,9 +1037,9 @@ void Abc_NtkSetCoRequiredTime( void * pAbc0, int iCo, float Rise, float Fall )
SeeAlso []
***********************************************************************/
void Abc_NtkSetAndGateDelay( void * pAbc0, float Delay )
void Abc_NtkSetAndGateDelay( Abc_Frame_t * pAbc, float Delay )
{
Abc_Frame_t * pAbc = (Abc_Frame_t *)pAbc0;
//Abc_Frame_t * pAbc = (Abc_Frame_t *)pAbc0;
Abc_Ntk_t * pNtk;
if ( pAbc == NULL )
{
......
......@@ -351,9 +351,8 @@ void Abc_NtkPrintStats( Abc_Ntk_t * pNtk, int fFactored, int fSaveBest, int fDum
Abc_Print( 1," power =%7.2f", Abc_NtkMfsTotalSwitching(pNtk) );
if ( fGlitch )
{
extern float Abc_NtkMfsTotalGlitching( Abc_Ntk_t * pNtk );
if ( Abc_NtkIsLogic(pNtk) && Abc_NtkGetFaninMax(pNtk) <= 6 )
Abc_Print( 1," glitch =%7.2f %%", Abc_NtkMfsTotalGlitching(pNtk) );
Abc_Print( 1," glitch =%7.2f %%", Abc_NtkMfsTotalGlitching(pNtk, 4000, 8, 0) );
else
printf( "\nCurrently computes glitching only for K-LUT networks with K <= 6." );
}
......@@ -1744,7 +1743,7 @@ extern Gli_Man_t * Gli_ManAlloc( int nObjs, int nRegs, int nFanioPairs );
extern void Gli_ManStop( Gli_Man_t * p );
extern int Gli_ManCreateCi( Gli_Man_t * p, int nFanouts );
extern int Gli_ManCreateCo( Gli_Man_t * p, int iFanin );
extern int Gli_ManCreateNode( Gli_Man_t * p, Vec_Int_t * vFanins, int nFanouts, unsigned * puTruth );
extern int Gli_ManCreateNode( Gli_Man_t * p, Vec_Int_t * vFanins, int nFanouts, word * pGateTruth );
extern void Gli_ManSwitchesAndGlitches( Gli_Man_t * p, int nPatterns, float PiTransProb, int fVerbose );
extern int Gli_ObjNumSwitches( Gli_Man_t * p, int iNode );
......@@ -1761,13 +1760,14 @@ extern int Gli_ObjNumGlitches( Gli_Man_t * p, int iNode );
SeeAlso []
***********************************************************************/
float Abc_NtkMfsTotalGlitching( Abc_Ntk_t * pNtk )
float Abc_NtkMfsTotalGlitchingLut( Abc_Ntk_t * pNtk, int nPats, int Prob, int fVerbose )
{
int nSwitches, nGlitches;
Gli_Man_t * p;
Vec_Ptr_t * vNodes;
Vec_Int_t * vFanins, * vTruth;
Abc_Obj_t * pObj, * pFanin;
Vec_Wrd_t * vTruths; word * pTruth;
unsigned * puTruth;
int i, k;
assert( Abc_NtkIsLogic(pNtk) );
......@@ -1781,6 +1781,7 @@ float Abc_NtkMfsTotalGlitching( Abc_Ntk_t * pNtk )
vNodes = Abc_NtkDfs( pNtk, 0 );
vFanins = Vec_IntAlloc( 6 );
vTruth = Vec_IntAlloc( 1 << 12 );
vTruths = Vec_WrdStart( Abc_NtkObjNumMax(pNtk) );
// derive network for glitch computation
p = Gli_ManAlloc( Vec_PtrSize(vNodes) + Abc_NtkCiNum(pNtk) + Abc_NtkCoNum(pNtk),
......@@ -1795,7 +1796,9 @@ float Abc_NtkMfsTotalGlitching( Abc_Ntk_t * pNtk )
Abc_ObjForEachFanin( pObj, pFanin, k )
Vec_IntPush( vFanins, pFanin->iTemp );
puTruth = Hop_ManConvertAigToTruth( (Hop_Man_t *)pNtk->pManFunc, (Hop_Obj_t *)pObj->pData, Abc_ObjFaninNum(pObj), vTruth, 0 );
pObj->iTemp = Gli_ManCreateNode( p, vFanins, Abc_ObjFanoutNum(pObj), puTruth );
pTruth = Vec_WrdEntryP( vTruths, Abc_ObjId(pObj) );
*pTruth = ((word)puTruth[Abc_ObjFaninNum(pObj) == 6] << 32) | (word)puTruth[0];
pObj->iTemp = Gli_ManCreateNode( p, vFanins, Abc_ObjFanoutNum(pObj), pTruth );
}
Abc_NtkForEachCo( pNtk, pObj, i )
Gli_ManCreateCo( p, Abc_ObjFanin0(pObj)->iTemp );
......@@ -1816,6 +1819,72 @@ float Abc_NtkMfsTotalGlitching( Abc_Ntk_t * pNtk )
Vec_PtrFree( vNodes );
Vec_IntFree( vTruth );
Vec_IntFree( vFanins );
Vec_WrdFree( vTruths );
return nSwitches ? 100.0*(nGlitches-nSwitches)/nSwitches : 0.0;
}
/**Function*************************************************************
Synopsis [Returns the percentable of increased power due to glitching.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
float Abc_NtkMfsTotalGlitching( Abc_Ntk_t * pNtk, int nPats, int Prob, int fVerbose )
{
int nSwitches, nGlitches;
Gli_Man_t * p;
Vec_Ptr_t * vNodes;
Vec_Int_t * vFanins;
Abc_Obj_t * pObj, * pFanin;
int i, k, nFaninMax = Abc_NtkGetFaninMax(pNtk);
if ( !Abc_NtkIsMappedLogic(pNtk) )
return Abc_NtkMfsTotalGlitchingLut( pNtk, nPats, Prob, fVerbose );
assert( Abc_NtkIsMappedLogic(pNtk) );
if ( nFaninMax > 16 )
{
printf( "Abc_NtkMfsTotalGlitching() This procedure works only for mapped networks with LUTs size up to 6 inputs.\n" );
return -1.0;
}
vNodes = Abc_NtkDfs( pNtk, 0 );
vFanins = Vec_IntAlloc( 6 );
// derive network for glitch computation
p = Gli_ManAlloc( Vec_PtrSize(vNodes) + Abc_NtkCiNum(pNtk) + Abc_NtkCoNum(pNtk),
Abc_NtkLatchNum(pNtk), Abc_NtkGetTotalFanins(pNtk) + Abc_NtkCoNum(pNtk) );
Abc_NtkForEachObj( pNtk, pObj, i )
pObj->iTemp = -1;
Abc_NtkForEachCi( pNtk, pObj, i )
pObj->iTemp = Gli_ManCreateCi( p, Abc_ObjFanoutNum(pObj) );
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
{
Vec_IntClear( vFanins );
Abc_ObjForEachFanin( pObj, pFanin, k )
Vec_IntPush( vFanins, pFanin->iTemp );
pObj->iTemp = Gli_ManCreateNode( p, vFanins, Abc_ObjFanoutNum(pObj), Mio_GateReadTruthP((Mio_Gate_t *)pObj->pData) );
}
Abc_NtkForEachCo( pNtk, pObj, i )
Gli_ManCreateCo( p, Abc_ObjFanin0(pObj)->iTemp );
// compute glitching
Gli_ManSwitchesAndGlitches( p, nPats, 1.0/Prob, fVerbose );
// compute the ratio
nSwitches = nGlitches = 0;
Abc_NtkForEachObj( pNtk, pObj, i )
if ( pObj->iTemp >= 0 )
{
nSwitches += Abc_ObjFanoutNum(pObj) * Gli_ObjNumSwitches(p, pObj->iTemp);
nGlitches += Abc_ObjFanoutNum(pObj) * Gli_ObjNumGlitches(p, pObj->iTemp);
}
Gli_ManStop( p );
Vec_PtrFree( vNodes );
Vec_IntFree( vFanins );
return nSwitches ? 100.0*(nGlitches-nSwitches)/nSwitches : 0.0;
}
......
......@@ -17,6 +17,7 @@ SRC += src/base/abci/abc.c \
src/base/abci/abcDress2.c \
src/base/abci/abcDress3.c \
src/base/abci/abcDsd.c \
src/base/abci/abcEco.c \
src/base/abci/abcExact.c \
src/base/abci/abcExtract.c \
src/base/abci/abcFraig.c \
......
......@@ -30,6 +30,8 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define ABC_USE_HISTORY 1
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
......@@ -99,7 +101,7 @@ void Cmd_HistoryAddCommand( Abc_Frame_t * p, const char * command )
***********************************************************************/
void Cmd_HistoryRead( Abc_Frame_t * p )
{
#if defined(WIN32)
#if defined(WIN32) && defined(ABC_USE_HISTORY)
char Buffer[ABC_MAX_STR];
FILE * pFile;
assert( Vec_PtrSize(p->aHistory) == 0 );
......@@ -130,7 +132,7 @@ void Cmd_HistoryRead( Abc_Frame_t * p )
***********************************************************************/
void Cmd_HistoryWrite( Abc_Frame_t * p, int Limit )
{
#if defined(WIN32)
#if defined(WIN32) && defined(ABC_USE_HISTORY)
FILE * pFile;
char * pStr;
int i;
......@@ -160,7 +162,7 @@ void Cmd_HistoryWrite( Abc_Frame_t * p, int Limit )
***********************************************************************/
void Cmd_HistoryPrint( Abc_Frame_t * p, int Limit )
{
#if defined(WIN32)
#if defined(WIN32) && defined(ABC_USE_HISTORY)
char * pStr;
int i;
Limit = Abc_MaxInt( 0, Vec_PtrSize(p->aHistory)-Limit );
......
/**CFile****************************************************************
FileName [abcapis.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Include this file in the external code calling ABC.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 29, 2012.]
Revision [$Id: abcapis.h,v 1.00 2012/09/29 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef MINI_AIG__abc_apis_h
#define MINI_AIG__abc_apis_h
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Abc_Frame_t_ Abc_Frame_t;
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
#ifdef WIN32
#ifdef WIN32_NO_DLL
#define ABC_DLLEXPORT
#define ABC_DLLIMPORT
#else
#define ABC_DLLEXPORT __declspec(dllexport)
#define ABC_DLLIMPORT __declspec(dllimport)
#endif
#else /* defined(WIN32) */
#define ABC_DLLIMPORT
#endif /* defined(WIN32) */
#ifndef ABC_DLL
#define ABC_DLL ABC_DLLIMPORT
#endif
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
// procedures to start and stop the ABC framework
extern ABC_DLL void Abc_Start();
extern ABC_DLL void Abc_Stop();
// procedures to get the ABC framework (pAbc) and execute commands in it
extern ABC_DLL Abc_Frame_t * Abc_FrameGetGlobalFrame();
extern ABC_DLL int Cmd_CommandExecute( Abc_Frame_t * pAbc, const char * pCommandLine );
// procedures to input/output 'mini AIG'
extern ABC_DLL void Abc_NtkInputMiniAig( Abc_Frame_t * pAbc, void * pMiniAig );
extern ABC_DLL void * Abc_NtkOutputMiniAig( Abc_Frame_t * pAbc );
extern ABC_DLL void Abc_FrameGiaInputMiniAig( Abc_Frame_t * pAbc, void * p );
extern ABC_DLL void * Abc_FrameGiaOutputMiniAig( Abc_Frame_t * pAbc );
extern ABC_DLL void Abc_NtkSetFlopNum( Abc_Frame_t * pAbc, int nFlops );
// procedures to input/output 'mini LUT'
extern ABC_DLL void Abc_FrameGiaInputMiniLut( Abc_Frame_t * pAbc, void * pMiniLut );
extern ABC_DLL void * Abc_FrameGiaOutputMiniLut( Abc_Frame_t * pAbc );
// procedures to set CI/CO arrival/required times
extern ABC_DLL void Abc_NtkSetCiArrivalTime( Abc_Frame_t * pAbc, int iCi, float Rise, float Fall );
extern ABC_DLL void Abc_NtkSetCoRequiredTime( Abc_Frame_t * pAbc, int iCo, float Rise, float Fall );
// procedure to set AND-gate delay to tech-independent synthesis and mapping
extern ABC_DLL void Abc_NtkSetAndGateDelay( Abc_Frame_t * pAbc, float Delay );
// procedures to return the mapped network
extern ABC_DLL int * Abc_NtkOutputMiniMapping( Abc_Frame_t * pAbc );
extern ABC_DLL void Abc_NtkPrintMiniMapping( int * pArray );
// procedures to access verifization status and a counter-example
extern ABC_DLL int Abc_FrameReadProbStatus( Abc_Frame_t * pAbc );
extern ABC_DLL void * Abc_FrameReadCex( Abc_Frame_t * pAbc );
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -18,8 +18,8 @@
***********************************************************************/
#ifndef MINI_AIG__abc_apis_h
#define MINI_AIG__abc_apis_h
#ifndef MINI_AIG__abc_apis_old_h
#define MINI_AIG__abc_apis_old_h
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
......
......@@ -34,10 +34,8 @@
#include "misc/vec/vec.h"
#include "misc/st/st.h"
ABC_NAMESPACE_HEADER_START
// the framework containing all data
typedef struct Abc_Frame_t_ Abc_Frame_t;
ABC_NAMESPACE_HEADER_END
// the framework containing all data is defined here
#include "abcapis.h"
#include "base/cmd/cmd.h"
#include "base/io/ioAbc.h"
......@@ -116,7 +114,7 @@ extern ABC_DLL void Abc_FrameSetBridgeMode();
extern ABC_DLL int Abc_FrameReadBmcFrames( Abc_Frame_t * p );
extern ABC_DLL int Abc_FrameReadProbStatus( Abc_Frame_t * p );
extern ABC_DLL Abc_Cex_t * Abc_FrameReadCex( Abc_Frame_t * p );
extern ABC_DLL void * Abc_FrameReadCex( Abc_Frame_t * p );
extern ABC_DLL Vec_Ptr_t * Abc_FrameReadCexVec( Abc_Frame_t * p );
extern ABC_DLL Vec_Int_t * Abc_FrameReadStatusVec( Abc_Frame_t * p );
extern ABC_DLL Vec_Ptr_t * Abc_FrameReadPoEquivs( Abc_Frame_t * p );
......
......@@ -69,7 +69,7 @@ char * Abc_FrameReadFlag( char * pFlag ) { return Cmd_FlagRe
int Abc_FrameReadBmcFrames( Abc_Frame_t * p ) { return s_GlobalFrame->nFrames; }
int Abc_FrameReadProbStatus( Abc_Frame_t * p ) { return s_GlobalFrame->Status; }
Abc_Cex_t * Abc_FrameReadCex( Abc_Frame_t * p ) { return s_GlobalFrame->pCex; }
void * Abc_FrameReadCex( Abc_Frame_t * p ) { return s_GlobalFrame->pCex; }
Vec_Ptr_t * Abc_FrameReadCexVec( Abc_Frame_t * p ) { return s_GlobalFrame->vCexVec; }
Vec_Int_t * Abc_FrameReadStatusVec( Abc_Frame_t * p ) { return s_GlobalFrame->vStatuses; }
Vec_Ptr_t * Abc_FrameReadPoEquivs( Abc_Frame_t * p ) { return s_GlobalFrame->vPoEquivs; }
......
......@@ -169,9 +169,14 @@ struct Wlc_Par_t_
int nBitsMux; // MUX bit-width
int nBitsFlop; // flop bit-width
int nIterMax; // the max number of iterations
int nLimit; // the max number of signals
int fXorOutput; // XOR outputs of word-level miter
int fCheckClauses; // Check clauses in the reloaded trace
int fPushClauses; // Push clauses in the reloaded trace
int fMFFC; // Refine the entire MFFC of a PPI
int fPdra; // Use pdr -nct
int fProofRefine; // Use proof-based refinement
int fHybrid; // Use a hybrid of CBR and PBR
int fVerbose; // verbose output
int fPdrVerbose; // verbose output
};
......@@ -309,6 +314,7 @@ extern void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p );
extern char * Wlc_NtkNewName( Wlc_Ntk_t * p, int iCoId, int fSeq );
extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq );
extern Wlc_Ntk_t * Wlc_NtkDupDfsAbs( Wlc_Ntk_t * p, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops );
extern Wlc_Ntk_t * Wlc_NtkDupDfsSimple( Wlc_Ntk_t * p );
extern void Wlc_NtkCleanMarks( Wlc_Ntk_t * p );
extern void Wlc_NtkMarkCone( Wlc_Ntk_t * p, int iCoId, int Range, int fSeq, int fAllPis );
extern void Wlc_NtkProfileCones( Wlc_Ntk_t * p );
......
......@@ -462,7 +462,7 @@ int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv )
int c;
Wlc_ManSetDefaultParams( pPars );
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIcpxvwh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFILabrcpmxvwh" ) ) != EOF )
{
switch ( c )
{
......@@ -521,6 +521,26 @@ int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nIterMax < 0 )
goto usage;
break;
case 'L':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-L\" should be followed by an integer.\n" );
goto usage;
}
pPars->nLimit = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pPars->nLimit < 0 )
goto usage;
break;
case 'a':
pPars->fPdra ^= 1;
break;
case 'b':
pPars->fProofRefine ^= 1;
break;
case 'r':
pPars->fHybrid ^= 1;
break;
case 'x':
pPars->fXorOutput ^= 1;
break;
......@@ -530,6 +550,9 @@ int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'p':
pPars->fPushClauses ^= 1;
break;
case 'm':
pPars->fMFFC ^= 1;
break;
case 'v':
pPars->fVerbose ^= 1;
break;
......@@ -550,16 +573,21 @@ int Abc_CommandPdrAbs( Abc_Frame_t * pAbc, int argc, char ** argv )
Wlc_NtkPdrAbs( pNtk, pPars );
return 0;
usage:
Abc_Print( -2, "usage: %%pdra [-AMXFI num] [-cpxvwh]\n" );
Abc_Print( -2, "usage: %%pdra [-AMXFIL num] [-abrcpmxvwh]\n" );
Abc_Print( -2, "\t abstraction for word-level networks\n" );
Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd );
Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul );
Abc_Print( -2, "\t-X num : minimum bit-width of a MUX operator to abstract [default = %d]\n", pPars->nBitsMux );
Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop );
Abc_Print( -2, "\t-I num : maximum number of CEGAR iterations [default = %d]\n", pPars->nIterMax );
Abc_Print( -2, "\t-L num : maximum number of each type of signals [default = %d]\n", pPars->nLimit );
Abc_Print( -2, "\t-x : toggle XORing outputs of word-level miter [default = %s]\n", pPars->fXorOutput? "yes": "no" );
Abc_Print( -2, "\t-a : toggle running pdr with -nct [default = %s]\n", pPars->fPdra? "yes": "no" );
Abc_Print( -2, "\t-b : toggle using proof-based refinement [default = %s]\n", pPars->fProofRefine? "yes": "no" );
Abc_Print( -2, "\t-r : toggle using both cex-based and proof-based refinement [default = %s]\n", pPars->fHybrid? "yes": "no" );
Abc_Print( -2, "\t-c : toggle checking clauses in the reloaded trace [default = %s]\n", pPars->fCheckClauses? "yes": "no" );
Abc_Print( -2, "\t-p : toggle pushing clauses in the reloaded trace [default = %s]\n", pPars->fPushClauses? "yes": "no" );
Abc_Print( -2, "\t-m : toggle refining the whole MFFC of a PPI [default = %s]\n", pPars->fMFFC? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" );
Abc_Print( -2, "\t-w : toggle printing verbose PDR output [default = %s]\n", pPars->fPdrVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
......@@ -585,7 +613,7 @@ int Abc_CommandAbs( Abc_Frame_t * pAbc, int argc, char ** argv )
int c;
Wlc_ManSetDefaultParams( pPars );
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFIxvwh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "AMXFILxvwh" ) ) != EOF )
{
switch ( c )
{
......@@ -644,6 +672,17 @@ int Abc_CommandAbs( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nIterMax < 0 )
goto usage;
break;
case 'L':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-L\" should be followed by an integer.\n" );
goto usage;
}
pPars->nLimit = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pPars->nLimit < 0 )
goto usage;
break;
case 'x':
pPars->fXorOutput ^= 1;
break;
......@@ -667,13 +706,14 @@ int Abc_CommandAbs( Abc_Frame_t * pAbc, int argc, char ** argv )
Wlc_NtkAbsCore( pNtk, pPars );
return 0;
usage:
Abc_Print( -2, "usage: %%abs [-AMXFI num] [-xvwh]\n" );
Abc_Print( -2, "usage: %%abs [-AMXFIL num] [-xvwh]\n" );
Abc_Print( -2, "\t abstraction for word-level networks\n" );
Abc_Print( -2, "\t-A num : minimum bit-width of an adder/subtractor to abstract [default = %d]\n", pPars->nBitsAdd );
Abc_Print( -2, "\t-M num : minimum bit-width of a multiplier to abstract [default = %d]\n", pPars->nBitsMul );
Abc_Print( -2, "\t-X num : minimum bit-width of a MUX operator to abstract [default = %d]\n", pPars->nBitsMux );
Abc_Print( -2, "\t-F num : minimum bit-width of a flip-flop to abstract [default = %d]\n", pPars->nBitsFlop );
Abc_Print( -2, "\t-I num : maximum number of CEGAR iterations [default = %d]\n", pPars->nIterMax );
Abc_Print( -2, "\t-L num : maximum number of each type of signals [default = %d]\n", pPars->nLimit );
Abc_Print( -2, "\t-x : toggle XORing outputs of word-level miter [default = %s]\n", pPars->fXorOutput? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" );
Abc_Print( -2, "\t-w : toggle printing verbose PDR output [default = %s]\n", pPars->fPdrVerbose? "yes": "no" );
......
......@@ -113,9 +113,14 @@ void Wlc_ManSetDefaultParams( Wlc_Par_t * pPars )
pPars->nBitsMux = ABC_INFINITY; // MUX bit-width
pPars->nBitsFlop = ABC_INFINITY; // flop bit-width
pPars->nIterMax = 1000; // the max number of iterations
pPars->nLimit = ABC_INFINITY; // the max number of signals
pPars->fXorOutput = 1; // XOR outputs of word-level miter
pPars->fCheckClauses = 1; // Check clauses in the reloaded trace
pPars->fPushClauses = 0; // Push clauses in the reloaded trace
pPars->fMFFC = 1; // Refine the entire MFFC of a PPI
pPars->fPdra = 0; // Use pdr -nct
pPars->fProofRefine = 0; // Use proof-based refinement
pPars->fHybrid = 1; // Use a hybrid of CBR and PBR
pPars->fVerbose = 0; // verbose output`
pPars->fPdrVerbose = 0; // show verbose PDR output
}
......@@ -830,6 +835,33 @@ void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * v
Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins );
Wlc_ObjDup( pNew, p, iObj, vFanins );
}
Wlc_Ntk_t * Wlc_NtkDupDfsSimple( Wlc_Ntk_t * p )
{
Wlc_Ntk_t * pNew;
Wlc_Obj_t * pObj;
Vec_Int_t * vFanins;
int i;
Wlc_NtkCleanCopy( p );
vFanins = Vec_IntAlloc( 100 );
pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc );
pNew->fSmtLib = p->fSmtLib;
Wlc_NtkForEachCi( p, pObj, i )
Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
Wlc_NtkForEachCo( p, pObj, i )
Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins );
Wlc_NtkForEachCo( p, pObj, i )
Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), pObj->fIsFi );
if ( p->vInits )
pNew->vInits = Vec_IntDup( p->vInits );
if ( p->pInits )
pNew->pInits = Abc_UtilStrsav( p->pInits );
Vec_IntFree( vFanins );
if ( p->pSpec )
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
return pNew;
}
Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq )
{
Wlc_Ntk_t * pNew;
......
......@@ -239,7 +239,7 @@ int Wlc_StdinProcessSmt( Abc_Frame_t * pAbc, char * pCmd )
return 0;
}
// report value of this variable
Wlc_NtkReport( (Wlc_Ntk_t *)pAbc->pAbcWlc, Abc_FrameReadCex(pAbc), pName, 16 );
Wlc_NtkReport( (Wlc_Ntk_t *)pAbc->pAbcWlc, (Abc_Cex_t *)Abc_FrameReadCex(pAbc), pName, 16 );
Vec_StrFree( vInput );
fflush( stdout );
}
......
......@@ -1823,13 +1823,17 @@ int Scl_CommandReadConstr( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
FILE * pFile;
char * pFileName;
int fUseNewFormat = 0;
int c, fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "nvh" ) ) != EOF )
{
switch ( c )
{
case 'n':
fVerbose ^= 1;
break;
case 'v':
fVerbose ^= 1;
break;
......@@ -1850,25 +1854,29 @@ int Scl_CommandReadConstr( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
fclose( pFile );
// Abc_SclReadTimingConstr( pAbc, pFileName, fVerbose );
if ( !fUseNewFormat )
Abc_SclReadTimingConstr( pAbc, pFileName, fVerbose );
else
{
if ( pNtk == NULL )
{
fprintf( pAbc->Err, "There is no current network.\n" );
return 1;
}
// input constraint manager
if ( pNtk )
{
Scl_Con_t * pCon = Scl_ConRead( pFileName, Abc_NtkNameMan(pNtk, 0), Abc_NtkNameMan(pNtk, 1) );
if ( pCon ) Scl_ConUpdateMan( pAbc, pCon );
}
}
return 0;
usage:
fprintf( pAbc->Err, "usage: read_constr [-vh] <file>\n" );
fprintf( pAbc->Err, "usage: read_constr [-nvh] <file>\n" );
fprintf( pAbc->Err, "\t read file with timing constraints for standard-cell designs\n" );
fprintf( pAbc->Err, "\t-n : toggle using new constraint file format [default = %s]\n", fUseNewFormat? "yes": "no" );
fprintf( pAbc->Err, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pAbc->Err, "\t-h : prints the command summary\n" );
fprintf( pAbc->Err, "\t<file> : the name of a file to read\n" );
......
......@@ -254,21 +254,21 @@ void Abc_SclReadTimingConstr( Abc_Frame_t * pAbc, char * pFileName, int fVerbose
pToken = strtok( Buffer, " \t\r\n" );
if ( pToken == NULL )
continue;
// if ( !strcmp(pToken, "set_driving_cell") )
if ( !strcmp(pToken, "default_input_cell") )
if ( !strcmp(pToken, "set_driving_cell") )
// if ( !strcmp(pToken, "default_input_cell") )
{
Abc_FrameSetDrivingCell( Abc_UtilStrsav(strtok(NULL, " \t\r\n")) );
if ( fVerbose )
printf( "Setting driving cell to be \"%s\".\n", Abc_FrameReadDrivingCell() );
}
// else if ( !strcmp(pToken, "set_load") )
else if ( !strcmp(pToken, "default_output_load") )
else if ( !strcmp(pToken, "set_load") )
// else if ( !strcmp(pToken, "default_output_load") )
{
Abc_FrameSetMaxLoad( atof(strtok(NULL, " \t\r\n")) );
if ( fVerbose )
printf( "Setting driving cell to be %f.\n", Abc_FrameReadMaxLoad() );
}
// else printf( "Unrecognized token \"%s\".\n", pToken );
else printf( "Unrecognized token \"%s\".\n", pToken );
}
fclose( pFile );
}
......
......@@ -19,6 +19,7 @@
***********************************************************************/
#include "sbdInt.h"
#include "misc/vec/vecHsh.h"
ABC_NAMESPACE_IMPL_START
......@@ -42,6 +43,68 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
int Sbd_CountConfigVars( Vec_Int_t * vSet, int nVars )
{
int i, k, Entry = 0, Entry2, Count = 0, Below;
int Prev = Vec_IntEntry( vSet, 0 );
Vec_IntForEachEntryStart( vSet, Entry, i, 1 )
{
assert( 2*Prev >= Entry );
if ( 2*Prev == Entry )
{
Prev = Entry;
continue;
}
Below = nVars;
Vec_IntForEachEntryStart( vSet, Entry2, k, i )
Below += Entry2;
Count += Below * (2*Prev - 1);
Prev = Entry;
}
Count += nVars * 2*Prev;
return Vec_IntSum(vSet) < nVars - 1 ? 0 : Count;
}
void Sbd_CountTopos()
{
Hsh_VecMan_t * p = Hsh_VecManStart( 100000 ); // hash table for arrays
Vec_Int_t * vSet = Vec_IntAlloc( 100 );
int i, k, e, Start, Stop;
Start = Hsh_VecManAdd( p, vSet );
for ( i = 1; i < 9; i++ )
{
Stop = Hsh_VecSize( p );
for ( e = Start; e < Stop; e++ )
{
Vec_Int_t * vTemp = Hsh_VecReadEntry( p, e );
Vec_IntClear( vSet );
Vec_IntAppend( vSet, vTemp );
for ( k = 0; k < Vec_IntSize(vSet); k++ )
{
// skip if the number of entries on this level is equal to the number of fanins on the previous level
if ( k ? (Vec_IntEntry(vSet, k) == 2*Vec_IntEntry(vSet, k-1)) : (Vec_IntEntry(vSet, 0) > 0) )
continue;
Vec_IntAddToEntry( vSet, k, 1 );
Hsh_VecManAdd( p, vSet );
Vec_IntAddToEntry( vSet, k, -1 );
}
Vec_IntPush( vSet, 1 );
Hsh_VecManAdd( p, vSet );
}
printf( "%2d : This = %8d All = %8d\n", i, Hsh_VecSize(p) - Stop, Hsh_VecSize(p) );
if ( 0 )
{
for ( e = Stop; e < Hsh_VecSize(p); e++ )
{
Vec_Int_t * vTemp = Hsh_VecReadEntry( p, e );
printf( "Params = %3d. ", Sbd_CountConfigVars(vTemp, 5) );
Vec_IntPrint( vTemp );
}
}
Start = Stop;
}
Vec_IntFree( vSet );
Hsh_VecManStop( p );
}
////////////////////////////////////////////////////////////////////////
......
......@@ -1539,9 +1539,37 @@ int Gia_ManPerformGla( Gia_Man_t * pAig, Abs_Par_t * pPars )
Abc_Print( 1, "LrnStart = %d LrnDelta = %d LrnRatio = %d %% Skip = %d SimpleCNF = %d Dump = %d\n",
pPars->nLearnedStart, pPars->nLearnedDelta, pPars->nLearnedPerce, pPars->fUseSkip, pPars->fUseSimple, pPars->fDumpVabs|pPars->fDumpMabs );
if ( pPars->fDumpVabs || pPars->fDumpMabs )
Abc_Print( 1, "%s will be dumped into file \"%s\".\n",
Abc_Print( 1, "%s will be continously dumped into file \"%s\".\n",
pPars->fDumpVabs ? "Abstracted model" : "Miter with abstraction map",
Ga2_GlaGetFileName(p, pPars->fDumpVabs) );
if ( pPars->fDumpMabs )
{
{
char Command[1000];
Abc_FrameSetStatus( -1 );
Abc_FrameSetCex( NULL );
Abc_FrameSetNFrames( -1 );
sprintf( Command, "write_status %s", Extra_FileNameGenericAppend((char *)(p->pPars->pFileVabs ? p->pPars->pFileVabs : "glabs.aig"), ".status"));
Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), Command );
}
{
// create trivial abstraction map
Gia_Obj_t * pObj;
char * pFileName = Ga2_GlaGetFileName(p, 0);
Vec_Int_t * vMap = pAig->vGateClasses; pAig->vGateClasses = NULL;
pAig->vGateClasses = Vec_IntStart( Gia_ManObjNum(pAig) );
Vec_IntWriteEntry( pAig->vGateClasses, 0, 1 );
Gia_ManForEachAnd( pAig, pObj, i )
Vec_IntWriteEntry( pAig->vGateClasses, i, 1 );
Gia_ManForEachRo( pAig, pObj, i )
Vec_IntWriteEntry( pAig->vGateClasses, Gia_ObjId(pAig, pObj), 1 );
Gia_AigerWrite( pAig, pFileName, 0, 0 );
Vec_IntFree( pAig->vGateClasses );
pAig->vGateClasses = vMap;
if ( p->pPars->fVerbose )
Abc_Print( 1, "Dumping miter with abstraction map into file \"%s\"...\n", pFileName );
}
}
Abc_Print( 1, " Frame %% Abs PPI FF LUT Confl Cex Vars Clas Lrns Time Mem\n" );
}
// iterate unrolling
......
......@@ -288,7 +288,7 @@ int * Pdr_ManSortByPriority( Pdr_Man_t * p, Pdr_Set_t * pCube )
best_i = i;
for ( j = i+1; j < nSize; j++ )
// if ( pArray[j] < pArray[best_i] )
if ( pPrios[pCube->Lits[pArray[j]]>>1] < pPrios[pCube->Lits[pArray[best_i]]>>1] )
if ( pPrios[pCube->Lits[pArray[j]]>>1] < pPrios[pCube->Lits[pArray[best_i]]>>1] ) // list lower priority first (these will be removed first)
best_i = j;
temp = pArray[i];
pArray[i] = pArray[best_i];
......@@ -488,7 +488,7 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred,
/**Function*************************************************************
Synopsis [Specialized sorting of flops based on cost.]
Synopsis [Specialized sorting of flops based on priority.]
Description []
......@@ -497,17 +497,171 @@ int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred,
SeeAlso []
***********************************************************************/
static inline void Vec_IntSelectSortCostReverseLit( int * pArray, int nSize, Vec_Int_t * vCosts )
static inline int Vec_IntSelectSortPrioReverseLit( int * pArray, int nSize, Vec_Int_t * vPrios )
{
int i, j, best_i;
for ( i = 0; i < nSize-1; i++ )
{
best_i = i;
for ( j = i+1; j < nSize; j++ )
if ( Vec_IntEntry(vCosts, Abc_Lit2Var(pArray[j])) > Vec_IntEntry(vCosts, Abc_Lit2Var(pArray[best_i])) )
if ( Vec_IntEntry(vPrios, Abc_Lit2Var(pArray[j])) > Vec_IntEntry(vPrios, Abc_Lit2Var(pArray[best_i])) ) // prefer higher priority
best_i = j;
ABC_SWAP( int, pArray[i], pArray[best_i] );
}
return 1;
}
/**Function*************************************************************
Synopsis [Performs generalization using a different idea.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Pdr_ManGeneralize2( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppCubeMin )
{
int fUseMinAss = 0;
sat_solver * pSat = Pdr_ManFetchSolver( p, k );
int Order = Vec_IntSelectSortPrioReverseLit( pCube->Lits, pCube->nLits, p->vPrio );
Vec_Int_t * vLits1 = Pdr_ManCubeToLits( p, k, pCube, 1, 0 );
int RetValue, Count = 0, iLit, Lits[2], nLits = Vec_IntSize( vLits1 );
// create free variables
int i, iUseVar, iAndVar;
iAndVar = Pdr_ManFreeVar(p, k);
for ( i = 1; i < nLits; i++ )
Pdr_ManFreeVar(p, k);
iUseVar = Pdr_ManFreeVar(p, k);
for ( i = 1; i < nLits; i++ )
Pdr_ManFreeVar(p, k);
assert( iUseVar == iAndVar + nLits );
// if there is only one positive literal, put it in front and always assume
if ( fUseMinAss )
{
for ( i = 0; i < pCube->nLits && Count < 2; i++ )
Count += !Abc_LitIsCompl(pCube->Lits[i]);
if ( Count == 1 )
{
for ( i = 0; i < pCube->nLits; i++ )
if ( !Abc_LitIsCompl(pCube->Lits[i]) )
break;
assert( i < pCube->nLits );
iLit = pCube->Lits[i];
for ( ; i > 0; i-- )
pCube->Lits[i] = pCube->Lits[i-1];
pCube->Lits[0] = iLit;
}
}
// add clauses for the additional AND-gates
Vec_IntForEachEntry( vLits1, iLit, i )
{
sat_solver_add_buffer_enable( pSat, iAndVar + i, Abc_Lit2Var(iLit), iUseVar + i, Abc_LitIsCompl(iLit) );
Vec_IntWriteEntry( vLits1, i, Abc_Var2Lit(iAndVar + i, 0) );
}
// add clauses for the additional OR-gate
RetValue = sat_solver_addclause( pSat, Vec_IntArray(vLits1), Vec_IntLimit(vLits1) );
assert( RetValue == 1 );
// add implications
vLits1 = Pdr_ManCubeToLits( p, k, pCube, 0, 1 );
assert( Vec_IntSize(vLits1) == nLits );
Vec_IntForEachEntry( vLits1, iLit, i )
{
Lits[0] = Abc_Var2Lit(iUseVar + i, 1);
Lits[1] = iLit;
RetValue = sat_solver_addclause( pSat, Lits, Lits+2 );
assert( RetValue == 1 );
Vec_IntWriteEntry( vLits1, i, Abc_Var2Lit(iUseVar + i, 0) );
}
sat_solver_compress( pSat );
// perform minimization
if ( fUseMinAss )
{
if ( Count == 1 ) // always assume the only positive literal
{
if ( !sat_solver_push(pSat, Vec_IntEntry(vLits1, 0)) ) // UNSAT with the first (mandatory) literal
nLits = 1;
else
nLits = 1 + sat_solver_minimize_assumptions2( pSat, Vec_IntArray(vLits1)+1, nLits-1, p->pPars->nConfLimit );
sat_solver_pop(pSat); // unassume the first literal
}
else
nLits = sat_solver_minimize_assumptions2( pSat, Vec_IntArray(vLits1), nLits, p->pPars->nConfLimit );
Vec_IntShrink( vLits1, nLits );
}
else
{
// try removing one literal at a time in the old-fashioned way
int k, Entry;
Vec_Int_t * vTemp = Vec_IntAlloc( nLits );
for ( i = nLits - 1; i >= 0; i-- )
{
// if we are about to remove a positive lit, make sure at least one positive lit remains
if ( !Abc_LitIsCompl(Vec_IntEntry(vLits1, i)) )
{
Vec_IntForEachEntry( vLits1, iLit, k )
if ( iLit != -1 && k != i && !Abc_LitIsCompl(iLit) )
break;
if ( k == Vec_IntSize(vLits1) ) // no other positive literals, except the i-th one
continue;
}
// load remaining literals
Vec_IntClear( vTemp );
Vec_IntForEachEntry( vLits1, Entry, k )
if ( Entry != -1 && k != i )
Vec_IntPush( vTemp, Entry );
else if ( Entry != -1 ) // assume opposite literal
Vec_IntPush( vTemp, Abc_LitNot(Entry) );
// solve with assumptions
RetValue = sat_solver_solve( pSat, Vec_IntArray(vTemp), Vec_IntLimit(vTemp), p->pPars->nConfLimit, 0, 0, 0 );
// commit the literal
if ( RetValue == l_False )
{
int LitNot = Abc_LitNot(Vec_IntEntry(vLits1, i));
int RetValue = sat_solver_addclause( pSat, &LitNot, &LitNot+1 );
assert( RetValue );
}
// update the clause
if ( RetValue == l_False )
Vec_IntWriteEntry( vLits1, i, -1 );
}
Vec_IntFree( vTemp );
// compact
k = 0;
Vec_IntForEachEntry( vLits1, Entry, i )
if ( Entry != -1 )
Vec_IntWriteEntry( vLits1, k++, Entry );
Vec_IntShrink( vLits1, k );
}
// remap auxiliary literals into original literals
Vec_IntForEachEntry( vLits1, iLit, i )
Vec_IntWriteEntry( vLits1, i, pCube->Lits[Abc_Lit2Var(iLit)-iUseVar] );
// make sure the cube has at least one positive literal
if ( fUseMinAss )
{
Vec_IntForEachEntry( vLits1, iLit, i )
if ( !Abc_LitIsCompl(iLit) )
break;
if ( i == Vec_IntSize(vLits1) ) // has no positive literals
{
// find positive lit in the cube
for ( i = 0; i < pCube->nLits; i++ )
if ( !Abc_LitIsCompl(pCube->Lits[i]) )
break;
assert( i < pCube->nLits );
Vec_IntPush( vLits1, pCube->Lits[i] );
// printf( "-" );
}
// else
// printf( "+" );
}
// create a subset cube
*ppCubeMin = Pdr_SetCreateSubset( pCube, Vec_IntArray(vLits1), Vec_IntSize(vLits1) );
assert( !Pdr_SetIsInit(*ppCubeMin, -1) );
Order = 0;
return 0;
}
/**Function*************************************************************
......@@ -532,7 +686,7 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP
// if there is no induction, return
*ppCubeMin = NULL;
if ( p->pPars->fFlopOrder )
Vec_IntSelectSortCostReverseLit( pCube->Lits, pCube->nLits, p->vPrio );
Vec_IntSelectSortPrioReverseLit( pCube->Lits, pCube->nLits, p->vPrio );
RetValue = Pdr_ManCheckCube( p, k, pCube, ppPred, p->pPars->nConfLimit, 0, 1 );
if ( p->pPars->fFlopOrder )
Vec_IntSelectSort( pCube->Lits, pCube->nLits );
......@@ -544,14 +698,37 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP
return 0;
}
keep = p->pPars->fSkipDown ? NULL : Hash_IntAlloc( 1 );
// reduce clause using assumptions
// pCubeMin = Pdr_SetDup( pCube );
pCubeMin = Pdr_ManReduceClause( p, k, pCube );
if ( pCubeMin == NULL )
pCubeMin = Pdr_SetDup( pCube );
// perform simplified generalization
if ( p->pPars->fSimpleGeneral )
{
assert( pCubeMin->nLits > 0 );
if ( pCubeMin->nLits > 1 )
{
RetValue = Pdr_ManGeneralize2( p, k, pCubeMin, ppCubeMin );
Pdr_SetDeref( pCubeMin );
assert( ppCubeMin != NULL );
pCubeMin = *ppCubeMin;
}
*ppCubeMin = pCubeMin;
if ( p->pPars->fVeryVerbose )
{
printf("Cube:\n");
for ( i = 0; i < pCubeMin->nLits; i++)
printf ("%d ", pCubeMin->Lits[i]);
printf("\n");
}
p->tGeneral += Abc_Clock() - clk;
return 1;
}
keep = p->pPars->fSkipDown ? NULL : Hash_IntAlloc( 1 );
// perform generalization
if ( !p->pPars->fSkipGeneral )
{
......@@ -691,9 +868,7 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP
{
printf("Cube:\n");
for ( i = 0; i < pCubeMin->nLits; i++)
{
printf ("%d ", pCubeMin->Lits[i]);
}
printf("\n");
}
*ppCubeMin = pCubeMin;
......
......@@ -190,6 +190,21 @@ sat_solver * IPdr_ManSetSolver( Pdr_Man_t * p, int k, int nTotal )
SeeAlso []
***********************************************************************/
int IPdr_ManRestoreAbsFlops( Pdr_Man_t * p )
{
Pdr_Set_t * pSet; int i, j, k;
Vec_VecForEachEntry( Pdr_Set_t *, p->vClauses, pSet, i, j )
{
for ( k = 0; k < pSet->nLits; k++ )
{
Vec_IntWriteEntry( p->vAbsFlops, Abc_Lit2Var(pSet->Lits[k]), 1 );
}
}
return 0;
}
int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses, Vec_Int_t * vMap )
{
int i;
......@@ -288,6 +303,17 @@ int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPushClauses )
return 1;
}
}
if ( p->pPars->fUseAbs && p->vAbsFlops == NULL && iFrame >= 1 )
{
assert( p->vAbsFlops == NULL );
p->vAbsFlops = Vec_IntStart( Saig_ManRegNum(p->pAig) );
p->vMapFf2Ppi = Vec_IntStartFull( Saig_ManRegNum(p->pAig) );
p->vMapPpi2Ff = Vec_IntAlloc( 100 );
IPdr_ManRestoreAbsFlops( p );
}
}
while ( 1 )
{
......@@ -442,6 +468,9 @@ int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPushClauses )
break; // keep solving
}
p->pAig->pSeqModel = pCex;
if ( p->pPars->fVerbose && p->pPars->fUseAbs )
Pdr_ManPrintProgress( p, !p->pPars->fSolveAll, Abc_Clock() - clkStart );
return 0; // SAT
}
p->pPars->nFailOuts++;
......@@ -491,6 +520,7 @@ int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPushClauses )
p->timeToStopOne = 0;
}
}
/*
if ( p->pPars->fUseAbs && p->vAbsFlops && !fRefined )
{
int i, Used;
......@@ -498,6 +528,17 @@ int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPushClauses )
if ( Used && (Vec_IntEntry(p->vPrio, i) >> p->nPrioShift) == 0 )
Vec_IntWriteEntry( p->vAbsFlops, i, 0 );
}
*/
if ( p->pPars->fUseAbs && p->vAbsFlops && !fRefined )
{
Pdr_Set_t * pSet;
int i, j, k;
Vec_IntFill( p->vAbsFlops, Vec_IntSize( p->vAbsFlops ), 0 );
Vec_VecForEachEntry( Pdr_Set_t *, p->vClauses, pSet, i, j )
for ( k = 0; k < pSet->nLits; k++ )
Vec_IntWriteEntry( p->vAbsFlops, Abc_Lit2Var(pSet->Lits[k]), 1 );
}
if ( p->pPars->fVerbose )
Pdr_ManPrintProgress( p, !fRefined, Abc_Clock() - clkStart );
if ( fRefined )
......
......@@ -353,11 +353,37 @@ int Bmc_CollapseIrredundantFull( Vec_Str_t * vSop, int nCubes, int nVars )
SeeAlso []
***********************************************************************/
int Bmc_CollapseExpandRound2( sat_solver * pSat, Vec_Int_t * vLits, Vec_Int_t * vTemp, int nBTLimit, int fOnOffSetLit )
{
// put into new array
int i, iLit, nLits;
Vec_IntClear( vTemp );
Vec_IntForEachEntry( vLits, iLit, i )
if ( iLit != -1 )
Vec_IntPush( vTemp, iLit );
assert( Vec_IntSize(vTemp) > 0 );
// assume condition literal
if ( fOnOffSetLit >= 0 )
sat_solver_push( pSat, fOnOffSetLit );
// minimize
nLits = sat_solver_minimize_assumptions( pSat, Vec_IntArray(vTemp), Vec_IntSize(vTemp), nBTLimit );
Vec_IntShrink( vTemp, nLits );
// assume conditional literal
if ( fOnOffSetLit >= 0 )
sat_solver_pop( pSat );
// modify output literas
Vec_IntForEachEntry( vLits, iLit, i )
if ( iLit != -1 && Vec_IntFind(vTemp, iLit) == -1 )
Vec_IntWriteEntry( vLits, i, -1 );
return 0;
}
int Bmc_CollapseExpandRound( sat_solver * pSat, sat_solver * pSatOn, Vec_Int_t * vLits, Vec_Int_t * vNums, Vec_Int_t * vTemp, int nBTLimit, int fCanon, int fOnOffSetLit )
{
int fProfile = 0;
int k, n, iLit, status;
abctime clk;
//return Bmc_CollapseExpandRound2( pSat, vLits, vTemp, nBTLimit, fOnOffSetLit );
// try removing one literal at a time
for ( k = Vec_IntSize(vLits) - 1; k >= 0; k-- )
{
......
......@@ -2168,6 +2168,153 @@ int sat_solver_solve_lexsat( sat_solver* s, int * pLits, int nLits )
return status;
}
// This procedure is called on a set of assumptions to minimize their number.
// The procedure relies on the fact that the current set of assumptions is UNSAT.
// It receives and returns SAT solver without assumptions. It returns the number
// of assumptions after minimization. The set of assumptions is returned in pLits.
int sat_solver_minimize_assumptions( sat_solver* s, int * pLits, int nLits, int nConfLimit )
{
int i, k, nLitsL, nLitsR, nResL, nResR;
if ( nLits == 1 )
{
// since the problem is UNSAT, we will try to solve it without assuming the last literal
// if the result is UNSAT, the last literal can be dropped; otherwise, it is needed
int status = l_False;
int Temp = s->nConfLimit;
s->nConfLimit = nConfLimit;
status = sat_solver_solve_internal( s );
s->nConfLimit = Temp;
return (int)(status != l_False); // return 1 if the problem is not UNSAT
}
assert( nLits >= 2 );
nLitsL = nLits / 2;
nLitsR = nLits - nLitsL;
// assume the left lits
for ( i = 0; i < nLitsL; i++ )
if ( !sat_solver_push(s, pLits[i]) )
{
for ( k = i; k >= 0; k-- )
sat_solver_pop(s);
return sat_solver_minimize_assumptions( s, pLits, i+1, nConfLimit );
}
// solve for the right lits
nResL = sat_solver_minimize_assumptions( s, pLits + nLitsL, nLitsR, nConfLimit );
for ( i = 0; i < nLitsL; i++ )
sat_solver_pop(s);
// swap literals
// assert( nResL <= nLitsL );
// for ( i = 0; i < nResL; i++ )
// ABC_SWAP( int, pLits[i], pLits[nLitsL+i] );
veci_resize( &s->temp_clause, 0 );
for ( i = 0; i < nLitsL; i++ )
veci_push( &s->temp_clause, pLits[i] );
for ( i = 0; i < nResL; i++ )
pLits[i] = pLits[nLitsL+i];
for ( i = 0; i < nLitsL; i++ )
pLits[nResL+i] = veci_begin(&s->temp_clause)[i];
// assume the right lits
for ( i = 0; i < nResL; i++ )
if ( !sat_solver_push(s, pLits[i]) )
{
for ( k = i; k >= 0; k-- )
sat_solver_pop(s);
return sat_solver_minimize_assumptions( s, pLits, i+1, nConfLimit );
}
// solve for the left lits
nResR = sat_solver_minimize_assumptions( s, pLits + nResL, nLitsL, nConfLimit );
for ( i = 0; i < nResL; i++ )
sat_solver_pop(s);
return nResL + nResR;
}
// This is a specialized version of the above procedure with several custom changes:
// - makes sure that at least one of the marked literals is preserved in the clause
// - sets literals to zero when they do not have to be used
// - sets literals to zero for disproved variables
int sat_solver_minimize_assumptions2( sat_solver* s, int * pLits, int nLits, int nConfLimit )
{
int i, k, nLitsL, nLitsR, nResL, nResR;
if ( nLits == 1 )
{
// since the problem is UNSAT, we will try to solve it without assuming the last literal
// if the result is UNSAT, the last literal can be dropped; otherwise, it is needed
int RetValue = 1, LitNot = Abc_LitNot(pLits[0]);
int status = l_False;
int Temp = s->nConfLimit;
s->nConfLimit = nConfLimit;
RetValue = sat_solver_push( s, LitNot ); assert( RetValue );
status = sat_solver_solve_internal( s );
sat_solver_pop( s );
// if the problem is UNSAT, add clause
if ( status == l_False )
{
RetValue = sat_solver_addclause( s, &LitNot, &LitNot+1 );
assert( RetValue );
}
s->nConfLimit = Temp;
return (int)(status != l_False); // return 1 if the problem is not UNSAT
}
assert( nLits >= 2 );
nLitsL = nLits / 2;
nLitsR = nLits - nLitsL;
// assume the left lits
for ( i = 0; i < nLitsL; i++ )
if ( !sat_solver_push(s, pLits[i]) )
{
for ( k = i; k >= 0; k-- )
sat_solver_pop(s);
// add clauses for these literal
for ( k = i+1; k > nLitsL; k++ )
{
int LitNot = Abc_LitNot(pLits[i]);
int RetValue = sat_solver_addclause( s, &LitNot, &LitNot+1 );
assert( RetValue );
}
return sat_solver_minimize_assumptions2( s, pLits, i+1, nConfLimit );
}
// solve for the right lits
nResL = sat_solver_minimize_assumptions2( s, pLits + nLitsL, nLitsR, nConfLimit );
for ( i = 0; i < nLitsL; i++ )
sat_solver_pop(s);
// swap literals
// assert( nResL <= nLitsL );
veci_resize( &s->temp_clause, 0 );
for ( i = 0; i < nLitsL; i++ )
veci_push( &s->temp_clause, pLits[i] );
for ( i = 0; i < nResL; i++ )
pLits[i] = pLits[nLitsL+i];
for ( i = 0; i < nLitsL; i++ )
pLits[nResL+i] = veci_begin(&s->temp_clause)[i];
// assume the right lits
for ( i = 0; i < nResL; i++ )
if ( !sat_solver_push(s, pLits[i]) )
{
for ( k = i; k >= 0; k-- )
sat_solver_pop(s);
// add clauses for these literal
for ( k = i+1; k > nResL; k++ )
{
int LitNot = Abc_LitNot(pLits[i]);
int RetValue = sat_solver_addclause( s, &LitNot, &LitNot+1 );
assert( RetValue );
}
return sat_solver_minimize_assumptions2( s, pLits, i+1, nConfLimit );
}
// solve for the left lits
nResR = sat_solver_minimize_assumptions2( s, pLits + nResL, nLitsL, nConfLimit );
for ( i = 0; i < nResL; i++ )
sat_solver_pop(s);
return nResL + nResR;
}
int sat_solver_nvars(sat_solver* s)
{
......
......@@ -50,6 +50,8 @@ extern int sat_solver_simplify(sat_solver* s);
extern int sat_solver_solve(sat_solver* s, lit* begin, lit* end, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, ABC_INT64_T nConfLimitGlobal, ABC_INT64_T nInsLimitGlobal);
extern int sat_solver_solve_internal(sat_solver* s);
extern int sat_solver_solve_lexsat(sat_solver* s, int * pLits, int nLits);
extern int sat_solver_minimize_assumptions( sat_solver* s, int * pLits, int nLits, int nConfLimit );
extern int sat_solver_minimize_assumptions2( sat_solver* s, int * pLits, int nLits, int nConfLimit );
extern int sat_solver_push(sat_solver* s, int p);
extern void sat_solver_pop(sat_solver* s);
extern void sat_solver_set_resource_limits(sat_solver* s, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, ABC_INT64_T nConfLimitGlobal, ABC_INT64_T nInsLimitGlobal);
......
......@@ -59,5 +59,19 @@ static inline void clause_print(struct clause *clause)
printf("}\n");
}
static inline void clause_dump(FILE *file, struct clause *clause, int no_zero_var)
{
unsigned i;
for (i = 0; i < clause->size; i++) {
int var = (clause->data[i].lit >> 1);
char pol = (clause->data[i].lit & 1);
fprintf(file, "%d ", pol ? -(var + no_zero_var) : (var + no_zero_var));
}
if (no_zero_var)
fprintf(file, "0\n");
else
fprintf(file, "\n");
}
ABC_NAMESPACE_HEADER_END
#endif /* satoko__clause_h */
......@@ -150,7 +150,7 @@ int satoko_parse_dimacs(char *fname, satoko_t **solver)
vec_uint_free(lits);
satoko_free(buffer);
*solver = p;
return satoko_simplify(p);
return SATOKO_OK;
}
ABC_NAMESPACE_IMPL_END
......@@ -60,6 +60,7 @@ struct satoko_opts {
unsigned clause_min_lbd_bin_resol;
float garbage_max_ratio;
char verbose;
char no_simplify;
};
typedef struct satoko_stats satoko_stats_t;
......@@ -108,6 +109,16 @@ extern void satoko_unbookmark(satoko_t *);
*/
extern int satoko_final_conflict(satoko_t *, unsigned *);
/* Procedure to dump a DIMACS file.
* - It receives as input the solver, a file name string and two integers.
* - If the file name string is NULL the solver will dump in stdout.
* - The first argument can be either 0 or 1 and is an option to dump learnt
* clauses. (value 1 will dump them).
* - The seccond argument can be either 0 or 1 and is an option to use 0 as a
* variable ID or not. Keep in mind that if 0 is used as an ID the generated
* file will not be a DIMACS. (value 1 will use 0 as ID).
*/
extern void satoko_write_dimacs(satoko_t *, char *, int, int);
extern satoko_stats_t satoko_stats(satoko_t *);
ABC_NAMESPACE_HEADER_END
......
......@@ -644,7 +644,7 @@ char solver_search(solver_t *s)
solver_cancel_until(s, 0);
return SATOKO_UNDEC;
}
if (solver_dlevel(s) == 0)
if (!s->opts.no_simplify && solver_dlevel(s) == 0)
satoko_simplify(s);
/* Reduce the set of learnt clauses */
......
......@@ -152,6 +152,7 @@ void satoko_default_opts(satoko_opts_t *opts)
{
memset(opts, 0, sizeof(satoko_opts_t));
opts->verbose = 0;
opts->no_simplify = 0;
/* Limits */
opts->conf_limit = 0;
opts->prop_limit = 0;
......@@ -290,6 +291,10 @@ int satoko_solve(solver_t *s)
//if (s->opts.verbose)
// print_opts(s);
if (!s->opts.no_simplify)
if (satoko_simplify(s) != SATOKO_OK)
return SATOKO_UNDEC;
while (status == SATOKO_UNDEC) {
status = solver_search(s);
if (solver_check_limits(s) == 0)
......@@ -297,6 +302,7 @@ int satoko_solve(solver_t *s)
}
if (s->opts.verbose)
print_stats(s);
solver_cancel_until(s, vec_uint_size(s->assumptions));
return status;
}
......@@ -309,7 +315,6 @@ int satoko_final_conflict(solver_t *s, unsigned *out)
memcpy(out, vec_uint_data(s->final_conflict),
sizeof(unsigned) * vec_uint_size(s->final_conflict));
return vec_uint_size(s->final_conflict);
}
satoko_stats_t satoko_stats(satoko_t *s)
......@@ -324,6 +329,7 @@ void satoko_bookmark(satoko_t *s)
s->book_cl_lrnt = vec_uint_size(s->learnts);
s->book_vars = vec_char_size(s->assigns);
s->book_trail = vec_uint_size(s->trail);
s->opts.no_simplify = 1;
}
void satoko_unbookmark(satoko_t *s)
......@@ -333,6 +339,7 @@ void satoko_unbookmark(satoko_t *s)
s->book_cdb = 0;
s->book_vars = 0;
s->book_trail = 0;
s->opts.no_simplify = 0;
}
void satoko_reset(satoko_t *s)
......@@ -442,4 +449,43 @@ void satoko_unmark_cone(satoko_t *s, int *pvars, int n_vars)
var_clean_mark(s, pvars[i]);
}
void satoko_write_dimacs(satoko_t *s, char *fname, int wrt_lrnt, int zero_var)
{
FILE *file;
unsigned i;
unsigned n_vars = vec_act_size(s->activity);
unsigned n_orig = vec_uint_size(s->originals) + vec_uint_size(s->assumptions);
unsigned n_lrnts = vec_uint_size(s->learnts);
unsigned *array;
assert(wrt_lrnt == 0 || wrt_lrnt == 1);
assert(zero_var == 0 || zero_var == 1);
if (fname != NULL)
file = fopen(fname, "w");
else
file = stdout;
if (file == NULL) {
printf( "Error: Cannot open output file.\n");
return;
}
fprintf(file, "p cnf %d %d\n", n_vars, wrt_lrnt ? n_orig + n_lrnts : n_orig);
array = vec_uint_data(s->assumptions);
for (i = 0; i < vec_uint_size(s->assumptions); i++)
fprintf(file, "%d\n", array[i] & 1 ? -(array[i] + !zero_var) : array[i] + !zero_var);
array = vec_uint_data(s->originals);
for (i = 0; i < vec_uint_size(s->originals); i++)
clause_dump(file, clause_read(s, array[i]), !zero_var);
if (wrt_lrnt) {
printf(" Lertns %u", n_lrnts);
array = vec_uint_data(s->learnts);
for (i = 0; i < n_lrnts; i++)
clause_dump(file, clause_read(s, array[i]), !zero_var);
}
}
ABC_NAMESPACE_IMPL_END
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment